From 9e5385009d8780f0f129a8b2280f92e3f52115e6 Mon Sep 17 00:00:00 2001 From: Slawomir Jankowski Date: Fri, 29 May 2020 13:22:20 +0200 Subject: [PATCH] Test for clean remove of core without fs from cache Signed-off-by: Slawomir Jankowski --- .../lazy_writes/test_lazy_writes_clean.py | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/test/functional/tests/lazy_writes/test_lazy_writes_clean.py b/test/functional/tests/lazy_writes/test_lazy_writes_clean.py index dad06f5..9754f2c 100644 --- a/test/functional/tests/lazy_writes/test_lazy_writes_clean.py +++ b/test/functional/tests/lazy_writes/test_lazy_writes_clean.py @@ -238,6 +238,137 @@ def test_clean_remove_core_with_fs(cache_mode, fs): remove(mnt_point, True, True, True) +@pytest.mark.parametrize("cache_mode", CacheMode.with_traits(CacheModeTrait.LazyWrites)) +@pytest.mark.require_disk("cache", DiskTypeSet([DiskType.optane, DiskType.nand])) +@pytest.mark.require_disk("core", DiskTypeLowerThan("cache")) +def test_clean_remove_core_without_fs(cache_mode): + """ + title: Test of the ability to remove core from cache in lazy-write modes without filesystem. + description: | + Test if OpenCAS removes core without filesystem in modes with lazy writes + without data loss. + pass_criteria: + - Core removing works properly. + - Writes to exported object and core device during OpenCAS's work are equal + - Data on core device is correct after core is removed. + """ + with TestRun.step("Prepare devices for cache and core."): + cache_dev = TestRun.disks['cache'] + cache_dev.create_partitions([Size(256, Unit.MebiByte)]) + cache_part = cache_dev.partitions[0] + core_dev = TestRun.disks['core'] + core_dev.create_partitions([Size(512, Unit.MebiByte)]) + core_part = core_dev.partitions[0] + Udev.disable() + + with TestRun.step(f"Start cache in {cache_mode} mode."): + cache = casadm.start_cache(cache_part, cache_mode) + + with TestRun.step("Add core to cache."): + core = cache.add_core(core_part) + + with TestRun.step("Disable cleaning and sequential cutoff."): + cache.set_cleaning_policy(CleaningPolicy.nop) + cache.set_seq_cutoff_policy(SeqCutOffPolicy.never) + + with TestRun.step("Read IO stats before test"): + core_disk_writes_initial = check_device_write_stats(core_part) + exp_obj_writes_initial = check_device_write_stats(core) + + with TestRun.step("Write data to exported object."): + test_file_main = create_random_test_file("/tmp/test_file_main", Size(64, Unit.MebiByte)) + dd = Dd().output(core.system_path) \ + .input(test_file_main.full_path) \ + .block_size(bs) \ + .count(int(test_file_main.size / bs)) \ + .oflag("direct") + dd.run() + test_file_md5sum_main = test_file_main.md5sum() + + with TestRun.step("Read IO stats after write to the exported object."): + core_disk_writes_increase = ( + check_device_write_stats(core_part) - core_disk_writes_initial + ) + exp_obj_writes_increase = ( + check_device_write_stats(core) - exp_obj_writes_initial + ) + + with TestRun.step("Validate IO stats after write to the exported object."): + if core_disk_writes_increase > 0: + TestRun.LOGGER.error("Writes should occur only on the exported object.") + if exp_obj_writes_increase != test_file_main.size.value: + TestRun.LOGGER.error("Not all writes reached the exported object.") + + with TestRun.step("Read data from the exported object."): + test_file_1 = File.create_file("/tmp/test_file_1") + dd = Dd().output(test_file_1.full_path) \ + .input(core.system_path) \ + .block_size(bs) \ + .count(int(test_file_main.size / bs)) \ + .oflag("direct") + dd.run() + test_file_1.refresh_item() + sync() + + with TestRun.step("Compare md5 sum of test files."): + if test_file_md5sum_main != test_file_1.md5sum(): + TestRun.LOGGER.error("Md5 sums should be equal.") + + with TestRun.step("Read data from the core device."): + test_file_2 = File.create_file("/tmp/test_file_2") + dd = Dd().output(test_file_2.full_path) \ + .input(core_part.system_path) \ + .block_size(bs) \ + .count(int(test_file_main.size / bs)) \ + .oflag("direct") + dd.run() + test_file_2.refresh_item() + sync() + + with TestRun.step("Compare md5 sum of test files."): + if test_file_md5sum_main == test_file_2.md5sum(): + TestRun.LOGGER.error("Md5 sums should be different.") + + with TestRun.step("Read IO stats before removing core."): + core_disk_writes_before_remove = check_device_write_stats(core_part) + + with TestRun.step("Remove core."): + core.remove_core() + + with TestRun.step("Read IO stats after removing core."): + core_disk_writes_increase = ( + check_device_write_stats(core_part) - core_disk_writes_before_remove + ) + + with TestRun.step("Validate IO stats after removing core."): + if core_disk_writes_increase == 0: + TestRun.LOGGER.error("Writes should occur on the core device after removing core.") + if core_disk_writes_increase != exp_obj_writes_increase: + TestRun.LOGGER.error("Write statistics for the core device should be equal " + "to those from the exported object.") + + with TestRun.step("Read data from core device again."): + test_file_3 = File.create_file("/tmp/test_file_3") + dd = Dd().output(test_file_3.full_path) \ + .input(core_part.system_path) \ + .block_size(bs) \ + .count(int(test_file_main.size / bs)) \ + .oflag("direct") + dd.run() + test_file_3.refresh_item() + sync() + + with TestRun.step("Compare md5 sum of test files."): + if test_file_md5sum_main != test_file_3.md5sum(): + TestRun.LOGGER.error("Md5 sums should be equal.") + + with TestRun.step("Delete test files."): + test_file_main.remove(True) + test_file_1.remove(True) + test_file_2.remove(True) + test_file_3.remove(True) + remove(mnt_point, True, True, True) + def check_device_write_stats(device: Device): return IOstatBasic.get_iostat_list(devices_list=[device])[0].total_writes.value