From ecd5342c1d41be1cadca1cbf1661835f4c2d58f7 Mon Sep 17 00:00:00 2001 From: Yossi Segev Date: Sun, 28 Jun 2026 18:16:55 +0300 Subject: [PATCH 1/2] [net] Multi-arch tests with VMs with primary UDN interfaces Test that a VM with ARM64 archirecture can successfuly connect with an AMD64 VM over primary UDN interface. Signed-off-by: Yossi Segev Assisted-by: Claude Code --- tests/network/libs/vm_factory.py | 4 ++ .../network/user_defined_network/conftest.py | 58 +++++++++++++++++++ .../test_user_defined_network_multiarch.py | 24 ++++++-- 3 files changed, 81 insertions(+), 5 deletions(-) diff --git a/tests/network/libs/vm_factory.py b/tests/network/libs/vm_factory.py index 532088e105..8e2e3f16ea 100644 --- a/tests/network/libs/vm_factory.py +++ b/tests/network/libs/vm_factory.py @@ -17,6 +17,7 @@ def udn_vm( template_labels: dict | None = None, anti_affinity_namespaces: list[str] | None = None, affinity: Affinity | None = None, + architecture: str | None = None, ) -> BaseVirtualMachine: """Create a Fedora VM connected to a primary UDN using the specified binding. @@ -28,11 +29,14 @@ def udn_vm( template_labels: Optional labels to add to the VM pod template, also used as anti-affinity key. anti_affinity_namespaces: Optional namespaces to scope the pod anti-affinity rule. affinity: Optional explicit affinity rules. When set, takes precedence over auto-generated anti-affinity from template_labels. + architecture: Optional specific desired architecture of the target VM image. Returns: Configured BaseVirtualMachine object (not yet started). """ spec = base_vmspec() + if architecture is not None: + spec.template.spec.architecture = architecture iface, network = udn_primary_network(name="udn-primary", binding=binding) spec.template.spec.domain.devices.interfaces = [iface] # type: ignore spec.template.spec.networks = [network] diff --git a/tests/network/user_defined_network/conftest.py b/tests/network/user_defined_network/conftest.py index aad1b12192..1fa6829835 100644 --- a/tests/network/user_defined_network/conftest.py +++ b/tests/network/user_defined_network/conftest.py @@ -1,9 +1,17 @@ +from collections.abc import Generator + import pytest +from kubernetes.dynamic import DynamicClient from ocp_resources.user_defined_network import Layer2UserDefinedNetwork from libs.net.ip import random_ipv4_address +from libs.net.udn import UDN_BINDING_DEFAULT_PLUGIN_NAME from libs.vm import affinity +from libs.vm.oper import run_vms +from libs.vm.vm import BaseVirtualMachine +from tests.network.libs.vm_factory import udn_vm from utilities.infra import create_ns +from utilities.constants.architecture import AMD_64, ARM_64 @pytest.fixture(scope="module") @@ -35,3 +43,53 @@ def namespaced_layer2_user_defined_network(admin_client, udn_namespace): @pytest.fixture(scope="module") def udn_affinity_label(): return affinity.new_label(key_prefix="udn") + + +@pytest.fixture(scope="class") +def arm64_udn_vm( + admin_client: DynamicClient, + namespaced_layer2_user_defined_network: Layer2UserDefinedNetwork, +) -> Generator[BaseVirtualMachine]: + """ + ARM64 VM with UDN as primary interface. + """ + with udn_vm( + namespace_name=namespaced_layer2_user_defined_network.namespace, + name="arm64-udn-vm", + client=admin_client, + binding=UDN_BINDING_DEFAULT_PLUGIN_NAME, + architecture=ARM_64, + ) as vm: + yield vm + + +@pytest.fixture(scope="class") +def amd64_udn_vm( + admin_client: DynamicClient, + namespaced_layer2_user_defined_network: Layer2UserDefinedNetwork, +) -> Generator[BaseVirtualMachine]: + """ + AMD64 VM with UDN as primary interface. + """ + with udn_vm( + namespace_name=namespaced_layer2_user_defined_network.namespace, + name="amd64-udn-vm", + client=admin_client, + binding=UDN_BINDING_DEFAULT_PLUGIN_NAME, + architecture=AMD_64, + ) as vm: + yield vm + + +@pytest.fixture(scope="class") +def running_amd_and_arm_vms( + amd64_udn_vm: BaseVirtualMachine, arm64_udn_vm: BaseVirtualMachine +) -> tuple[BaseVirtualMachine, BaseVirtualMachine]: + """ + Start AMD64 and ARM64 UDN VMs in parallel. + + Returns: + Tuple of (amd64_vm, arm64_vm) both running with agent connected. + """ + amd64_vm, arm64_vm = run_vms(vms=(amd64_udn_vm, arm64_udn_vm)) + return amd64_vm, arm64_vm diff --git a/tests/network/user_defined_network/test_user_defined_network_multiarch.py b/tests/network/user_defined_network/test_user_defined_network_multiarch.py index accd59db73..810c6e2122 100644 --- a/tests/network/user_defined_network/test_user_defined_network_multiarch.py +++ b/tests/network/user_defined_network/test_user_defined_network_multiarch.py @@ -7,6 +7,9 @@ import pytest +from libs.net.traffic_generator import client_server_active_connection, is_tcp_connection +from libs.net.vmspec import lookup_primary_network + @pytest.mark.multiarch @pytest.mark.single_nic @@ -25,7 +28,7 @@ class TestMultiArchUdn: """ @pytest.mark.polarion("CNV-15942") - def test_udn_connectivity_amd_client_to_arm_server(self): + def test_udn_connectivity_amd_client_to_arm_server(self, running_amd_and_arm_vms): """ Test UDN connectivity between VMs on different architectures - client on AMD, server on ARM. @@ -35,9 +38,16 @@ def test_udn_connectivity_amd_client_to_arm_server(self): Expected: - TCP connection succeeds """ + amd64_udn_vm, arm64_udn_vm = running_amd_and_arm_vms + with client_server_active_connection( + client_vm=amd64_udn_vm, + server_vm=arm64_udn_vm, + spec_logical_network=lookup_primary_network(vm=arm64_udn_vm).name, + ) as (client, server): + assert is_tcp_connection(server=server, client=client) @pytest.mark.polarion("CNV-15970") - def test_udn_connectivity_arm_client_to_amd_server(self): + def test_udn_connectivity_arm_client_to_amd_server(self, running_amd_and_arm_vms): """ Test UDN connectivity between VMs on different architectures - client on ARM, server on AMD. @@ -47,6 +57,10 @@ def test_udn_connectivity_arm_client_to_amd_server(self): Expected: - TCP connection succeeds """ - - test_udn_connectivity_arm_client_to_amd_server.__test__ = False - test_udn_connectivity_amd_client_to_arm_server.__test__ = False + amd64_udn_vm, arm64_udn_vm = running_amd_and_arm_vms + with client_server_active_connection( + client_vm=arm64_udn_vm, + server_vm=amd64_udn_vm, + spec_logical_network=lookup_primary_network(vm=amd64_udn_vm).name, + ) as (client, server): + assert is_tcp_connection(server=server, client=client) From 8f62e0670a5acb60a0618351d07b6b3f1bd77c9f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 2 Jul 2026 13:51:12 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/network/user_defined_network/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/network/user_defined_network/conftest.py b/tests/network/user_defined_network/conftest.py index 1fa6829835..d3e0aed968 100644 --- a/tests/network/user_defined_network/conftest.py +++ b/tests/network/user_defined_network/conftest.py @@ -10,8 +10,8 @@ from libs.vm.oper import run_vms from libs.vm.vm import BaseVirtualMachine from tests.network.libs.vm_factory import udn_vm -from utilities.infra import create_ns from utilities.constants.architecture import AMD_64, ARM_64 +from utilities.infra import create_ns @pytest.fixture(scope="module")