From 117d1d7c39d73d2657b55563d5dd5ffc33c71c84 Mon Sep 17 00:00:00 2001 From: Bernhard Kaindl Date: Thu, 28 Mar 2024 12:00:00 +0100 Subject: [PATCH] CP-48198: Support running pytest within the test directories Signed-off-by: Bernhard Kaindl --- tests/conftest.py | 39 ++++++++++++++++++++++ tests/integration/conftest.py | 15 +++++++-- tests/integration/test_system_load.py | 4 +-- tests/integration/test_xenserver_config.py | 4 +-- tests/integration/utils.py | 12 +++---- tests/unit/conftest.py | 6 ---- tests/unit/test_main.py | 5 ++- tests/unit/test_output.py | 3 +- 8 files changed, 65 insertions(+), 23 deletions(-) create mode 100644 tests/conftest.py diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..ded69b06 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,39 @@ +"""tests/conftest.py: top-level pytest fixtures for testing xen-bugtool + +Introduction to fixtures: +https://docs.pytest.org/en/8.0.x/fixture.html + +How to use fixtures: +https://docs.pytest.org/en/8.0.x/how-to/fixtures.html + +The full documentation on fixtures: +https://docs.pytest.org/en/8.0.x/reference/fixtures.html +""" + +import os + +import pytest + + +@pytest.fixture(scope="session") +def tests_dir(): + """pytest fixture to provide the path to status-report/tests""" + return os.path.dirname(__file__) + + +@pytest.fixture(scope="session") +def bugtool_script(tests_dir): + """pytest fixture to provide the path to status-report/tests""" + return os.path.abspath(os.path.join(tests_dir, os.pardir, "xen-bugtool")) + + +@pytest.fixture(scope="session") +def mocks_dir(tests_dir): + """pytest fixture to provide the path to status-report/tests/mocks""" + return os.path.join(tests_dir, "mocks") + + +@pytest.fixture(scope="session") +def dom0_template(tests_dir): + """Fixture to provide the path to status-report/tests/integration/dom0-template""" + return os.path.join(tests_dir, "integration", "dom0-template") diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index a7f92935..a213cdfb 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -6,6 +6,7 @@ from __future__ import print_function import os +import sys import pytest @@ -18,10 +19,18 @@ @pytest.fixture(autouse=True, scope="session") -def create_and_enter_test_environment(): +def create_and_enter_test_environment(mocks_dir): """Activate a namespace with bind mounts for testing xen-bugtool""" - activate_private_test_namespace(BUGTOOL_DOM0_TEMPL, ["/etc", "/opt", "/usr/sbin", "/usr/lib/systemd"]) - os.environ["PYTHONPATH"] = "tests/mocks" + + activate_private_test_namespace( + BUGTOOL_DOM0_TEMPL, + ["/etc", "/opt", "/usr/sbin", "/usr/lib/systemd"], + ) + + # Add the mocks directory to the PYTHONPATH for sub-processes to find the mocks: + os.environ["PYTHONPATH"] = mocks_dir + # Add the mocks directory to the sys.path for the current process to find the mocks: + sys.path.insert(0, mocks_dir) # zip, tar, tar.bz2 are the three output formats supported by xen_bugtool: diff --git a/tests/integration/test_system_load.py b/tests/integration/test_system_load.py index d6b20960..0da3abaa 100644 --- a/tests/integration/test_system_load.py +++ b/tests/integration/test_system_load.py @@ -11,7 +11,7 @@ # In this test case we need to sleep for 1 sec, and it is sufficient # to test to only with zip archives to keep the test duration short: -def test_system_load(output_archive_type="zip"): +def test_system_load(bugtool_script, output_archive_type="zip"): """Test xen-bugtool --entries=system-load""" entry = "system-load" @@ -30,7 +30,7 @@ def test_system_load(output_archive_type="zip"): sar.write("#!/bin/sh\nsleep 1;cat /etc/xensource-inventory\n") os.chmod("/var/sar", 0o777) # nosec - run_bugtool_entry(output_archive_type, entry) + run_bugtool_entry(bugtool_script, output_archive_type, entry) assert_content_from_dom0_template("sar-A.out", "etc/xensource-inventory") assert_file("var/log/sa/sa01", "sa01 test data") diff --git a/tests/integration/test_xenserver_config.py b/tests/integration/test_xenserver_config.py index 797dbc12..415264e0 100644 --- a/tests/integration/test_xenserver_config.py +++ b/tests/integration/test_xenserver_config.py @@ -10,14 +10,14 @@ ) -def test_xenserver_config(output_archive_type): +def test_xenserver_config(bugtool_script, output_archive_type): """ Run xen-bugtool --entries=xenserver-config in test jail (created by auto-fixtures, see README-pytest-chroot.md) """ entry = "xenserver-config" - run_bugtool_entry(output_archive_type, entry) + run_bugtool_entry(bugtool_script, output_archive_type, entry) # Check the output of xen-bugtool --entries=xenserver-config: diff --git a/tests/integration/utils.py b/tests/integration/utils.py index 072f8adc..1b428f24 100644 --- a/tests/integration/utils.py +++ b/tests/integration/utils.py @@ -19,7 +19,7 @@ from subprocess import getstatusoutput BUGTOOL_OUTPUT_DIR = "/var/opt/xen/bug-report/" -BUGTOOL_DOM0_TEMPL = "tests/integration/dom0-template/" +BUGTOOL_DOM0_TEMPL = os.path.join(os.path.dirname(__file__), "dom0-template") def run(command): @@ -78,7 +78,7 @@ def assert_content_from_dom0_template(path, control_path=None): """Check the given path against the files from the test's Dom0 template""" assert path[0] != "/" # We expect a relative path in the report archive - control = BUGTOOL_DOM0_TEMPL + (control_path or path) + control = os.path.join(BUGTOOL_DOM0_TEMPL, (control_path or path)) print(control) if os.path.isdir(path): # path is a directory, compare it recursively using dircmp(): @@ -126,7 +126,7 @@ def extract(zip_or_tar_archive, archive_type): # pragma: no cover os.unlink(zip_or_tar_archive) -def run_bugtool_entry(archive_type, test_entries): +def run_bugtool_entry(bugtool_script, archive_type, test_entries): """ Execute the bugtool script with the given entries and prepare testing it. @@ -150,8 +150,6 @@ def run_bugtool_entry(archive_type, test_entries): if error_code: raise RuntimeError(output) - src_dir = os.getcwd() - # # Switch to the BUGTOOL_OUTPUT_DIR and extract the bugball in it. # @@ -166,9 +164,7 @@ def run_bugtool_entry(archive_type, test_entries): os.chdir(test_entries) # Validate the extracted inventory.xml using the XML schema from the test framework: - with open(src_dir + "/tests/integration/inventory.xsd") as xml_schema: + with open(os.path.join(os.path.dirname(__file__), "inventory.xsd")) as xml_schema: XMLSchema(parse(xml_schema)).assertValid(parse("inventory.xml")) # Remove valid inventory.xml (not removed files will make the tests fail): os.unlink("inventory.xml") - # Add a symlink, so assert_content_from_dom0_template() can find the tests: - os.symlink(src_dir + "/tests", "tests") diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py index c30d173c..d8a84eb2 100644 --- a/tests/unit/conftest.py +++ b/tests/unit/conftest.py @@ -41,12 +41,6 @@ def testdir(): return os.path.dirname(__file__) -@pytest.fixture(scope="session") -def dom0_template(testdir): - """Test fixture to get the directory of the dom0 template""" - return testdir + "/../integration/dom0-template" - - @pytest.fixture(scope="session") def imported_bugtool(testdir, dom0_template): """Fixture to provide the xen-bugtool script as a module for unit tests""" diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py index 566799f6..82b22510 100644 --- a/tests/unit/test_main.py +++ b/tests/unit/test_main.py @@ -249,7 +249,10 @@ def assert_bugtool_logfile_data(logfile): # caught and logged, the log file should contain the backtrace from the # raised exception: # - assert len(lines) == 9 + if sys.version_info >= (3, 11): # pragma: no cover + assert len(lines) == 10 # Python 3.11+ includes a new line in the backtrace + else: + assert len(lines) == 9 for backtrace_string in MOCK_EXCEPTION_STRINGS: assert backtrace_string in log diff --git a/tests/unit/test_output.py b/tests/unit/test_output.py index ee661354..7260d848 100644 --- a/tests/unit/test_output.py +++ b/tests/unit/test_output.py @@ -33,7 +33,8 @@ def mock_data_collector(capability): def assert_valid_inventory_schema(inventory_tree): """Assert that the passed inventory validates against the inventory schema""" - with open(os.getcwd() + "/tests/integration/inventory.xsd") as xml_schema: + inventory_schema = os.path.dirname(__file__) + "/../integration/inventory.xsd" + with open(inventory_schema) as xml_schema: XMLSchema(parse(xml_schema)).assertValid(inventory_tree)