diff --git a/jobs.py b/jobs.py index cf0de8b0d..d5c4b6985 100755 --- a/jobs.py +++ b/jobs.py @@ -368,6 +368,66 @@ class JobData(TypedDict): "paths": ["tests/storage"], "markers": "unused_4k_disks and quicktest", }, + "qcow2-4k-main": { + "description": "tests QCOW2 image format on EXT and LVM SRs backed by native 4KiB block devices. " + "avoids quicktest, migrations and reboots", + "requirements": [ + "A pool >= 8.3 with at least 1 host.", + "An additional free native 4KiB disk on the first host.", + "A small VM that can be imported on the SRs.", + ], + "nb_pools": 1, + "params": { + "--vm": "single/small_vm", + }, + "paths": ["tests/storage/ext", "tests/storage/lvm"], + "markers": "(small_vm or no_vm) and unused_4k_disks and not reboot and not quicktest", + "name_filter": "_4k and not migration", + }, + "qcow2-4k-migrations": { + "description": "storage migration tests for QCOW2 VDIs on EXT and LVM SRs backed by native 4KiB block devices", + "requirements": [ + "A pool >= 8.3 with at least 2 hosts, each with a local SR.", + "An additional free native 4KiB disk on the first host.", + "A second pool with a SR to receive migrated VMs.", + "A small VM that can be imported on the SRs.", + ], + "nb_pools": 2, + "params": { + "--vm": "single/small_vm", + }, + "paths": ["tests/storage/ext", "tests/storage/lvm"], + "markers": "unused_4k_disks", + "name_filter": "_4k and migration", + }, + "qcow2-4k-reboots": { + "description": "QCOW2 on native 4KiB block device tests on EXT and LVM SRs that involve rebooting hosts", + "requirements": [ + "A pool >= 8.3 with at least 1 host.", + "An additional free native 4KiB disk on the first host.", + "A small VM that can be imported on the SRs.", + ], + "nb_pools": 1, + "params": { + "--vm": "single/small_vm", + }, + "paths": ["tests/storage/ext", "tests/storage/lvm"], + "markers": "unused_4k_disks and reboot", + "name_filter": "_4k", + }, + "qcow2-4k-quicktest": { + "description": "runs `quicktest` for QCOW2 VDIs on EXT and LVM SRs backed by native 4KiB block devices", + "requirements": [ + "A pool >= 8.3 with at least 1 host", + "An additional free native 4KiB disk on the first host.", + ], + "nb_pools": 1, + "params": { + }, + "paths": ["tests/storage/ext", "tests/storage/lvm"], + "markers": "unused_4k_disks and quicktest", + "name_filter": "_4k", + }, "sb-main": { "description": "tests uefistored/varstored and SecureBoot using a small unix VM (or no VM when none needed)", "requirements": [ diff --git a/lib/vdi.py b/lib/vdi.py index 0ad83a580..beee6e004 100644 --- a/lib/vdi.py +++ b/lib/vdi.py @@ -23,6 +23,8 @@ ImageFormat = Literal['qcow2', 'raw', 'vhd'] +QCOW2_IMAGE_FORMAT: ImageFormat = 'qcow2' + class VDI: xe_prefix = "vdi" sr: SR diff --git a/tests/storage/ext/conftest.py b/tests/storage/ext/conftest.py index bb7ace75a..9e740de33 100644 --- a/tests/storage/ext/conftest.py +++ b/tests/storage/ext/conftest.py @@ -7,7 +7,7 @@ from lib import config from lib.host import Host from lib.sr import SR -from lib.vdi import VDI, ImageFormat +from lib.vdi import QCOW2_IMAGE_FORMAT, VDI, ImageFormat from lib.vm import VM from typing import Any, Generator @@ -39,3 +39,29 @@ def vm_on_ext_sr(host: Host, ext_sr: SR, vm_ref: str) -> Generator[VM, None, Non # teardown logging.info("<< Destroy VM") vm.destroy(verify=True) + +@pytest.fixture(scope='package') +def ext_sr_4k(host: Host, + unused_4k_disks: dict[Host, list[Host.BlockDeviceInfo]]) -> Generator[SR, None, None]: + """An EXT SR on a native 4KiB block device, using the QCOW2 image format.""" + sr_disk = unused_4k_disks[host][0].name + sr = host.sr_create('ext', "EXT-4K-local-SR-test", + {'device': '/dev/' + sr_disk, + 'preferred-image-formats': QCOW2_IMAGE_FORMAT}) + yield sr + # teardown + sr.destroy() + +@pytest.fixture(scope='module') +def vdi_on_ext_sr_4k(ext_sr_4k: SR) -> Generator[VDI, None, None]: + vdi = ext_sr_4k.create_vdi('EXT-4K-local-VDI-test', virtual_size=config.volume_size) + yield vdi + vdi.destroy() + +@pytest.fixture(scope='module') +def vm_on_ext_sr_4k(host: Host, ext_sr_4k: SR, vm_ref: str) -> Generator[VM, None, None]: + vm = host.import_vm(vm_ref, sr_uuid=ext_sr_4k.uuid) + yield vm + # teardown + logging.info("<< Destroy VM") + vm.destroy(verify=True) diff --git a/tests/storage/ext/test_ext_sr_4k.py b/tests/storage/ext/test_ext_sr_4k.py new file mode 100644 index 000000000..ffb8f3904 --- /dev/null +++ b/tests/storage/ext/test_ext_sr_4k.py @@ -0,0 +1,147 @@ +from __future__ import annotations + +import pytest + +from lib.commands import SSHCommandFailed +from lib.common import Defer, vm_image, wait_for +from lib.fistpoint import FistPoint +from lib.host import Host +from lib.sr import SR +from lib.vdi import QCOW2_IMAGE_FORMAT, VDI +from lib.vm import VM +from tests.storage import ( + MAX_VDI_SIZE, + CoalesceOperation, + XVACompression, + coalesce_integrity, + full_vdi_write, + try_to_create_sr_with_missing_device, + vdi_export_import, + vdi_is_open, + xva_export_import, +) + +# Requirements: +# - one XCP-ng host >= 8.3 with an additional unused native 4KiB disk for the SR + +class TestEXTSR4KCreateDestroy: + """ + Tests that do not use fixtures that setup the SR or import VMs, + because they precisely need to test SR creation and destruction, + and VM import. + """ + + def test_create_sr_with_missing_device(self, host: Host) -> None: + try_to_create_sr_with_missing_device('ext', 'EXT-4K-local-SR-test', host) + + def test_create_and_destroy_sr(self, host: Host, + unused_4k_disks: dict[Host, list[Host.BlockDeviceInfo]]) -> None: + # Create and destroy tested in the same test to leave the host as unchanged as possible + sr_disk = unused_4k_disks[host][0].name + sr = host.sr_create('ext', "EXT-4K-local-SR-test", + {'device': '/dev/' + sr_disk, + 'preferred-image-formats': QCOW2_IMAGE_FORMAT}, verify=True) + # import a VM in order to detect vm import issues here rather than in the vm_on_xfs_fixture used in + # the next tests, because errors in fixtures break teardown + vm = host.import_vm(vm_image('mini-linux-x86_64-bios'), sr_uuid=sr.uuid) + vm.destroy(verify=True) + sr.destroy(verify=True) + +@pytest.mark.usefixtures("ext_sr_4k") +class TestEXTSR4K: + @pytest.mark.quicktest + def test_quicktest(self, ext_sr_4k: SR) -> None: + ext_sr_4k.run_quicktest() + + def test_vdi_is_not_open(self, vdi_on_ext_sr_4k: VDI) -> None: + assert not vdi_is_open(vdi_on_ext_sr_4k) + + def test_vdi_image_format(self, vdi_on_ext_sr_4k: VDI) -> None: + fmt = vdi_on_ext_sr_4k.get_image_format() + # feature-detect: if the SM doesn't report image-format, skip this check + if not fmt: + pytest.skip("SM does not report sm-config:image-format; skipping format check") + assert fmt == QCOW2_IMAGE_FORMAT + + @pytest.mark.small_vm # run with a small VM to test the features + @pytest.mark.big_vm # and ideally with a big VM to test it scales + def test_start_and_shutdown_VM(self, vm_on_ext_sr_4k: VM) -> None: + vm = vm_on_ext_sr_4k + vm.start() + vm.wait_for_os_booted() + vm.shutdown(verify=True) + + @pytest.mark.small_vm + @pytest.mark.big_vm + def test_snapshot(self, vm_on_ext_sr_4k: VM) -> None: + vm = vm_on_ext_sr_4k + vm.start() + try: + vm.wait_for_os_booted() + vm.test_snapshot_on_running_vm() + finally: + vm.shutdown(verify=True) + + @pytest.mark.small_vm + @pytest.mark.parametrize("vdi_op", ["snapshot", "clone"]) + def test_coalesce(self, storage_test_vm: VM, vdi_on_ext_sr_4k: VDI, vdi_op: CoalesceOperation, + defer: Defer) -> None: + coalesce_integrity(storage_test_vm, vdi_on_ext_sr_4k, vdi_op, defer) + + @pytest.mark.small_vm + @pytest.mark.parametrize("compression", ["none", "gzip", "zstd"]) + def test_xva_export_import(self, vm_on_ext_sr_4k: VM, compression: XVACompression, temp_large_dir: str, + defer: Defer) -> None: + xva_export_import(vm_on_ext_sr_4k, compression, temp_large_dir, defer) + + @pytest.mark.small_vm + def test_vdi_export_import(self, storage_test_vm: VM, ext_sr_4k: SR, temp_large_dir: str, + defer: Defer) -> None: + vdi_export_import(storage_test_vm, ext_sr_4k, QCOW2_IMAGE_FORMAT, temp_large_dir, defer) + + @pytest.mark.small_vm + @pytest.mark.disk_throughput_intensive + def test_full_vdi_write(self, storage_test_vm: VM, vdi_on_ext_sr_4k: VDI, defer: Defer): + full_vdi_write(storage_test_vm, vdi_on_ext_sr_4k, defer) + + @pytest.mark.small_vm + def test_invalid_vdi_size(self, ext_sr_4k: SR): + with pytest.raises(SSHCommandFailed) as excinfo: + ext_sr_4k.create_vdi(virtual_size=MAX_VDI_SIZE[QCOW2_IMAGE_FORMAT] + 1) + assert 'VDI Invalid size' in excinfo.value.stdout + + # *** tests with blktap activate failure (longer tests). + + @pytest.mark.small_vm + @pytest.mark.big_vm + def test_blktap_activate_failure(self, vm_on_ext_sr_4k: VM) -> None: + vm = vm_on_ext_sr_4k + with FistPoint(vm.host, "blktap_activate_inject_failure"), pytest.raises(SSHCommandFailed): + vm.start() + vm.shutdown(force=True) + + @pytest.mark.small_vm + @pytest.mark.big_vm + def test_resize(self, vm_on_ext_sr_4k: VM) -> None: + vm = vm_on_ext_sr_4k + vdi = VDI(vm.vdi_uuids()[0], host=vm.host) + old_size = vdi.get_virtual_size() + new_size = old_size + (1 * 1024 * 1024 * 1024) # Adding a 1GiB to size + + vdi.resize(new_size) + + assert vdi.get_virtual_size() == new_size + + @pytest.mark.reboot + @pytest.mark.small_vm + def test_reboot(self, host: Host, ext_sr_4k: SR, vm_on_ext_sr_4k: VM) -> None: + sr = ext_sr_4k + vm = vm_on_ext_sr_4k + host.reboot(verify=True) + wait_for(sr.all_pbds_attached, "Wait for PBD attached") + # start the VM as a way to check that the underlying SR is operational + vm.start() + vm.wait_for_os_booted() + vm.shutdown(verify=True) + + # *** End of tests with reboots diff --git a/tests/storage/ext/test_ext_sr_4k_crosspool_migration.py b/tests/storage/ext/test_ext_sr_4k_crosspool_migration.py new file mode 100644 index 000000000..a608e74d0 --- /dev/null +++ b/tests/storage/ext/test_ext_sr_4k_crosspool_migration.py @@ -0,0 +1,26 @@ +import pytest + +from lib.host import Host +from lib.sr import SR +from lib.vm import VM +from tests.storage import cold_migration_then_come_back, live_storage_migration_then_come_back + +# Requirements: +# From --hosts parameter: +# - host(A1): first XCP-ng host >= 8.3 with an additional unused native 4KiB disk for the EXT SR. +# - hostB1: Master of a second pool. Any local SR. +# From --vm parameter +# - A VM to import to the EXT SR + +@pytest.mark.small_vm +@pytest.mark.big_vm +class Test: + def test_cold_crosspool_migration( + self, host: Host, hostB1: Host, vm_on_ext_sr_4k: VM, local_sr_on_hostB1: SR + ) -> None: + cold_migration_then_come_back(vm_on_ext_sr_4k, host, hostB1, local_sr_on_hostB1) + + def test_live_crosspool_migration( + self, host: Host, hostB1: Host, vm_on_ext_sr_4k: VM, local_sr_on_hostB1: SR + ) -> None: + live_storage_migration_then_come_back(vm_on_ext_sr_4k, host, hostB1, local_sr_on_hostB1) diff --git a/tests/storage/ext/test_ext_sr_4k_intrapool_migration.py b/tests/storage/ext/test_ext_sr_4k_intrapool_migration.py new file mode 100644 index 000000000..2cbfbf60f --- /dev/null +++ b/tests/storage/ext/test_ext_sr_4k_intrapool_migration.py @@ -0,0 +1,26 @@ +import pytest + +from lib.host import Host +from lib.sr import SR +from lib.vm import VM +from tests.storage import cold_migration_then_come_back, live_storage_migration_then_come_back + +# Requirements: +# From --hosts parameter: +# - host(A1): first XCP-ng host >= 8.3 with an additional unused native 4KiB disk for the EXT SR. +# - hostA2: Second member of the pool. Can have any local SR. No need to specify it on CLI. +# From --vm parameter +# - A VM to import to the EXT SR + +@pytest.mark.small_vm +@pytest.mark.big_vm +class Test: + def test_cold_intrapool_migration( + self, host: Host, hostA2: Host, vm_on_ext_sr_4k: VM, local_sr_on_hostA2: SR + ) -> None: + cold_migration_then_come_back(vm_on_ext_sr_4k, host, hostA2, local_sr_on_hostA2) + + def test_live_intrapool_migration( + self, host: Host, hostA2: Host, vm_on_ext_sr_4k: VM, local_sr_on_hostA2: SR + ) -> None: + live_storage_migration_then_come_back(vm_on_ext_sr_4k, host, hostA2, local_sr_on_hostA2) diff --git a/tests/storage/lvm/conftest.py b/tests/storage/lvm/conftest.py index 88fd1fba5..fdd7b2a97 100644 --- a/tests/storage/lvm/conftest.py +++ b/tests/storage/lvm/conftest.py @@ -7,7 +7,7 @@ from lib import config from lib.host import Host from lib.sr import SR -from lib.vdi import VDI, ImageFormat +from lib.vdi import QCOW2_IMAGE_FORMAT, VDI, ImageFormat from lib.vm import VM from typing import Generator @@ -39,3 +39,29 @@ def vm_on_lvm_sr(host: Host, lvm_sr: SR, vm_ref: str) -> Generator[VM, None, Non # teardown logging.info("<< Destroy VM") vm.destroy(verify=True) + +@pytest.fixture(scope='package') +def lvm_sr_4k(host: Host, + unused_4k_disks: dict[Host, list[Host.BlockDeviceInfo]]) -> Generator[SR, None, None]: + """An LVM SR on a native 4KiB block device, using the QCOW2 image format.""" + sr_disk = unused_4k_disks[host][0].name + sr = host.sr_create('lvm', "LVM-4K-local-SR-test", + {'device': '/dev/' + sr_disk, + 'preferred-image-formats': QCOW2_IMAGE_FORMAT}) + yield sr + # teardown + sr.destroy() + +@pytest.fixture(scope='module') +def vdi_on_lvm_sr_4k(lvm_sr_4k: SR) -> Generator[VDI, None, None]: + vdi = lvm_sr_4k.create_vdi('LVM-4K-local-VDI-test', virtual_size=config.volume_size) + yield vdi + vdi.destroy() + +@pytest.fixture(scope='module') +def vm_on_lvm_sr_4k(host: Host, lvm_sr_4k: SR, vm_ref: str) -> Generator[VM, None, None]: + vm = host.import_vm(vm_ref, sr_uuid=lvm_sr_4k.uuid) + yield vm + # teardown + logging.info("<< Destroy VM") + vm.destroy(verify=True) diff --git a/tests/storage/lvm/test_lvm_sr_4k.py b/tests/storage/lvm/test_lvm_sr_4k.py new file mode 100644 index 000000000..53ac9c9ff --- /dev/null +++ b/tests/storage/lvm/test_lvm_sr_4k.py @@ -0,0 +1,128 @@ +from __future__ import annotations + +import pytest + +from lib.commands import SSHCommandFailed +from lib.common import Defer, vm_image, wait_for +from lib.host import Host +from lib.sr import SR +from lib.vdi import QCOW2_IMAGE_FORMAT, VDI +from lib.vm import VM +from tests.storage import ( + MAX_VDI_SIZE, + CoalesceOperation, + XVACompression, + coalesce_integrity, + full_vdi_write, + try_to_create_sr_with_missing_device, + vdi_export_import, + vdi_is_open, + xva_export_import, +) + +# Requirements: +# - one XCP-ng host >= 8.3 with an additional unused native 4KiB disk for the SR + +class TestLVMSR4KCreateDestroy: + """ + Tests that do not use fixtures that setup the SR or import VMs, + because they precisely need to test SR creation and destruction, + and VM import. + """ + + def test_create_sr_with_missing_device(self, host: Host) -> None: + try_to_create_sr_with_missing_device('lvm', 'LVM-4K-local-SR-test', host) + + def test_create_and_destroy_sr(self, host: Host, + unused_4k_disks: dict[Host, list[Host.BlockDeviceInfo]]) -> None: + sr_disk = unused_4k_disks[host][0].name + # Create and destroy tested in the same test to leave the host as unchanged as possible + sr = host.sr_create('lvm', "LVM-4K-local-SR-test", { + 'device': '/dev/' + sr_disk, + 'preferred-image-formats': QCOW2_IMAGE_FORMAT + }, verify=True) + # import a VM in order to detect vm import issues here rather than in the vm_on_xfs_fixture used in + # the next tests, because errors in fixtures break teardown + vm = host.import_vm(vm_image('mini-linux-x86_64-bios'), sr_uuid=sr.uuid) + vm.destroy(verify=True) + sr.destroy(verify=True) + +@pytest.mark.usefixtures("lvm_sr_4k") +@pytest.mark.thick_provisioned +class TestLVMSR4K: + @pytest.mark.quicktest + def test_quicktest(self, lvm_sr_4k: SR) -> None: + lvm_sr_4k.run_quicktest() + + def test_vdi_is_not_open(self, vdi_on_lvm_sr_4k: VDI) -> None: + assert not vdi_is_open(vdi_on_lvm_sr_4k) + + def test_vdi_image_format(self, vdi_on_lvm_sr_4k: VDI) -> None: + fmt = vdi_on_lvm_sr_4k.get_image_format() + # feature-detect: if the SM doesn't report image-format, skip this check + if not fmt: + pytest.skip("SM does not report sm-config:image-format; skipping format check") + assert fmt == QCOW2_IMAGE_FORMAT + + @pytest.mark.small_vm + @pytest.mark.big_vm + def test_start_and_shutdown_VM(self, vm_on_lvm_sr_4k: VM) -> None: + vm = vm_on_lvm_sr_4k + vm.start() + vm.wait_for_os_booted() + vm.shutdown(verify=True) + + @pytest.mark.small_vm # run with a small VM to test the features + @pytest.mark.big_vm # and ideally with a big VM to test it scales + def test_snapshot(self, vm_on_lvm_sr_4k: VM) -> None: + vm = vm_on_lvm_sr_4k + vm.start() + try: + vm.wait_for_os_booted() + vm.test_snapshot_on_running_vm() + finally: + vm.shutdown(verify=True) + + @pytest.mark.small_vm + @pytest.mark.parametrize("vdi_op", ["snapshot", "clone"]) + def test_coalesce(self, storage_test_vm: VM, vdi_on_lvm_sr_4k: VDI, vdi_op: CoalesceOperation, + defer: Defer) -> None: + coalesce_integrity(storage_test_vm, vdi_on_lvm_sr_4k, vdi_op, defer) + + @pytest.mark.small_vm + @pytest.mark.parametrize("compression", ["none", "gzip", "zstd"]) + def test_xva_export_import(self, vm_on_lvm_sr_4k: VM, compression: XVACompression, temp_large_dir: str, + defer: Defer) -> None: + xva_export_import(vm_on_lvm_sr_4k, compression, temp_large_dir, defer) + + @pytest.mark.small_vm + def test_vdi_export_import(self, storage_test_vm: VM, lvm_sr_4k: SR, temp_large_dir: str, + defer: Defer) -> None: + vdi_export_import(storage_test_vm, lvm_sr_4k, QCOW2_IMAGE_FORMAT, temp_large_dir, defer) + + @pytest.mark.small_vm + @pytest.mark.disk_throughput_intensive + def test_full_vdi_write(self, storage_test_vm: VM, vdi_on_lvm_sr_4k: VDI, defer: Defer): + full_vdi_write(storage_test_vm, vdi_on_lvm_sr_4k, defer) + + @pytest.mark.small_vm + def test_invalid_vdi_size(self, lvm_sr_4k: SR): + with pytest.raises(SSHCommandFailed) as excinfo: + lvm_sr_4k.create_vdi(virtual_size=MAX_VDI_SIZE[QCOW2_IMAGE_FORMAT] + 1) + assert 'VDI Invalid size' in excinfo.value.stdout + + # *** tests with reboots (longer tests). + + @pytest.mark.reboot + @pytest.mark.small_vm + def test_reboot(self, host: Host, lvm_sr_4k: SR, vm_on_lvm_sr_4k: VM) -> None: + sr = lvm_sr_4k + vm = vm_on_lvm_sr_4k + host.reboot(verify=True) + wait_for(sr.all_pbds_attached, "Wait for PBD attached") + # start the VM as a way to check that the underlying SR is operational + vm.start() + vm.wait_for_os_booted() + vm.shutdown(verify=True) + + # *** End of tests with reboots diff --git a/tests/storage/lvm/test_lvm_sr_4k_crosspool_migration.py b/tests/storage/lvm/test_lvm_sr_4k_crosspool_migration.py new file mode 100644 index 000000000..2bfce2623 --- /dev/null +++ b/tests/storage/lvm/test_lvm_sr_4k_crosspool_migration.py @@ -0,0 +1,27 @@ +import pytest + +from lib.host import Host +from lib.sr import SR +from lib.vm import VM +from tests.storage import cold_migration_then_come_back, live_storage_migration_then_come_back + +# Requirements: +# From --hosts parameter: +# - host(A1): first XCP-ng host >= 8.3 with an additional unused native 4KiB disk for the LVM SR. +# - hostB1: Master of a second pool. Any local SR. +# From --vm parameter +# - A VM to import to the LVM SR + +@pytest.mark.small_vm # run with a small VM to test the features +@pytest.mark.big_vm # and ideally with a big VM to test it scales +@pytest.mark.thick_provisioned +class Test: + def test_cold_crosspool_migration( + self, host: Host, hostB1: Host, vm_on_lvm_sr_4k: VM, local_sr_on_hostB1: SR + ) -> None: + cold_migration_then_come_back(vm_on_lvm_sr_4k, host, hostB1, local_sr_on_hostB1) + + def test_live_crosspool_migration( + self, host: Host, hostB1: Host, vm_on_lvm_sr_4k: VM, local_sr_on_hostB1: SR + ) -> None: + live_storage_migration_then_come_back(vm_on_lvm_sr_4k, host, hostB1, local_sr_on_hostB1) diff --git a/tests/storage/lvm/test_lvm_sr_4k_intrapool_migration.py b/tests/storage/lvm/test_lvm_sr_4k_intrapool_migration.py new file mode 100644 index 000000000..a75e6e4b4 --- /dev/null +++ b/tests/storage/lvm/test_lvm_sr_4k_intrapool_migration.py @@ -0,0 +1,27 @@ +import pytest + +from lib.host import Host +from lib.sr import SR +from lib.vm import VM +from tests.storage import cold_migration_then_come_back, live_storage_migration_then_come_back + +# Requirements: +# From --hosts parameter: +# - host(A1): first XCP-ng host >= 8.3 with an additional unused native 4KiB disk for the LVM SR. +# - hostA2: Second member of the pool. Can have any local SR. No need to specify it on CLI. +# From --vm parameter +# - A VM to import to the LVM SR + +@pytest.mark.small_vm # run with a small VM to test the features +@pytest.mark.big_vm # and ideally with a big VM to test it scales +@pytest.mark.thick_provisioned +class Test: + def test_cold_intrapool_migration( + self, host: Host, hostA2: Host, vm_on_lvm_sr_4k: VM, local_sr_on_hostA2: SR + ) -> None: + cold_migration_then_come_back(vm_on_lvm_sr_4k, host, hostA2, local_sr_on_hostA2) + + def test_live_intrapool_migration( + self, host: Host, hostA2: Host, vm_on_lvm_sr_4k: VM, local_sr_on_hostA2: SR + ) -> None: + live_storage_migration_then_come_back(vm_on_lvm_sr_4k, host, hostA2, local_sr_on_hostA2)