From 7fe9ba8b9121c5457fdfef4ddbf04e603c29ce9f Mon Sep 17 00:00:00 2001 From: Samuel Verschelde Date: Thu, 21 May 2026 01:40:34 +0200 Subject: [PATCH 1/3] Fix the package scope of xfs_sr_on_hostA2 and xfs_sr_on_hostB1 It's the same old pytest bug, that requires importing package-scoped fixtures in the package's own conftest.py for the scope to be properly applied. This caused the fixture to be left alive across multiple packages that required it, closer to a session scope than to a package scope. Package-scoped fixtures moved to pkgfixtures.py and imported in each relevant package's conftest.py. Signed-off-by: Samuel Verschelde --- pkgfixtures.py | 88 +++++++++++++++++++++++++++++ tests/storage/cephfs/conftest.py | 10 +++- tests/storage/conftest.py | 88 ----------------------------- tests/storage/ext/conftest.py | 10 ++++ tests/storage/glusterfs/conftest.py | 10 +++- tests/storage/linstor/conftest.py | 10 +++- tests/storage/lvm/conftest.py | 10 ++++ tests/storage/lvmohba/conftest.py | 10 ++++ tests/storage/lvmoiscsi/conftest.py | 10 ++++ tests/storage/moosefs/conftest.py | 14 ++++- tests/storage/nfs/conftest.py | 10 ++++ tests/storage/xfs/conftest.py | 10 ++++ tests/storage/zfs/conftest.py | 11 +++- 13 files changed, 196 insertions(+), 95 deletions(-) diff --git a/pkgfixtures.py b/pkgfixtures.py index a48f5fa92..62f4ae4bf 100644 --- a/pkgfixtures.py +++ b/pkgfixtures.py @@ -3,8 +3,11 @@ import pytest import logging +from dataclasses import dataclass from lib.common import setup_formatted_and_mounted_disk, teardown_formatted_and_mounted_disk +from lib.sr import SR +from lib.vdi import ImageFormat from typing import TYPE_CHECKING, Generator @@ -80,3 +83,88 @@ def pool_with_saved_yum_state(host: Host) -> Generator[Pool]: h.yum_save_state() yield host.pool host.pool.exec_on_hosts_on_error_continue(lambda h: h.yum_restore_saved_state()) + + +@dataclass +class XfsConfig: + uninstall_xfs: bool = True + +@pytest.fixture(scope='package') +def _xfs_config_on_hostA2() -> XfsConfig: + return XfsConfig() + +# NOTE: @pytest.mark.usefixtures does not parametrize this fixture. +# To recreate host_with_xfsprogs for each image_format value, accept +# image_format in the fixture arguments. +# ref https://docs.pytest.org/en/7.1.x/how-to/fixtures.html#use-fixtures-in-classes-and-modules-with-usefixtures +@pytest.fixture(scope='package') +def hostA2_with_xfsprogs(hostA2: Host, image_format: ImageFormat, _xfs_config_on_hostA2: XfsConfig) \ + -> Generator[Host, None, None]: + assert not hostA2.file_exists('/usr/sbin/mkfs.xfs'), \ + "xfsprogs must not be installed on the host at the beginning of the tests" + hostA2.yum_save_state() + hostA2.yum_install(['xfsprogs']) + yield hostA2 + # teardown + if _xfs_config_on_hostA2.uninstall_xfs: + hostA2.yum_restore_saved_state() + +@pytest.fixture(scope='package') +def xfs_sr_on_hostA2( + unused_512B_disks: dict[Host, list[Host.BlockDeviceInfo]], + hostA2_with_xfsprogs: Host, + image_format: ImageFormat, + _xfs_config_on_hostA2: XfsConfig, +) -> Generator[SR, None, None]: + """ A XFS SR on first host. """ + sr_disk = unused_512B_disks[hostA2_with_xfsprogs][0].name + sr = hostA2_with_xfsprogs.sr_create('xfs', "XFS-local-SR-test", + {'device': '/dev/' + sr_disk, + 'preferred-image-formats': image_format}) + yield sr + # teardown + try: + sr.destroy() + except Exception as e: + _xfs_config_on_hostA2.uninstall_xfs = False + raise pytest.fail("Could not destroy xfs SR, leaving packages in place for manual cleanup") from e + +@pytest.fixture(scope='package') +def _xfs_config_on_hostB1() -> XfsConfig: + return XfsConfig() + +# NOTE: @pytest.mark.usefixtures does not parametrize this fixture. +# To recreate host_with_xfsprogs for each image_format value, accept +# image_format in the fixture arguments. +# ref https://docs.pytest.org/en/7.1.x/how-to/fixtures.html#use-fixtures-in-classes-and-modules-with-usefixtures +@pytest.fixture(scope='package') +def hostB1_with_xfsprogs(hostB1: Host, image_format: ImageFormat, _xfs_config_on_hostB1: XfsConfig) \ + -> Generator[Host, None, None]: + assert not hostB1.file_exists('/usr/sbin/mkfs.xfs'), \ + "xfsprogs must not be installed on the host at the beginning of the tests" + hostB1.yum_save_state() + hostB1.yum_install(['xfsprogs']) + yield hostB1 + # teardown + if _xfs_config_on_hostB1.uninstall_xfs: + hostB1.yum_restore_saved_state() + +@pytest.fixture(scope='package') +def xfs_sr_on_hostB1( + unused_512B_disks: dict[Host, list[Host.BlockDeviceInfo]], + hostB1_with_xfsprogs: Host, + image_format: ImageFormat, + _xfs_config_on_hostB1: XfsConfig, +) -> Generator[SR, None, None]: + """ A XFS SR on first host. """ + sr_disk = unused_512B_disks[hostB1_with_xfsprogs][0].name + sr = hostB1_with_xfsprogs.sr_create('xfs', "XFS-local-SR-test", + {'device': '/dev/' + sr_disk, + 'preferred-image-formats': image_format}) + yield sr + # teardown + try: + sr.destroy() + except Exception as e: + _xfs_config_on_hostB1.uninstall_xfs = False + raise pytest.fail("Could not destroy xfs SR, leaving packages in place for manual cleanup") from e diff --git a/tests/storage/cephfs/conftest.py b/tests/storage/cephfs/conftest.py index d84961381..8f69a9728 100644 --- a/tests/storage/cephfs/conftest.py +++ b/tests/storage/cephfs/conftest.py @@ -11,7 +11,15 @@ from lib.vm import VM # explicit import for package-scope fixtures -from pkgfixtures import pool_with_saved_yum_state +from pkgfixtures import ( + _xfs_config_on_hostA2, + _xfs_config_on_hostB1, + hostA2_with_xfsprogs, + hostB1_with_xfsprogs, + pool_with_saved_yum_state, + xfs_sr_on_hostA2, + xfs_sr_on_hostB1, +) from typing import Generator diff --git a/tests/storage/conftest.py b/tests/storage/conftest.py index 5f7f006da..be2e938fa 100644 --- a/tests/storage/conftest.py +++ b/tests/storage/conftest.py @@ -3,13 +3,10 @@ import pytest import logging -from dataclasses import dataclass from lib import config from lib.common import randid from lib.host import Host -from lib.sr import SR -from lib.vdi import ImageFormat from lib.vm import VM from tests.storage import install_randstream @@ -49,88 +46,3 @@ def temp_large_dir(host: Host) -> Generator[str, None, None]: host.ssh(f'mkdir {path}') yield path host.ssh(f'rm -rf {path}') - - -@dataclass -class XfsConfig: - uninstall_xfs: bool = True - -@pytest.fixture(scope='package') -def _xfs_config_on_hostA2() -> XfsConfig: - return XfsConfig() - -# NOTE: @pytest.mark.usefixtures does not parametrize this fixture. -# To recreate host_with_xfsprogs for each image_format value, accept -# image_format in the fixture arguments. -# ref https://docs.pytest.org/en/7.1.x/how-to/fixtures.html#use-fixtures-in-classes-and-modules-with-usefixtures -@pytest.fixture(scope='package') -def hostA2_with_xfsprogs(hostA2: Host, image_format: ImageFormat, _xfs_config_on_hostA2: XfsConfig) \ - -> Generator[Host, None, None]: - assert not hostA2.file_exists('/usr/sbin/mkfs.xfs'), \ - "xfsprogs must not be installed on the host at the beginning of the tests" - hostA2.yum_save_state() - hostA2.yum_install(['xfsprogs']) - yield hostA2 - # teardown - if _xfs_config_on_hostA2.uninstall_xfs: - hostA2.yum_restore_saved_state() - -@pytest.fixture(scope='package') -def xfs_sr_on_hostA2( - unused_512B_disks: dict[Host, list[Host.BlockDeviceInfo]], - hostA2_with_xfsprogs: Host, - image_format: ImageFormat, - _xfs_config_on_hostA2: XfsConfig, -) -> Generator[SR, None, None]: - """ A XFS SR on first host. """ - sr_disk = unused_512B_disks[hostA2_with_xfsprogs][0].name - sr = hostA2_with_xfsprogs.sr_create('xfs', "XFS-local-SR-test", - {'device': '/dev/' + sr_disk, - 'preferred-image-formats': image_format}) - yield sr - # teardown - try: - sr.destroy() - except Exception as e: - _xfs_config_on_hostA2.uninstall_xfs = False - raise pytest.fail("Could not destroy xfs SR, leaving packages in place for manual cleanup") from e - -@pytest.fixture(scope='package') -def _xfs_config_on_hostB1() -> XfsConfig: - return XfsConfig() - -# NOTE: @pytest.mark.usefixtures does not parametrize this fixture. -# To recreate host_with_xfsprogs for each image_format value, accept -# image_format in the fixture arguments. -# ref https://docs.pytest.org/en/7.1.x/how-to/fixtures.html#use-fixtures-in-classes-and-modules-with-usefixtures -@pytest.fixture(scope='package') -def hostB1_with_xfsprogs(hostB1: Host, image_format: ImageFormat, _xfs_config_on_hostB1: XfsConfig) \ - -> Generator[Host, None, None]: - assert not hostB1.file_exists('/usr/sbin/mkfs.xfs'), \ - "xfsprogs must not be installed on the host at the beginning of the tests" - hostB1.yum_save_state() - hostB1.yum_install(['xfsprogs']) - yield hostB1 - # teardown - if _xfs_config_on_hostB1.uninstall_xfs: - hostB1.yum_restore_saved_state() - -@pytest.fixture(scope='package') -def xfs_sr_on_hostB1( - unused_512B_disks: dict[Host, list[Host.BlockDeviceInfo]], - hostB1_with_xfsprogs: Host, - image_format: ImageFormat, - _xfs_config_on_hostB1: XfsConfig, -) -> Generator[SR, None, None]: - """ A XFS SR on first host. """ - sr_disk = unused_512B_disks[hostB1_with_xfsprogs][0].name - sr = hostB1_with_xfsprogs.sr_create('xfs', "XFS-local-SR-test", - {'device': '/dev/' + sr_disk, - 'preferred-image-formats': image_format}) - yield sr - # teardown - try: - sr.destroy() - except Exception as e: - _xfs_config_on_hostB1.uninstall_xfs = False - raise pytest.fail("Could not destroy xfs SR, leaving packages in place for manual cleanup") from e diff --git a/tests/storage/ext/conftest.py b/tests/storage/ext/conftest.py index bb7ace75a..a00eaed4e 100644 --- a/tests/storage/ext/conftest.py +++ b/tests/storage/ext/conftest.py @@ -10,6 +10,16 @@ from lib.vdi import VDI, ImageFormat from lib.vm import VM +# explicit import for package-scope fixtures +from pkgfixtures import ( + _xfs_config_on_hostA2, + _xfs_config_on_hostB1, + hostA2_with_xfsprogs, + hostB1_with_xfsprogs, + xfs_sr_on_hostA2, + xfs_sr_on_hostB1, +) + from typing import Any, Generator @pytest.fixture(scope='package') diff --git a/tests/storage/glusterfs/conftest.py b/tests/storage/glusterfs/conftest.py index c17dc35ed..93983bba3 100644 --- a/tests/storage/glusterfs/conftest.py +++ b/tests/storage/glusterfs/conftest.py @@ -19,7 +19,15 @@ from lib.vm import VM # explicit import for package-scope fixtures -from pkgfixtures import pool_with_saved_yum_state +from pkgfixtures import ( + _xfs_config_on_hostA2, + _xfs_config_on_hostB1, + hostA2_with_xfsprogs, + hostB1_with_xfsprogs, + pool_with_saved_yum_state, + xfs_sr_on_hostA2, + xfs_sr_on_hostB1, +) GLUSTERFS_PORTS = [('24007', 'tcp'), ('49152:49251', 'tcp')] diff --git a/tests/storage/linstor/conftest.py b/tests/storage/linstor/conftest.py index 6b21caf80..d3f9d1ce4 100644 --- a/tests/storage/linstor/conftest.py +++ b/tests/storage/linstor/conftest.py @@ -16,7 +16,15 @@ LINSTOR_REDUNDANCY = 2 # explicit import for package-scope fixtures -from pkgfixtures import pool_with_saved_yum_state +from pkgfixtures import ( + _xfs_config_on_hostA2, + _xfs_config_on_hostB1, + hostA2_with_xfsprogs, + hostB1_with_xfsprogs, + pool_with_saved_yum_state, + xfs_sr_on_hostA2, + xfs_sr_on_hostB1, +) from typing import TYPE_CHECKING, Generator diff --git a/tests/storage/lvm/conftest.py b/tests/storage/lvm/conftest.py index 88fd1fba5..99b4e5f5a 100644 --- a/tests/storage/lvm/conftest.py +++ b/tests/storage/lvm/conftest.py @@ -10,6 +10,16 @@ from lib.vdi import VDI, ImageFormat from lib.vm import VM +# explicit import for package-scope fixtures +from pkgfixtures import ( + _xfs_config_on_hostA2, + _xfs_config_on_hostB1, + hostA2_with_xfsprogs, + hostB1_with_xfsprogs, + xfs_sr_on_hostA2, + xfs_sr_on_hostB1, +) + from typing import Generator @pytest.fixture(scope='package') diff --git a/tests/storage/lvmohba/conftest.py b/tests/storage/lvmohba/conftest.py index 15c0c591f..79ac2e3c5 100644 --- a/tests/storage/lvmohba/conftest.py +++ b/tests/storage/lvmohba/conftest.py @@ -6,6 +6,16 @@ from lib.sr import SR from lib.vdi import ImageFormat +# explicit import for package-scope fixtures +from pkgfixtures import ( + _xfs_config_on_hostA2, + _xfs_config_on_hostB1, + hostA2_with_xfsprogs, + hostB1_with_xfsprogs, + xfs_sr_on_hostA2, + xfs_sr_on_hostB1, +) + @pytest.fixture(scope='package') def lvmohba_device_config(): return config.sr_device_config("LVMOHBA_DEVICE_CONFIG") diff --git a/tests/storage/lvmoiscsi/conftest.py b/tests/storage/lvmoiscsi/conftest.py index 1cd671531..69a450929 100644 --- a/tests/storage/lvmoiscsi/conftest.py +++ b/tests/storage/lvmoiscsi/conftest.py @@ -8,6 +8,16 @@ from lib.vdi import VDI, ImageFormat from lib.vm import VM +# explicit import for package-scope fixtures +from pkgfixtures import ( + _xfs_config_on_hostA2, + _xfs_config_on_hostB1, + hostA2_with_xfsprogs, + hostB1_with_xfsprogs, + xfs_sr_on_hostA2, + xfs_sr_on_hostB1, +) + from typing import Generator @pytest.fixture(scope='package') diff --git a/tests/storage/moosefs/conftest.py b/tests/storage/moosefs/conftest.py index 836c8e80d..ddb7dd841 100644 --- a/tests/storage/moosefs/conftest.py +++ b/tests/storage/moosefs/conftest.py @@ -5,14 +5,22 @@ import logging from lib import config - -# explicit import for package-scope fixtures from lib.host import Host from lib.pool import Pool from lib.sr import SR from lib.vdi import VDI from lib.vm import VM -from pkgfixtures import pool_with_saved_yum_state + +# explicit import for package-scope fixtures +from pkgfixtures import ( + _xfs_config_on_hostA2, + _xfs_config_on_hostB1, + hostA2_with_xfsprogs, + hostB1_with_xfsprogs, + pool_with_saved_yum_state, + xfs_sr_on_hostA2, + xfs_sr_on_hostB1, +) from typing import Generator diff --git a/tests/storage/nfs/conftest.py b/tests/storage/nfs/conftest.py index c01668f88..157c071d9 100644 --- a/tests/storage/nfs/conftest.py +++ b/tests/storage/nfs/conftest.py @@ -10,6 +10,16 @@ from lib.vdi import VDI, ImageFormat from lib.vm import VM +# explicit import for package-scope fixtures +from pkgfixtures import ( + _xfs_config_on_hostA2, + _xfs_config_on_hostB1, + hostA2_with_xfsprogs, + hostB1_with_xfsprogs, + xfs_sr_on_hostA2, + xfs_sr_on_hostB1, +) + from typing import Generator # --- Dispatch fixture for NFS versions ---------------------------------------- diff --git a/tests/storage/xfs/conftest.py b/tests/storage/xfs/conftest.py index 66d3225c1..3570f4cee 100644 --- a/tests/storage/xfs/conftest.py +++ b/tests/storage/xfs/conftest.py @@ -11,6 +11,16 @@ from lib.vdi import VDI, ImageFormat from lib.vm import VM +# explicit import for package-scope fixtures +from pkgfixtures import ( + _xfs_config_on_hostA2, + _xfs_config_on_hostB1, + hostA2_with_xfsprogs, + hostB1_with_xfsprogs, + xfs_sr_on_hostA2, + xfs_sr_on_hostB1, +) + from typing import Generator @dataclass diff --git a/tests/storage/zfs/conftest.py b/tests/storage/zfs/conftest.py index 3b546bdbd..87d7f85c5 100644 --- a/tests/storage/zfs/conftest.py +++ b/tests/storage/zfs/conftest.py @@ -11,7 +11,16 @@ from lib.vm import VM # Explicitly import package-scoped fixtures (see explanation in pkgfixtures.py) -from pkgfixtures import host_with_saved_yum_state, sr_disk_wiped +from pkgfixtures import ( + _xfs_config_on_hostA2, + _xfs_config_on_hostB1, + host_with_saved_yum_state, + hostA2_with_xfsprogs, + hostB1_with_xfsprogs, + sr_disk_wiped, + xfs_sr_on_hostA2, + xfs_sr_on_hostB1, +) from typing import Generator From 2121c6f651399adbf1448e6fa1804a80e9757691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Lehmann?= Date: Fri, 22 May 2026 17:40:08 +0200 Subject: [PATCH 2/3] Revert "gclusterfs: Add tests to Broken tests" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit e58c592f7e45685485f63218234319e622cfcc84. Signed-off-by: Gaëtan Lehmann --- jobs.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/jobs.py b/jobs.py index cf0de8b0d..fc2db6ff3 100755 --- a/jobs.py +++ b/jobs.py @@ -584,8 +584,6 @@ class JobData(TypedDict): BROKEN_TESTS = [ # not really broken but has complex prerequisites (3 NICs on 3 different networks) "tests/migration/test_host_evacuate.py::TestHostEvacuateWithNetwork", - # needs maintenance (fail on xfs) - "tests/storage/glusterfs", # needs Fibre Channel host bus adapter (HBA) "tests/storage/lvmohba", # running quicktest on zfsvol generates dangling TAP devices that are hard to From acf1a43b8f2c49f5562ce414984de6ef837adb87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Lehmann?= Date: Fri, 22 May 2026 17:40:08 +0200 Subject: [PATCH 3/3] Revert "lvmohba: Add tests to Broken tests" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 178bd4c0b731f45b3e712b2b77d73982c2ee0453. Signed-off-by: Gaëtan Lehmann --- jobs.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/jobs.py b/jobs.py index fc2db6ff3..299d88a8c 100755 --- a/jobs.py +++ b/jobs.py @@ -584,8 +584,6 @@ class JobData(TypedDict): BROKEN_TESTS = [ # not really broken but has complex prerequisites (3 NICs on 3 different networks) "tests/migration/test_host_evacuate.py::TestHostEvacuateWithNetwork", - # needs Fibre Channel host bus adapter (HBA) - "tests/storage/lvmohba", # running quicktest on zfsvol generates dangling TAP devices that are hard to # cleanup. Bug needs to be fixed before enabling quicktest on zfsvol. "tests/storage/zfsvol/test_zfsvol_sr.py::TestZfsvolVm::test_quicktest",