From 3cef639568faf64d187b608991d1e49096694506 Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Fri, 24 Apr 2026 15:04:33 +0200 Subject: [PATCH 01/21] add `create_windows_vm_with_vtpm_validate_guest_agent_info` function Co-Authored: Claude Code Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/test_clone.py | 89 +++++++++++++++++++++++++++ tests/storage/utils.py | 45 ++++++++++++++ 2 files changed, 134 insertions(+) diff --git a/tests/storage/cdi_clone/test_clone.py b/tests/storage/cdi_clone/test_clone.py index a6667224e9..74919d8429 100644 --- a/tests/storage/cdi_clone/test_clone.py +++ b/tests/storage/cdi_clone/test_clone.py @@ -4,6 +4,12 @@ import pytest from ocp_resources.datavolume import DataVolume +from ocp_resources.virtual_machine_cluster_instancetype import ( + VirtualMachineClusterInstancetype, +) +from ocp_resources.virtual_machine_cluster_preference import ( + VirtualMachineClusterPreference, +) from tests.os_params import FEDORA_LATEST, WINDOWS_11, WINDOWS_11_TEMPLATE_LABELS from tests.storage.utils import ( @@ -64,6 +70,47 @@ def create_vm_from_clone_dv_template( running_vm(vm=vm) +def create_windows_vm_with_vtpm_validate_guest_agent_info( + dv, + namespace, + unprivileged_client, + windows_version, + admin_client=None, +): + """ + Create Windows VM with vTPM using instance types and preferences. + + Args: + dv: DataVolume to use for the VM + namespace: Namespace object + unprivileged_client: Client to use + windows_version: Windows version string ("11", "2k22", etc.) + admin_client: Optional admin client for vTPM validation + """ + from tests.storage.utils import validate_os_info_vmi_vs_windows_os, wait_for_windows_vm + + # Map Windows version to preference name + preference_name = f"windows.{windows_version}" # e.g., "windows.11", "windows.2k22" + + with VirtualMachineForTests( + name=f"vm-win-{windows_version}-vtpm", + namespace=namespace.name, + client=unprivileged_client, + os_flavor=OS_FLAVOR_WINDOWS, + vm_instance_type=VirtualMachineClusterInstancetype(name="u1.large", client=unprivileged_client), + vm_preference=VirtualMachineClusterPreference(name=preference_name, client=unprivileged_client), + data_volume_template={"metadata": dv.res["metadata"], "spec": dv.res["spec"]}, + ) as vm: + wait_for_windows_vm(vm=vm, version=windows_version, timeout=TIMEOUT_40MIN) + validate_os_info_vmi_vs_windows_os(vm=vm) + + # Validate vTPM if admin_client provided + if admin_client: + from tests.storage.utils import verify_vtpm_in_windows_vm + + verify_vtpm_in_windows_vm(vm=vm, admin_client=admin_client) + + @pytest.mark.tier3 @pytest.mark.parametrize( "data_volume_multi_storage_scope_function", @@ -189,6 +236,48 @@ def test_successful_vm_from_cloned_dv_windows( ) +@pytest.mark.tier3 +@pytest.mark.parametrize( + "data_volume_multi_storage_scope_function", + [ + pytest.param( + { + "dv_name": "dv-source-win11-vtpm", + "source": "http", + "image": f"{Images.Windows.DIR}/{Images.Windows.WIN11_IMG}", + "dv_size": Images.Windows.DEFAULT_DV_SIZE, + }, + marks=pytest.mark.polarion("CNV-XXXXX"), + ), + ], + indirect=True, +) +def test_successful_vm_from_cloned_dv_windows_with_vtpm( + unprivileged_client, + admin_client, + data_volume_multi_storage_scope_function, + namespace, +): + """Test cloning Windows 11 DV and creating VM with vTPM using instance types.""" + with create_dv( + client=unprivileged_client, + source="pvc", + dv_name="dv-target-win11-vtpm", + namespace=data_volume_multi_storage_scope_function.namespace, + size=data_volume_multi_storage_scope_function.size, + source_pvc=data_volume_multi_storage_scope_function.name, + storage_class=data_volume_multi_storage_scope_function.storage_class, + ) as cdv: + cdv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) + create_windows_vm_with_vtpm_validate_guest_agent_info( + dv=cdv, + namespace=namespace, + unprivileged_client=unprivileged_client, + windows_version="11", + admin_client=admin_client, + ) + + @pytest.mark.parametrize( "data_volume_snapshot_capable_storage_scope_function", [ diff --git a/tests/storage/utils.py b/tests/storage/utils.py index 2166af9168..9f1bcb4150 100644 --- a/tests/storage/utils.py +++ b/tests/storage/utils.py @@ -513,3 +513,48 @@ def check_file_in_vm( vm_console.expect(pattern=file_name, timeout=TIMEOUT_20SEC) vm_console.sendline(f"cat {file_name}") vm_console.expect(pattern=file_content, timeout=TIMEOUT_20SEC) + + +def verify_vtpm_in_windows_vm(vm, admin_client): # TODO: Remove - debug only + """ + Verify vTPM is properly configured and detected in a Windows VM. + + **DEBUG ONLY - MARKED FOR DELETION** + + Performs two-layer validation: + 1. KubeVirt configuration validation via VM XML + 2. Windows OS TPM detection via WMI + + Args: + vm (VirtualMachineForTests): Running Windows VM instance + admin_client (DynamicClient): Admin client for privileged VM XML access + + Raises: + AssertionError: If vTPM is not properly configured or detected + """ + LOGGER.info(f"Validating vTPM configuration and detection for VM: {vm.name}") + + # Layer 1: Validate TPM in KubeVirt VM XML + LOGGER.info("Validating vTPM configuration in KubeVirt VM spec") + xml_dict_tpm = vm.vmi.get_xml_dict(privileged_client=admin_client)["domain"]["devices"]["tpm"] + + tpm_model = xml_dict_tpm.get("@model") + assert tpm_model == "tpm-crb", f"Expected TPM model 'tpm-crb', got '{tpm_model}'" + + persistent_state = xml_dict_tpm.get("backend", {}).get("@persistent_state") + assert persistent_state == "yes", f"Expected TPM persistent state 'yes', got '{persistent_state}'" + LOGGER.info("vTPM configuration validated in VM spec") + + # Layer 2: Validate TPM detection in Windows OS + LOGGER.info("Validating vTPM detection in Windows OS") + vtpm_enabled = run_ssh_commands( + host=vm.ssh_exec, + commands=shlex.split( + r"wmic /namespace:\\root\cimv2\security\microsofttpm path Win32_Tpm get IsEnabled_InitialValue", + posix=False, + ), + )[0] + assert "TRUE" in vtpm_enabled, f"TPM not enabled in Windows. Output: {vtpm_enabled}" + LOGGER.info("vTPM detection validated in Windows OS") + + LOGGER.info(f"vTPM validation completed for VM: {vm.name}") From 7a5f86aa18f7196f0977357b8d96995d64dad765 Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Mon, 27 Apr 2026 08:03:01 +0200 Subject: [PATCH 02/21] fix the polarion mark Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/test_clone.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/storage/cdi_clone/test_clone.py b/tests/storage/cdi_clone/test_clone.py index 74919d8429..7c2d76015c 100644 --- a/tests/storage/cdi_clone/test_clone.py +++ b/tests/storage/cdi_clone/test_clone.py @@ -247,7 +247,7 @@ def test_successful_vm_from_cloned_dv_windows( "image": f"{Images.Windows.DIR}/{Images.Windows.WIN11_IMG}", "dv_size": Images.Windows.DEFAULT_DV_SIZE, }, - marks=pytest.mark.polarion("CNV-XXXXX"), + marks=pytest.mark.polarion("CNV-3638"), ), ], indirect=True, From 46a43ce77fb0a2b90ea88b8e15d1d1eaffbe2ec6 Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Tue, 28 Apr 2026 12:52:38 +0200 Subject: [PATCH 03/21] add source dv Windows from registry Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/conftest.py | 49 +++++++++++- tests/storage/cdi_clone/constants.py | 5 ++ tests/storage/cdi_clone/test_clone.py | 105 +++++++------------------- utilities/constants.py | 1 + 4 files changed, 82 insertions(+), 78 deletions(-) create mode 100644 tests/storage/cdi_clone/constants.py diff --git a/tests/storage/cdi_clone/conftest.py b/tests/storage/cdi_clone/conftest.py index 7647297a4d..b94f74984d 100644 --- a/tests/storage/cdi_clone/conftest.py +++ b/tests/storage/cdi_clone/conftest.py @@ -1,8 +1,11 @@ import pytest from ocp_resources.datavolume import DataVolume +from tests.storage.cdi_clone.constants import WINDOWS_CLONE_TIMEOUT from tests.storage.constants import QUAY_FEDORA_CONTAINER_IMAGE -from utilities.constants import REGISTRY_STR, Images +from utilities.artifactory import get_artifactory_config_map, get_artifactory_secret, get_test_artifact_server_url +from utilities.constants import REGISTRY_STR, WIN_2K22, Images +from utilities.os_utils import get_windows_container_disk_path from utilities.storage import create_dv, data_volume @@ -59,3 +62,47 @@ def fedora_dv_with_block_volume_mode( ) as dv: dv.wait_for_dv_success() yield dv + + +@pytest.fixture(scope="function") +def source_dv_windows_registry( + unprivileged_client, + namespace, + storage_class_name_scope_function, +): + """Fixture that creates a Windows 2022 DataVolume from registry.""" + secret = get_artifactory_secret(namespace=namespace.name) + cert = get_artifactory_config_map(namespace=namespace.name) + + with create_dv( + client=unprivileged_client, + dv_name=f"dv-source-{WIN_2K22}-registry", + namespace=namespace.name, + source="registry", + size=Images.Windows.CONTAINER_DISK_DV_SIZE, + storage_class=storage_class_name_scope_function, + url=f"{get_test_artifact_server_url(schema='registry')}/{get_windows_container_disk_path(os_value=WIN_2K22)}", + secret=secret, + cert_configmap=cert.name, + ) as dv: + dv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) + yield dv + + +@pytest.fixture(scope="function") +def cloned_windows_dv_from_registry( + unprivileged_client, + source_dv_windows_registry, +): + """Fixture that creates a cloned DataVolume from registry source.""" + with create_dv( + client=unprivileged_client, + source="pvc", + dv_name=f"dv-target-{WIN_2K22}-vtpm", + namespace=source_dv_windows_registry.namespace, + size=source_dv_windows_registry.size, + source_pvc=source_dv_windows_registry.name, + storage_class=source_dv_windows_registry.storage_class, + ) as cdv: + cdv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) + yield cdv diff --git a/tests/storage/cdi_clone/constants.py b/tests/storage/cdi_clone/constants.py new file mode 100644 index 0000000000..adc832bde4 --- /dev/null +++ b/tests/storage/cdi_clone/constants.py @@ -0,0 +1,5 @@ +"""Constants for CDI clone tests.""" + +from utilities.constants import TIMEOUT_40MIN + +WINDOWS_CLONE_TIMEOUT = TIMEOUT_40MIN diff --git a/tests/storage/cdi_clone/test_clone.py b/tests/storage/cdi_clone/test_clone.py index 7c2d76015c..84ea2d220c 100644 --- a/tests/storage/cdi_clone/test_clone.py +++ b/tests/storage/cdi_clone/test_clone.py @@ -12,16 +12,24 @@ ) from tests.os_params import FEDORA_LATEST, WINDOWS_11, WINDOWS_11_TEMPLATE_LABELS +from tests.storage.cdi_clone.constants import WINDOWS_CLONE_TIMEOUT from tests.storage.utils import ( assert_pvc_snapshot_clone_annotation, assert_use_populator, create_windows_vm_validate_guest_agent_info, + validate_os_info_vmi_vs_windows_os, + verify_vtpm_in_windows_vm, + wait_for_windows_vm, ) from utilities.constants import ( OS_FLAVOR_FEDORA, + OS_FLAVOR_WIN_CONTAINER_DISK, OS_FLAVOR_WINDOWS, TIMEOUT_1MIN, TIMEOUT_40MIN, + U1_LARGE, + WIN_2K22, + WINDOWS_2K22_PREFERENCE, Images, ) from utilities.storage import ( @@ -39,8 +47,6 @@ running_vm, ) -WINDOWS_CLONE_TIMEOUT = TIMEOUT_40MIN - def create_vm_from_clone_dv_template( vm_name, @@ -70,47 +76,6 @@ def create_vm_from_clone_dv_template( running_vm(vm=vm) -def create_windows_vm_with_vtpm_validate_guest_agent_info( - dv, - namespace, - unprivileged_client, - windows_version, - admin_client=None, -): - """ - Create Windows VM with vTPM using instance types and preferences. - - Args: - dv: DataVolume to use for the VM - namespace: Namespace object - unprivileged_client: Client to use - windows_version: Windows version string ("11", "2k22", etc.) - admin_client: Optional admin client for vTPM validation - """ - from tests.storage.utils import validate_os_info_vmi_vs_windows_os, wait_for_windows_vm - - # Map Windows version to preference name - preference_name = f"windows.{windows_version}" # e.g., "windows.11", "windows.2k22" - - with VirtualMachineForTests( - name=f"vm-win-{windows_version}-vtpm", - namespace=namespace.name, - client=unprivileged_client, - os_flavor=OS_FLAVOR_WINDOWS, - vm_instance_type=VirtualMachineClusterInstancetype(name="u1.large", client=unprivileged_client), - vm_preference=VirtualMachineClusterPreference(name=preference_name, client=unprivileged_client), - data_volume_template={"metadata": dv.res["metadata"], "spec": dv.res["spec"]}, - ) as vm: - wait_for_windows_vm(vm=vm, version=windows_version, timeout=TIMEOUT_40MIN) - validate_os_info_vmi_vs_windows_os(vm=vm) - - # Validate vTPM if admin_client provided - if admin_client: - from tests.storage.utils import verify_vtpm_in_windows_vm - - verify_vtpm_in_windows_vm(vm=vm, admin_client=admin_client) - - @pytest.mark.tier3 @pytest.mark.parametrize( "data_volume_multi_storage_scope_function", @@ -237,45 +202,31 @@ def test_successful_vm_from_cloned_dv_windows( @pytest.mark.tier3 -@pytest.mark.parametrize( - "data_volume_multi_storage_scope_function", - [ - pytest.param( - { - "dv_name": "dv-source-win11-vtpm", - "source": "http", - "image": f"{Images.Windows.DIR}/{Images.Windows.WIN11_IMG}", - "dv_size": Images.Windows.DEFAULT_DV_SIZE, - }, - marks=pytest.mark.polarion("CNV-3638"), - ), - ], - indirect=True, -) +@pytest.mark.polarion("CNV-3638") def test_successful_vm_from_cloned_dv_windows_with_vtpm( + admin_client, # only needed for `verify_vtpm_in_windows_vm`, to be deleted once verified unprivileged_client, - admin_client, - data_volume_multi_storage_scope_function, namespace, + cloned_windows_dv_from_registry, ): - """Test cloning Windows 11 DV and creating VM with vTPM using instance types.""" - with create_dv( + """Test cloning Windows 2022 DV and creating VM with vTPM using instance types.""" + + with VirtualMachineForTests( + name=f"vm-{WIN_2K22}-vtpm", + namespace=namespace.name, client=unprivileged_client, - source="pvc", - dv_name="dv-target-win11-vtpm", - namespace=data_volume_multi_storage_scope_function.namespace, - size=data_volume_multi_storage_scope_function.size, - source_pvc=data_volume_multi_storage_scope_function.name, - storage_class=data_volume_multi_storage_scope_function.storage_class, - ) as cdv: - cdv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) - create_windows_vm_with_vtpm_validate_guest_agent_info( - dv=cdv, - namespace=namespace, - unprivileged_client=unprivileged_client, - windows_version="11", - admin_client=admin_client, - ) + os_flavor=OS_FLAVOR_WIN_CONTAINER_DISK, + vm_instance_type=VirtualMachineClusterInstancetype(name=U1_LARGE, client=unprivileged_client), + vm_preference=VirtualMachineClusterPreference(name=WINDOWS_2K22_PREFERENCE, client=unprivileged_client), + data_volume_template={ + "metadata": cloned_windows_dv_from_registry.res["metadata"], + "spec": cloned_windows_dv_from_registry.res["spec"], + }, + ) as vm: + vm.start() + wait_for_windows_vm(vm=vm, version="2k22", timeout=TIMEOUT_40MIN) + validate_os_info_vmi_vs_windows_os(vm=vm) + verify_vtpm_in_windows_vm(vm=vm, admin_client=admin_client) @pytest.mark.parametrize( diff --git a/utilities/constants.py b/utilities/constants.py index 4ba19fd9c7..73e11ea36f 100644 --- a/utilities/constants.py +++ b/utilities/constants.py @@ -819,6 +819,7 @@ class NamespacesNames: RHEL8_PREFERENCE = "rhel.8" RHEL9_PREFERENCE = "rhel.9" RHEL10_PREFERENCE = "rhel.10" +WINDOWS_2K22_PREFERENCE = "windows.2k22" U1_SMALL = "u1.small" U1_LARGE = "u1.large" PROMETHEUS_K8S = "prometheus-k8s" From 5b055878bb87d4c838e10b28b3610984ed53eabf Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Tue, 28 Apr 2026 13:00:37 +0200 Subject: [PATCH 04/21] fix `wait_for_windows_vm` version string Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/test_clone.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/storage/cdi_clone/test_clone.py b/tests/storage/cdi_clone/test_clone.py index 84ea2d220c..ab1baa0d87 100644 --- a/tests/storage/cdi_clone/test_clone.py +++ b/tests/storage/cdi_clone/test_clone.py @@ -224,7 +224,7 @@ def test_successful_vm_from_cloned_dv_windows_with_vtpm( }, ) as vm: vm.start() - wait_for_windows_vm(vm=vm, version="2k22", timeout=TIMEOUT_40MIN) + wait_for_windows_vm(vm=vm, version="2022", timeout=TIMEOUT_40MIN) validate_os_info_vmi_vs_windows_os(vm=vm) verify_vtpm_in_windows_vm(vm=vm, admin_client=admin_client) From c7115668af57d6ad92f9c34259b98060f1c5bec0 Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Tue, 28 Apr 2026 15:36:00 +0200 Subject: [PATCH 05/21] remove `verify_vtpm_in_windows_vm` from storage utils Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/test_clone.py | 3 -- tests/storage/utils.py | 45 --------------------------- 2 files changed, 48 deletions(-) diff --git a/tests/storage/cdi_clone/test_clone.py b/tests/storage/cdi_clone/test_clone.py index ab1baa0d87..df65a73d8a 100644 --- a/tests/storage/cdi_clone/test_clone.py +++ b/tests/storage/cdi_clone/test_clone.py @@ -18,7 +18,6 @@ assert_use_populator, create_windows_vm_validate_guest_agent_info, validate_os_info_vmi_vs_windows_os, - verify_vtpm_in_windows_vm, wait_for_windows_vm, ) from utilities.constants import ( @@ -204,7 +203,6 @@ def test_successful_vm_from_cloned_dv_windows( @pytest.mark.tier3 @pytest.mark.polarion("CNV-3638") def test_successful_vm_from_cloned_dv_windows_with_vtpm( - admin_client, # only needed for `verify_vtpm_in_windows_vm`, to be deleted once verified unprivileged_client, namespace, cloned_windows_dv_from_registry, @@ -226,7 +224,6 @@ def test_successful_vm_from_cloned_dv_windows_with_vtpm( vm.start() wait_for_windows_vm(vm=vm, version="2022", timeout=TIMEOUT_40MIN) validate_os_info_vmi_vs_windows_os(vm=vm) - verify_vtpm_in_windows_vm(vm=vm, admin_client=admin_client) @pytest.mark.parametrize( diff --git a/tests/storage/utils.py b/tests/storage/utils.py index 9f1bcb4150..2166af9168 100644 --- a/tests/storage/utils.py +++ b/tests/storage/utils.py @@ -513,48 +513,3 @@ def check_file_in_vm( vm_console.expect(pattern=file_name, timeout=TIMEOUT_20SEC) vm_console.sendline(f"cat {file_name}") vm_console.expect(pattern=file_content, timeout=TIMEOUT_20SEC) - - -def verify_vtpm_in_windows_vm(vm, admin_client): # TODO: Remove - debug only - """ - Verify vTPM is properly configured and detected in a Windows VM. - - **DEBUG ONLY - MARKED FOR DELETION** - - Performs two-layer validation: - 1. KubeVirt configuration validation via VM XML - 2. Windows OS TPM detection via WMI - - Args: - vm (VirtualMachineForTests): Running Windows VM instance - admin_client (DynamicClient): Admin client for privileged VM XML access - - Raises: - AssertionError: If vTPM is not properly configured or detected - """ - LOGGER.info(f"Validating vTPM configuration and detection for VM: {vm.name}") - - # Layer 1: Validate TPM in KubeVirt VM XML - LOGGER.info("Validating vTPM configuration in KubeVirt VM spec") - xml_dict_tpm = vm.vmi.get_xml_dict(privileged_client=admin_client)["domain"]["devices"]["tpm"] - - tpm_model = xml_dict_tpm.get("@model") - assert tpm_model == "tpm-crb", f"Expected TPM model 'tpm-crb', got '{tpm_model}'" - - persistent_state = xml_dict_tpm.get("backend", {}).get("@persistent_state") - assert persistent_state == "yes", f"Expected TPM persistent state 'yes', got '{persistent_state}'" - LOGGER.info("vTPM configuration validated in VM spec") - - # Layer 2: Validate TPM detection in Windows OS - LOGGER.info("Validating vTPM detection in Windows OS") - vtpm_enabled = run_ssh_commands( - host=vm.ssh_exec, - commands=shlex.split( - r"wmic /namespace:\\root\cimv2\security\microsofttpm path Win32_Tpm get IsEnabled_InitialValue", - posix=False, - ), - )[0] - assert "TRUE" in vtpm_enabled, f"TPM not enabled in Windows. Output: {vtpm_enabled}" - LOGGER.info("vTPM detection validated in Windows OS") - - LOGGER.info(f"vTPM validation completed for VM: {vm.name}") From 3f2d7787b29a62795242cbdbc98dbce6d377a058 Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Tue, 28 Apr 2026 15:48:15 +0200 Subject: [PATCH 06/21] cleanup constants and imports Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/conftest.py | 5 +-- tests/storage/cdi_clone/constants.py | 5 --- tests/storage/cdi_clone/test_clone.py | 52 ++------------------------- 3 files changed, 5 insertions(+), 57 deletions(-) delete mode 100644 tests/storage/cdi_clone/constants.py diff --git a/tests/storage/cdi_clone/conftest.py b/tests/storage/cdi_clone/conftest.py index b94f74984d..f11475ab86 100644 --- a/tests/storage/cdi_clone/conftest.py +++ b/tests/storage/cdi_clone/conftest.py @@ -1,13 +1,14 @@ import pytest from ocp_resources.datavolume import DataVolume -from tests.storage.cdi_clone.constants import WINDOWS_CLONE_TIMEOUT from tests.storage.constants import QUAY_FEDORA_CONTAINER_IMAGE from utilities.artifactory import get_artifactory_config_map, get_artifactory_secret, get_test_artifact_server_url -from utilities.constants import REGISTRY_STR, WIN_2K22, Images +from utilities.constants import REGISTRY_STR, TIMEOUT_40MIN, WIN_2K22, Images from utilities.os_utils import get_windows_container_disk_path from utilities.storage import create_dv, data_volume +WINDOWS_CLONE_TIMEOUT = TIMEOUT_40MIN + @pytest.fixture() def data_volume_snapshot_capable_storage_scope_function( diff --git a/tests/storage/cdi_clone/constants.py b/tests/storage/cdi_clone/constants.py deleted file mode 100644 index adc832bde4..0000000000 --- a/tests/storage/cdi_clone/constants.py +++ /dev/null @@ -1,5 +0,0 @@ -"""Constants for CDI clone tests.""" - -from utilities.constants import TIMEOUT_40MIN - -WINDOWS_CLONE_TIMEOUT = TIMEOUT_40MIN diff --git a/tests/storage/cdi_clone/test_clone.py b/tests/storage/cdi_clone/test_clone.py index df65a73d8a..c450a6d8a7 100644 --- a/tests/storage/cdi_clone/test_clone.py +++ b/tests/storage/cdi_clone/test_clone.py @@ -11,12 +11,10 @@ VirtualMachineClusterPreference, ) -from tests.os_params import FEDORA_LATEST, WINDOWS_11, WINDOWS_11_TEMPLATE_LABELS -from tests.storage.cdi_clone.constants import WINDOWS_CLONE_TIMEOUT +from tests.os_params import FEDORA_LATEST from tests.storage.utils import ( assert_pvc_snapshot_clone_annotation, assert_use_populator, - create_windows_vm_validate_guest_agent_info, validate_os_info_vmi_vs_windows_os, wait_for_windows_vm, ) @@ -104,7 +102,7 @@ def test_successful_clone_of_large_image( storage_class=data_volume_multi_storage_scope_function.storage_class, client=namespace.client, ) as cdv: - cdv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) + cdv.wait_for_dv_success(timeout=TIMEOUT_40MIN) @pytest.mark.sno @@ -154,52 +152,6 @@ def test_successful_vm_restart_with_cloned_dv( ) -@pytest.mark.tier3 -@pytest.mark.parametrize( - ("data_volume_multi_storage_scope_function", "vm_params"), - [ - pytest.param( - { - "dv_name": "dv-source", - "source": "http", - "image": f"{Images.Windows.DIR}/{Images.Windows.WIN11_IMG}", - "dv_size": Images.Windows.DEFAULT_DV_SIZE, - }, - { - "vm_name": f"vm-win-{WINDOWS_11.get('os_version')}", - "template_labels": WINDOWS_11_TEMPLATE_LABELS, - "os_version": WINDOWS_11.get("os_version"), - "ssh": True, - }, - marks=pytest.mark.polarion("CNV-3638"), - ), - ], - indirect=["data_volume_multi_storage_scope_function"], -) -def test_successful_vm_from_cloned_dv_windows( - unprivileged_client, - data_volume_multi_storage_scope_function, - vm_params, - namespace, -): - with create_dv( - client=unprivileged_client, - source="pvc", - dv_name="dv-target", - namespace=data_volume_multi_storage_scope_function.namespace, - size=data_volume_multi_storage_scope_function.size, - source_pvc=data_volume_multi_storage_scope_function.name, - storage_class=data_volume_multi_storage_scope_function.storage_class, - ) as cdv: - cdv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) - create_windows_vm_validate_guest_agent_info( - dv=cdv, - namespace=namespace, - unprivileged_client=unprivileged_client, - vm_params=vm_params, - ) - - @pytest.mark.tier3 @pytest.mark.polarion("CNV-3638") def test_successful_vm_from_cloned_dv_windows_with_vtpm( From 7d7914ac720731d233bb1bd448035c19fbf62170 Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Tue, 28 Apr 2026 16:12:37 +0200 Subject: [PATCH 07/21] fix fixture names Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/conftest.py | 8 ++++---- tests/storage/cdi_clone/test_clone.py | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/storage/cdi_clone/conftest.py b/tests/storage/cdi_clone/conftest.py index f11475ab86..88546b1697 100644 --- a/tests/storage/cdi_clone/conftest.py +++ b/tests/storage/cdi_clone/conftest.py @@ -65,8 +65,8 @@ def fedora_dv_with_block_volume_mode( yield dv -@pytest.fixture(scope="function") -def source_dv_windows_registry( +@pytest.fixture() +def source_dv_windows_registry_scope_function( unprivileged_client, namespace, storage_class_name_scope_function, @@ -90,8 +90,8 @@ def source_dv_windows_registry( yield dv -@pytest.fixture(scope="function") -def cloned_windows_dv_from_registry( +@pytest.fixture() +def cloned_windows_dv_from_registry_scope_function( unprivileged_client, source_dv_windows_registry, ): diff --git a/tests/storage/cdi_clone/test_clone.py b/tests/storage/cdi_clone/test_clone.py index c450a6d8a7..3d76fb2a99 100644 --- a/tests/storage/cdi_clone/test_clone.py +++ b/tests/storage/cdi_clone/test_clone.py @@ -157,7 +157,7 @@ def test_successful_vm_restart_with_cloned_dv( def test_successful_vm_from_cloned_dv_windows_with_vtpm( unprivileged_client, namespace, - cloned_windows_dv_from_registry, + cloned_windows_dv_from_registry_scope_function, ): """Test cloning Windows 2022 DV and creating VM with vTPM using instance types.""" @@ -169,8 +169,8 @@ def test_successful_vm_from_cloned_dv_windows_with_vtpm( vm_instance_type=VirtualMachineClusterInstancetype(name=U1_LARGE, client=unprivileged_client), vm_preference=VirtualMachineClusterPreference(name=WINDOWS_2K22_PREFERENCE, client=unprivileged_client), data_volume_template={ - "metadata": cloned_windows_dv_from_registry.res["metadata"], - "spec": cloned_windows_dv_from_registry.res["spec"], + "metadata": cloned_windows_dv_from_registry_scope_function.res["metadata"], + "spec": cloned_windows_dv_from_registry_scope_function.res["spec"], }, ) as vm: vm.start() From 1b94a4b6df05dcc1d7935d455a3784b4dd28d71b Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Wed, 29 Apr 2026 09:54:46 +0200 Subject: [PATCH 08/21] fix fixture name in `cloned_windows_dv_from_registry_scope_function` Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/conftest.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/storage/cdi_clone/conftest.py b/tests/storage/cdi_clone/conftest.py index 88546b1697..ba28645353 100644 --- a/tests/storage/cdi_clone/conftest.py +++ b/tests/storage/cdi_clone/conftest.py @@ -93,17 +93,17 @@ def source_dv_windows_registry_scope_function( @pytest.fixture() def cloned_windows_dv_from_registry_scope_function( unprivileged_client, - source_dv_windows_registry, + source_dv_windows_registry_scope_function, ): """Fixture that creates a cloned DataVolume from registry source.""" with create_dv( client=unprivileged_client, source="pvc", dv_name=f"dv-target-{WIN_2K22}-vtpm", - namespace=source_dv_windows_registry.namespace, - size=source_dv_windows_registry.size, - source_pvc=source_dv_windows_registry.name, - storage_class=source_dv_windows_registry.storage_class, + namespace=source_dv_windows_registry_scope_function.namespace, + size=source_dv_windows_registry_scope_function.size, + source_pvc=source_dv_windows_registry_scope_function.name, + storage_class=source_dv_windows_registry_scope_function.storage_class, ) as cdv: cdv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) yield cdv From c743ba3b5446f950d8c095de3341081dd0e876ca Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Wed, 29 Apr 2026 14:29:27 +0200 Subject: [PATCH 09/21] remove `WINDOWS_CLONE_TIMEOUT` as per reviewer's suggestion Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/conftest.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/storage/cdi_clone/conftest.py b/tests/storage/cdi_clone/conftest.py index ba28645353..99d2a9fcbc 100644 --- a/tests/storage/cdi_clone/conftest.py +++ b/tests/storage/cdi_clone/conftest.py @@ -7,8 +7,6 @@ from utilities.os_utils import get_windows_container_disk_path from utilities.storage import create_dv, data_volume -WINDOWS_CLONE_TIMEOUT = TIMEOUT_40MIN - @pytest.fixture() def data_volume_snapshot_capable_storage_scope_function( @@ -86,7 +84,7 @@ def source_dv_windows_registry_scope_function( secret=secret, cert_configmap=cert.name, ) as dv: - dv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) + dv.wait_for_dv_success(timeout=TIMEOUT_40MIN) yield dv @@ -105,5 +103,5 @@ def cloned_windows_dv_from_registry_scope_function( source_pvc=source_dv_windows_registry_scope_function.name, storage_class=source_dv_windows_registry_scope_function.storage_class, ) as cdv: - cdv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) + cdv.wait_for_dv_success(timeout=TIMEOUT_40MIN) yield cdv From 5c56e47d63ef10f294e45758461120c582bbca94 Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Mon, 4 May 2026 08:01:15 +0200 Subject: [PATCH 10/21] fix DV cloning Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/conftest.py | 7 ++++--- tests/storage/cdi_clone/constants.py | 5 +++++ tests/storage/cdi_clone/test_clone.py | 8 +++----- 3 files changed, 12 insertions(+), 8 deletions(-) create mode 100644 tests/storage/cdi_clone/constants.py diff --git a/tests/storage/cdi_clone/conftest.py b/tests/storage/cdi_clone/conftest.py index 99d2a9fcbc..8bcee73d9e 100644 --- a/tests/storage/cdi_clone/conftest.py +++ b/tests/storage/cdi_clone/conftest.py @@ -1,9 +1,10 @@ import pytest from ocp_resources.datavolume import DataVolume +from tests.storage.cdi_clone.constants import WINDOWS_CLONE_TIMEOUT from tests.storage.constants import QUAY_FEDORA_CONTAINER_IMAGE from utilities.artifactory import get_artifactory_config_map, get_artifactory_secret, get_test_artifact_server_url -from utilities.constants import REGISTRY_STR, TIMEOUT_40MIN, WIN_2K22, Images +from utilities.constants import REGISTRY_STR, WIN_2K22, Images from utilities.os_utils import get_windows_container_disk_path from utilities.storage import create_dv, data_volume @@ -84,7 +85,7 @@ def source_dv_windows_registry_scope_function( secret=secret, cert_configmap=cert.name, ) as dv: - dv.wait_for_dv_success(timeout=TIMEOUT_40MIN) + dv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) yield dv @@ -103,5 +104,5 @@ def cloned_windows_dv_from_registry_scope_function( source_pvc=source_dv_windows_registry_scope_function.name, storage_class=source_dv_windows_registry_scope_function.storage_class, ) as cdv: - cdv.wait_for_dv_success(timeout=TIMEOUT_40MIN) + cdv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) yield cdv diff --git a/tests/storage/cdi_clone/constants.py b/tests/storage/cdi_clone/constants.py new file mode 100644 index 0000000000..5d91201387 --- /dev/null +++ b/tests/storage/cdi_clone/constants.py @@ -0,0 +1,5 @@ +"""Constants for CDI clone tests.""" + +from utilities.constants import TIMEOUT_60MIN + +WINDOWS_CLONE_TIMEOUT = TIMEOUT_60MIN diff --git a/tests/storage/cdi_clone/test_clone.py b/tests/storage/cdi_clone/test_clone.py index 3d76fb2a99..d9b35d60db 100644 --- a/tests/storage/cdi_clone/test_clone.py +++ b/tests/storage/cdi_clone/test_clone.py @@ -12,6 +12,7 @@ ) from tests.os_params import FEDORA_LATEST +from tests.storage.cdi_clone.constants import WINDOWS_CLONE_TIMEOUT from tests.storage.utils import ( assert_pvc_snapshot_clone_annotation, assert_use_populator, @@ -168,13 +169,10 @@ def test_successful_vm_from_cloned_dv_windows_with_vtpm( os_flavor=OS_FLAVOR_WIN_CONTAINER_DISK, vm_instance_type=VirtualMachineClusterInstancetype(name=U1_LARGE, client=unprivileged_client), vm_preference=VirtualMachineClusterPreference(name=WINDOWS_2K22_PREFERENCE, client=unprivileged_client), - data_volume_template={ - "metadata": cloned_windows_dv_from_registry_scope_function.res["metadata"], - "spec": cloned_windows_dv_from_registry_scope_function.res["spec"], - }, + data_volume=cloned_windows_dv_from_registry_scope_function, ) as vm: vm.start() - wait_for_windows_vm(vm=vm, version="2022", timeout=TIMEOUT_40MIN) + wait_for_windows_vm(vm=vm, version="2022", timeout=WINDOWS_CLONE_TIMEOUT) validate_os_info_vmi_vs_windows_os(vm=vm) From 37da3f6d3e39f1ba923b517333290d8d5306bebd Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Wed, 6 May 2026 10:36:40 +0200 Subject: [PATCH 11/21] add artifactory secret and config_map cleanup Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/conftest.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/storage/cdi_clone/conftest.py b/tests/storage/cdi_clone/conftest.py index 8bcee73d9e..afb46635b6 100644 --- a/tests/storage/cdi_clone/conftest.py +++ b/tests/storage/cdi_clone/conftest.py @@ -3,7 +3,12 @@ from tests.storage.cdi_clone.constants import WINDOWS_CLONE_TIMEOUT from tests.storage.constants import QUAY_FEDORA_CONTAINER_IMAGE -from utilities.artifactory import get_artifactory_config_map, get_artifactory_secret, get_test_artifact_server_url +from utilities.artifactory import ( + cleanup_artifactory_secret_and_config_map, + get_artifactory_config_map, + get_artifactory_secret, + get_test_artifact_server_url, +) from utilities.constants import REGISTRY_STR, WIN_2K22, Images from utilities.os_utils import get_windows_container_disk_path from utilities.storage import create_dv, data_volume @@ -87,6 +92,7 @@ def source_dv_windows_registry_scope_function( ) as dv: dv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) yield dv + cleanup_artifactory_secret_and_config_map(artifactory_secret=secret, artifactory_config_map=cert) @pytest.fixture() From 5358eddbbb18351b5f1eb78ba64754ccff75713b Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Mon, 18 May 2026 13:11:42 +0200 Subject: [PATCH 12/21] clean up artifactory Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/conftest.py | 44 ++++++++++++++------------- tests/storage/cdi_clone/constants.py | 4 +-- tests/storage/cdi_clone/test_clone.py | 11 ++++--- 3 files changed, 31 insertions(+), 28 deletions(-) diff --git a/tests/storage/cdi_clone/conftest.py b/tests/storage/cdi_clone/conftest.py index afb46635b6..39dd259efa 100644 --- a/tests/storage/cdi_clone/conftest.py +++ b/tests/storage/cdi_clone/conftest.py @@ -70,7 +70,7 @@ def fedora_dv_with_block_volume_mode( @pytest.fixture() -def source_dv_windows_registry_scope_function( +def source_dv_windows_with_vtpm_registry_scope_function( unprivileged_client, namespace, storage_class_name_scope_function, @@ -79,36 +79,38 @@ def source_dv_windows_registry_scope_function( secret = get_artifactory_secret(namespace=namespace.name) cert = get_artifactory_config_map(namespace=namespace.name) - with create_dv( - client=unprivileged_client, - dv_name=f"dv-source-{WIN_2K22}-registry", - namespace=namespace.name, - source="registry", - size=Images.Windows.CONTAINER_DISK_DV_SIZE, - storage_class=storage_class_name_scope_function, - url=f"{get_test_artifact_server_url(schema='registry')}/{get_windows_container_disk_path(os_value=WIN_2K22)}", - secret=secret, - cert_configmap=cert.name, - ) as dv: - dv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) - yield dv - cleanup_artifactory_secret_and_config_map(artifactory_secret=secret, artifactory_config_map=cert) + try: + with create_dv( + client=unprivileged_client, + dv_name=f"dv-source-{WIN_2K22}-registry", + namespace=namespace.name, + source="registry", + size=Images.Windows.CONTAINER_DISK_DV_SIZE, + storage_class=storage_class_name_scope_function, + url=f"{get_test_artifact_server_url(schema='registry')}/{get_windows_container_disk_path(os_value=WIN_2K22)}", + secret=secret, + cert_configmap=cert.name, + ) as dv: + dv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) + yield dv + finally: + cleanup_artifactory_secret_and_config_map(artifactory_secret=secret, artifactory_config_map=cert) @pytest.fixture() -def cloned_windows_dv_from_registry_scope_function( +def cloned_windows_with_vtpm_dv_from_registry_scope_function( unprivileged_client, - source_dv_windows_registry_scope_function, + source_dv_windows_with_vtpm_registry_scope_function, ): """Fixture that creates a cloned DataVolume from registry source.""" with create_dv( client=unprivileged_client, source="pvc", dv_name=f"dv-target-{WIN_2K22}-vtpm", - namespace=source_dv_windows_registry_scope_function.namespace, - size=source_dv_windows_registry_scope_function.size, - source_pvc=source_dv_windows_registry_scope_function.name, - storage_class=source_dv_windows_registry_scope_function.storage_class, + namespace=source_dv_windows_with_vtpm_registry_scope_function.namespace, + size=source_dv_windows_with_vtpm_registry_scope_function.size, + source_pvc=source_dv_windows_with_vtpm_registry_scope_function.name, + storage_class=source_dv_windows_with_vtpm_registry_scope_function.storage_class, ) as cdv: cdv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) yield cdv diff --git a/tests/storage/cdi_clone/constants.py b/tests/storage/cdi_clone/constants.py index 5d91201387..18c2f698ad 100644 --- a/tests/storage/cdi_clone/constants.py +++ b/tests/storage/cdi_clone/constants.py @@ -1,5 +1,5 @@ """Constants for CDI clone tests.""" -from utilities.constants import TIMEOUT_60MIN +from utilities.constants import TIMEOUT_30MIN -WINDOWS_CLONE_TIMEOUT = TIMEOUT_60MIN +WINDOWS_CLONE_TIMEOUT = TIMEOUT_30MIN diff --git a/tests/storage/cdi_clone/test_clone.py b/tests/storage/cdi_clone/test_clone.py index d9b35d60db..b58a20d3cb 100644 --- a/tests/storage/cdi_clone/test_clone.py +++ b/tests/storage/cdi_clone/test_clone.py @@ -155,13 +155,13 @@ def test_successful_vm_restart_with_cloned_dv( @pytest.mark.tier3 @pytest.mark.polarion("CNV-3638") -def test_successful_vm_from_cloned_dv_windows_with_vtpm( +def test_successful_vm_from_cloned_dv_windows( unprivileged_client, namespace, - cloned_windows_dv_from_registry_scope_function, + modern_cpu_for_migration, + cloned_windows_with_vtpm_dv_from_registry_scope_function, ): """Test cloning Windows 2022 DV and creating VM with vTPM using instance types.""" - with VirtualMachineForTests( name=f"vm-{WIN_2K22}-vtpm", namespace=namespace.name, @@ -169,9 +169,10 @@ def test_successful_vm_from_cloned_dv_windows_with_vtpm( os_flavor=OS_FLAVOR_WIN_CONTAINER_DISK, vm_instance_type=VirtualMachineClusterInstancetype(name=U1_LARGE, client=unprivileged_client), vm_preference=VirtualMachineClusterPreference(name=WINDOWS_2K22_PREFERENCE, client=unprivileged_client), - data_volume=cloned_windows_dv_from_registry_scope_function, + data_volume=cloned_windows_with_vtpm_dv_from_registry_scope_function, + cpu_model=modern_cpu_for_migration, ) as vm: - vm.start() + running_vm(vm=vm) wait_for_windows_vm(vm=vm, version="2022", timeout=WINDOWS_CLONE_TIMEOUT) validate_os_info_vmi_vs_windows_os(vm=vm) From 20fc6ee3892ed3424385432e036e85656a27844d Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Thu, 21 May 2026 14:28:48 +0200 Subject: [PATCH 13/21] use the helper functions from `tests/utils.py` merged earlier Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/conftest.py | 55 +++++++++++---------------- tests/storage/cdi_clone/test_clone.py | 25 +++--------- tests/storage/test_hotplug.py | 8 ++-- tests/utils.py | 10 ++--- 4 files changed, 37 insertions(+), 61 deletions(-) diff --git a/tests/storage/cdi_clone/conftest.py b/tests/storage/cdi_clone/conftest.py index 39dd259efa..87b2956c0d 100644 --- a/tests/storage/cdi_clone/conftest.py +++ b/tests/storage/cdi_clone/conftest.py @@ -3,14 +3,8 @@ from tests.storage.cdi_clone.constants import WINDOWS_CLONE_TIMEOUT from tests.storage.constants import QUAY_FEDORA_CONTAINER_IMAGE -from utilities.artifactory import ( - cleanup_artifactory_secret_and_config_map, - get_artifactory_config_map, - get_artifactory_secret, - get_test_artifact_server_url, -) +from tests.utils import create_windows2022_dv_template_from_registry from utilities.constants import REGISTRY_STR, WIN_2K22, Images -from utilities.os_utils import get_windows_container_disk_path from utilities.storage import create_dv, data_volume @@ -70,47 +64,44 @@ def fedora_dv_with_block_volume_mode( @pytest.fixture() -def source_dv_windows_with_vtpm_registry_scope_function( +def source_dv_windows_registry_scope_function( unprivileged_client, namespace, storage_class_name_scope_function, ): """Fixture that creates a Windows 2022 DataVolume from registry.""" - secret = get_artifactory_secret(namespace=namespace.name) - cert = get_artifactory_config_map(namespace=namespace.name) - - try: - with create_dv( - client=unprivileged_client, + with ( + create_windows2022_dv_template_from_registry( dv_name=f"dv-source-{WIN_2K22}-registry", namespace=namespace.name, - source="registry", - size=Images.Windows.CONTAINER_DISK_DV_SIZE, + client=unprivileged_client, storage_class=storage_class_name_scope_function, - url=f"{get_test_artifact_server_url(schema='registry')}/{get_windows_container_disk_path(os_value=WIN_2K22)}", - secret=secret, - cert_configmap=cert.name, - ) as dv: - dv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) - yield dv - finally: - cleanup_artifactory_secret_and_config_map(artifactory_secret=secret, artifactory_config_map=cert) + ) as dv_template, + DataVolume( + kind_dict={"apiVersion": f"{DataVolume.api_group}/v1beta1", "kind": "DataVolume", **dv_template}, + client=unprivileged_client, + ) as dv, + ): + dv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) + yield dv @pytest.fixture() -def cloned_windows_with_vtpm_dv_from_registry_scope_function( +def cloned_windows_dv_template_from_registry_scope_function( unprivileged_client, - source_dv_windows_with_vtpm_registry_scope_function, + source_dv_windows_registry_scope_function, ): """Fixture that creates a cloned DataVolume from registry source.""" + source_dv_spec = source_dv_windows_registry_scope_function.instance.spec with create_dv( client=unprivileged_client, source="pvc", - dv_name=f"dv-target-{WIN_2K22}-vtpm", - namespace=source_dv_windows_with_vtpm_registry_scope_function.namespace, - size=source_dv_windows_with_vtpm_registry_scope_function.size, - source_pvc=source_dv_windows_with_vtpm_registry_scope_function.name, - storage_class=source_dv_windows_with_vtpm_registry_scope_function.storage_class, + dv_name=f"dv-target-{WIN_2K22}-clone", + namespace=source_dv_windows_registry_scope_function.namespace, + size=source_dv_spec.storage.resources.requests.storage, + source_pvc=source_dv_windows_registry_scope_function.name, + storage_class=source_dv_spec.storage.storageClassName, ) as cdv: cdv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) - yield cdv + cdv.to_dict() + yield cdv.res diff --git a/tests/storage/cdi_clone/test_clone.py b/tests/storage/cdi_clone/test_clone.py index b58a20d3cb..30443747cb 100644 --- a/tests/storage/cdi_clone/test_clone.py +++ b/tests/storage/cdi_clone/test_clone.py @@ -4,30 +4,20 @@ import pytest from ocp_resources.datavolume import DataVolume -from ocp_resources.virtual_machine_cluster_instancetype import ( - VirtualMachineClusterInstancetype, -) -from ocp_resources.virtual_machine_cluster_preference import ( - VirtualMachineClusterPreference, -) from tests.os_params import FEDORA_LATEST -from tests.storage.cdi_clone.constants import WINDOWS_CLONE_TIMEOUT from tests.storage.utils import ( assert_pvc_snapshot_clone_annotation, assert_use_populator, validate_os_info_vmi_vs_windows_os, - wait_for_windows_vm, ) +from tests.utils import create_windows2022_vm_with_vtpm from utilities.constants import ( OS_FLAVOR_FEDORA, - OS_FLAVOR_WIN_CONTAINER_DISK, OS_FLAVOR_WINDOWS, TIMEOUT_1MIN, TIMEOUT_40MIN, - U1_LARGE, WIN_2K22, - WINDOWS_2K22_PREFERENCE, Images, ) from utilities.storage import ( @@ -159,21 +149,16 @@ def test_successful_vm_from_cloned_dv_windows( unprivileged_client, namespace, modern_cpu_for_migration, - cloned_windows_with_vtpm_dv_from_registry_scope_function, + cloned_windows_dv_template_from_registry_scope_function, ): """Test cloning Windows 2022 DV and creating VM with vTPM using instance types.""" - with VirtualMachineForTests( - name=f"vm-{WIN_2K22}-vtpm", + with create_windows2022_vm_with_vtpm( + dv_template=cloned_windows_dv_template_from_registry_scope_function, namespace=namespace.name, client=unprivileged_client, - os_flavor=OS_FLAVOR_WIN_CONTAINER_DISK, - vm_instance_type=VirtualMachineClusterInstancetype(name=U1_LARGE, client=unprivileged_client), - vm_preference=VirtualMachineClusterPreference(name=WINDOWS_2K22_PREFERENCE, client=unprivileged_client), - data_volume=cloned_windows_with_vtpm_dv_from_registry_scope_function, + vm_name=f"vm-{WIN_2K22}", cpu_model=modern_cpu_for_migration, ) as vm: - running_vm(vm=vm) - wait_for_windows_vm(vm=vm, version="2022", timeout=WINDOWS_CLONE_TIMEOUT) validate_os_info_vmi_vs_windows_os(vm=vm) diff --git a/tests/storage/test_hotplug.py b/tests/storage/test_hotplug.py index 9a85843336..30a1b82d84 100644 --- a/tests/storage/test_hotplug.py +++ b/tests/storage/test_hotplug.py @@ -11,7 +11,7 @@ from ocp_resources.storage_profile import StorageProfile from tests.storage.utils import assert_disk_bus -from tests.utils import create_windows2022_dv_from_registry, create_windows2022_vm_with_vtpm_from_registry +from tests.utils import create_windows2022_dv_template_from_registry, create_windows2022_vm_with_vtpm from utilities.constants import HOTPLUG_DISK_SCSI_BUS, HOTPLUG_DISK_SERIAL, HOTPLUG_DISK_VIRTIO_BUS, Images from utilities.hco import ResourceEditorValidateHCOReconcile from utilities.jira import is_jira_open @@ -78,7 +78,7 @@ def windows_dv_from_registry_scope_class( storage_class_matrix__class__, ): """Creates a Windows 2022 DataVolume from registry container disk.""" - with create_windows2022_dv_from_registry( + with create_windows2022_dv_template_from_registry( dv_name="dv-windows-2022-hotplug", namespace=namespace.name, client=unprivileged_client, @@ -95,8 +95,8 @@ def vm_instance_from_template_multi_storage_scope_class( windows_dv_from_registry_scope_class, ): """Creates a Windows 2022 VM with vTPM from registry container disk.""" - with create_windows2022_vm_with_vtpm_from_registry( - dv_dict=windows_dv_from_registry_scope_class, + with create_windows2022_vm_with_vtpm( + dv_template=windows_dv_from_registry_scope_class, namespace=namespace.name, client=unprivileged_client, vm_name="vm-win-2022-hotplug", diff --git a/tests/utils.py b/tests/utils.py index 1ab4742c0e..8f8153b4a5 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -702,7 +702,7 @@ def verify_rwx_default_storage(client: DynamicClient) -> None: @contextmanager -def create_windows2022_dv_from_registry( +def create_windows2022_dv_template_from_registry( dv_name: str, namespace: str, client: DynamicClient, @@ -746,8 +746,8 @@ def create_windows2022_dv_from_registry( @contextmanager -def create_windows2022_vm_with_vtpm_from_registry( - dv_dict: dict, +def create_windows2022_vm_with_vtpm( + dv_template: dict, namespace: str, client: DynamicClient, vm_name: str, @@ -757,7 +757,7 @@ def create_windows2022_vm_with_vtpm_from_registry( Creates a Windows Server 2022 VM with vTPM from registry container disk. Args: - dv_dict: DataVolume template dictionary with metadata and spec + dv_template: DataVolume template dictionary with metadata and spec namespace: Kubernetes namespace client: Kubernetes client vm_name: Name for the VirtualMachine @@ -773,7 +773,7 @@ def create_windows2022_vm_with_vtpm_from_registry( os_flavor=OS_FLAVOR_WIN_CONTAINER_DISK, vm_instance_type=VirtualMachineClusterInstancetype(name=U1_LARGE, client=client), vm_preference=VirtualMachineClusterPreference(name=WINDOWS_2K22_PREFERENCE, client=client), - data_volume_template=dv_dict, + data_volume_template=dv_template, cpu_model=cpu_model, ) as vm: running_vm(vm=vm) From 37beb5b4afd1aa8c358de55e780e3d3302107439 Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Fri, 22 May 2026 08:16:58 +0200 Subject: [PATCH 14/21] change timeout to 40 minutes Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/constants.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/storage/cdi_clone/constants.py b/tests/storage/cdi_clone/constants.py index 18c2f698ad..adc832bde4 100644 --- a/tests/storage/cdi_clone/constants.py +++ b/tests/storage/cdi_clone/constants.py @@ -1,5 +1,5 @@ """Constants for CDI clone tests.""" -from utilities.constants import TIMEOUT_30MIN +from utilities.constants import TIMEOUT_40MIN -WINDOWS_CLONE_TIMEOUT = TIMEOUT_30MIN +WINDOWS_CLONE_TIMEOUT = TIMEOUT_40MIN From 706fd7138765c1fcf3a0c120f99528b14d95f6ff Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Fri, 22 May 2026 08:25:43 +0200 Subject: [PATCH 15/21] replace generic timeout with windows clone specific one Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/test_clone.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/storage/cdi_clone/test_clone.py b/tests/storage/cdi_clone/test_clone.py index 30443747cb..ebd28add1b 100644 --- a/tests/storage/cdi_clone/test_clone.py +++ b/tests/storage/cdi_clone/test_clone.py @@ -6,6 +6,7 @@ from ocp_resources.datavolume import DataVolume from tests.os_params import FEDORA_LATEST +from tests.storage.cdi_clone.constants import WINDOWS_CLONE_TIMEOUT from tests.storage.utils import ( assert_pvc_snapshot_clone_annotation, assert_use_populator, @@ -93,7 +94,7 @@ def test_successful_clone_of_large_image( storage_class=data_volume_multi_storage_scope_function.storage_class, client=namespace.client, ) as cdv: - cdv.wait_for_dv_success(timeout=TIMEOUT_40MIN) + cdv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) @pytest.mark.sno From c39a16faf6c8076ec8901862c63f03be2c078e84 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 22 May 2026 06:26:14 +0000 Subject: [PATCH 16/21] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/storage/cdi_clone/test_clone.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/storage/cdi_clone/test_clone.py b/tests/storage/cdi_clone/test_clone.py index ebd28add1b..e3a7c8b23c 100644 --- a/tests/storage/cdi_clone/test_clone.py +++ b/tests/storage/cdi_clone/test_clone.py @@ -17,7 +17,6 @@ OS_FLAVOR_FEDORA, OS_FLAVOR_WINDOWS, TIMEOUT_1MIN, - TIMEOUT_40MIN, WIN_2K22, Images, ) From b6e402faacaf4d970457803a4294db6075389977 Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Fri, 22 May 2026 08:41:20 +0200 Subject: [PATCH 17/21] remove duplicate constant Signed-off-by: Adam Cinko --- utilities/constants.py | 1 - 1 file changed, 1 deletion(-) diff --git a/utilities/constants.py b/utilities/constants.py index 73e11ea36f..4ba19fd9c7 100644 --- a/utilities/constants.py +++ b/utilities/constants.py @@ -819,7 +819,6 @@ class NamespacesNames: RHEL8_PREFERENCE = "rhel.8" RHEL9_PREFERENCE = "rhel.9" RHEL10_PREFERENCE = "rhel.10" -WINDOWS_2K22_PREFERENCE = "windows.2k22" U1_SMALL = "u1.small" U1_LARGE = "u1.large" PROMETHEUS_K8S = "prometheus-k8s" From 79553be392b33fcd0a745a7b7533cb2aa76bc1df Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Fri, 22 May 2026 09:36:19 +0200 Subject: [PATCH 18/21] use `create_dv` to handle WFFC better Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/conftest.py | 38 ++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/tests/storage/cdi_clone/conftest.py b/tests/storage/cdi_clone/conftest.py index 87b2956c0d..2141401c88 100644 --- a/tests/storage/cdi_clone/conftest.py +++ b/tests/storage/cdi_clone/conftest.py @@ -3,8 +3,14 @@ from tests.storage.cdi_clone.constants import WINDOWS_CLONE_TIMEOUT from tests.storage.constants import QUAY_FEDORA_CONTAINER_IMAGE -from tests.utils import create_windows2022_dv_template_from_registry +from utilities.artifactory import ( + cleanup_artifactory_secret_and_config_map, + get_artifactory_config_map, + get_artifactory_secret, + get_test_artifact_server_url, +) from utilities.constants import REGISTRY_STR, WIN_2K22, Images +from utilities.os_utils import get_windows_container_disk_path from utilities.storage import create_dv, data_volume @@ -70,20 +76,30 @@ def source_dv_windows_registry_scope_function( storage_class_name_scope_function, ): """Fixture that creates a Windows 2022 DataVolume from registry.""" - with ( - create_windows2022_dv_template_from_registry( + artifactory_secret = get_artifactory_secret(namespace=namespace.name) + artifactory_config_map = get_artifactory_config_map(namespace=namespace.name) + registry_url = ( + f"{get_test_artifact_server_url(schema='registry')}/{get_windows_container_disk_path(os_value=WIN_2K22)}" + ) + try: + with create_dv( dv_name=f"dv-source-{WIN_2K22}-registry", namespace=namespace.name, client=unprivileged_client, + source=REGISTRY_STR, + url=registry_url, + size=Images.Windows.CONTAINER_DISK_DV_SIZE, storage_class=storage_class_name_scope_function, - ) as dv_template, - DataVolume( - kind_dict={"apiVersion": f"{DataVolume.api_group}/v1beta1", "kind": "DataVolume", **dv_template}, - client=unprivileged_client, - ) as dv, - ): - dv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) - yield dv + secret=artifactory_secret, + cert_configmap=artifactory_config_map.name, + ) as dv: + dv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) + yield dv + finally: + cleanup_artifactory_secret_and_config_map( + artifactory_secret=artifactory_secret, + artifactory_config_map=artifactory_config_map, + ) @pytest.fixture() From 91156202fda881f124dc7ec4157e9624571f20d1 Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Wed, 10 Jun 2026 09:53:58 +0200 Subject: [PATCH 19/21] use CDV directly instead of a template Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/conftest.py | 3 +-- tests/storage/cdi_clone/test_clone.py | 2 +- tests/utils.py | 9 +++++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/storage/cdi_clone/conftest.py b/tests/storage/cdi_clone/conftest.py index 2141401c88..5744c98712 100644 --- a/tests/storage/cdi_clone/conftest.py +++ b/tests/storage/cdi_clone/conftest.py @@ -119,5 +119,4 @@ def cloned_windows_dv_template_from_registry_scope_function( storage_class=source_dv_spec.storage.storageClassName, ) as cdv: cdv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) - cdv.to_dict() - yield cdv.res + yield cdv diff --git a/tests/storage/cdi_clone/test_clone.py b/tests/storage/cdi_clone/test_clone.py index e3a7c8b23c..8f746baa2f 100644 --- a/tests/storage/cdi_clone/test_clone.py +++ b/tests/storage/cdi_clone/test_clone.py @@ -153,7 +153,7 @@ def test_successful_vm_from_cloned_dv_windows( ): """Test cloning Windows 2022 DV and creating VM with vTPM using instance types.""" with create_windows2022_vm_with_vtpm( - dv_template=cloned_windows_dv_template_from_registry_scope_function, + dv=cloned_windows_dv_template_from_registry_scope_function, namespace=namespace.name, client=unprivileged_client, vm_name=f"vm-{WIN_2K22}", diff --git a/tests/utils.py b/tests/utils.py index be773fb0a8..f2c516e278 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -750,11 +750,12 @@ def create_windows2022_dv_template_from_registry( @contextmanager def create_windows2022_vm_with_vtpm( - dv_template: dict, namespace: str, client: DynamicClient, vm_name: str, cpu_model: str | None, + dv_template: dict | None = None, + dv: DataVolume | None = None, ) -> Generator[VirtualMachineForTests]: """ Creates a Windows Server 2022 VM with vTPM from registry container disk. @@ -769,6 +770,9 @@ def create_windows2022_vm_with_vtpm( Yields: VirtualMachineForTests: Running Windows 2022 VM with vTPM """ + if dv_template is None and dv is None: + raise ValueError("Either dv_template or dv must be provided") + with VirtualMachineForTests( name=vm_name, namespace=namespace, @@ -776,7 +780,8 @@ def create_windows2022_vm_with_vtpm( os_flavor=OS_FLAVOR_WIN_CONTAINER_DISK, vm_instance_type=VirtualMachineClusterInstancetype(name=U1_LARGE, client=client), vm_preference=VirtualMachineClusterPreference(name=WINDOWS_2K22_PREFERENCE, client=client), - data_volume_template=dv_template, + data_volume_template=dv_template if dv is None else None, + data_volume=dv, cpu_model=cpu_model, ) as vm: running_vm(vm=vm) From a8b6a725a2a3c5ac927984ae5f754e22119408be Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Mon, 22 Jun 2026 10:45:54 +0200 Subject: [PATCH 20/21] apply reviewer's suggestions Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/conftest.py | 60 +++++--------- tests/storage/cdi_clone/constants.py | 4 +- tests/storage/cdi_clone/test_clone.py | 111 ++++++++++++++------------ tests/storage/conftest.py | 11 ++- tests/storage/test_hotplug.py | 4 +- tests/utils.py | 91 +++++++++++++++++++-- 6 files changed, 176 insertions(+), 105 deletions(-) diff --git a/tests/storage/cdi_clone/conftest.py b/tests/storage/cdi_clone/conftest.py index 5744c98712..d5d8f4adea 100644 --- a/tests/storage/cdi_clone/conftest.py +++ b/tests/storage/cdi_clone/conftest.py @@ -3,14 +3,8 @@ from tests.storage.cdi_clone.constants import WINDOWS_CLONE_TIMEOUT from tests.storage.constants import QUAY_FEDORA_CONTAINER_IMAGE -from utilities.artifactory import ( - cleanup_artifactory_secret_and_config_map, - get_artifactory_config_map, - get_artifactory_secret, - get_test_artifact_server_url, -) +from tests.utils import create_windows2022_dv_from_registry from utilities.constants import REGISTRY_STR, WIN_2K22, Images -from utilities.os_utils import get_windows_container_disk_path from utilities.storage import create_dv, data_volume @@ -69,53 +63,37 @@ def fedora_dv_with_block_volume_mode( yield dv -@pytest.fixture() -def source_dv_windows_registry_scope_function( +@pytest.fixture(scope="class") +def source_dv_windows_registry_scope_class( unprivileged_client, namespace, - storage_class_name_scope_function, + storage_class_name_scope_class, ): """Fixture that creates a Windows 2022 DataVolume from registry.""" - artifactory_secret = get_artifactory_secret(namespace=namespace.name) - artifactory_config_map = get_artifactory_config_map(namespace=namespace.name) - registry_url = ( - f"{get_test_artifact_server_url(schema='registry')}/{get_windows_container_disk_path(os_value=WIN_2K22)}" - ) - try: - with create_dv( - dv_name=f"dv-source-{WIN_2K22}-registry", - namespace=namespace.name, - client=unprivileged_client, - source=REGISTRY_STR, - url=registry_url, - size=Images.Windows.CONTAINER_DISK_DV_SIZE, - storage_class=storage_class_name_scope_function, - secret=artifactory_secret, - cert_configmap=artifactory_config_map.name, - ) as dv: - dv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) - yield dv - finally: - cleanup_artifactory_secret_and_config_map( - artifactory_secret=artifactory_secret, - artifactory_config_map=artifactory_config_map, - ) + with create_windows2022_dv_from_registry( + dv_name=f"dv-source-{WIN_2K22}-registry", + namespace=namespace.name, + client=unprivileged_client, + storage_class=storage_class_name_scope_class, + ) as dv: + dv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) + yield dv -@pytest.fixture() -def cloned_windows_dv_template_from_registry_scope_function( +@pytest.fixture(scope="class") +def cloned_windows_dv_scope_class( unprivileged_client, - source_dv_windows_registry_scope_function, + source_dv_windows_registry_scope_class, ): """Fixture that creates a cloned DataVolume from registry source.""" - source_dv_spec = source_dv_windows_registry_scope_function.instance.spec + source_dv_spec = source_dv_windows_registry_scope_class.instance.spec with create_dv( client=unprivileged_client, source="pvc", dv_name=f"dv-target-{WIN_2K22}-clone", - namespace=source_dv_windows_registry_scope_function.namespace, - size=source_dv_spec.storage.resources.requests.storage, - source_pvc=source_dv_windows_registry_scope_function.name, + namespace=source_dv_windows_registry_scope_class.namespace, + size=Images.Windows.CONTAINER_DISK_DV_SIZE, + source_pvc=source_dv_windows_registry_scope_class.name, storage_class=source_dv_spec.storage.storageClassName, ) as cdv: cdv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) diff --git a/tests/storage/cdi_clone/constants.py b/tests/storage/cdi_clone/constants.py index adc832bde4..d58196af1e 100644 --- a/tests/storage/cdi_clone/constants.py +++ b/tests/storage/cdi_clone/constants.py @@ -1,4 +1,6 @@ -"""Constants for CDI clone tests.""" +""" +Constants for CDI clone tests. +""" from utilities.constants import TIMEOUT_40MIN diff --git a/tests/storage/cdi_clone/test_clone.py b/tests/storage/cdi_clone/test_clone.py index 8f746baa2f..55b2e84a0c 100644 --- a/tests/storage/cdi_clone/test_clone.py +++ b/tests/storage/cdi_clone/test_clone.py @@ -6,13 +6,11 @@ from ocp_resources.datavolume import DataVolume from tests.os_params import FEDORA_LATEST -from tests.storage.cdi_clone.constants import WINDOWS_CLONE_TIMEOUT from tests.storage.utils import ( assert_pvc_snapshot_clone_annotation, assert_use_populator, - validate_os_info_vmi_vs_windows_os, ) -from tests.utils import create_windows2022_vm_with_vtpm +from tests.utils import create_windows2022_vm_from_dv_with_vtpm from utilities.constants import ( OS_FLAVOR_FEDORA, OS_FLAVOR_WINDOWS, @@ -20,6 +18,7 @@ WIN_2K22, Images, ) +from utilities.ssp import validate_os_info_vmi_vs_windows_os from utilities.storage import ( check_disk_count_in_vm, create_dv, @@ -64,38 +63,6 @@ def create_vm_from_clone_dv_template( running_vm(vm=vm) -@pytest.mark.tier3 -@pytest.mark.parametrize( - "data_volume_multi_storage_scope_function", - [ - pytest.param( - { - "dv_name": "dv-source", - "image": f"{Images.Windows.DIR}/{Images.Windows.WIN11_IMG}", - "dv_size": Images.Windows.DEFAULT_DV_SIZE, - }, - marks=(pytest.mark.polarion("CNV-1892")), - ), - ], - indirect=True, -) -@pytest.mark.s390x -def test_successful_clone_of_large_image( - namespace, - data_volume_multi_storage_scope_function, -): - with create_dv( - source="pvc", - dv_name="dv-target", - namespace=namespace.name, - size=data_volume_multi_storage_scope_function.size, - source_pvc=data_volume_multi_storage_scope_function.name, - storage_class=data_volume_multi_storage_scope_function.storage_class, - client=namespace.client, - ) as cdv: - cdv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) - - @pytest.mark.sno @pytest.mark.polarion("CNV-2148") @pytest.mark.gating() @@ -144,22 +111,64 @@ def test_successful_vm_restart_with_cloned_dv( @pytest.mark.tier3 -@pytest.mark.polarion("CNV-3638") -def test_successful_vm_from_cloned_dv_windows( - unprivileged_client, - namespace, - modern_cpu_for_migration, - cloned_windows_dv_template_from_registry_scope_function, -): - """Test cloning Windows 2022 DV and creating VM with vTPM using instance types.""" - with create_windows2022_vm_with_vtpm( - dv=cloned_windows_dv_template_from_registry_scope_function, - namespace=namespace.name, - client=unprivileged_client, - vm_name=f"vm-{WIN_2K22}", - cpu_model=modern_cpu_for_migration, - ) as vm: - validate_os_info_vmi_vs_windows_os(vm=vm) +@pytest.mark.incremental +class TestWindowsClonedDv: + """ + Tests for Windows 2022 DV cloning from registry and VM creation with vTPM. + + Preconditions: + - Windows Server 2022 DataVolume imported from registry + - Cloned DataVolume created from the source DataVolume (PVC clone) + """ + + @pytest.mark.polarion("CNV-1892") + def test_clone_dv_windows(self, cloned_windows_dv_scope_class): + """ + Test that a Windows 2022 DataVolume can be cloned from a registry source. + + Preconditions: + - Cloned DataVolume created from the source DataVolume (PVC clone) + + Steps: + 1. Verify the cloned DataVolume status + + Expected: + - Cloned DataVolume status is "Succeeded" + """ + assert cloned_windows_dv_scope_class.status == DataVolume.Status.SUCCEEDED, ( + f"Cloned DV status is {cloned_windows_dv_scope_class.status}, expected {DataVolume.Status.SUCCEEDED}" + ) + + @pytest.mark.polarion("CNV-3638") + def test_vm_from_cloned_dv_windows( + self, + unprivileged_client, + namespace, + modern_cpu_for_migration, + cloned_windows_dv_scope_class, + ): + """ + Test that a Windows 2022 VM with vTPM boots from a cloned DataVolume. + + Preconditions: + - Cloned DataVolume created from the source DataVolume (PVC clone) + + Steps: + 1. Create a Windows 2022 VM with vTPM from the cloned DataVolume using instance type and preference + 2. Wait for the VM to reach Running state + 3. Wait for Windows OS to be ready inside the VM + + Expected: + - VM OS info reported by VMI matches the expected Windows OS parameters + """ + with create_windows2022_vm_from_dv_with_vtpm( + dv=cloned_windows_dv_scope_class, + namespace=namespace.name, + client=unprivileged_client, + vm_name=f"vm-{WIN_2K22}", + cpu_model=modern_cpu_for_migration, + ) as vm: + validate_os_info_vmi_vs_windows_os(vm=vm) @pytest.mark.parametrize( diff --git a/tests/storage/conftest.py b/tests/storage/conftest.py index 80f0e5bcca..d8e4309460 100644 --- a/tests/storage/conftest.py +++ b/tests/storage/conftest.py @@ -43,7 +43,10 @@ is_hpp_cr_legacy, ) from tests.utils import create_cirros_vm -from utilities.artifactory import get_artifactory_config_map, get_artifactory_secret +from utilities.artifactory import ( + get_artifactory_config_map, + get_artifactory_secret, +) from utilities.constants import ( CDI_OPERATOR, CDI_UPLOADPROXY, @@ -66,7 +69,11 @@ INTERNAL_HTTP_SERVER_ADDRESS, ExecCommandOnPod, ) -from utilities.storage import data_volume_template_with_source_ref_dict, get_downloaded_artifact, write_file_via_ssh +from utilities.storage import ( + data_volume_template_with_source_ref_dict, + get_downloaded_artifact, + write_file_via_ssh, +) from utilities.virt import VirtualMachineForTests, running_vm LOGGER = logging.getLogger(__name__) diff --git a/tests/storage/test_hotplug.py b/tests/storage/test_hotplug.py index 30a1b82d84..a77f4ddf90 100644 --- a/tests/storage/test_hotplug.py +++ b/tests/storage/test_hotplug.py @@ -11,7 +11,7 @@ from ocp_resources.storage_profile import StorageProfile from tests.storage.utils import assert_disk_bus -from tests.utils import create_windows2022_dv_template_from_registry, create_windows2022_vm_with_vtpm +from tests.utils import create_windows2022_dv_template_from_registry, create_windows2022_vm_from_template_with_vtpm from utilities.constants import HOTPLUG_DISK_SCSI_BUS, HOTPLUG_DISK_SERIAL, HOTPLUG_DISK_VIRTIO_BUS, Images from utilities.hco import ResourceEditorValidateHCOReconcile from utilities.jira import is_jira_open @@ -95,7 +95,7 @@ def vm_instance_from_template_multi_storage_scope_class( windows_dv_from_registry_scope_class, ): """Creates a Windows 2022 VM with vTPM from registry container disk.""" - with create_windows2022_vm_with_vtpm( + with create_windows2022_vm_from_template_with_vtpm( dv_template=windows_dv_from_registry_scope_class, namespace=namespace.name, client=unprivileged_client, diff --git a/tests/utils.py b/tests/utils.py index f2c516e278..38492ba5ba 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -704,6 +704,48 @@ def verify_rwx_default_storage(client: DynamicClient) -> None: ) +@contextmanager +def create_windows2022_dv_from_registry( + dv_name: str, + namespace: str, + client: DynamicClient, + storage_class: str, +) -> Generator[DataVolume]: + """ + Creates a Windows Server 2022 DataVolume from registry container disk. + + Args: + dv_name: Name for the DataVolume + namespace: Kubernetes namespace + client: Kubernetes client + storage_class: Storage class name + + Yields: + dict: DataVolume template dictionary with metadata and spec + """ + artifactory_secret = get_artifactory_secret(namespace=namespace, client=client) + artifactory_config_map = get_artifactory_config_map(namespace=namespace, client=client) + + try: + with DataVolume( + name=dv_name, + namespace=namespace, + storage_class=storage_class, + source="registry", + url=f"{get_test_artifact_server_url(schema='registry')}/{get_windows_container_disk_path(os_value=WIN_2K22)}", + size=Images.Windows.CONTAINER_DISK_DV_SIZE, + client=client, + api_name="storage", + secret=artifactory_secret, + cert_configmap=artifactory_config_map.name, + ) as dv: + yield dv + finally: + cleanup_artifactory_secret_and_config_map( + artifactory_secret=artifactory_secret, artifactory_config_map=artifactory_config_map + ) + + @contextmanager def create_windows2022_dv_template_from_registry( dv_name: str, @@ -723,8 +765,8 @@ def create_windows2022_dv_template_from_registry( Yields: dict: DataVolume template dictionary with metadata and spec """ - artifactory_secret = get_artifactory_secret(namespace=namespace) - artifactory_config_map = get_artifactory_config_map(namespace=namespace) + artifactory_secret = get_artifactory_secret(namespace=namespace, client=client) + artifactory_config_map = get_artifactory_config_map(namespace=namespace, client=client) dv = DataVolume( name=dv_name, @@ -749,16 +791,15 @@ def create_windows2022_dv_template_from_registry( @contextmanager -def create_windows2022_vm_with_vtpm( +def create_windows2022_vm_from_dv_with_vtpm( namespace: str, client: DynamicClient, vm_name: str, cpu_model: str | None, - dv_template: dict | None = None, dv: DataVolume | None = None, ) -> Generator[VirtualMachineForTests]: """ - Creates a Windows Server 2022 VM with vTPM from registry container disk. + Creates a Windows Server 2022 VM with vTPM. Args: dv_template: DataVolume template dictionary with metadata and spec @@ -770,8 +811,6 @@ def create_windows2022_vm_with_vtpm( Yields: VirtualMachineForTests: Running Windows 2022 VM with vTPM """ - if dv_template is None and dv is None: - raise ValueError("Either dv_template or dv must be provided") with VirtualMachineForTests( name=vm_name, @@ -780,10 +819,46 @@ def create_windows2022_vm_with_vtpm( os_flavor=OS_FLAVOR_WIN_CONTAINER_DISK, vm_instance_type=VirtualMachineClusterInstancetype(name=U1_LARGE, client=client), vm_preference=VirtualMachineClusterPreference(name=WINDOWS_2K22_PREFERENCE, client=client), - data_volume_template=dv_template if dv is None else None, data_volume=dv, cpu_model=cpu_model, ) as vm: running_vm(vm=vm) wait_for_windows_vm(vm=vm, version="2022") yield vm + + +@contextmanager +def create_windows2022_vm_from_template_with_vtpm( + namespace: str, + client: DynamicClient, + vm_name: str, + cpu_model: str | None, + dv_template: dict | None = None, +) -> Generator[VirtualMachineForTests]: + """ + Creates a Windows Server 2022 VM with vTPM from dv template. + + Args: + dv_template: DataVolume template dictionary with metadata and spec + namespace: Kubernetes namespace + client: Kubernetes client + vm_name: Name for the VirtualMachine + cpu_model: CPU model specification (can be None) + + Yields: + VirtualMachineForTests: Running Windows 2022 VM with vTPM + """ + + with VirtualMachineForTests( + name=vm_name, + namespace=namespace, + client=client, + os_flavor=OS_FLAVOR_WIN_CONTAINER_DISK, + vm_instance_type=VirtualMachineClusterInstancetype(name=U1_LARGE, client=client), + vm_preference=VirtualMachineClusterPreference(name=WINDOWS_2K22_PREFERENCE, client=client), + data_volume_template=dv_template, + cpu_model=cpu_model, + ) as vm: + running_vm(vm=vm) + wait_for_windows_vm(vm=vm, version="2022") + yield vm From faab71ecda6a0d2c08287a530ff121fed685f19c Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Mon, 22 Jun 2026 14:37:40 +0200 Subject: [PATCH 21/21] consume when wffc is present Signed-off-by: Adam Cinko --- tests/storage/cdi_clone/conftest.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/storage/cdi_clone/conftest.py b/tests/storage/cdi_clone/conftest.py index d5d8f4adea..972040eef2 100644 --- a/tests/storage/cdi_clone/conftest.py +++ b/tests/storage/cdi_clone/conftest.py @@ -5,7 +5,7 @@ from tests.storage.constants import QUAY_FEDORA_CONTAINER_IMAGE from tests.utils import create_windows2022_dv_from_registry from utilities.constants import REGISTRY_STR, WIN_2K22, Images -from utilities.storage import create_dv, data_volume +from utilities.storage import create_dummy_first_consumer_pod, create_dv, data_volume, sc_volume_binding_mode_is_wffc @pytest.fixture() @@ -76,6 +76,8 @@ def source_dv_windows_registry_scope_class( client=unprivileged_client, storage_class=storage_class_name_scope_class, ) as dv: + if sc_volume_binding_mode_is_wffc(sc=storage_class_name_scope_class, client=unprivileged_client): + create_dummy_first_consumer_pod(dv=dv) dv.wait_for_dv_success(timeout=WINDOWS_CLONE_TIMEOUT) yield dv