From f4e17bc1ecc546f079beefc4f18b6e1cb4e26e60 Mon Sep 17 00:00:00 2001 From: Adam Seyda Date: Mon, 3 Oct 2022 19:44:15 +0200 Subject: [PATCH] Add test test_ci_read_write Signed-off-by: Adam Seyda Signed-off-by: Robert Baldyga --- .../functional/tests/ci/test_ci_read_write.py | 303 ++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 test/functional/tests/ci/test_ci_read_write.py diff --git a/test/functional/tests/ci/test_ci_read_write.py b/test/functional/tests/ci/test_ci_read_write.py new file mode 100644 index 0000000..d2358f0 --- /dev/null +++ b/test/functional/tests/ci/test_ci_read_write.py @@ -0,0 +1,303 @@ +# +# Copyright(c) 2022 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause +# + +import pytest + +from api.cas import casadm +from api.cas.cache_config import CacheMode +from core.test_run import TestRun +from storage_devices.disk import DiskType, DiskTypeSet, DiskTypeLowerThan +from test_utils.os_utils import Udev +from test_utils.size import Unit, Size +from test_tools.dd import Dd +from test_tools.iostat import IOstatBasic + +dd_count = 100 + + +@pytest.mark.require_disk("cache", DiskTypeSet([DiskType.nand, DiskType.optane])) +@pytest.mark.require_disk("core", DiskTypeLowerThan("cache")) +@pytest.mark.parametrize("cache_mode", [CacheMode.WT, CacheMode.WA, CacheMode.WB]) +@pytest.mark.CI() +def test_ci_read(cache_mode): + """ + title: Verification test for write mode: write around + description: Verify if write mode: write around, works as expected and cache only reads + and does not cache write + pass criteria: + - writes are not cached + - reads are cached + """ + + with TestRun.step("Prepare partitions"): + cache_device = TestRun.disks["cache"] + core_device = TestRun.disks["core"] + + cache_device.create_partitions([Size(1, Unit.GibiByte)]) + core_device.create_partitions([Size(2, Unit.GibiByte)]) + + cache_device = cache_device.partitions[0] + core_device = core_device.partitions[0] + + with TestRun.step("Disable udev"): + Udev.disable() + + with TestRun.step(f"Start cache with cache_mode={cache_mode}"): + cache = casadm.start_cache(cache_dev=cache_device, cache_id=1, force=True, + cache_mode=cache_mode) + casadm.add_core(cache, core_device) + + with TestRun.step("Insert data into the cache using reads"): + data_read = Size(dd_count, Unit.Blocks4096) + dd = ( + Dd() + .input("/dev/cas1-1") + .output("/dev/null") + .count(dd_count) + .block_size(Size(1, Unit.Blocks4096)) + .iflag("direct") + ) + dd.run() + + with TestRun.step("Collect iostat"): + iostat = IOstatBasic.get_iostat_list([cache_device.parent_device]) + read_cache_1 = iostat[0].total_reads + + with TestRun.step("Generate cache hits using reads"): + dd = ( + Dd() + .input("/dev/cas1-1") + .output("/dev/null") + .count(dd_count) + .block_size(Size(1, Unit.Blocks4096)) + .iflag("direct") + ) + dd.run() + + with TestRun.step("Collect iostat"): + iostat = IOstatBasic.get_iostat_list([cache_device.parent_device]) + read_cache_2 = iostat[0].total_reads + + with TestRun.step("Stop cache"): + cache.stop() + + with TestRun.step("Enable udev"): + Udev.enable() + + with TestRun.step("Check if reads are cached"): + read_cache_delta = read_cache_2 - read_cache_1 + if read_cache_delta == data_read: + TestRun.LOGGER.info(f"Reads from cache: {read_cache_delta} == {data_read}") + else: + TestRun.LOGGER.error(f"Reads from cache: {read_cache_delta} != {data_read}") + + +@pytest.mark.require_disk("cache", DiskTypeSet([DiskType.nand, DiskType.optane])) +@pytest.mark.require_disk("core", DiskTypeLowerThan("cache")) +@pytest.mark.CI() +def test_ci_write_around_write(): + with TestRun.step("Prepare partitions"): + cache_device = TestRun.disks["cache"] + core_device = TestRun.disks["core"] + + cache_device.create_partitions([Size(1, Unit.GibiByte)]) + core_device.create_partitions([Size(2, Unit.GibiByte)]) + + cache_device = cache_device.partitions[0] + core_device = core_device.partitions[0] + + with TestRun.step("Disable udev"): + Udev.disable() + + with TestRun.step("Start CAS Linux in Write Around mode"): + cache = casadm.start_cache(cache_dev=cache_device, cache_id=1, force=True, + cache_mode=CacheMode.WA) + casadm.add_core(cache, core_device) + + with TestRun.step("Collect iostat before I/O"): + iostat_core = IOstatBasic.get_iostat_list([core_device.parent_device]) + write_core_0 = iostat_core[0].total_writes + + iostat_cache = IOstatBasic.get_iostat_list([cache_device.parent_device]) + write_cache_0 = iostat_cache[0].total_writes + + with TestRun.step("Submit writes to exported object"): + data_write = Size(dd_count, Unit.Blocks4096) + dd = ( + Dd() + .input("/dev/zero") + .output("/dev/cas1-1") + .count(dd_count) + .block_size(Size(1, Unit.Blocks4096)) + .oflag("direct") + ) + dd.run() + + with TestRun.step("Collect iostat"): + iostat_core = IOstatBasic.get_iostat_list([core_device.parent_device]) + write_core_1 = iostat_core[0].total_writes + read_core_1 = iostat_core[0].total_reads + + iostat_cache = IOstatBasic.get_iostat_list([cache_device.parent_device]) + write_cache_1 = iostat_cache[0].total_writes + read_cache_1 = iostat_cache[0].total_reads + + with TestRun.step("Submit reads to exported object"): + dd = ( + Dd() + .input("/dev/cas1-1") + .output("/dev/null") + .count(dd_count) + .block_size(Size(1, Unit.Blocks4096)) + .iflag("direct") + ) + dd.run() + + with TestRun.step("Collect iostat"): + iostat_core = IOstatBasic.get_iostat_list([core_device.parent_device]) + read_core_2 = iostat_core[0].total_reads + + iostat_cache = IOstatBasic.get_iostat_list([cache_device.parent_device]) + read_cache_2 = iostat_cache[0].total_reads + + with TestRun.step("Stop cache"): + cache.stop() + + with TestRun.step("Enable udev"): + Udev.enable() + + with TestRun.step("Verify that writes propagated to core"): + write_core_delta_1 = write_core_1 - write_core_0 + if write_core_delta_1 == data_write: + TestRun.LOGGER.info(f"Writes to core: {write_core_delta_1} == {data_write}") + else: + TestRun.LOGGER.error(f"Writes to core: {write_core_delta_1} != {data_write}") + + with TestRun.step("Verify that writes did not insert into cache"): + write_cache_delta_1 = write_cache_1 - write_cache_0 + if write_cache_delta_1.value == 0: + TestRun.LOGGER.info(f"Writes to cache: {write_cache_delta_1} == 0") + else: + TestRun.LOGGER.error(f"Writes to cache: {write_cache_delta_1} != 0") + + with TestRun.step("Verify that reads propagated to core"): + read_core_delta_2 = read_core_2 - read_core_1 + if read_core_delta_2 == data_write: + TestRun.LOGGER.info(f"Reads from core: {read_core_delta_2} == {data_write}") + else: + TestRun.LOGGER.error(f"Reads from core: {read_core_delta_2} != {data_write}") + + with TestRun.step("Verify that reads did not occur on cache"): + read_cache_delta_2 = read_cache_2 - read_cache_1 + if read_cache_delta_2.value == 0: + TestRun.LOGGER.info(f"Reads from cache: {read_cache_delta_2} == 0") + else: + TestRun.LOGGER.error(f"Reads from cache: {read_cache_delta_2} != 0") + + + +@pytest.mark.require_disk("cache", DiskTypeSet([DiskType.nand, DiskType.optane])) +@pytest.mark.require_disk("core", DiskTypeLowerThan("cache")) +@pytest.mark.CI() +def test_ci_write_through_write(): + with TestRun.step("Prepare partitions"): + cache_device = TestRun.disks["cache"] + core_device = TestRun.disks["core"] + + cache_device.create_partitions([Size(1, Unit.GibiByte)]) + core_device.create_partitions([Size(2, Unit.GibiByte)]) + + cache_device = cache_device.partitions[0] + core_device = core_device.partitions[0] + + with TestRun.step("Disable udev"): + Udev.disable() + + with TestRun.step("Start CAS Linux in Write Through mode"): + cache = casadm.start_cache(cache_dev=cache_device, cache_id=1, force=True, + cache_mode=CacheMode.WT) + casadm.add_core(cache, core_device) + + with TestRun.step("Collect iostat before I/O"): + iostat_core = IOstatBasic.get_iostat_list([core_device.parent_device]) + write_core_0 = iostat_core[0].total_writes + + iostat_cache = IOstatBasic.get_iostat_list([cache_device.parent_device]) + write_cache_0 = iostat_cache[0].total_writes + + with TestRun.step("Insert data into the cache using writes"): + data_write = Size(dd_count, Unit.Blocks4096) + dd = ( + Dd() + .input("/dev/zero") + .output("/dev/cas1-1") + .count(dd_count) + .block_size(Size(1, Unit.Blocks4096)) + .oflag("direct") + .seek(20000) + ) + dd.run() + + with TestRun.step("Collect iostat"): + iostat_core = IOstatBasic.get_iostat_list([core_device.parent_device]) + write_core_1 = iostat_core[0].total_writes + read_core_1 = iostat_core[0].total_reads + + iostat_cache = IOstatBasic.get_iostat_list([cache_device.parent_device]) + write_cache_1 = iostat_cache[0].total_writes + read_cache_1 = iostat_cache[0].total_reads + + with TestRun.step("Generate cache hits using reads"): + dd = ( + Dd() + .input("/dev/cas1-1") + .output("/dev/null") + .count(dd_count) + .block_size(Size(1, Unit.Blocks4096)) + .iflag("direct") + .skip(20000) + ) + dd.run() + + with TestRun.step("Collect iostat"): + iostat_core = IOstatBasic.get_iostat_list([core_device.parent_device]) + read_core_2 = iostat_core[0].total_reads + + iostat_cache = IOstatBasic.get_iostat_list([cache_device.parent_device]) + read_cache_2 = iostat_cache[0].total_reads + + with TestRun.step("Stop cache"): + cache.stop() + + with TestRun.step("Enable udev"): + Udev.enable() + + with TestRun.step("Verify that writes propagated to core"): + write_core_delta_1 = write_core_1 - write_core_0 + if write_core_delta_1 == data_write: + TestRun.LOGGER.info(f"Writes to core: {write_core_delta_1} == {data_write}") + else: + TestRun.LOGGER.error(f"Writes to core: {write_core_delta_1} != {data_write}") + + with TestRun.step("Verify that writes inserted into cache"): + write_cache_delta_1 = write_cache_1 - write_cache_0 + if write_cache_delta_1 == data_write: + TestRun.LOGGER.info(f"Writes to cache: {write_cache_delta_1} == {data_write}") + else: + TestRun.LOGGER.error(f"Writes to cache: {write_cache_delta_1} != {data_write}") + + with TestRun.step("Verify that reads did not propagate to core"): + read_core_delta_2 = read_core_2 - read_core_1 + if read_core_delta_2.value == 0: + TestRun.LOGGER.info(f"Reads from core: {read_core_delta_2} == 0") + else: + TestRun.LOGGER.error(f"Reads from core: {read_core_delta_2} != 0") + + with TestRun.step("Verify that reads were hits from cache"): + read_cache_delta_2 = read_cache_2 - read_cache_1 + if read_cache_delta_2 == data_write: + TestRun.LOGGER.info(f"Reads from cache: {read_cache_delta_2} == {data_write}") + else: + TestRun.LOGGER.error(f"Reads from cache: {read_cache_delta_2} != {data_write}")