|
7 | 7 |
|
8 | 8 | from api.cas.cas_module import CasModule |
9 | 9 | from core.test_run import TestRun |
10 | | -from test_utils.size import Unit |
| 10 | +from test_utils.size import Unit, Size |
11 | 11 | from test_utils.os_utils import (allocate_memory, |
12 | 12 | defaultize_memory_affecting_functions, |
13 | 13 | disable_memory_affecting_functions, |
|
16 | 16 | is_kernel_module_loaded, |
17 | 17 | load_kernel_module, |
18 | 18 | unload_kernel_module, |
19 | | - unmount_ramfs) |
| 19 | + unmount_ramfs, |
| 20 | + get_dut_cpu_number) |
| 21 | + |
| 22 | + |
| 23 | +@pytest.mark.os_dependent |
| 24 | +def test_cas_module_memory_usage(): |
| 25 | + """ |
| 26 | + title: Validate OpenCAS kernel module memory usage. |
| 27 | + description: | |
| 28 | + Check that OpenCAS kernel module memory usage is in acceptable limits. |
| 29 | + pass_criteria: | |
| 30 | + - Loaded OpenCAS kernel module should not consume more than 110% of total memory |
| 31 | + calculated by requirement formula: |
| 32 | + 7.5 MiB * active CPUs number |
| 33 | + """ |
| 34 | + with TestRun.step("Disable caching and memory over-committing."): |
| 35 | + disable_memory_affecting_functions() |
| 36 | + drop_caches() |
| 37 | + |
| 38 | + with TestRun.step("Measure memory usage without OpenCAS module."): |
| 39 | + if is_kernel_module_loaded(CasModule.cache.value): |
| 40 | + unload_kernel_module(CasModule.cache.value) |
| 41 | + unload_kernel_module(CasModule.disk.value) |
| 42 | + available_mem_before_cas = get_free_memory() |
| 43 | + |
| 44 | + with TestRun.step("Load OpenCAS module"): |
| 45 | + output = load_kernel_module(CasModule.cache.value) |
| 46 | + if output.exit_code != 0: |
| 47 | + TestRun.fail("Cannot load OpenCAS module!") |
| 48 | + |
| 49 | + with TestRun.step("Measure memory usage with OpenCAS module."): |
| 50 | + available_mem_with_cas = get_free_memory() |
| 51 | + memory_used_by_cas = available_mem_before_cas - available_mem_with_cas |
| 52 | + TestRun.LOGGER.info( |
| 53 | + f"OpenCAS module uses {memory_used_by_cas.get_value(Unit.MiB):.2f} MiB of DRAM." |
| 54 | + ) |
| 55 | + |
| 56 | + with TestRun.step("Validate amount of memory used by OpenCAS module"): |
| 57 | + expected_memory_used = Size(7.5 * get_dut_cpu_number(), Unit.MiB) |
| 58 | + TestRun.LOGGER.info( |
| 59 | + f"Expected module memory consumption:" |
| 60 | + f" {expected_memory_used.get_value(Unit.MiB):.2f} MiB of DRAM." |
| 61 | + ) |
| 62 | + requirement_fulfillment_ratio = ( |
| 63 | + memory_used_by_cas.get_value() / expected_memory_used.get_value() |
| 64 | + ) |
| 65 | + TestRun.LOGGER.info(f"Actual to expected usage ratio: {requirement_fulfillment_ratio:.2f}") |
| 66 | + if requirement_fulfillment_ratio > 1.1: |
| 67 | + if requirement_fulfillment_ratio < 1.4: |
| 68 | + TestRun.LOGGER.warning("Memory usage corresponds to required limit " |
| 69 | + "(between 110-140%% of expected value)") |
| 70 | + else: |
| 71 | + TestRun.LOGGER.error("Memory usage exceeded required limit " |
| 72 | + "(over 140% of expected value)") |
| 73 | + elif requirement_fulfillment_ratio < 0.8: |
| 74 | + TestRun.LOGGER.warning("Memory usage is strangely small (below 80% of expected value)") |
| 75 | + else: |
| 76 | + TestRun.LOGGER.info("Memory usage corresponds to required limit") |
20 | 77 |
|
21 | 78 |
|
22 | 79 | @pytest.mark.os_dependent |
|
0 commit comments