diff --git a/test/functional/tests/lazy_writes/test_lazy_writes_signals.py b/test/functional/tests/lazy_writes/test_lazy_writes_signals.py index 1c4cae3..9215167 100644 --- a/test/functional/tests/lazy_writes/test_lazy_writes_signals.py +++ b/test/functional/tests/lazy_writes/test_lazy_writes_signals.py @@ -1,9 +1,8 @@ # -# Copyright(c) 2020-2021 Intel Corporation +# Copyright(c) 2020-2022 Intel Corporation # SPDX-License-Identifier: BSD-3-Clause # -import re import pytest from time import sleep @@ -17,11 +16,11 @@ from storage_devices.disk import DiskType, DiskTypeSet from core.test_run import TestRun from test_tools.disk_utils import Filesystem from test_tools.fs_utils import create_random_test_file +from test_utils.scsi_debug import Logs, syslog_path from test_utils import os_utils from test_utils.size import Size, Unit mount_point = "/mnt/cas" -syslog_path = "/var/log/messages" @pytest.mark.os_dependent @@ -330,70 +329,3 @@ def test_flush_signal_multilevel_cache(cache_mode): with TestRun.step("Stop both caches."): cache2.stop() cache1.stop() - - -class Logs: - last_read_line = 1 - FLUSH = re.compile(r"scsi_debug:[\s\S]*cmd 35") - FUA = re.compile(r"scsi_debug:[\s\S]*cmd 2a 08") - - @staticmethod - def check_syslog_for_signals(): - Logs.check_syslog_for_flush() - Logs.check_syslog_for_fua() - - @staticmethod - def check_syslog_for_flush(): - """Check syslog for FLUSH logs""" - log_lines = Logs._read_syslog(Logs.last_read_line) - flush_logs_counter = Logs._count_logs(log_lines, Logs.FLUSH) - log_type = "FLUSH" - Logs._validate_logs_amount(flush_logs_counter, log_type) - - @staticmethod - def check_syslog_for_fua(): - """Check syslog for FUA logs""" - log_lines = Logs._read_syslog(Logs.last_read_line) - fua_logs_counter = Logs._count_logs(log_lines, Logs.FUA) - log_type = "FUA" - Logs._validate_logs_amount(fua_logs_counter, log_type) - - @staticmethod - def _read_syslog(last_read_line: int): - """Read recent lines in syslog, mark last line and return read lines as list.""" - log_lines = TestRun.executor.run_expect_success( - f"tail -qn +{last_read_line} {syslog_path}" - ).stdout.splitlines() - # mark last read line to continue next reading from here - Logs.last_read_line += len(log_lines) - - return log_lines - - @staticmethod - def _count_logs(log_lines: list, expected_log): - """Count specified log in list and return its amount.""" - logs_counter = 0 - - for line in log_lines: - is_log_in_line = expected_log.search(line) - if is_log_in_line is not None: - logs_counter += 1 - - return logs_counter - - @staticmethod - def _validate_logs_amount(logs_counter: int, log_type: str): - """Validate amount of logs and return""" - if logs_counter == 0: - if Logs._is_flush(log_type): - TestRun.LOGGER.error(f"{log_type} log not occured") - else: - TestRun.LOGGER.warning(f"{log_type} log not occured") - elif logs_counter == 1: - TestRun.LOGGER.warning(f"{log_type} log occured only once.") - else: - TestRun.LOGGER.info(f"{log_type} log occured {logs_counter} times.") - - @staticmethod - def _is_flush(log_type: str): - return log_type == "FLUSH" diff --git a/test/functional/tests/misc/test_flush_propagation.py b/test/functional/tests/misc/test_flush_propagation.py new file mode 100644 index 0000000..e22237a --- /dev/null +++ b/test/functional/tests/misc/test_flush_propagation.py @@ -0,0 +1,116 @@ +# +# Copyright(c) 2020-2022 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause +# + +import re +import pytest +from time import sleep + +from api.cas import casadm +from api.cas.cache_config import ( + CacheMode, + CleaningPolicy, + SeqCutOffPolicy, +) +from storage_devices.disk import DiskType, DiskTypeSet +from core.test_run import TestRun +from test_tools.disk_utils import Filesystem +from test_utils.scsi_debug import Logs, syslog_path +from test_tools.fs_utils import create_random_test_file +from test_utils import os_utils +from test_utils.size import Size, Unit + +mount_point = "/mnt/cas" + + +@pytest.mark.os_dependent +@pytest.mark.require_plugin("scsi_debug_fua_signals", dev_size_mb="8192", opts="1") +@pytest.mark.require_disk("core", DiskTypeSet([DiskType.optane, DiskType.nand])) +def test_flush_signal_propagation_cache(): + """ + title: Test for FLUSH signals propagation to cache device + description: | + Test if OpenCAS propagates FLUSH signal to underlaying cache device + pass_criteria: + - FLUSH requests should be propagated to cache device. + """ + with TestRun.step("Set mark in syslog to not read entries existing before the test."): + Logs._read_syslog(Logs.last_read_line) + + with TestRun.step("Prepare devices for cache and core."): + cache_dev = TestRun.scsi_debug_devices[0] + core_dev = TestRun.disks["core"] + core_dev.create_partitions([Size(2, Unit.GibiByte)]) + core_dev = core_dev.partitions[0] + + with TestRun.step("Start cache on SCSI device and add core with xfs filesystem"): + cache = casadm.start_cache(cache_dev, CacheMode.WT) + core_dev.create_filesystem(Filesystem.xfs) + core = cache.add_core(core_dev) + + with TestRun.step("Turn off cleaning policy and sequential cutoff"): + cache.set_cleaning_policy(CleaningPolicy.nop) + cache.set_seq_cutoff_policy(SeqCutOffPolicy.never) + + with TestRun.step("Mount exported object."): + if core.is_mounted(): + core.unmount() + core.mount(mount_point) + os_utils.sync() + + with TestRun.step("Create temporary file on the exported object."): + Logs._read_syslog(Logs.last_read_line) + tmp_file = create_random_test_file(f"{mount_point}/tmp.file", Size(1, Unit.GibiByte)) + os_utils.sync() + sleep(3) + + with TestRun.step(f"Check {syslog_path} for flush request and delete temporary file."): + Logs.check_syslog_for_flush() + tmp_file.remove(True) + + +@pytest.mark.os_dependent +@pytest.mark.require_plugin("scsi_debug_fua_signals", dev_size_mb="8192", opts="1") +@pytest.mark.require_disk("cache", DiskTypeSet([DiskType.optane, DiskType.nand])) +def test_flush_signal_propagation_core(): + """ + title: Test for FLUSH signals propagation to core device + description: | + Test if OpenCAS propagates FLUSH signal to underlaying core device + pass_criteria: + - FLUSH requests should be propagated to core device. + """ + with TestRun.step("Set mark in syslog to not read entries existing before the test."): + Logs._read_syslog(Logs.last_read_line) + + with TestRun.step("Prepare devices for cache and core."): + cache_dev = TestRun.disks["cache"] + core_dev = TestRun.scsi_debug_devices[0] + cache_dev.create_partitions([Size(2, Unit.GibiByte)]) + cache_dev = cache_dev.partitions[0] + + with TestRun.step("Start cache and add SCSI device with xfs filesystem as core."): + cache = casadm.start_cache(cache_dev, CacheMode.WT) + core_dev.create_filesystem(Filesystem.xfs) + core = cache.add_core(core_dev) + + with TestRun.step("Turn off cleaning policy and sequential cutoff"): + cache.set_cleaning_policy(CleaningPolicy.nop) + cache.set_seq_cutoff_policy(SeqCutOffPolicy.never) + + with TestRun.step("Mount exported object."): + if core.is_mounted(): + core.unmount() + core.mount(mount_point) + os_utils.sync() + + with TestRun.step("Create temporary file on the exported object."): + Logs._read_syslog(Logs.last_read_line) + tmp_file = create_random_test_file(f"{mount_point}/tmp.file", Size(1, Unit.GibiByte)) + os_utils.sync() + sleep(3) + + with TestRun.step(f"Check {syslog_path} for flush request and delete temporary file."): + Logs.check_syslog_for_flush() + tmp_file.remove(True)