From 8d2c826fef0494d1a970fc79a862984aa302a6c9 Mon Sep 17 00:00:00 2001 From: Kamil Gierszewski Date: Wed, 30 Oct 2024 01:00:27 +0100 Subject: [PATCH 1/7] tests: Don't prepare disks if test doesn't use them Signed-off-by: Kamil Gierszewski --- test/functional/tests/conftest.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/test/functional/tests/conftest.py b/test/functional/tests/conftest.py index 9c3017e69..f5f2c17c5 100644 --- a/test/functional/tests/conftest.py +++ b/test/functional/tests/conftest.py @@ -254,20 +254,21 @@ def base_prepare(item): Lvm.remove_all() LvmConfiguration.remove_filters_from_config() - raids = Raid.discover() - for raid in raids: - # stop only those RAIDs, which are comprised of test disks - if all(map(lambda device: - any(map(lambda disk_path: - disk_path in device.get_device_id(), - [bd.get_device_id() for bd in TestRun.dut.disks])), - raid.array_devices)): - raid.remove_partitions() - raid.unmount() - raid.stop() - for device in raid.array_devices: - Mdadm.zero_superblock(posixpath.join('/dev', device.get_device_id())) - Udev.settle() + if len(TestRun.disks): + raids = Raid.discover() + for raid in raids: + # stop only those RAIDs, which are comprised of test disks + if all(map(lambda device: + any(map(lambda disk_path: + disk_path in device.get_device_id(), + [bd.get_device_id() for bd in TestRun.dut.disks])), + raid.array_devices)): + raid.umount_all_partitions() + raid.remove_partitions() + raid.stop() + for device in raid.array_devices: + Mdadm.zero_superblock(posixpath.join('/dev', device.get_device_id())) + Udev.settle() RamDisk.remove_all() for disk in TestRun.dut.disks: From 8e74f84c8c10dbbe8d0cbca7d5e8922d968ce6ef Mon Sep 17 00:00:00 2001 From: Kamil Gierszewski Date: Wed, 30 Oct 2024 01:05:52 +0100 Subject: [PATCH 2/7] tests: reformat tests Signed-off-by: Kamil Gierszewski --- .../tests/cli/test_zero_metadata_command.py | 68 ++++++++++--------- .../tests/misc/test_device_capabilities.py | 16 +++-- 2 files changed, 45 insertions(+), 39 deletions(-) diff --git a/test/functional/tests/cli/test_zero_metadata_command.py b/test/functional/tests/cli/test_zero_metadata_command.py index 0fed8af08..b50e3ed08 100644 --- a/test/functional/tests/cli/test_zero_metadata_command.py +++ b/test/functional/tests/cli/test_zero_metadata_command.py @@ -3,11 +3,12 @@ # Copyright(c) 2024 Huawei Technologies Co., Ltd. # SPDX-License-Identifier: BSD-3-Clause # -import time -from datetime import timedelta +import time import pytest +from datetime import timedelta + from api.cas import casadm, cli_messages, cli from api.cas.cache_config import CacheMode, CleaningPolicy from core.test_run import TestRun @@ -24,15 +25,16 @@ @pytest.mark.require_disk("core", DiskTypeLowerThan("cache")) def test_zero_metadata_negative_cases(): """ - title: Test for '--zero-metadata' negative cases. - description: | - Test for '--zero-metadata' scenarios with expected failures. - pass_criteria: - - Zeroing metadata without '--force' failed when run on cache. - - Zeroing metadata with '--force' failed when run on cache. - - Zeroing metadata failed when run on system drive. - - Load cache command failed after successfully zeroing metadata on the cache device. + title: Test for '--zero-metadata' negative cases. + description: | + Test for '--zero-metadata' scenarios with expected failures. + pass_criteria: + - Zeroing metadata without '--force' failed when run on cache. + - Zeroing metadata with '--force' failed when run on cache. + - Zeroing metadata failed when run on system drive. + - Load cache command failed after successfully zeroing metadata on the cache device. """ + with TestRun.step("Prepare cache and core devices."): cache_dev, core_dev, cache_disk = prepare_devices() @@ -86,14 +88,15 @@ def test_zero_metadata_negative_cases(): @pytest.mark.parametrizex("filesystem", Filesystem) def test_zero_metadata_filesystem(filesystem): """ - title: Test for '--zero-metadata' and filesystem. - description: | - Test for '--zero-metadata' on drive with filesystem. - pass_criteria: - - Zeroing metadata on device with filesystem failed and not removed filesystem. - - Zeroing metadata on mounted device failed. + title: Test for '--zero-metadata' and filesystem. + description: | + Test for '--zero-metadata' on drive with filesystem. + pass_criteria: + - Zeroing metadata on device with filesystem failed and not removed filesystem. + - Zeroing metadata on mounted device failed. """ mount_point = "/mnt" + with TestRun.step("Prepare devices."): cache_dev, core_disk, cache_disk = prepare_devices() @@ -131,15 +134,16 @@ def test_zero_metadata_filesystem(filesystem): @pytest.mark.require_disk("core", DiskTypeLowerThan("cache")) def test_zero_metadata_dirty_data(): """ - title: Test for '--zero-metadata' and dirty data scenario. - description: | - Test for '--zero-metadata' with and without 'force' option if there are dirty data - on cache. - pass_criteria: - - Zeroing metadata without force failed on cache with dirty data. - - Zeroing metadata with force ran successfully on cache with dirty data. - - Cache started successfully after zeroing metadata on cache with dirty data. + title: Test for '--zero-metadata' and dirty data scenario. + description: | + Test for '--zero-metadata' with and without 'force' option if there are dirty data + on cache. + pass_criteria: + - Zeroing metadata without force failed on cache with dirty data. + - Zeroing metadata with force ran successfully on cache with dirty data. + - Cache started successfully after zeroing metadata on cache with dirty data. """ + with TestRun.step("Prepare cache and core devices."): cache_dev, core_disk, cache_disk = prepare_devices() @@ -196,14 +200,14 @@ def test_zero_metadata_dirty_data(): @pytest.mark.require_disk("core", DiskTypeLowerThan("cache")) def test_zero_metadata_dirty_shutdown(): """ - title: Test for '--zero-metadata' and dirty shutdown scenario. - description: | - Test for '--zero-metadata' with and without 'force' option on cache which had been dirty - shut down before. - pass_criteria: - - Zeroing metadata without force failed on cache after dirty shutdown. - - Zeroing metadata with force ran successfully on cache after dirty shutdown. - - Cache started successfully after dirty shutdown and zeroing metadata on cache. + title: Test for '--zero-metadata' and dirty shutdown scenario. + description: | + Test for '--zero-metadata' with and without 'force' option on cache which had been dirty + shut down before. + pass_criteria: + - Zeroing metadata without force failed on cache after dirty shutdown. + - Zeroing metadata with force ran successfully on cache after dirty shutdown. + - Cache started successfully after dirty shutdown and zeroing metadata on cache. """ with TestRun.step("Prepare cache and core devices."): cache_dev, core_disk, cache_disk = prepare_devices() diff --git a/test/functional/tests/misc/test_device_capabilities.py b/test/functional/tests/misc/test_device_capabilities.py index 95e591d8c..0f05133b6 100644 --- a/test/functional/tests/misc/test_device_capabilities.py +++ b/test/functional/tests/misc/test_device_capabilities.py @@ -1,11 +1,13 @@ # # Copyright(c) 2020-2021 Intel Corporation +# Copyright(c) 2024 Huawei Technologies Co., Ltd. # SPDX-License-Identifier: BSD-3-Clause # import math import pytest import os + from api.cas import casadm, cli_messages from api.cas.cache_config import CacheLineSize from core.test_run import TestRun @@ -22,13 +24,13 @@ @pytest.mark.require_plugin("scsi_debug") def test_device_capabilities(): """ - title: Test whether CAS device capabilities are properly set. - description: | - Test if CAS device takes into consideration differences between devices which are used to - create it. - pass_criteria: - - CAS device starts successfully using differently configured devices. - - CAS device capabilities are as expected. + title: Test whether CAS device capabilities are properly set. + description: | + Test if CAS device takes into consideration differences between devices which are used to + create it. + pass_criteria: + - CAS device starts successfully using differently configured devices. + - CAS device capabilities are as expected. """ core_device = TestRun.disks['core'] From 6ebfe476e7784def14bb9fff48aabeb5c817ab80 Mon Sep 17 00:00:00 2001 From: Kamil Gierszewski Date: Wed, 30 Oct 2024 01:07:50 +0100 Subject: [PATCH 3/7] tests: Use cached device_ids + fix posix path Signed-off-by: Kamil Gierszewski --- test/functional/tests/conftest.py | 6 ++-- .../tests/misc/test_device_capabilities.py | 29 +++++++++---------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/test/functional/tests/conftest.py b/test/functional/tests/conftest.py index f5f2c17c5..942086052 100644 --- a/test/functional/tests/conftest.py +++ b/test/functional/tests/conftest.py @@ -260,8 +260,8 @@ def base_prepare(item): # stop only those RAIDs, which are comprised of test disks if all(map(lambda device: any(map(lambda disk_path: - disk_path in device.get_device_id(), - [bd.get_device_id() for bd in TestRun.dut.disks])), + disk_path in device.device_id, + [bd.device_id for bd in TestRun.dut.disks])), raid.array_devices)): raid.umount_all_partitions() raid.remove_partitions() @@ -280,7 +280,7 @@ def base_prepare(item): ) disk.remove_partitions() disk.unmount() - Mdadm.zero_superblock(posixpath.join('/dev', disk.get_device_id())) + Mdadm.zero_superblock(posixpath.join('/dev', disk.device_id)) create_partition_table(disk, PartitionTable.gpt) TestRun.usr.already_updated = True diff --git a/test/functional/tests/misc/test_device_capabilities.py b/test/functional/tests/misc/test_device_capabilities.py index 0f05133b6..4ce8ce42b 100644 --- a/test/functional/tests/misc/test_device_capabilities.py +++ b/test/functional/tests/misc/test_device_capabilities.py @@ -5,8 +5,8 @@ # import math +import posixpath import pytest -import os from api.cas import casadm, cli_messages from api.cas.cache_config import CacheLineSize @@ -32,12 +32,11 @@ def test_device_capabilities(): - CAS device starts successfully using differently configured devices. - CAS device capabilities are as expected. """ - - core_device = TestRun.disks['core'] - max_io_size_path = os.path.join(disk_utils.get_sysfs_path(core_device.get_device_id()), - 'queue/max_sectors_kb') + core_device = TestRun.disks["core"] + max_io_size_path = posixpath.join( + disk_utils.get_sysfs_path(core_device.device_id), "queue/max_sectors_kb" + ) default_max_io_size = fs_utils.read_file(max_io_size_path) - iteration_settings = [ {"device": "SCSI-debug module", "dev_size_mb": 1024, "logical_block_size": 512, "max_sectors_kb": 1024}, @@ -106,8 +105,8 @@ def create_scsi_debug_device(sector_size: int, physblk_exp: int, dev_size_mb=102 def prepare_cas_device(cache_device, core_device): cache = casadm.start_cache(cache_device, cache_line_size=CacheLineSize.LINE_64KiB, force=True) try: - cache_dev_bs = disk_utils.get_block_size(cache_device.get_device_id()) - core_dev_bs = disk_utils.get_block_size(core_device.get_device_id()) + cache_dev_bs = disk_utils.get_block_size(cache_device.device_id) + core_dev_bs = disk_utils.get_block_size(core_device.device_id) core = cache.add_core(core_device) if cache_dev_bs > core_dev_bs: TestRun.LOGGER.error( @@ -147,10 +146,10 @@ def method_lcm_not_zero(a, b): def measure_capabilities(dev): dev_capabilities = {} - dev_id = dev.parent_device.get_device_id() if isinstance(dev, Partition) \ - else dev.get_device_id() + dev_id = dev.parent_device.device_id if isinstance(dev, Partition) \ + else dev.device_id for c in capabilities: - path = os.path.join(disk_utils.get_sysfs_path(dev_id), 'queue', c) + path = posixpath.join(disk_utils.get_sysfs_path(dev_id), 'queue', c) command = f"cat {path}" output = TestRun.executor.run(command) if output.exit_code == 0: @@ -167,10 +166,10 @@ def compare_capabilities(cache_device, core_device, cache, core, msg): cli_messages.try_add_core_sector_size_mismatch) else: core_dev_sectors_num = \ - disk_utils.get_size(core_device.get_device_id()) / disk_utils.get_block_size( - core_device.get_device_id()) - core_sectors_num = disk_utils.get_size(core.get_device_id()) / disk_utils.get_block_size( - core.get_device_id()) + disk_utils.get_size(core_device.device_id) / disk_utils.get_block_size( + core_device.device_id) + core_sectors_num = disk_utils.get_size(core.device_id) / disk_utils.get_block_size( + core.device_id) if core_dev_sectors_num != core_sectors_num: TestRun.LOGGER.error( "Number of sectors in CAS device and attached core device is different.") From 3ec2e40dd89c1bc106b27e8d268244829cf83d7b Mon Sep 17 00:00:00 2001 From: Kamil Gierszewski Date: Wed, 30 Oct 2024 01:26:22 +0100 Subject: [PATCH 4/7] tests: Kill IO faster in prepare/teardown Signed-off-by: Kamil Gierszewski --- test/functional/tests/conftest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/functional/tests/conftest.py b/test/functional/tests/conftest.py index 942086052..36a5e5942 100644 --- a/test/functional/tests/conftest.py +++ b/test/functional/tests/conftest.py @@ -142,7 +142,7 @@ def pytest_runtest_teardown(): if not TestRun.executor.is_active(): TestRun.executor.wait_for_connection() Udev.enable() - kill_all_io() + kill_all_io(graceful=False) unmount_cas_devices() if installer.check_if_installed(): @@ -230,7 +230,7 @@ def base_prepare(item): with TestRun.LOGGER.step("Cleanup before test"): TestRun.executor.run("pkill --signal=SIGKILL fsck") Udev.enable() - kill_all_io() + kill_all_io(graceful=False) DeviceMapper.remove_all() if installer.check_if_installed(): From 86bf6bc6c85097821c63d37e20436e52cf788633 Mon Sep 17 00:00:00 2001 From: Kamil Gierszewski Date: Wed, 30 Oct 2024 01:28:28 +0100 Subject: [PATCH 5/7] tests: More readable RAID teardown Signed-off-by: Kamil Gierszewski --- test/functional/tests/conftest.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/test/functional/tests/conftest.py b/test/functional/tests/conftest.py index 36a5e5942..34f3711a6 100644 --- a/test/functional/tests/conftest.py +++ b/test/functional/tests/conftest.py @@ -258,11 +258,8 @@ def base_prepare(item): raids = Raid.discover() for raid in raids: # stop only those RAIDs, which are comprised of test disks - if all(map(lambda device: - any(map(lambda disk_path: - disk_path in device.device_id, - [bd.device_id for bd in TestRun.dut.disks])), - raid.array_devices)): + test_run_disk_ids = {dev.device_id for dev in TestRun.disks.values()} + if filter(lambda dev: dev.device_id in test_run_disk_ids, raid.array_devices): raid.umount_all_partitions() raid.remove_partitions() raid.stop() From 05dcc202d1b5b7330c83afc828428ad42d5fc9f4 Mon Sep 17 00:00:00 2001 From: Kamil Gierszewski Date: Wed, 30 Oct 2024 01:29:08 +0100 Subject: [PATCH 6/7] tests: Don't clean-up drives that won't be used Signed-off-by: Kamil Gierszewski --- test/functional/tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/tests/conftest.py b/test/functional/tests/conftest.py index 34f3711a6..62c1a6ae2 100644 --- a/test/functional/tests/conftest.py +++ b/test/functional/tests/conftest.py @@ -268,7 +268,7 @@ def base_prepare(item): Udev.settle() RamDisk.remove_all() - for disk in TestRun.dut.disks: + for disk in TestRun.disks.values(): disk_serial = get_disk_serial_number(disk.path) if disk.serial_number and disk.serial_number != disk_serial: raise Exception( From b4c366e19a3ac8d7d42650c2ce99a4d58026d592 Mon Sep 17 00:00:00 2001 From: Kamil Gierszewski Date: Wed, 30 Oct 2024 02:39:13 +0100 Subject: [PATCH 7/7] tests: reformat conftest Signed-off-by: Kamil Gierszewski --- test/functional/tests/conftest.py | 226 ++++++++++++++++-------------- 1 file changed, 118 insertions(+), 108 deletions(-) diff --git a/test/functional/tests/conftest.py b/test/functional/tests/conftest.py index 62c1a6ae2..465eadc39 100644 --- a/test/functional/tests/conftest.py +++ b/test/functional/tests/conftest.py @@ -8,12 +8,12 @@ import posixpath import sys import traceback -from datetime import timedelta - import paramiko import pytest import yaml +from datetime import timedelta + sys.path.append(os.path.join(os.path.dirname(__file__), "../test-framework")) from core.test_run import Blocked @@ -33,14 +33,27 @@ from log.logger import create_log, Log from test_utils.singleton import Singleton from storage_devices.lvm import Lvm, LvmConfiguration +from storage_devices.drbd import Drbd +from api.cas.init_config import InitConfig -class Opencas(metaclass=Singleton): - def __init__(self, repo_dir, working_dir): - self.repo_dir = repo_dir - self.working_dir = working_dir - self.already_updated = False - self.fuzzy_iter_count = 1000 +def pytest_addoption(parser): + TestRun.addoption(parser) + parser.addoption("--dut-config", action="append", type=str) + parser.addoption( + "--log-path", + action="store", + default=f"{os.path.join(os.path.dirname(__file__), '../results')}", + ) + parser.addoption("--fuzzy-iter-count", action="store") + + +def pytest_configure(config): + TestRun.configure(config) + + +def pytest_generate_tests(metafunc): + TestRun.generate_tests(metafunc) def pytest_collection_modifyitems(config, items): @@ -63,15 +76,16 @@ def pytest_runtest_setup(item): # User can also have own test wrapper, which runs test prepare, cleanup, etc. # Then it should be placed in plugins package - test_name = item.name.split('[')[0] - TestRun.LOGGER = create_log(item.config.getoption('--log-path'), test_name) + test_name = item.name.split("[")[0] + TestRun.LOGGER = create_log(item.config.getoption("--log-path"), test_name) - duts = item.config.getoption('--dut-config') + duts = item.config.getoption("--dut-config") required_duts = next(item.iter_markers(name="multidut"), None) required_duts = required_duts.args[0] if required_duts is not None else 1 if required_duts > len(duts): - raise Exception(f"Test requires {required_duts} DUTs, only {len(duts)} DUT configs " - f"provided") + raise Exception( + f"Test requires {required_duts} DUTs, only {len(duts)} DUT configs " f"provided" + ) else: duts = duts[:required_duts] @@ -81,12 +95,13 @@ def pytest_runtest_setup(item): with open(dut) as cfg: dut_config = yaml.safe_load(cfg) except Exception as ex: - raise Exception(f"{ex}\n" - f"You need to specify DUT config. See the example_dut_config.py file") + raise Exception( + f"{ex}\n" f"You need to specify DUT config. See the example_dut_config.py file" + ) - dut_config['plugins_dir'] = os.path.join(os.path.dirname(__file__), "../lib") - dut_config['opt_plugins'] = {"test_wrapper": {}, "serial_log": {}, "power_control": {}} - dut_config['extra_logs'] = {"cas": "/var/log/opencas.log"} + dut_config["plugins_dir"] = os.path.join(os.path.dirname(__file__), "../lib") + dut_config["opt_plugins"] = {"test_wrapper": {}, "serial_log": {}, "power_control": {}} + dut_config["extra_logs"] = {"cas": "/var/log/opencas.log"} try: TestRun.prepare(item, dut_config) @@ -98,20 +113,22 @@ def pytest_runtest_setup(item): raise except Exception: try: - TestRun.plugin_manager.get_plugin('power_control').power_cycle() + TestRun.plugin_manager.get_plugin("power_control").power_cycle() TestRun.executor.wait_for_connection() except Exception: raise Exception("Failed to connect to DUT.") TestRun.setup() except Exception as ex: - raise Exception(f"Exception occurred during test setup:\n" - f"{str(ex)}\n{traceback.format_exc()}") + raise Exception( + f"Exception occurred during test setup:\n" f"{str(ex)}\n{traceback.format_exc()}" + ) TestRun.usr = Opencas( repo_dir=os.path.join(os.path.dirname(__file__), "../../.."), - working_dir=dut_config['working_dir']) - if item.config.getoption('--fuzzy-iter-count'): - TestRun.usr.fuzzy_iter_count = int(item.config.getoption('--fuzzy-iter-count')) + working_dir=dut_config["working_dir"], + ) + if item.config.getoption("--fuzzy-iter-count"): + TestRun.usr.fuzzy_iter_count = int(item.config.getoption("--fuzzy-iter-count")) TestRun.LOGGER.info(f"DUT info: {TestRun.dut}") TestRun.dut.plugin_manager = TestRun.plugin_manager @@ -123,6 +140,65 @@ def pytest_runtest_setup(item): TestRun.LOGGER.start_group("Test body") +def base_prepare(item): + with TestRun.LOGGER.step("Cleanup before test"): + TestRun.executor.run("pkill --signal=SIGKILL fsck") + Udev.enable() + kill_all_io(graceful=False) + DeviceMapper.remove_all() + + if installer.check_if_installed(): + try: + InitConfig.create_default_init_config() + unmount_cas_devices() + casadm.stop_all_caches() + casadm.remove_all_detached_cores() + except Exception: + pass # TODO: Reboot DUT if test is executed remotely + + remove(str(opencas_drop_in_directory), recursive=True, ignore_errors=True) + + if Drbd.is_installed(): + __drbd_cleanup() + + lvms = Lvm.discover() + if lvms: + Lvm.remove_all() + LvmConfiguration.remove_filters_from_config() + + if len(TestRun.disks): + raids = Raid.discover() + for raid in raids: + # stop only those RAIDs, which are comprised of test disks + test_run_disk_ids = {dev.device_id for dev in TestRun.disks.values()} + if filter(lambda dev: dev.device_id in test_run_disk_ids, raid.array_devices): + raid.umount_all_partitions() + raid.remove_partitions() + raid.stop() + for device in raid.array_devices: + Mdadm.zero_superblock(posixpath.join("/dev", device.get_device_id())) + Udev.settle() + + RamDisk.remove_all() + for disk in TestRun.disks.values(): + disk_serial = get_disk_serial_number(disk.path) + if disk.serial_number and disk.serial_number != disk_serial: + raise Exception( + f"Serial for {disk.path} doesn't match the one from the config." + f"Serial from config {disk.serial_number}, actual serial {disk_serial}" + ) + disk.remove_partitions() + disk.unmount() + Mdadm.zero_superblock(posixpath.join("/dev", disk.device_id)) + create_partition_table(disk, PartitionTable.gpt) + + TestRun.usr.already_updated = True + TestRun.LOGGER.add_build_info(f"Commit hash:") + TestRun.LOGGER.add_build_info(f"{git.get_current_commit_hash()}") + TestRun.LOGGER.add_build_info(f"Commit message:") + TestRun.LOGGER.add_build_info(f"{git.get_current_commit_message()}") + + @pytest.hookimpl(tryfirst=True, hookwrapper=True) def pytest_runtest_makereport(item, call): res = (yield).get_result() @@ -148,10 +224,8 @@ def pytest_runtest_teardown(): if installer.check_if_installed(): casadm.remove_all_detached_cores() casadm.stop_all_caches() - from api.cas.init_config import InitConfig InitConfig.create_default_init_config() - from storage_devices.drbd import Drbd if installer.check_if_installed() and Drbd.is_installed(): try: casadm.stop_all_caches() @@ -163,38 +237,28 @@ def pytest_runtest_teardown(): DeviceMapper.remove_all() RamDisk.remove_all() except Exception as ex: - TestRun.LOGGER.warning(f"Exception occurred during platform cleanup.\n" - f"{str(ex)}\n{traceback.format_exc()}") + TestRun.LOGGER.warning( + f"Exception occurred during platform cleanup.\n" + f"{str(ex)}\n{traceback.format_exc()}" + ) TestRun.LOGGER.end() for dut in TestRun.duts: with TestRun.use_dut(dut): if TestRun.executor: - os.makedirs(os.path.join(TestRun.LOGGER.base_dir, "dut_info", - dut.ip if dut.ip is not None - else dut.config.get("host")), - exist_ok=True) + os.makedirs( + os.path.join( + TestRun.LOGGER.base_dir, + "dut_info", + dut.ip if dut.ip is not None else dut.config.get("host"), + ), + exist_ok=True, + ) TestRun.LOGGER.get_additional_logs() Log.destroy() TestRun.teardown() -def pytest_configure(config): - TestRun.configure(config) - - -def pytest_generate_tests(metafunc): - TestRun.generate_tests(metafunc) - - -def pytest_addoption(parser): - TestRun.addoption(parser) - parser.addoption("--dut-config", action="append", type=str) - parser.addoption("--log-path", action="store", - default=f"{os.path.join(os.path.dirname(__file__), '../results')}") - parser.addoption("--fuzzy-iter-count", action="store") - - def unmount_cas_devices(): output = TestRun.executor.run("cat /proc/mounts | grep cas") # If exit code is '1' but stdout is empty, there is no mounted cas devices @@ -218,7 +282,6 @@ def unmount_cas_devices(): def __drbd_cleanup(): - from storage_devices.drbd import Drbd Drbd.down_all() # If drbd instance had been configured on top of the CAS, the previos attempt to stop # failed. As drbd has been stopped try to stop CAS one more time. @@ -226,62 +289,9 @@ def __drbd_cleanup(): casadm.stop_all_caches() -def base_prepare(item): - with TestRun.LOGGER.step("Cleanup before test"): - TestRun.executor.run("pkill --signal=SIGKILL fsck") - Udev.enable() - kill_all_io(graceful=False) - DeviceMapper.remove_all() - - if installer.check_if_installed(): - try: - from api.cas.init_config import InitConfig - InitConfig.create_default_init_config() - unmount_cas_devices() - casadm.stop_all_caches() - casadm.remove_all_detached_cores() - except Exception: - pass # TODO: Reboot DUT if test is executed remotely - - remove(str(opencas_drop_in_directory), recursive=True, ignore_errors=True) - - from storage_devices.drbd import Drbd - if Drbd.is_installed(): - __drbd_cleanup() - - lvms = Lvm.discover() - if lvms: - Lvm.remove_all() - LvmConfiguration.remove_filters_from_config() - - if len(TestRun.disks): - raids = Raid.discover() - for raid in raids: - # stop only those RAIDs, which are comprised of test disks - test_run_disk_ids = {dev.device_id for dev in TestRun.disks.values()} - if filter(lambda dev: dev.device_id in test_run_disk_ids, raid.array_devices): - raid.umount_all_partitions() - raid.remove_partitions() - raid.stop() - for device in raid.array_devices: - Mdadm.zero_superblock(posixpath.join('/dev', device.get_device_id())) - Udev.settle() - - RamDisk.remove_all() - for disk in TestRun.disks.values(): - disk_serial = get_disk_serial_number(disk.path) - if disk.serial_number and disk.serial_number != disk_serial: - raise Exception( - f"Serial for {disk.path} doesn't match the one from the config." - f"Serial from config {disk.serial_number}, actual serial {disk_serial}" - ) - disk.remove_partitions() - disk.unmount() - Mdadm.zero_superblock(posixpath.join('/dev', disk.device_id)) - create_partition_table(disk, PartitionTable.gpt) - - TestRun.usr.already_updated = True - TestRun.LOGGER.add_build_info(f'Commit hash:') - TestRun.LOGGER.add_build_info(f"{git.get_current_commit_hash()}") - TestRun.LOGGER.add_build_info(f'Commit message:') - TestRun.LOGGER.add_build_info(f'{git.get_current_commit_message()}') +class Opencas(metaclass=Singleton): + def __init__(self, repo_dir, working_dir): + self.repo_dir = repo_dir + self.working_dir = working_dir + self.already_updated = False + self.fuzzy_iter_count = 1000