From 149274d770f40abe10df704da294b65e03edcc02 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Wed, 20 Apr 2022 11:56:52 +0200 Subject: [PATCH 1/4] test api: add missing cache states Signed-off-by: Michal Mielewczyk --- test/functional/api/cas/cache_config.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/functional/api/cas/cache_config.py b/test/functional/api/cas/cache_config.py index 419be1c..98504d8 100644 --- a/test/functional/api/cas/cache_config.py +++ b/test/functional/api/cas/cache_config.py @@ -117,6 +117,8 @@ class CacheStatus(Enum): initializing = "initializing" flushing = "flushing" incomplete = "incomplete" + standby = "standby" + standby_detached = "standby detached" def __str__(self): return self.value From 22cb22cfc917e81deae58ff5f5169023a98f6dca Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Wed, 20 Apr 2022 11:57:46 +0200 Subject: [PATCH 2/4] test api: don't retrieving redundant cache stats Retrieving full cache stats is redundant to get cache state Signed-off-by: Michal Mielewczyk --- test/functional/api/cas/cache.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/functional/api/cas/cache.py b/test/functional/api/cas/cache.py index 5645342..9729b64 100644 --- a/test/functional/api/cas/cache.py +++ b/test/functional/api/cas/cache.py @@ -49,7 +49,11 @@ class Cache: return self.get_statistics().usage_stats.occupancy def get_status(self): - status = self.get_statistics().config_stats.status.replace(' ', '_').lower() + status = ( + self.get_statistics(stat_filter=[StatsFilter.conf]) + .config_stats.status.replace(" ", "_") + .lower() + ) return CacheStatus[status] @property From 4172fba303a855c570491f7ea55b434cf0c2ea41 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Thu, 21 Apr 2022 07:40:52 +0200 Subject: [PATCH 3/4] test api: add missing cli error message Signed-off-by: Michal Mielewczyk --- test/functional/api/cas/cli_messages.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/functional/api/cas/cli_messages.py b/test/functional/api/cas/cli_messages.py index 749c486..70881a9 100644 --- a/test/functional/api/cas/cli_messages.py +++ b/test/functional/api/cas/cli_messages.py @@ -145,6 +145,10 @@ mutually_exclusive_params_load = [ r"forbidden." ] +activate_with_different_cache_id = [ + r"Cache id specified by user and loaded from metadata are different" +] + def check_stderr_msg(output: Output, expected_messages): return __check_string_msg(output.stderr, expected_messages) From 251485b7b018fca2ba8c4fc9fbbeda76a7a442d0 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Thu, 21 Apr 2022 07:41:14 +0200 Subject: [PATCH 4/4] tests: add test_activate_neg_cache_id Signed-off-by: Michal Mielewczyk --- .../tests/fault_injection/test_standby.py | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 test/functional/tests/fault_injection/test_standby.py diff --git a/test/functional/tests/fault_injection/test_standby.py b/test/functional/tests/fault_injection/test_standby.py new file mode 100644 index 0000000..03b29f9 --- /dev/null +++ b/test/functional/tests/fault_injection/test_standby.py @@ -0,0 +1,85 @@ +# +# Copyright(c) 2019-2021 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause +# + +import pytest + +from api.cas import cli, casadm +from storage_devices.disk import DiskType, DiskTypeSet, DiskTypeLowerThan +from core.test_run import TestRun +from test_utils.size import Size, Unit +from api.cas.cache_config import CacheLineSize, CacheMode, CacheStatus +from test_tools.dd import Dd +from api.cas.cli import standby_activate_cmd +from api.cas.cli_messages import check_stderr_msg, activate_with_different_cache_id + + +@pytest.mark.require_disk("cache", DiskTypeSet([DiskType.optane, DiskType.nand])) +def test_activate_neg_cache_id(): + """ + title: Blocking cache with mismatching cache ID activation + description: | + Try restoring cache operations from a replicated cache that was initialized + with different cache ID than the original cache + pass_criteria: + - The activation is cancelled + - The cache remains in Standby detached state after an unsuccessful activation + - The cache exported object is present after an unsuccessful activation + - A proper error message is displayed + """ + with TestRun.step("Prepare two partitions of the same size"): + disk = TestRun.disks["cache"] + disk.create_partitions([Size(200, Unit.MebiByte), Size(200, Unit.MebiByte)]) + active_dev = disk.partitions[0] + standby_dev = disk.partitions[1] + + with TestRun.step( + "Start a regular cache instance explicitly providing a valid cache id and stop it" + ): + active_cache_id = 5 + standby_cache_id = 15 + cache_exp_obj_name = f"cas-cache-{standby_cache_id}" + cls = CacheLineSize.LINE_32KiB + cache = casadm.start_cache( + active_dev, cache_id=active_cache_id, cache_line_size=cls, force=True + ) + cache.stop() + + with TestRun.step( + "On the second partition initialize standby instance with different cache id" + ): + standby_cache = casadm.standby_init( + standby_dev, + cache_line_size=int(cls.value.value / Unit.KibiByte.value), + cache_id=standby_cache_id, + force=True, + ) + + with TestRun.step("Copy contents of the first partition into the cache exported object"): + Dd().input(active_dev.path).output(f"/dev/{cache_exp_obj_name}").run() + + with TestRun.step("Verify if the cache exported object appeared in the system"): + output = TestRun.executor.run_expect_success(f"ls -la /dev/ | grep {cache_exp_obj_name}") + if output.stdout[0] != "b": + TestRun.fail("The cache exported object is not a block device") + + with TestRun.step("Detach the standby instance"): + standby_cache.standby_detach() + + with TestRun.step("Try to activate the standby cache instance with different cache id"): + output = TestRun.executor.run_expect_fail( + standby_activate_cmd(cache_dev=standby_dev.path, cache_id=str(standby_cache_id)) + ) + if not check_stderr_msg(output, activate_with_different_cache_id): + TestRun.LOGGER.error( + f"Invalid error message. Expected {activate_with_different_cache_id}." + f"Got {output.stderr}" + ) + + status = standby_cache.get_status() + if status != CacheStatus.standby_detached: + TestRun.LOGGER.error( + "The standby cache instance is in an invalid state " + f"Expected {CacheStatus.standby_detached}. Got {status}" + )