def test_cli_start_stop_default_value(shortcut): with TestRun.LOGGER.step("Prepare devices"): cache_device = TestRun.disks['cache'] cache_device.create_partitions([Size(500, Unit.MebiByte)]) cache_device = cache_device.partitions[0] with TestRun.LOGGER.step("Start cache"): casadm.start_cache(cache_device, shortcut=shortcut, force=True) with TestRun.LOGGER.step("Check if cache started successfully"): caches = casadm_parser.get_caches() if len(caches) != 1: TestRun.LOGGER.error( f"There is wrong caches count found in OS: {len(caches)}") if caches[0].cache_device.system_path != cache_device.system_path: TestRun.LOGGER.error(f"Cache started using wrong device: " f"{caches[0].cache_device.system_path}. " f"Should be {cache_device.system_path}") with TestRun.LOGGER.step("Stop cache"): casadm.stop_cache(cache_id=caches[0].cache_id, shortcut=shortcut) with TestRun.LOGGER.step("Check if cache stopped properly"): output = casadm.list_caches(shortcut=shortcut) caches = casadm_parser.get_caches() if len(caches) != 0: TestRun.LOGGER.error( f"There is wrong caches count found in OS: {len(caches)}. " f"Should be 0.") if output.stdout != "No caches running": TestRun.LOGGER.error( "There is no 'No caches running' info in casadm -L output")
def test_stress_load(cache_mode): """ title: Stress test for stopping and loading CAS device. description: | Validate the ability of the CAS to load and stop cache in the loop using different cache modes. pass_criteria: - No system crash while stop and load cache in the loop. - CAS device loads successfully. """ with TestRun.step("Prepare cache and core."): cache_dev, core_dev = prepare() with TestRun.step("Start cache and add core."): cache = casadm.start_cache(cache_dev, cache_mode, force=True) casadm.add_core(cache, core_dev) for _ in TestRun.iteration(range(0, iterations_per_config), f"Stop cache and load it {iterations_per_config} times."): with TestRun.step("Stop cache."): casadm.stop_cache(cache.cache_id) if len(casadm_parser.get_caches()) != 0: TestRun.fail("Cache did not stop successfully.") with TestRun.step("Load cache."): casadm.load_cache(cache_dev) caches_count = len(casadm_parser.get_caches()) if caches_count != 1: TestRun.fail( f"Cache did not load successfully - wrong number of caches: {caches_count}.") cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != 1: TestRun.LOGGER.error(f"Cache loaded with wrong cores count: {cores_count}.") with TestRun.step("Stop all caches."): casadm.stop_all_caches()
def test_cli_add_remove_default_value(shortcut): cache_device = TestRun.disks['cache'] cache_device.create_partitions([Size(500, Unit.MebiByte)]) cache_device = cache_device.partitions[0] cache = casadm.start_cache(cache_device, shortcut=shortcut, force=True) core_device = TestRun.disks['core'] casadm.add_core(cache, core_device, shortcut=shortcut) caches = casadm_parser.get_caches() assert len(caches[0].get_core_devices()) == 1 assert caches[0].get_core_devices( )[0].core_device.system_path == core_device.system_path casadm.remove_core(cache.cache_id, 1, shortcut=shortcut) caches = casadm_parser.get_caches() assert len(caches) == 1 assert len(caches[0].get_core_devices()) == 0 casadm.stop_cache(cache_id=cache.cache_id, shortcut=shortcut) output = casadm.list_caches(shortcut=shortcut) caches = casadm_parser.get_caches() assert len(caches) == 0 assert output.stdout == "No caches running"
def test_stress_reload_cache(cache_mode): """ title: Stress test for reloading cache with simple data integrity check. description: | Validate the ability of CAS to reload cache in the loop with no data corruption. pass_criteria: - No system crash while reloading cache. - CAS device loads successfully. - No data corruption. """ with TestRun.step("Prepare cache and core. Create test file and count it's checksum."): cache, core, md5_before_load, size_before_load, permissions_before_load = \ prepare_with_file_creation(cache_mode) for _ in TestRun.iteration(range(0, iterations_per_config), f"Stop and load cache {iterations_per_config} times."): with TestRun.step("Stop cache."): cache.stop() caches_count = len(casadm_parser.get_caches()) if caches_count != 0: TestRun.fail(f"Expected caches count: 0; Actual caches count: {caches_count}.") with TestRun.step("Load cache."): cache = casadm.load_cache(cache.cache_device) caches_count = len(casadm_parser.get_caches()) if caches_count != 1: TestRun.fail(f"Expected caches count: 1; Actual caches count: {caches_count}.") cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != 1: TestRun.fail(f"Expected cores count: 1; Actual cores count: {cores_count}.") with TestRun.step("Check md5 of test file."): check_files(core, size_before_load, permissions_before_load, md5_before_load) with TestRun.step("Stop all caches."): casadm.stop_all_caches()
def test_cli_add_remove_default_value(shortcut): cache_device = TestRun.disks['cache'] cache_device.create_partitions([Size(50, Unit.MebiByte)]) cache_device = cache_device.partitions[0] cache = casadm.start_cache(cache_device, shortcut=shortcut, force=True) core_device = TestRun.disks['core'] casadm.add_core(cache, core_device, shortcut=shortcut) caches = casadm_parser.get_caches() if len(caches[0].get_core_devices()) != 1: TestRun.fail("One core should be present in cache") if caches[0].get_core_devices( )[0].core_device.system_path != core_device.system_path: TestRun.fail("Core path should equal to path of core added") casadm.remove_core(cache.cache_id, 1, shortcut=shortcut) caches = casadm_parser.get_caches() if len(caches) != 1: TestRun.fail("One cache should be present still after removing core") if len(caches[0].get_core_devices()) != 0: TestRun.fail("No core devices should be present after removing core") casadm.stop_cache(cache_id=cache.cache_id, shortcut=shortcut) output = casadm.list_caches(shortcut=shortcut) caches = casadm_parser.get_caches() if len(caches) != 0: TestRun.fail("No cache should be present after stopping the cache") if output.stdout != "No caches running": TestRun.fail( f"Invalid message, expected 'No caches running', got {output.stdout}" )
def test_stress_start(cache_mode): """ title: Stress test for starting and stopping cache. description: Validate the ability of CAS to start and stop cache in the loop. pass_criteria: - No system crash while starting and stopping cache in the loop. - Cache starts and stops successfully. """ with TestRun.step("Prepare cache and core."): cache_dev, core_dev = prepare() for _ in TestRun.iteration(range(0, iterations_per_config), f"Start and stop CAS {iterations_per_config} times."): with TestRun.step("Start cache."): cache = casadm.start_cache(cache_dev, cache_mode, force=True) caches_count = len(casadm_parser.get_caches()) if caches_count != 1: TestRun.fail(f"Expected caches count: 1; Actual caches count: {caches_count}.") with TestRun.step("Add core."): cache.add_core(core_dev) cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != 1: TestRun.fail(f"Expected cores count: 1; Actual cores count: {cores_count}.") with TestRun.step("Stop cache."): cache.stop() caches_count = len(casadm_parser.get_caches()) if caches_count != 0: TestRun.fail(f"Expected caches count: 0; Actual caches count: {caches_count}.") with TestRun.step("Stop all caches."): casadm.stop_all_caches()
def test_cli_add_remove_default_value(prepare_and_cleanup, shortcut): prepare() cache_device = next(disk for disk in TestRun.dut.disks if disk.disk_type == DiskType.optane) cache_device.create_partitions([Size(500, Unit.MebiByte)]) cache_device = cache_device.partitions[0] cache = casadm.start_cache(cache_device, shortcut=shortcut, force=True) core_device = next(disk for disk in TestRun.dut.disks if disk.disk_type != DiskType.optane) casadm.add_core(cache, core_device, shortcut=shortcut) caches = casadm_parser.get_caches() assert len(caches[0].get_core_devices()) == 1 assert caches[0].get_core_devices( )[0].core_device.system_path == core_device.system_path casadm.remove_core(cache.cache_id, 1, shortcut=shortcut) caches = casadm_parser.get_caches() assert len(caches) == 1 assert len(caches[0].get_core_devices()) == 0 casadm.stop_cache(cache_id=cache.cache_id, shortcut=shortcut) output = casadm.list_caches(shortcut=shortcut) caches = casadm_parser.get_caches() assert len(caches) == 0 assert output.stdout == "No caches running"
def test_cli_add_remove_custom_id(shortcut): """ title: Test for adding and removing a core with a custom ID - short and long command description: | Start a new cache and add a core to it with passing a random core ID (from allowed pool) as an argument and then remove this core from the cache. pass_criteria: - The core is added to the cache with a default ID - The core is successfully removed from the cache """ with TestRun.step("Prepare the devices."): cache_disk = TestRun.disks['cache'] cache_disk.create_partitions([Size(50, Unit.MebiByte)]) cache_device = cache_disk.partitions[0] core_device = TestRun.disks['core'] with TestRun.step("Start the cache and add the core with a random ID."): core_id = randint(*CORE_ID_RANGE) cache = casadm.start_cache(cache_device, shortcut=shortcut, force=True) core = casadm.add_core(cache, core_device, core_id=core_id, shortcut=shortcut) TestRun.LOGGER.info(f"Core ID: {core_id}") with TestRun.step("Check if the core is added to the cache."): caches = casadm_parser.get_caches() if len(caches[0].get_core_devices()) != 1: TestRun.fail("One core should be present in the cache.") if caches[0].get_core_devices()[0].path != core.path: TestRun.fail( "The core path should be equal to the path of the core added.") with TestRun.step("Remove the core from the cache."): casadm.remove_core(cache.cache_id, core.core_id, shortcut=shortcut) with TestRun.step( "Check if the core is successfully removed from still running cache." ): caches = casadm_parser.get_caches() if len(caches) != 1: TestRun.fail( "One cache should be still present after removing the core.") if len(caches[0].get_core_devices()) != 0: TestRun.fail( "No core device should be present after removing the core.") with TestRun.step("Stop the cache."): casadm.stop_cache(cache_id=cache.cache_id, shortcut=shortcut) with TestRun.step("Check if the cache has successfully stopped."): caches = casadm_parser.get_caches() if len(caches) != 0: TestRun.fail( "No cache should be present after stopping the cache.") output = casadm.list_caches(shortcut=shortcut) cli_messages.check_stdout_msg(output, cli_messages.no_caches_running)
def test_load_cache_with_mounted_core(cache_mode): """ title: Fault injection test for adding mounted core on cache load. description: | Negative test of the ability of CAS to add to cache while its loading core device which is mounted. pass_criteria: - No system crash while loading cache. - Adding mounted core while loading cache fails. """ with TestRun.step("Prepare cache and core devices. Start CAS."): cache_dev = TestRun.disks['cache'] cache_dev.create_partitions([Size(1, Unit.GibiByte)]) cache_part = cache_dev.partitions[0] core_dev = TestRun.disks['core'] core_dev.create_partitions([Size(4, Unit.GibiByte)]) core_part = core_dev.partitions[0] cache = casadm.start_cache(cache_part, cache_mode, force=True) with TestRun.step("Add core device with xfs filesystem to cache and mount it."): core_part.create_filesystem(Filesystem.xfs) core = cache.add_core(core_part) core.mount(mount_point) with TestRun.step(f"Create test file in mount point of exported object and check its md5 sum."): test_file = fs_utils.create_random_test_file(test_file_path) test_file_md5_before = test_file.md5sum() with TestRun.step("Unmount core device."): core.unmount() with TestRun.step("Stop cache."): cache.stop() caches_count = len(casadm_parser.get_caches()) if caches_count != 0: TestRun.fail(f"Expected caches count: 0; Actual caches count: {caches_count}.") with TestRun.step("Mount core device."): core_part.mount(mount_point) with TestRun.step("Try to load cache."): cache = casadm.load_cache(cache.cache_device) caches_count = len(casadm_parser.get_caches()) if caches_count != 1: TestRun.fail(f"Expected caches count: 1 Actual caches count: {caches_count}.") cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != 0: TestRun.fail(f"Expected cores count: 0; Actual cores count: {cores_count}.") with TestRun.step("Check md5 sum of test file again."): if test_file_md5_before != test_file.md5sum(): TestRun.LOGGER.error("Md5 sum of test file is different.") core_part.unmount() with TestRun.step("Stop cache."): casadm.stop_all_caches()
def test_stress_add_remove_core(cache_mode): """ title: Stress test for adding and removing core. description: Validate the ability of CAS to add and remove core in the loop. pass_criteria: - No system crash while adding and removing core. - Core is added and removed successfully. - No data corruption. """ with TestRun.step( "Prepare cache and core. Create test file and count its checksum." ): cache, core, file, file_md5sum_before = prepare_with_file_creation( cache_mode) for _ in TestRun.iteration( range(0, iterations_per_config), f"Add and remove core {iterations_per_config} times."): with TestRun.step("Remove core."): core.remove_core() caches_count = len(casadm_parser.get_caches()) if caches_count != 1: TestRun.fail( f"Expected caches count: 1; Actual caches count: {caches_count}." ) cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != 0: TestRun.fail( f"Expected cores count: 0; Actual cores count: {cores_count}." ) with TestRun.step("Add core."): core = cache.add_core(core.core_device) caches_count = len(casadm_parser.get_caches()) if caches_count != 1: TestRun.fail( f"Expected caches count: 1; Actual caches count: {caches_count}." ) cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != 1: TestRun.fail( f"Expected cores count: 1; Actual cores count: {cores_count}." ) with TestRun.step("Check md5 sum of test file."): core.mount(mount_point) file_md5sum_after = file.md5sum() if file_md5sum_after != file_md5sum_before: TestRun.LOGGER.error("Md5 sum of test file is different.") core.unmount() with TestRun.step("Stop all caches."): casadm.stop_all_caches()
def test_stress_service(cache_mode): """ title: Stress test for starting and stopping CAS service. description: | Validate the ability of CAS to restart CAS service and load CAS device in the loop. pass_criteria: - No system crash while restarting CAS service or loading cache. - CAS service restarts with no errors. - CAS device loads successfully. """ with TestRun.step("Prepare cache and core."): cache_dev, core_dev = prepare() with TestRun.step("Start cache and add core."): cache = casadm.start_cache(cache_dev, cache_mode, force=True) casadm.add_core(cache, core_dev) for _ in TestRun.iteration( range(0, iterations_per_config), f"Stop and start CAS service {iterations_per_config} times."): with TestRun.step( "Create CAS init config based on current running CAS configuration." ): InitConfig.create_init_config_from_running_configuration() with TestRun.step("Stop CAS service."): casctl.stop() with TestRun.step("Check if service stopped successfully."): if len(casadm_parser.get_caches()) != 0: TestRun.fail( "There are still running caches after stopping service.") if len(casadm_parser.get_cores(cache.cache_id)) != 0: TestRun.fail( "There are still running cores after stopping service.") with TestRun.step("Start CAS service."): casctl.start() time.sleep(1) # Time for CAS devices to start with TestRun.step("Check if CAS configuration loaded successfully."): caches_count = len(casadm_parser.get_caches()) if caches_count != 1: TestRun.fail( f"Expected caches count: 1; Actual caches count: {caches_count}." ) cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != 1: TestRun.fail( f"Expected cores count: 1; Actual cores count: {cores_count}." ) with TestRun.step("Stop caches and create default init config file."): casadm.stop_all_caches() InitConfig.create_default_init_config()
def test_stress_reload_module(cache_mode): """ title: Stress test for reloading CAS modules. description: Validate the ability of CAS to reload modules in the loop. pass_criteria: - No system crash while reloading CAS modules. - CAS modules reloads with no errors. - No data corruption. """ with TestRun.step("Prepare cache and core. Create test file and count its checksum."): cache, core, file, file_md5sum_before = prepare_with_file_creation(cache_mode) with TestRun.step("Save current cache configuration."): cache_config = cache.get_cache_config() for _ in TestRun.iteration(range(0, iterations_per_config), f"Reload CAS modules and check loaded " f"cache configuration {iterations_per_config} times."): with TestRun.step("Stop cache."): cache.stop() caches_count = len(casadm_parser.get_caches()) if caches_count != 0: TestRun.fail(f"Expected caches count: 0; Actual caches count: {caches_count}.") cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != 0: TestRun.fail(f"Expected cores count: 0; Actual cores count: {cores_count}.") with TestRun.step("Reload CAS modules."): cas_module.reload_all_cas_modules() with TestRun.step("Load cache."): cache = casadm.load_cache(cache.cache_device) caches_count = len(casadm_parser.get_caches()) if caches_count != 1: TestRun.fail(f"Expected caches count: 1; Actual caches count: {caches_count}.") cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != 1: TestRun.fail(f"Expected cores count: 1; Actual cores count: {cores_count}.") with TestRun.step("Validate cache configuration."): if cache.get_cache_config() != cache_config: TestRun.fail("Cache configuration is different than before reloading modules.") with TestRun.step("Check md5 sum of test file."): core.mount(mount_point) file_md5sum_after = file.md5sum() if file_md5sum_after != file_md5sum_before: TestRun.LOGGER.error("Md5 sum of test file is different.") core.unmount() with TestRun.step("Stop all caches."): casadm.stop_all_caches()
def test_cli_start_stop_default_value(prepare_and_cleanup, shortcut): prepare() cache_device = next(disk for disk in TestProperties.dut.disks if disk.disk_type == DiskType.optane) casadm.start_cache(cache_device, shortcut=shortcut, force=True) caches = casadm_parser.get_caches() assert len(caches) == 1 assert caches[0].cache_device.system_path == cache_device.system_path casadm.stop_cache(cache_id=caches[0].cache_id, shortcut=shortcut) output = casadm.list_caches(shortcut=shortcut) caches = casadm_parser.get_caches() assert len(caches) == 0 assert output.stdout == "No caches running"
def test_dirty_load(): """ title: Loading cache after dirty shutdown. description: Test for loading cache containing dirty data after DUT hard restart. pass_criteria: - DUT should reboot successfully. - Cache should load successfully. """ with TestRun.step("Prepare devices."): cache_disk = TestRun.disks['cache'] cache_disk.create_partitions([Size(1, Unit.GibiByte)]) cache_dev = cache_disk.partitions[0] core_disk = TestRun.disks['core'] core_disk.create_partitions([Size(2, Unit.GibiByte)] * 2) core_devices = core_disk.partitions with TestRun.step("Start cache in Write-Back mode and add cores."): cache = casadm.start_cache(cache_dev, cache_mode=CacheMode.WB) cores = [] for dev in core_devices: cores.append(cache.add_core(dev)) with TestRun.step("Set cleaning policy to nop."): cache.set_cleaning_policy(CleaningPolicy.nop) with TestRun.step("Populate cache with dirty data."): fio = Fio().create_command()\ .size(Size(1, Unit.GibiByte))\ .read_write(ReadWrite.randwrite)\ .io_engine(IoEngine.libaio)\ .block_size(Size(1, Unit.Blocks4096)) for i, core in enumerate(cores): fio.add_job(f"core{i}").target(core.path) fio.run() if cache.get_dirty_blocks() <= Size.zero(): TestRun.fail("Cache does not contain dirty data.") with TestRun.step("Remove one core without flushing dirty data."): casadm.remove_core_with_script_command(cache.cache_id, core.core_id, True) with TestRun.step("Reset platform."): power_control = TestRun.plugin_manager.get_plugin('power_control') power_control.power_cycle() with TestRun.step("Load cache."): cache = casadm.load_cache(cache_dev) caches_num = len(casadm_parser.get_caches()) if caches_num != 1: TestRun.LOGGER.error( f"Wrong number of caches. Expected 1, actual {caches_num}.") cores_num = len(casadm_parser.get_cores(cache.cache_id)) if cores_num != 1: TestRun.LOGGER.error( f"Wrong number of cores. Expected 1, actual {cores_num}.")
def test_one_core_release(cache_mode): """ title: Test if OpenCAS dynamically allocates space according to core devices needs. description: | When one or more core devices are unused in a single cache instance all blocks previously occupied should be available to other core devices. Test is without pass through mode. pass_criteria: - No system crash. - The remaining core is able to use cache. - OpenCAS frees blocks occupied by unused core and allocates it to the remaining core. """ with TestRun.step("Prepare two cache and one core devices."): cache_dev = TestRun.disks['cache'] cache_dev.create_partitions([Size(512, Unit.MebiByte)]) cache_part = cache_dev.partitions[0] core_dev = TestRun.disks['core'] core_dev.create_partitions([Size(1, Unit.GibiByte)] * 2) core_part1 = core_dev.partitions[0] core_part2 = core_dev.partitions[1] Udev.disable() with TestRun.step("Start cache"): cache = casadm.start_cache(cache_part, cache_mode, force=True) caches_count = len(casadm_parser.get_caches()) if caches_count != 1: TestRun.fail(f"Expected caches count: 1; Actual caches count: {caches_count}.") with TestRun.step("Add both core devices to cache."): core1 = cache.add_core(core_part1) core2 = cache.add_core(core_part2) cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != 2: TestRun.fail(f"Expected cores count: 2; Actual cores count: {cores_count}.") with TestRun.step("Change sequential cutoff policy to 'never'."): cache.set_seq_cutoff_policy(SeqCutOffPolicy.never) with TestRun.step("Fill cache with pages from the first core."): dd_builder(cache_mode, core1, cache.size).run() core1_occupied_blocks_before = core1.get_occupancy() with TestRun.step("Check if the remaining core is able to use cache."): dd_builder(cache_mode, core2, Size(100, Unit.MebiByte)).run() core1_occupied_blocks_after = core1.get_occupancy() with TestRun.step("Check if occupancy from the first core is removed from cache."): # The first core's occupancy should be lower than cache's occupancy # by the value of the remaining core's occupancy because cache # should reallocate blocks from unused core to used core. if core1_occupied_blocks_after >= core1_occupied_blocks_before \ or cache.get_occupancy() <= core1_occupied_blocks_after \ or not float(core2.get_occupancy().get_value()) > 0: TestRun.LOGGER.error("Blocks previously occupied by the first core aren't released.") with TestRun.step("Stop cache."): casadm.stop_all_caches()
def test_cli_start_stop_custom_id(shortcut): """ title: Test for starting a cache with a custom ID - short and long command description: | Start a new cache with a random ID (from allowed pool) and then stop this cache. pass_criteria: - The cache has successfully started with a custom ID - The cache has successfully stopped """ with TestRun.step("Prepare the device for the cache."): cache_device = TestRun.disks['cache'] cache_device.create_partitions([Size(500, Unit.MebiByte)]) cache_device = cache_device.partitions[0] with TestRun.step("Start the cache with a random ID."): cache_id = randint(*CACHE_ID_RANGE) cache = casadm.start_cache(cache_device, cache_id=cache_id, shortcut=shortcut, force=True) TestRun.LOGGER.info(f"Cache ID: {cache_id}") with TestRun.step("Check if the cache has started successfully."): caches = casadm_parser.get_caches() if len(caches) != 1: TestRun.fail( f"There is a wrong number of caches found in the OS: {len(caches)}. " f"Should be only 1.") if cache.cache_device.path != cache_device.path: TestRun.fail(f"The cache has started using a wrong device:" f" {cache.cache_device.path}." f"\nShould use {cache_device.path}.") with TestRun.step("Stop the cache."): casadm.stop_cache(cache.cache_id, shortcut=shortcut) with TestRun.step("Check if the cache has stopped properly."): caches = casadm_parser.get_caches() if len(caches) != 0: TestRun.fail( f"There is a wrong number of caches found in the OS: {len(caches)}." f"\nNo cache should be present after stopping the cache.") output = casadm.list_caches(shortcut=shortcut) cli_messages.check_stdout_msg(output, cli_messages.no_caches_running)
def create_init_config_from_running_configuration(cls, load: bool = None, extra_flags=""): init_conf = cls() for cache in casadm_parser.get_caches(): init_conf.add_cache(cache.cache_id, cache.cache_device, cache.get_cache_mode(), load, extra_flags) for core in casadm_parser.get_cores(cache.cache_id): init_conf.add_core(cache.cache_id, core.core_id, core.core_device) init_conf.save_config_file() return init_conf
def test_load_occupied_id(prepare_and_cleanup): """ 1. Start new cache instance (don't specify cache id) 2. Add core to newly create cache. 3. Stop cache instance. 4. Start new cache instance on another device (don't specify cache id). 5. Try to load metadata from first device. * Load should fail. """ prepare() cache_device = next(disk for disk in TestProperties.dut.disks if disk.disk_type in [DiskType.optane, DiskType.nand]) core_device = next(disk for disk in TestProperties.dut.disks if (disk.disk_type.value > cache_device.disk_type.value and disk != cache_device)) TestProperties.LOGGER.info("Creating partitons for test") cache_device.create_partitions( [Size(500, Unit.MebiByte), Size(500, Unit.MebiByte)]) core_device.create_partitions([Size(1, Unit.GibiByte)]) cache_device_1 = cache_device.partitions[0] cache_device_2 = cache_device.partitions[1] core_device = core_device.partitions[0] TestProperties.LOGGER.info("Starting cache with default id and one core") cache1 = casadm.start_cache(cache_device_1, force=True) cache1.add_core(core_device) TestProperties.LOGGER.info("Stopping cache") cache1.stop() TestProperties.LOGGER.info( "Starting cache with default id on different device") cache2 = casadm.start_cache(cache_device_2, force=True) TestProperties.LOGGER.info( "Attempt to load metadata from first cache device") try: casadm.load_cache(cache_device_1) except Exception: pass caches = casadm_parser.get_caches() assert len(caches) == 1, "Inappropirate number of caches after load!" assert caches[0].cache_device.system_path == cache_device_2.system_path assert caches[0].cache_id == 1 cores = caches[0].get_core_devices() assert len(cores) == 0
def test_stress_add_remove_core(cache_mode): """ title: Stress test for adding and removing core. description: Validate the ability of CAS to add and remove core in the loop. pass_criteria: - No system crash while adding and removing core. - Core is added and removed successfully. - No data corruption. """ with TestRun.step("Prepare cache and core. Create test file and count it's checksum."): cache, core, md5_before_load, size_before_load, permissions_before_load = \ prepare_with_file_creation(cache_mode) for _ in TestRun.iteration(range(0, iterations_per_config), f"Add and remove core {iterations_per_config} times."): with TestRun.step("Remove core."): core.remove_core() caches_count = len(casadm_parser.get_caches()) if caches_count != 1: TestRun.fail(f"Expected caches count: 1; Actual caches count: {caches_count}.") cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != 0: TestRun.fail(f"Expected cores count: 0; Actual cores count: {cores_count}.") with TestRun.step("Add core."): core = cache.add_core(core.core_device) caches_count = len(casadm_parser.get_caches()) if caches_count != 1: TestRun.fail(f"Expected caches count: 1; Actual caches count: {caches_count}.") cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != 1: TestRun.fail(f"Expected cores count: 1; Actual cores count: {cores_count}.") with TestRun.step("Check md5 of test file."): check_files(core, size_before_load, permissions_before_load, md5_before_load) with TestRun.step("Stop all caches."): casadm.stop_all_caches()
def test_load_occupied_id(): """ title: Negative test for loading cache with occupied ID. description: | Verify that loading cache with occupied ID is not permitted. pass_criteria: - Loading cache with occupied ID should fail. """ with TestRun.step("Create partitions for test."): cache_device = TestRun.disks['cache'] core_device = TestRun.disks['core'] cache_device.create_partitions( [Size(500, Unit.MebiByte), Size(500, Unit.MebiByte)]) core_device.create_partitions([Size(1, Unit.GibiByte)]) cache_device_1 = cache_device.partitions[0] cache_device_2 = cache_device.partitions[1] core_device = core_device.partitions[0] with TestRun.step("Start cache with default id and one core."): cache1 = casadm.start_cache(cache_device_1, force=True) cache1.add_core(core_device) with TestRun.step("Stop cache."): cache1.stop() with TestRun.step("Start cache with default id on different device."): casadm.start_cache(cache_device_2, force=True) with TestRun.step("Attempt to load metadata from first cache device."): try: casadm.load_cache(cache_device_1) TestRun.fail("Cache loaded successfully but it should not.") except Exception: pass caches = casadm_parser.get_caches() if len(caches) != 1: TestRun.LOGGER.error("Inappropriate number of caches after load!") if caches[0].cache_device.path != cache_device_2.path: TestRun.LOGGER.error("Wrong cache device system path!") if caches[0].cache_id != 1: TestRun.LOGGER.error("Wrong cache id.") cores = caches[0].get_core_devices() if len(cores) != 0: TestRun.LOGGER.error("Inappropriate number of cores after load!")
def test_udev_cache_load(cache_mode): """ title: CAS udev rule execution after unplugging and plugging cache device. description: | Verify if CAS udev rule is executed after unplugging and plugging cache device and if cache is properly loaded. pass_criteria: - No kernel error - Cache is properly loaded after plugging cache device - Cache is not loaded after unplugging cache device """ with TestRun.step("Start cache."): cache_disk = TestRun.disks["cache"] cache_disk.create_partitions([Size(1, Unit.GibiByte)]) cache_dev = cache_disk.partitions[0] cache = casadm.start_cache(cache_dev, cache_mode=cache_mode) with TestRun.step("Create init config from running configuration"): InitConfig.create_init_config_from_running_configuration() with TestRun.step("Stop cache."): cache.stop() with TestRun.step("Unplug cache disk."): cache_disk.unplug() with TestRun.step("Plug cache disk."): cache_disk.plug() time.sleep(1) with TestRun.step("List caches and check if cache is loaded."): caches = casadm_parser.get_caches() if len(caches) < 1: TestRun.fail("Cache did not load.") elif len(caches) > 1: caches_list = '\n'.join(caches) TestRun.fail(f"There is more than 1 cache loaded:\n{caches_list}") elif caches[0].cache_device.path != cache_dev.path: TestRun.fail(f"Cache loaded on wrong device. " f"Actual: {caches[0].cache_device.path}, " f"expected: {cache_dev.path}") elif caches[0].get_cache_mode() != cache_mode: TestRun.fail( f"Cache did load with different cache mode. " f"Actual: {caches[0].get_cache_mode()}, expected: {cache_mode}" ) TestRun.LOGGER.info("Cache is correctly loaded.")
def validate_cache(cache_mode): caches = casadm_parser.get_caches() caches_count = len(caches) if caches_count != 1: TestRun.LOGGER.error( f"Cache did not start successfully - wrong number of caches: {caches_count}." ) cores = casadm_parser.get_cores(caches[0].cache_id) cores_count = len(cores) if cores_count != 1: TestRun.LOGGER.error(f"Cache started with wrong number of cores: {cores_count}.") current_mode = caches[0].get_cache_mode() if current_mode != cache_mode: TestRun.LOGGER.error( f"Cache started in wrong mode!\n" f"Should start in {cache_mode}, but started in {current_mode} mode." )
def check_configuration(cleaning_policy, cache_mode, cache_line_size): caches = casadm_parser.get_caches() if len(caches) != 1: TestRun.fail(f"There is wrong amount of caches running. " f"(Expected: 1, actual: {len(caches)}).") actual_cores_number = len(casadm_parser.get_cores(caches[0].cache_id)) if actual_cores_number != cores_number: TestRun.fail(f"There is wrong amount of CAS devices running. (Expected: {cores_number}, " f"actual: {actual_cores_number}).") actual_line_size = caches[0].get_cache_line_size() actual_cache_mode = caches[0].get_cache_mode() actual_cleaning_policy = caches[0].get_cleaning_policy() if actual_cleaning_policy != cleaning_policy: TestRun.fail(f"Cleaning policy: expected = {cleaning_policy.value}, " f"actual = {actual_cleaning_policy.value}.") if actual_cache_mode != cache_mode: TestRun.fail(f"Cache mode: expected = {cache_mode.value}, actual = {actual_cache_mode}.") if actual_line_size != cache_line_size: TestRun.fail(f"Cache line size: expected = {cache_line_size.name}, " f"actual: {actual_line_size.name}")
def create_init_config_from_running_configuration(load: bool = None, extra_flags=""): cache_lines = [] core_lines = [] for cache in casadm_parser.get_caches(): cache_lines.append( CacheConfigLine(cache.cache_id, cache.cache_device, cache.get_cache_mode(), load, extra_flags)) for core in casadm_parser.get_cores(cache.cache_id): core_lines.append( CoreConfigLine(cache.cache_id, core.core_id, core.core_device)) config_lines = [] create_default_init_config() if len(cache_lines) > 0: config_lines.append(CacheConfigLine.header) for c in cache_lines: config_lines.append(str(c)) if len(core_lines) > 0: config_lines.append(CoreConfigLine.header) for c in core_lines: config_lines.append(str(c)) fs_utils.write_file(cas_init_config_path, '\n'.join(config_lines), False)
def test_init_reboot_runlevels(runlevel, cache_mode): """ title: Initialize CAS devices after reboot description: | Verify that CAS init script starts cache properly after reboot in different runlevels. pass_criteria: - Cache should be loaded successfully after reboot. """ with TestRun.step(f"Set runlevel to {runlevel.value}."): os_utils.change_runlevel(runlevel) with TestRun.step("Prepare CAS device."): cache_disk = TestRun.disks['cache'] cache_disk.create_partitions([Size(2, Unit.GibiByte)]) cache_dev = cache_disk.partitions[0] core_disk = TestRun.disks['core'] core_disk.create_partitions([Size(1, Unit.GibiByte)]) core_dev = core_disk.partitions[0] cache = casadm.start_cache(cache_dev, cache_mode, force=True) core = cache.add_core(core_dev) with TestRun.step("Create CAS init config based on running configuration."): InitConfig.create_init_config_from_running_configuration() with TestRun.step("Make filesystem on CAS device and mount it."): core.create_filesystem(Filesystem.xfs) core.mount(mount_point) with TestRun.step("Start writing file to CAS."): fio = Fio().create_command()\ .file_name(os.path.join(mount_point, "test_file"))\ .read_write(ReadWrite.randwrite)\ .io_engine(IoEngine.sync)\ .num_jobs(1).direct()\ .file_size(Size(30, Unit.GibiByte)) fio.run_in_background() os_utils.sync() os_utils.drop_caches() time.sleep(10) TestRun.executor.run_expect_success("pgrep fio") with TestRun.step("Reboot machine during writing a file."): TestRun.executor.reboot() with TestRun.step("Check if cache was properly started at boot time"): # Wait for CAS to load after boot time.sleep(60) caches = casadm_parser.get_caches() if len(caches) == 1: TestRun.LOGGER.info("Cache started properly at boot time.") else: TestRun.LOGGER.error("Cache did not start properly at boot time.") with TestRun.step("Stop cache and set default runlevel."): if len(caches) != 0: casadm.stop_all_caches() os_utils.change_runlevel(Runlevel.runlevel3) TestRun.executor.reboot()
def test_stop_no_flush_load_cache(cache_mode, filesystem): """ title: Test to check that 'stop --no-data-flush' command works correctly. description: | Negative test of the ability of CAS to load unflushed cache on core device with filesystem. Test uses lazy flush cache modes. pass_criteria: - No system crash while load cache. - Starting cache without loading metadata fails. - Starting cache with loading metadata finishes with success. """ with TestRun.step("Prepare cache and core devices."): cache_part, core_part = prepare() with TestRun.step("Start cache."): cache = casadm.start_cache(cache_part, cache_mode, force=True) with TestRun.step("Change cleaning policy to NOP."): cache.set_cleaning_policy(CleaningPolicy.nop) with TestRun.step( f"Add core with {filesystem.name} filesystem to cache and mount it." ): core_part.create_filesystem(filesystem) core = cache.add_core(core_part) core.mount(mount_point) with TestRun.step( f"Create test file in mount point of exported object and check its md5 sum." ): test_file = fs_utils.create_random_test_file(test_file_path, Size(48, Unit.MebiByte)) test_file_md5_before = test_file.md5sum() with TestRun.step("Unmount exported object."): core.unmount() with TestRun.step("Count dirty blocks on exported object."): dirty_blocks_before = core.get_dirty_blocks() with TestRun.step("Stop cache with option '--no-data-flush'."): cache.stop(no_data_flush=True) caches_count = len(casadm_parser.get_caches()) if caches_count != 0: TestRun.fail( f"Expected caches count: 0; Actual caches count: {caches_count}." ) with TestRun.step("Try to start cache without loading metadata."): output = TestRun.executor.run_expect_fail( cli.start_cmd(cache_dev=str(cache_part.path), cache_mode=str(cache_mode.name.lower()), force=False, load=False)) cli_messages.check_stderr_msg( output, cli_messages.start_cache_with_existing_metadata) with TestRun.step("Load cache."): cache = casadm.load_cache(cache.cache_device) caches_count = len(casadm_parser.get_caches()) if caches_count != 1: TestRun.fail( f"Expected caches count: 1 Actual caches count: {caches_count}." ) cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != 1: TestRun.fail( f"Expected cores count: 1; Actual cores count: {cores_count}.") with TestRun.step( "Compare dirty blocks number before and after loading cache."): if dirty_blocks_before != core.get_dirty_blocks(): TestRun.LOGGER.error( "Dirty blocks number is different than before loading cache.") with TestRun.step("Mount exported object."): core.mount(mount_point) with TestRun.step( "Compare md5 sum of test file before and after loading cache."): if test_file_md5_before != test_file.md5sum(): TestRun.LOGGER.error( "Test file's md5 sum is different than before loading cache.") with TestRun.step("Unmount exported object."): core.unmount() with TestRun.step("Stop cache."): casadm.stop_all_caches()
def test_stop_no_flush_load_cache_no_fs(cache_mode): """ title: Test to check that 'stop --no-data-flush' command works correctly. description: | Negative test of the ability of CAS to load unflushed cache on core device without filesystem. Test uses lazy flush cache modes. pass_criteria: - No system crash while load cache. - Starting cache without loading metadata fails. - Starting cache with loading metadata finishes with success. """ with TestRun.step("Prepare cache and core devices."): cache_part, core_part = prepare() with TestRun.step("Start cache with --force option."): cache = casadm.start_cache(cache_part, cache_mode, force=True) with TestRun.step("Change cleaning policy to NOP."): cache.set_cleaning_policy(CleaningPolicy.nop) with TestRun.step("Add core device without filesystem."): core_part.wipe_filesystem() core = cache.add_core(core_part) with TestRun.step("Fill exported object with data."): dd = (Dd().input("/dev/zero").output(core.path).block_size( Size(1, Unit.Blocks4096)).oflag("direct")) dd.run() with TestRun.step("Count dirty blocks on exported object."): dirty_blocks_before = core.get_dirty_blocks() with TestRun.step("Stop cache with option '--no-data-flush'."): cache.stop(no_data_flush=True) caches_count = len(casadm_parser.get_caches()) if caches_count != 0: TestRun.fail( f"Expected caches count: 0; Actual caches count: {caches_count}." ) with TestRun.step("Try to start cache without loading metadata."): output = TestRun.executor.run_expect_fail( cli.start_cmd(cache_dev=str(cache_part.path), cache_mode=str(cache_mode.name.lower()), force=False, load=False)) cli_messages.check_stderr_msg( output, cli_messages.start_cache_with_existing_metadata) with TestRun.step("Load cache."): cache = casadm.load_cache(cache.cache_device) caches_count = len(casadm_parser.get_caches()) if caches_count != 1: TestRun.fail( f"Expected caches count: 1 Actual caches count: {caches_count}." ) cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != 1: TestRun.fail( f"Expected cores count: 1; Actual cores count: {cores_count}.") with TestRun.step( "Compare dirty blocks number before and after loading cache."): if dirty_blocks_before != core.get_dirty_blocks(): TestRun.LOGGER.error( "Dirty blocks number is different than before loading cache.") with TestRun.step("Stop cache."): casadm.stop_all_caches()
def test_load_x_to_one_diff_params(cache_mode, cleaning_policy, cache_line_size, cores_amount): """ title: Test for loading CAS with 1 cache and 1 or 4 cores with different params. description: | Verify that loading cache configurations works properly in every mode with 1 cache and 1 or 4 cores. Use different parameters with load command. pass_criteria: - OpenCAS should load successfully but with saved configuration. - No errors in cache are found. """ with TestRun.step(f"Prepare 1 cache and {cores_amount} core devices"): cache_dev = TestRun.disks['cache'] cache_dev.create_partitions([Size(512, Unit.MebiByte)]) cache_dev = cache_dev.partitions[0] core_dev = TestRun.disks['core'] core_size = [] for i in range(cores_amount): core_size.append(Size(1, Unit.GibiByte)) core_dev.create_partitions(core_size) with TestRun.step(f"Start cache with {cores_amount} cores."): cache = casadm.start_cache(cache_dev, cache_mode[0], cache_line_size[0], force=True) id_cache = cache.cache_id cores = [] for i in range(cores_amount): cores.append(cache.add_core(core_dev.partitions[i])) caches_count = len(casadm_parser.get_caches()) if caches_count != 1: TestRun.fail( f"Expected caches count: 1; Actual caches count: {caches_count}." ) cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != cores_amount: TestRun.fail( f"Expected cores count: {cores_amount}; Actual cores count: {cores_count}." ) with TestRun.step("Configure cleaning policy."): cache.set_cleaning_policy(cleaning_policy) if cleaning_policy == CleaningPolicy.alru: alru = FlushParametersAlru() alru.activity_threshold = Time(milliseconds=1000) alru.flush_max_buffers = 10 alru.staleness_time = Time(seconds=60) alru.wake_up_time = Time(seconds=5) cache.set_params_alru(alru) if cleaning_policy == CleaningPolicy.acp: acp = FlushParametersAcp() acp.flush_max_buffers = 100 acp.wake_up_time = Time(seconds=5) cache.set_params_acp(acp) with TestRun.step("Run FIO on exported object"): fio = (Fio().create_command().io_engine( IoEngine.libaio).io_depth(64).direct().read_write( ReadWrite.randrw).size(Size(1, Unit.GibiByte)).block_size( cache_line_size[0]).read_write(ReadWrite.randrw).num_jobs( cores_amount).cpus_allowed_policy( CpusAllowedPolicy.split)) for core in cores: fio.add_job(f"job_{core.core_id}").target(core.path) fio.run() with TestRun.step("Stop cache."): cache.stop() caches_count = len(casadm_parser.get_caches()) if caches_count != 0: TestRun.fail( f"There are still {caches_count} caches running after stopping service." ) cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != 0: TestRun.fail( f"There are still {cores_count} cores running after stopping service." ) with TestRun.step("Load cache."): try: cache = casadm.start_cache(cache_dev, cache_mode[1], cache_line_size[1], id_cache + 1, load=True) except Exception: TestRun.LOGGER.error("Cannot pass other cache ID to cache load.") TestRun.LOGGER.info( "Load cache without passing cache ID to command.") cache = casadm.start_cache(cache_dev, cache_mode[1], cache_line_size[1], load=True) caches_count = len(casadm_parser.get_caches()) if caches_count != 1: TestRun.fail( f"Expected caches count: 1; Actual caches count: {caches_count}." ) cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != cores_amount: TestRun.fail( f"Expected cores count: {cores_amount}; Actual cores count: {cores_count}." ) with TestRun.step("Compare cache configuration before and after load."): if cache_mode[0] != cache.get_cache_mode(): TestRun.fail("Cache modes are different. Should be the same.") if cache_line_size[0] != cache.get_cache_line_size(): TestRun.fail("Cache line sizes are different. Should be the same.") if id_cache != cache.cache_id: TestRun.fail("Cache IDs are different. Should be the same.") if cleaning_policy != cache.get_cleaning_policy(): TestRun.fail("Cleaning policies are different.") if cleaning_policy == CleaningPolicy.alru: if alru != cache.get_flush_parameters_alru(): TestRun.fail("Cleaning policy parameters are different.") if cleaning_policy == CleaningPolicy.acp: if acp != cache.get_flush_parameters_acp(): TestRun.fail("Cleaning policy parameters are different.") with TestRun.step("Run FIO again on exported object"): fio = (Fio().create_command().io_engine( IoEngine.libaio).io_depth(64).direct().read_write( ReadWrite.randrw).size(Size(1, Unit.GibiByte)).block_size( cache_line_size[1]).read_write(ReadWrite.randrw).num_jobs( cores_amount).cpus_allowed_policy( CpusAllowedPolicy.split)) for core in cores: fio.add_job(f"job_{core.core_id}").target(core.path) fio.run() with TestRun.step("Check if there are no error statistics."): if cache.get_statistics().error_stats.total_errors != 0: TestRun.fail("There are errors in the cache.") with TestRun.step("Stop caches."): casadm.stop_all_caches()
def test_cas_startup(cache_mode, filesystem): """ title: Test for starting CAS on system startup. pass_criteria: - System does not crash. - CAS modules are loaded before partitions are mounted. - Cache is loaded before partitions are mounted. - Exported object is mounted after startup is complete. """ with TestRun.step( "Prepare partitions for cache (200MiB) and for core (400MiB)"): cache_dev = TestRun.disks['cache'] cache_dev.create_partitions([Size(200, Unit.MebiByte)]) cache_part = cache_dev.partitions[0] core_dev = TestRun.disks['core'] core_dev.create_partitions([Size(400, Unit.MebiByte)]) core_part = core_dev.partitions[0] with TestRun.step("Start cache and add core"): cache = casadm.start_cache(cache_part, cache_mode, force=True) core = cache.add_core(core_part) with TestRun.step("Create and mount filesystem"): core.create_filesystem(filesystem) core.mount(mountpoint) with TestRun.step("Create test file and calculate md5 checksum"): (Dd().input("/dev/urandom").output(filepath).count(16).block_size( Size(1, Unit.MebiByte)).run()) test_file = File(filepath) md5_before = test_file.md5sum() with TestRun.step("Add mountpoint fstab and create intelcas.conf"): fstab.add_mountpoint(device=core, mount_point=mountpoint, fs_type=filesystem) InitConfig.create_init_config_from_running_configuration() with TestRun.step("Reboot"): TestRun.executor.reboot() with TestRun.step("Check if cache is started"): caches = list(get_caches()) if len(caches) != 1: TestRun.fail(f"Expected one cache, got {len(caches)}!") if caches[0].cache_id != cache.cache_id: TestRun.fail("Invalid cache id!") with TestRun.step("Check if core is added"): cores = list(get_cores(cache.cache_id)) if len(cores) != 1: TestRun.fail(f"Expected one core, got {len(cores)}!") if cores[0].core_id != core.core_id: TestRun.fail("Invalid core id!") with TestRun.step("Check if filesystem is mounted"): if not core.is_mounted(): TestRun.fail("Core is not mounted!") with TestRun.step("Check if md5 checksum matches"): md5_after = test_file.md5sum() if md5_before != md5_after: TestRun.fail("md5 checksum mismatch!") with TestRun.step("Test cleanup"): fstab.remove_mountpoint(device=core) core.unmount() InitConfig.create_default_init_config() casadm.stop_all_caches()
def test_stress_small_cas_device(cache_line_size, cores_number, cache_config): """ title: Stress test for verifying data on small CAS devices. description: | Validate the ability of CAS to handle many iops when device is small using different cache modes, cache line sizes and core numbers. pass_criteria: - No system crash. - Md5 sums of core device and exported object are equal. """ cache_mode, cleaning_policy = cache_config with TestRun.step(f"Prepare 1 cache and {cores_number} core devices."): cache_dev = TestRun.disks['cache'] cache_dev.create_partitions([Size(100, Unit.MebiByte)]) cache_part = cache_dev.partitions[0] core_dev = TestRun.disks['core'] core_sizes = [Size(200, Unit.MebiByte)] * cores_number core_dev.create_partitions(core_sizes) with TestRun.step(f"Start cache with {cores_number} cores."): cache = casadm.start_cache(cache_part, cache_mode, cache_line_size, force=True) cores = [] for i in range(cores_number): cores.append(cache.add_core(core_dev.partitions[i])) caches_count = len(casadm_parser.get_caches()) if caches_count != 1: TestRun.fail(f"Expected caches count: 1; Actual caches count: {caches_count}.") cores_count = len(casadm_parser.get_cores(cache.cache_id)) if cores_count != cores_number: TestRun.fail( f"Expected cores count: {cores_number}; Actual cores count: {cores_count}.") if cleaning_policy is not None: with TestRun.step("Set cleaning policy."): cache.set_cleaning_policy(cleaning_policy) with TestRun.step(f"Stress cache for {int(stress_time.total_seconds() / 60)} minutes."): fio = (Fio().create_command() .io_engine(IoEngine.libaio) .io_depth(128) .direct() .time_based() .run_time(stress_time) .read_write(ReadWrite.randrw) .block_size(cache_line_size) .num_jobs(cores_number) .cpus_allowed_policy(CpusAllowedPolicy.split)) for core in cores: fio.add_job(f"job_{core.core_id}").target(core.system_path) output = fio.run()[0] TestRun.LOGGER.info(f"Total read I/O [KiB]: {str(output.read_io())}\n" f"Total write I/O [KiB]: {str(output.write_io())}") with TestRun.step("Count md5 sum for exported objects"): md5sum_core = [] for core in cores: md5sum_core.append(TestRun.executor.run( f"md5sum -b {core.system_path}").stdout.split(" ")[0]) with TestRun.step("Stop cache."): cache.stop() with TestRun.step("Count md5 sum for core devices"): md5sum_core_dev = [] for core_dev in core_dev.partitions: md5sum_core_dev.append(TestRun.executor.run( f"md5sum -b {core_dev.system_path}").stdout.split(" ")[0]) with TestRun.step("Compare md5 sum of exported objects and cores."): if md5sum_core_dev != md5sum_core: TestRun.LOGGER.error(f"Md5 sums of core devices and of exported objects are different.") with TestRun.step("Stop all caches"): casadm.stop_all_caches()