diff --git a/jobs.py b/jobs.py index cf0de8b0d..299d88a8c 100755 --- a/jobs.py +++ b/jobs.py @@ -584,10 +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 # cleanup. Bug needs to be fixed before enabling quicktest on zfsvol. "tests/storage/zfsvol/test_zfsvol_sr.py::TestZfsvolVm::test_quicktest", 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