From aeae7c9765315e5e5586ca7055b6f002f2e2abf1 Mon Sep 17 00:00:00 2001 From: Katarzyna Lapinska Date: Mon, 8 Jun 2020 09:40:39 +0200 Subject: [PATCH] Add test for checking the ability of CAS to start cache instances upon system boot after dirty shutdown during IO workloads Signed-off-by: Katarzyna Lapinska --- .../tests/stress/test_stress_shutdown.py | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 test/functional/tests/stress/test_stress_shutdown.py diff --git a/test/functional/tests/stress/test_stress_shutdown.py b/test/functional/tests/stress/test_stress_shutdown.py new file mode 100644 index 0000000..c30a8ec --- /dev/null +++ b/test/functional/tests/stress/test_stress_shutdown.py @@ -0,0 +1,108 @@ +# +# Copyright(c) 2020 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# + +import time +import pytest +from datetime import timedelta +from api.cas import casadm, casadm_parser +from api.cas.cache_config import CacheLineSize, CacheMode, CleaningPolicy, CacheModeTrait +from api.cas.init_config import InitConfig +from core.test_run import TestRun +from storage_devices.disk import DiskType, DiskTypeLowerThan, DiskTypeSet +from test_tools.fio.fio import Fio +from test_tools.fio.fio_param import IoEngine, ReadWrite +from test_utils.size import Size, Unit + +cores_number = 2 +iterations_per_config = 5 + + +@pytest.mark.parametrize("cache_mode", CacheMode.with_traits(CacheModeTrait.LazyWrites)) +@pytest.mark.parametrize("cleaning_policy", CleaningPolicy) +@pytest.mark.parametrize("cache_line_size", CacheLineSize) +@pytest.mark.require_disk("cache", DiskTypeSet([DiskType.optane, DiskType.nand])) +@pytest.mark.require_disk("core", DiskTypeLowerThan("cache")) +@pytest.mark.require_plugin("power_control") +def test_stress_dirty_shutdown(cache_line_size, cache_mode, cleaning_policy): + """ + title: Stress test for dirty shutdowns during IO workload. + description: | + Validate the ability of CAS to start cache instances upon system boot after + dirty shutdown during IO workloads. + pass_criteria: + - No system crash. + - CAS loads correctly after DUT hard reset. + """ + with TestRun.step("Prepare devices."): + cache_dev = TestRun.disks['cache'] + cache_dev.create_partitions([Size(5, Unit.GibiByte)]) + cache_part = cache_dev.partitions[0] + core_dev = TestRun.disks['core'] + core_sizes = [Size(5, Unit.GibiByte)] * cores_number + core_dev.create_partitions(core_sizes) + + with TestRun.step("Start cache according to configuration and add core devices."): + cache = casadm.start_cache(cache_part, cache_mode, cache_line_size, force=True) + if cleaning_policy is not None: + cache.set_cleaning_policy(cleaning_policy) + exported_objects = [] + for i in range(0, cores_number): + exported_objects.append(cache.add_core(core_dev.partitions[i])) + + with TestRun.step("Create CAS init configuration file based on running configuration."): + InitConfig.create_init_config_from_running_configuration() + + for _ in TestRun.iteration(range(0, iterations_per_config), + "Load cache after reboot while heavy IO."): + with TestRun.step("Start heavy IO workload on both CAS devices."): + run_io(exported_objects) + time.sleep(120) + + with TestRun.step("Reset platform."): + power_control = TestRun.plugin_manager.get_plugin('power_control') + power_control.power_cycle() + + with TestRun.step("Check configuration after load."): + check_configuration(cleaning_policy, cache_mode, cache_line_size) + + with TestRun.step("Stop cache."): + cache.stop() + + +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 run_io(exported_objects): + for i in range(0, cores_number): + fio = Fio() \ + .create_command() \ + .read_write(ReadWrite.randrw) \ + .io_engine(IoEngine.libaio) \ + .direct() \ + .sync() \ + .io_depth(32) \ + .run_time(timedelta(minutes=5)) \ + .num_jobs(5) \ + .target(exported_objects[i].system_path) + fio.run_in_background()