From 453d9677a20bc9c4bb9151fa32bdc3521fe60375 Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Thu, 30 Apr 2026 15:27:14 +0200 Subject: [PATCH 1/8] refactor snapshots to use win 2k22 and vtpm Signed-off-by: Adam Cinko --- tests/storage/snapshots/conftest.py | 81 +++++++++++++++++------ tests/storage/snapshots/test_snapshots.py | 24 ++++--- tests/storage/utils.py | 38 ----------- utilities/constants.py | 1 + 4 files changed, 76 insertions(+), 68 deletions(-) diff --git a/tests/storage/snapshots/conftest.py b/tests/storage/snapshots/conftest.py index 25039dbf12..9adefbb243 100644 --- a/tests/storage/snapshots/conftest.py +++ b/tests/storage/snapshots/conftest.py @@ -8,17 +8,34 @@ import pytest from ocp_resources.datavolume import DataVolume from ocp_resources.role_binding import RoleBinding +from ocp_resources.virtual_machine_cluster_instancetype import VirtualMachineClusterInstancetype +from ocp_resources.virtual_machine_cluster_preference import VirtualMachineClusterPreference from ocp_resources.virtual_machine_snapshot import VirtualMachineSnapshot from pyhelper_utils.shell import run_ssh_commands from tests.storage.snapshots.constants import WINDOWS_DIRECTORY_PATH from tests.storage.utils import ( assert_windows_directory_existence, - create_windows19_vm, create_windows_directory, set_permissions, ) -from utilities.constants import TIMEOUT_2MIN, TIMEOUT_5SEC, TIMEOUT_10MIN, UNPRIVILEGED_USER +from utilities.artifactory import ( + cleanup_artifactory_secret_and_config_map, + get_artifactory_config_map, + get_artifactory_secret, + get_http_image_url, +) +from utilities.constants import ( + OS_FLAVOR_WINDOWS, + TIMEOUT_2MIN, + TIMEOUT_5SEC, + TIMEOUT_10MIN, + U1_LARGE, + UNPRIVILEGED_USER, + WINDOWS_2K22_PREFERENCE, + Images, +) +from utilities.virt import VirtualMachineForTests, running_vm, wait_for_windows_vm LOGGER = logging.getLogger(__name__) @@ -44,63 +61,89 @@ def permissions_for_dv(namespace, admin_client): @pytest.fixture() -def windows_vm_for_snapshot( +def windows_vm_with_vtpm_for_snapshot( request, namespace, unprivileged_client, modern_cpu_for_migration, storage_class_matrix_snapshot_matrix__module__, ): - with create_windows19_vm( - dv_name=request.param["dv_name"], + artifactory_secret = get_artifactory_secret(namespace=namespace.name) + artifactory_config_map = get_artifactory_config_map(namespace=namespace.name) + dv = DataVolume( + name=request.param["dv_name"], + namespace=namespace.name, + storage_class=[*storage_class_matrix_snapshot_matrix__module__][0], + source="http", + url=get_http_image_url(image_directory=Images.Windows.DIR, image_name=Images.Windows.WIN2022_IMG), + size=Images.Windows.DEFAULT_DV_SIZE, + client=unprivileged_client, + api_name="storage", + secret=artifactory_secret, + cert_configmap=artifactory_config_map.name, + ) + dv.to_dict() + with VirtualMachineForTests( + name=request.param["vm_name"], namespace=namespace.name, client=unprivileged_client, - vm_name=request.param["vm_name"], + os_flavor=OS_FLAVOR_WINDOWS, + vm_instance_type=VirtualMachineClusterInstancetype(name=U1_LARGE, client=unprivileged_client), + vm_preference=VirtualMachineClusterPreference(name=WINDOWS_2K22_PREFERENCE, client=unprivileged_client), + data_volume_template={"metadata": dv.res["metadata"], "spec": dv.res["spec"]}, cpu_model=modern_cpu_for_migration, - storage_class=[*storage_class_matrix_snapshot_matrix__module__][0], ) as vm: + running_vm(vm=vm, wait_for_interfaces=False, check_ssh_connectivity=False) + wait_for_windows_vm(vm=vm, version="2022") yield vm + cleanup_artifactory_secret_and_config_map( + artifactory_secret=artifactory_secret, artifactory_config_map=artifactory_config_map + ) @pytest.fixture() -def snapshot_windows_directory(windows_vm_for_snapshot): - create_windows_directory(windows_vm=windows_vm_for_snapshot, directory_path=WINDOWS_DIRECTORY_PATH) +def snapshot_windows_directory(windows_vm_with_vtpm_for_snapshot): + create_windows_directory(windows_vm=windows_vm_with_vtpm_for_snapshot, directory_path=WINDOWS_DIRECTORY_PATH) @pytest.fixture() def windows_snapshot( snapshot_windows_directory, - windows_vm_for_snapshot, + windows_vm_with_vtpm_for_snapshot, ): with VirtualMachineSnapshot( name="windows-snapshot", - namespace=windows_vm_for_snapshot.namespace, - vm_name=windows_vm_for_snapshot.name, + namespace=windows_vm_with_vtpm_for_snapshot.namespace, + vm_name=windows_vm_with_vtpm_for_snapshot.name, ) as snapshot: yield snapshot @pytest.fixture() -def snapshot_dirctory_removed(windows_vm_for_snapshot, windows_snapshot): +def snapshot_dirctory_removed(windows_vm_with_vtpm_for_snapshot, windows_snapshot): windows_snapshot.wait_ready_to_use(timeout=TIMEOUT_10MIN) cmd = shlex.split( f'powershell -command "Remove-Item -Path {WINDOWS_DIRECTORY_PATH} -Recurse"', ) - run_ssh_commands(host=windows_vm_for_snapshot.ssh_exec, commands=cmd, wait_timeout=TIMEOUT_2MIN, sleep=TIMEOUT_5SEC) + run_ssh_commands( + host=windows_vm_with_vtpm_for_snapshot.ssh_exec, commands=cmd, wait_timeout=TIMEOUT_2MIN, sleep=TIMEOUT_5SEC + ) assert_windows_directory_existence( expected_result=False, - windows_vm=windows_vm_for_snapshot, + windows_vm=windows_vm_with_vtpm_for_snapshot, directory_path=WINDOWS_DIRECTORY_PATH, ) - windows_vm_for_snapshot.stop(wait=True) + windows_vm_with_vtpm_for_snapshot.stop(wait=True) @pytest.fixture() -def file_created_during_snapshot(windows_vm_for_snapshot, windows_snapshot): +def file_created_during_snapshot(windows_vm_with_vtpm_for_snapshot, windows_snapshot): file = f"{WINDOWS_DIRECTORY_PATH}\\file.txt" cmd = shlex.split( f'powershell -command "for($i=1; $i -le 100; $i++){{$i| Out-File -FilePath {file} -Append}}"', ) - run_ssh_commands(host=windows_vm_for_snapshot.ssh_exec, commands=cmd, wait_timeout=TIMEOUT_2MIN, sleep=TIMEOUT_5SEC) + run_ssh_commands( + host=windows_vm_with_vtpm_for_snapshot.ssh_exec, commands=cmd, wait_timeout=TIMEOUT_2MIN, sleep=TIMEOUT_5SEC + ) windows_snapshot.wait_snapshot_done(timeout=TIMEOUT_10MIN) - windows_vm_for_snapshot.stop(wait=True) + windows_vm_with_vtpm_for_snapshot.stop(wait=True) diff --git a/tests/storage/snapshots/test_snapshots.py b/tests/storage/snapshots/test_snapshots.py index b7e0a999e5..ce710df282 100644 --- a/tests/storage/snapshots/test_snapshots.py +++ b/tests/storage/snapshots/test_snapshots.py @@ -397,8 +397,9 @@ def test_fail_to_snapshot_with_unprivileged_client_dv_permissions( ) +@pytest.mark.tier3 @pytest.mark.parametrize( - "windows_vm_for_snapshot", + "windows_vm_with_vtpm_for_snapshot", [ pytest.param( {"dv_name": "dv-8307", "vm_name": "vm-8307"}, @@ -408,26 +409,27 @@ def test_fail_to_snapshot_with_unprivileged_client_dv_permissions( indirect=True, ) def test_online_windows_vm_successful_restore( - windows_vm_for_snapshot, + windows_vm_with_vtpm_for_snapshot, windows_snapshot, snapshot_dirctory_removed, ): with VirtualMachineRestore( name="restore-vm", - namespace=windows_vm_for_snapshot.namespace, - vm_name=windows_vm_for_snapshot.name, + namespace=windows_vm_with_vtpm_for_snapshot.namespace, + vm_name=windows_vm_with_vtpm_for_snapshot.name, snapshot_name=windows_snapshot.name, ) as restore: - start_windows_vm_after_restore(vm_restore=restore, windows_vm=windows_vm_for_snapshot) + start_windows_vm_after_restore(vm_restore=restore, windows_vm=windows_vm_with_vtpm_for_snapshot) assert_windows_directory_existence( expected_result=True, - windows_vm=windows_vm_for_snapshot, + windows_vm=windows_vm_with_vtpm_for_snapshot, directory_path=WINDOWS_DIRECTORY_PATH, ) +@pytest.mark.tier3 @pytest.mark.parametrize( - "windows_vm_for_snapshot", + "windows_vm_with_vtpm_for_snapshot", [ pytest.param( {"dv_name": "dv-8536", "vm_name": "vm-8536"}, @@ -437,14 +439,14 @@ def test_online_windows_vm_successful_restore( indirect=True, ) def test_write_to_file_while_snapshot( - windows_vm_for_snapshot, + windows_vm_with_vtpm_for_snapshot, windows_snapshot, file_created_during_snapshot, ): with VirtualMachineRestore( name="restore-vm", - namespace=windows_vm_for_snapshot.namespace, - vm_name=windows_vm_for_snapshot.name, + namespace=windows_vm_with_vtpm_for_snapshot.namespace, + vm_name=windows_vm_with_vtpm_for_snapshot.name, snapshot_name=windows_snapshot.name, ) as restore: - start_windows_vm_after_restore(vm_restore=restore, windows_vm=windows_vm_for_snapshot) + start_windows_vm_after_restore(vm_restore=restore, windows_vm=windows_vm_with_vtpm_for_snapshot) diff --git a/tests/storage/utils.py b/tests/storage/utils.py index a05ecfcb29..9628cb2fea 100644 --- a/tests/storage/utils.py +++ b/tests/storage/utils.py @@ -19,7 +19,6 @@ from ocp_resources.service import Service from ocp_resources.storage_class import StorageClass from ocp_resources.storage_profile import StorageProfile -from ocp_resources.template import Template from ocp_resources.upload_token_request import UploadTokenRequest from pyhelper_utils.shell import run_ssh_commands from pytest_testconfig import config as py_config @@ -27,9 +26,6 @@ from utilities import console from utilities.artifactory import ( - cleanup_artifactory_secret_and_config_map, - get_artifactory_config_map, - get_artifactory_secret, get_http_image_url, ) from utilities.constants import ( @@ -53,8 +49,6 @@ ) from utilities.virt import ( VirtualMachineForTests, - VirtualMachineForTestsFromTemplate, - running_vm, vm_instance_from_template, wait_for_windows_vm, ) @@ -347,38 +341,6 @@ def get_hpp_daemonset(hco_namespace, hpp_cr_suffix, admin_client): return daemonset -@contextmanager -def create_windows19_vm(dv_name, namespace, client, vm_name, cpu_model, storage_class): - artifactory_secret = get_artifactory_secret(namespace=namespace) - artifactory_config_map = get_artifactory_config_map(namespace=namespace) - dv = DataVolume( - name=dv_name, - namespace=namespace, - storage_class=storage_class, - source="http", - url=get_http_image_url(image_directory=Images.Windows.UEFI_WIN_DIR, image_name=Images.Windows.WIN2k19_IMG), - size=Images.Windows.DEFAULT_DV_SIZE, - client=client, - api_name="storage", - secret=artifactory_secret, - cert_configmap=artifactory_config_map.name, - ) - dv.to_dict() - with VirtualMachineForTestsFromTemplate( - name=vm_name, - namespace=namespace, - client=client, - labels=Template.generate_template_labels(**py_config["latest_windows_os_dict"]["template_labels"]), - cpu_model=cpu_model, - data_volume_template={"metadata": dv.res["metadata"], "spec": dv.res["spec"]}, - ) as vm: - running_vm(vm=vm) - yield vm - cleanup_artifactory_secret_and_config_map( - artifactory_secret=artifactory_secret, artifactory_config_map=artifactory_config_map - ) - - @contextmanager def update_scratch_space_sc(cdi_config, new_sc, hco): def _wait_for_sc_update(): diff --git a/utilities/constants.py b/utilities/constants.py index 1daa476981..50dcc0e151 100644 --- a/utilities/constants.py +++ b/utilities/constants.py @@ -812,6 +812,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 c190196a539ac5572edbd12afc3fa1bf0d3262dd Mon Sep 17 00:00:00 2001 From: Ruth Netser Date: Mon, 4 May 2026 14:38:11 +0300 Subject: [PATCH 2/8] chore: ignore flake8 rules now handled by ruff (#4703) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ruff v0.15.x handles several rules with better context awareness than flake8 (dataclass fields, method overrides, formatter-managed line length). When ruff removes inline `# noqa` comments it considers unnecessary, flake8 still enforces those rules, causing CI conflicts. This PR ignores those rules in `.flake8` to prevent conflicts between the two linters: - **N815**: camelCase in class scope — ruff understands dataclass fields matching API schemas - **N802**: function name should be lowercase — ruff understands method overrides (e.g. `formatTime`) - **E501**: line too long — ruff formatter manages line length - **F821**: undefined name — used in global_config files with dynamic `exec()` loading - **E201**: whitespace after `(` — ruff formatter manages whitespace - **W503**: line break before binary operator — PEP 8 reversed this; ruff uses W504 (after) - **N818**: exception name should end with Error — ruff allows existing names like `MissingTemplateVariables` Also adds `with_suffix` and `writelines` to `fcn_exclude_functions` to prevent FCN001 false positives on standard library calls. Part 1 of a 6-PR series to clean up lint configuration and apply safe fixes: 1. **This PR** — `.flake8` ignore rules 2. `pyproject.toml` ruff ignore rules for preview rules 3. Remove stale `# noqa` comments (depends on PRs 1+2) 4. Remove obsolete utf-8 coding headers 5. Apply safe ruff fixes repo-wide (SIM118, SIM201, PLC0206, etc.) 6. Bump pre-commit hooks (ruff v0.15.12, mypy v1.20.2) Assisted-by: Claude Replaces #4701 with a smaller, incremental approach. No code changes — config only. All pre-commit hooks pass on all files. * **Chores** * Updated linting configuration: removed hard line-length enforcement in favor of centralized formatting, suppressed a targeted set of stylistic and specific error checks, and added inline notes clarifying that certain rules (including line-length and whitespace checks) are managed by the code formatter. Signed-off-by: rnetser Signed-off-by: Adam Cinko --- .flake8 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.flake8 b/.flake8 index 0771a566b1..82379cc899 100644 --- a/.flake8 +++ b/.flake8 @@ -11,9 +11,10 @@ jobs = 0 # F821 — undefined name; used in global_config files with dynamic exec() loading # # Intentionally suppressed (not enforced by either linter): +# N815 — mixedCaseVariable in class scope; dataclass fields match Kubernetes API schemas # N802 — function name should be lowercase; method overrides like formatTime from logging.Formatter # N818 — exception name should end with Error; existing names like MissingTemplateVariables -ignore = N802, E501, F821, E201, W503, N818 +ignore = N815, N802, E501, F821, E201, W503, N818 exclude = doc, .tox, From 3f16233f8c2a38f0bcd6e0291fc4c6515eac7af4 Mon Sep 17 00:00:00 2001 From: Ruth Netser Date: Mon, 4 May 2026 16:55:58 +0300 Subject: [PATCH 3/8] style: remove stale noqa comments and obsolete utf-8 headers (#4725) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ##### What this PR does / why we need it: Two cleanups in one PR: **1. Remove stale `# noqa` comments** that no linter enforces after .flake8 (#4703) and pyproject.toml (#4720) configuration changes: | Rule | Reason noqa is stale | |------|---------------------| | F821 | Scoped to `tests/global_config*.py` via ruff `per-file-ignores` (#4720) | | N802 | Flake8 no longer checks this (#4703) | | E501 | Ruff formatter manages line length | | E201 | Ruff formatter manages whitespace | **N815 (`camelCase` in class scope) noqa comments are intentionally kept** — flake8 still enforces N815. The existing `# noqa: N815` comments on dataclass fields matching Kubernetes API schemas remain in place. N815 was also **removed from the flake8 ignore list** to restore enforcement. `utilities/unittests/` E402 noqa comments are also kept — E402 is not globally ignored and these files use `sys.path` manipulation before imports. **2. Remove obsolete `# -*- coding: utf-8 -*-` headers** — Python 3 uses UTF-8 by default (PEP 3120), making these headers unnecessary (ruff UP009). Part 3 of a 5-PR lint cleanup series: 1. `.flake8` ignore rules (#4703) ✅ merged 2. `pyproject.toml` ruff ignore rules (#4720) ✅ merged 3. **This PR** — remove stale noqa + utf-8 headers 4. Apply safe ruff fixes repo-wide (SIM118, SIM201, PLC0206, etc.) 5. Bump pre-commit hooks (ruff v0.15.12, mypy v1.20.2) Assisted-by: Claude ##### Which issue(s) this PR fixes: ##### Special notes for reviewer: All changes are comment/header removals — zero behavioral changes. N815 enforcement is restored (removed from flake8 ignore list). ##### jira-ticket: ## Summary by CodeRabbit * **Chores** * Removed legacy UTF-8 encoding declarations from test files. * Removed redundant linter-suppression comments across codebase. * Updated linting configuration to improve code quality standards. * **Style** * Reformatted test assertions for improved readability. Signed-off-by: rnetser Signed-off-by: Adam Cinko --- .flake8 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.flake8 b/.flake8 index 82379cc899..0771a566b1 100644 --- a/.flake8 +++ b/.flake8 @@ -11,10 +11,9 @@ jobs = 0 # F821 — undefined name; used in global_config files with dynamic exec() loading # # Intentionally suppressed (not enforced by either linter): -# N815 — mixedCaseVariable in class scope; dataclass fields match Kubernetes API schemas # N802 — function name should be lowercase; method overrides like formatTime from logging.Formatter # N818 — exception name should end with Error; existing names like MissingTemplateVariables -ignore = N815, N802, E501, F821, E201, W503, N818 +ignore = N802, E501, F821, E201, W503, N818 exclude = doc, .tox, From 3f86e4839774ba0c9b86a216d4eda1979b69a3db Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Tue, 5 May 2026 15:42:58 +0200 Subject: [PATCH 4/8] use image from registry verified manually Signed-off-by: Adam Cinko --- tests/storage/snapshots/conftest.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/storage/snapshots/conftest.py b/tests/storage/snapshots/conftest.py index 9adefbb243..d5b33ca7f2 100644 --- a/tests/storage/snapshots/conftest.py +++ b/tests/storage/snapshots/conftest.py @@ -23,18 +23,20 @@ cleanup_artifactory_secret_and_config_map, get_artifactory_config_map, get_artifactory_secret, - get_http_image_url, + get_test_artifact_server_url, ) from utilities.constants import ( - OS_FLAVOR_WINDOWS, + OS_FLAVOR_WIN_CONTAINER_DISK, TIMEOUT_2MIN, TIMEOUT_5SEC, TIMEOUT_10MIN, U1_LARGE, UNPRIVILEGED_USER, + WIN_2K22, WINDOWS_2K22_PREFERENCE, Images, ) +from utilities.os_utils import get_windows_container_disk_path from utilities.virt import VirtualMachineForTests, running_vm, wait_for_windows_vm LOGGER = logging.getLogger(__name__) @@ -73,10 +75,10 @@ def windows_vm_with_vtpm_for_snapshot( dv = DataVolume( name=request.param["dv_name"], namespace=namespace.name, - storage_class=[*storage_class_matrix_snapshot_matrix__module__][0], - source="http", - url=get_http_image_url(image_directory=Images.Windows.DIR, image_name=Images.Windows.WIN2022_IMG), - size=Images.Windows.DEFAULT_DV_SIZE, + storage_class=next(iter(storage_class_matrix_snapshot_matrix__module__)), + 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=unprivileged_client, api_name="storage", secret=artifactory_secret, @@ -87,7 +89,7 @@ def windows_vm_with_vtpm_for_snapshot( name=request.param["vm_name"], namespace=namespace.name, client=unprivileged_client, - os_flavor=OS_FLAVOR_WINDOWS, + 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": dv.res["metadata"], "spec": dv.res["spec"]}, From 88386700f319154db2eed20a745d03293385a2e7 Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Thu, 21 May 2026 08:50:01 +0200 Subject: [PATCH 5/8] mild name refactor and change the workflow for the helper functions Signed-off-by: Adam Cinko --- tests/storage/snapshots/conftest.py | 56 +++++++++-------------------- tests/storage/test_hotplug.py | 8 ++--- tests/utils.py | 11 +++--- 3 files changed, 27 insertions(+), 48 deletions(-) diff --git a/tests/storage/snapshots/conftest.py b/tests/storage/snapshots/conftest.py index d5b33ca7f2..3bac6f087b 100644 --- a/tests/storage/snapshots/conftest.py +++ b/tests/storage/snapshots/conftest.py @@ -8,8 +8,6 @@ import pytest from ocp_resources.datavolume import DataVolume from ocp_resources.role_binding import RoleBinding -from ocp_resources.virtual_machine_cluster_instancetype import VirtualMachineClusterInstancetype -from ocp_resources.virtual_machine_cluster_preference import VirtualMachineClusterPreference from ocp_resources.virtual_machine_snapshot import VirtualMachineSnapshot from pyhelper_utils.shell import run_ssh_commands @@ -19,25 +17,14 @@ create_windows_directory, set_permissions, ) -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, create_windows2022_vm_with_vtpm from utilities.constants import ( - OS_FLAVOR_WIN_CONTAINER_DISK, TIMEOUT_2MIN, TIMEOUT_5SEC, TIMEOUT_10MIN, - U1_LARGE, UNPRIVILEGED_USER, - WIN_2K22, - WINDOWS_2K22_PREFERENCE, - Images, ) -from utilities.os_utils import get_windows_container_disk_path -from utilities.virt import VirtualMachineForTests, running_vm, wait_for_windows_vm +from utilities.virt import running_vm, wait_for_windows_vm LOGGER = logging.getLogger(__name__) @@ -63,44 +50,35 @@ def permissions_for_dv(namespace, admin_client): @pytest.fixture() -def windows_vm_with_vtpm_for_snapshot( +def windows_dv_template_from_registry( request, namespace, unprivileged_client, - modern_cpu_for_migration, storage_class_matrix_snapshot_matrix__module__, ): - artifactory_secret = get_artifactory_secret(namespace=namespace.name) - artifactory_config_map = get_artifactory_config_map(namespace=namespace.name) - dv = DataVolume( - name=request.param["dv_name"], + with create_windows2022_dv_template_from_registry( + dv_name=request.param["dv_name"], namespace=namespace.name, - storage_class=next(iter(storage_class_matrix_snapshot_matrix__module__)), - 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=unprivileged_client, - api_name="storage", - secret=artifactory_secret, - cert_configmap=artifactory_config_map.name, - ) - dv.to_dict() - with VirtualMachineForTests( - name=request.param["vm_name"], + storage_class=next(iter(storage_class_matrix_snapshot_matrix__module__)), + ) as dv_template: + yield dv_template + + +@pytest.fixture() +def windows_vm_with_vtpm_for_snapshot( + request, namespace, unprivileged_client, modern_cpu_for_migration, windows_dv_template_from_registry +): + with create_windows2022_vm_with_vtpm( + dv_template=windows_dv_template_from_registry, 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_template={"metadata": dv.res["metadata"], "spec": dv.res["spec"]}, + vm_name=request.param["vm_name"], cpu_model=modern_cpu_for_migration, ) as vm: running_vm(vm=vm, wait_for_interfaces=False, check_ssh_connectivity=False) wait_for_windows_vm(vm=vm, version="2022") yield vm - cleanup_artifactory_secret_and_config_map( - artifactory_secret=artifactory_secret, artifactory_config_map=artifactory_config_map - ) @pytest.fixture() 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..5ed73761bc 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -4,9 +4,10 @@ import re import shlex import tarfile +from collections.abc import Generator from contextlib import contextmanager from io import BytesIO -from typing import Generator, Optional +from typing import Any, Optional import bitmath import requests @@ -702,7 +703,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 +747,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, @@ -773,7 +774,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 aa7e977128261f9c239a1fcec17f7fdd8ac00937 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 21 May 2026 06:50:32 +0000 Subject: [PATCH 6/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/utils.py b/tests/utils.py index 5ed73761bc..b56b1ea482 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -7,7 +7,7 @@ from collections.abc import Generator from contextlib import contextmanager from io import BytesIO -from typing import Any, Optional +from typing import Optional import bitmath import requests From 7a477cf2d899ebfca265dd5ddd5d62b4bba0300c Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Thu, 21 May 2026 08:54:45 +0200 Subject: [PATCH 7/8] remove tox unused code Signed-off-by: Adam Cinko --- tests/storage/utils.py | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/tests/storage/utils.py b/tests/storage/utils.py index cda76e30ac..c4f0c2a2a3 100644 --- a/tests/storage/utils.py +++ b/tests/storage/utils.py @@ -339,38 +339,6 @@ def get_hpp_daemonset(hco_namespace, hpp_cr_suffix, admin_client): return daemonset -@contextmanager -def create_windows19_vm(dv_name, namespace, client, vm_name, cpu_model, storage_class): - artifactory_secret = get_artifactory_secret(namespace=namespace) - artifactory_config_map = get_artifactory_config_map(namespace=namespace) - dv = DataVolume( - name=dv_name, - namespace=namespace, - storage_class=storage_class, - source="http", - url=get_http_image_url(image_directory=Images.Windows.UEFI_WIN_DIR, image_name=Images.Windows.WIN2k19_IMG), - size=Images.Windows.DEFAULT_DV_SIZE, - client=client, - api_name="storage", - secret=artifactory_secret, - cert_configmap=artifactory_config_map.name, - ) - dv.to_dict() - with VirtualMachineForTestsFromTemplate( - name=vm_name, - namespace=namespace, - client=client, - labels=Template.generate_template_labels(**py_config["latest_windows_os_dict"]["template_labels"]), - cpu_model=cpu_model, - data_volume_template={"metadata": dv.res["metadata"], "spec": dv.res["spec"]}, - ) as vm: - running_vm(vm=vm) - yield vm - cleanup_artifactory_secret_and_config_map( - artifactory_secret=artifactory_secret, artifactory_config_map=artifactory_config_map - ) - - def create_cirros_dv( namespace, name, From cc132ab32aeda7f2cc2fb27fe55e3f6791d760b6 Mon Sep 17 00:00:00 2001 From: Adam Cinko Date: Thu, 21 May 2026 09:30:43 +0200 Subject: [PATCH 8/8] fix the test parameters Signed-off-by: Adam Cinko --- tests/storage/snapshots/test_snapshots.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/storage/snapshots/test_snapshots.py b/tests/storage/snapshots/test_snapshots.py index ce710df282..5a49df3047 100644 --- a/tests/storage/snapshots/test_snapshots.py +++ b/tests/storage/snapshots/test_snapshots.py @@ -399,10 +399,11 @@ def test_fail_to_snapshot_with_unprivileged_client_dv_permissions( @pytest.mark.tier3 @pytest.mark.parametrize( - "windows_vm_with_vtpm_for_snapshot", + "windows_dv_template_from_registry, windows_vm_with_vtpm_for_snapshot", [ pytest.param( - {"dv_name": "dv-8307", "vm_name": "vm-8307"}, + {"dv_name": "dv-8307"}, + {"vm_name": "vm-8307"}, marks=pytest.mark.polarion("CNV-8307"), ), ],