Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion libs/vm/vm.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from ocp_resources.virtual_machine import VirtualMachine
from ocp_resources.virtual_machine_instance import VirtualMachineInstance
from pytest_testconfig import config as py_config
from timeout_sampler import retry

from libs.net.vmspec import VMInterfaceSpecNotFoundError
from libs.vm.spec import (
Expand Down Expand Up @@ -130,7 +131,7 @@ def set_networks(self, networks: list[Network]) -> None:
ResourceEditor(patches={self: {"spec": {"template": {"spec": {"networks": serialized}}}}}).update()

def set_template_affinity(self, affinity: Affinity | None) -> None:
"""Replace the VM template affinity.
"""Replace the VM template affinity and wait for the VMI to reflect it.

Serializes without dict_factory so that None-valued fields (e.g. podAffinity: None)
are preserved as null in the merge patch, ensuring the old affinity type is removed.
Expand All @@ -142,6 +143,17 @@ def set_template_affinity(self, affinity: Affinity | None) -> None:
template_affinity = asdict(obj=affinity) if affinity else None
patches = {self: {"spec": {"template": {"spec": {"affinity": template_affinity}}}}}
ResourceEditor(patches=patches).update()
expected_affinity = (
asdict(obj=affinity, dict_factory=self._filter_out_none_values) if affinity else None
)
self._expected_vmi_affinity(expected_affinity=expected_affinity)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it work by just using template_affinity (instead of expected_affinity)?


@retry(wait_timeout=10, sleep=1)
Comment thread
Anatw marked this conversation as resolved.
def _expected_vmi_affinity(self, expected_affinity: dict[str, Any] | None) -> bool:
vmi_affinity = self.vmi.instance.to_dict()["spec"].get("affinity")
if vmi_affinity != expected_affinity:
raise ValueError(f"VMI {self.name} affinity mismatch: expected {expected_affinity}, got {vmi_affinity}")
return True

@property
def template_spec(self) -> VMISpec:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@
import pytest

from libs.vm.affinity import new_pod_affinity, new_pod_anti_affinity
from tests.network.libs.stuntime import CLIENT_VM_LABEL, SERVER_VM_LABEL, STUNTIME_THRESHOLD_SECONDS, measure_stuntime
from tests.network.libs.stuntime import (
CLIENT_VM_LABEL,
SERVER_VM_LABEL,
STUNTIME_THRESHOLD_SECONDS,
measure_stuntime,
)
from utilities.virt import migrate_vm_and_verify

pytestmark = [pytest.mark.tier3]
Expand Down Expand Up @@ -71,6 +76,7 @@ def test_client_migrates_off_server_node(
- Measured stuntime does not exceed the global threshold.
"""
stuntime_client_vm.set_template_affinity(affinity=new_pod_anti_affinity(label=SERVER_VM_LABEL))

migrate_vm_and_verify(vm=stuntime_client_vm, client=admin_client)
measured_stuntime = measure_stuntime(active_ping=l2_bridge_active_ping)
assert measured_stuntime <= STUNTIME_THRESHOLD_SECONDS, (
Expand Down Expand Up @@ -130,6 +136,7 @@ def test_client_migrates_to_server_node(
- Measured stuntime does not exceed the global threshold.
"""
stuntime_client_vm.set_template_affinity(affinity=new_pod_affinity(label=SERVER_VM_LABEL))

migrate_vm_and_verify(vm=stuntime_client_vm, client=admin_client)
measured_stuntime = measure_stuntime(active_ping=l2_bridge_active_ping)
assert measured_stuntime <= STUNTIME_THRESHOLD_SECONDS, (
Expand Down Expand Up @@ -160,6 +167,7 @@ def test_server_migrates_off_client_node(
- Measured stuntime does not exceed the global threshold.
"""
stuntime_server_vm.set_template_affinity(affinity=new_pod_anti_affinity(label=CLIENT_VM_LABEL))

migrate_vm_and_verify(vm=stuntime_server_vm, client=admin_client)
measured_stuntime = measure_stuntime(active_ping=l2_bridge_active_ping)
assert measured_stuntime <= STUNTIME_THRESHOLD_SECONDS, (
Expand Down Expand Up @@ -189,7 +197,6 @@ def test_server_migrates_between_non_client_nodes(
Expected:
- Measured stuntime does not exceed the global threshold.
"""
stuntime_server_vm.set_template_affinity(affinity=new_pod_anti_affinity(label=CLIENT_VM_LABEL))
migrate_vm_and_verify(vm=stuntime_server_vm, client=admin_client)
measured_stuntime = measure_stuntime(active_ping=l2_bridge_active_ping)
assert measured_stuntime <= STUNTIME_THRESHOLD_SECONDS, (
Expand Down Expand Up @@ -220,6 +227,7 @@ def test_server_migrates_to_client_node(
- Measured stuntime does not exceed the global threshold.
"""
stuntime_server_vm.set_template_affinity(affinity=new_pod_affinity(label=CLIENT_VM_LABEL))

migrate_vm_and_verify(vm=stuntime_server_vm, client=admin_client)
measured_stuntime = measure_stuntime(active_ping=l2_bridge_active_ping)
assert measured_stuntime <= STUNTIME_THRESHOLD_SECONDS, (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def test_client_migrates_off_server_node(self, admin_client, ip_family, localnet
- Measured stuntime does not exceed the global threshold.
"""
localnet_stuntime_client_vm.set_template_affinity(affinity=new_pod_anti_affinity(label=SERVER_VM_LABEL))

migrate_vm_and_verify(vm=localnet_stuntime_client_vm, client=admin_client)
measured_stuntime = measure_stuntime(active_ping=active_ping)
assert measured_stuntime <= STUNTIME_THRESHOLD_SECONDS, (
Expand Down Expand Up @@ -133,6 +134,7 @@ def test_client_migrates_to_server_node(self, admin_client, ip_family, localnet_
- Measured stuntime does not exceed the global threshold.
"""
localnet_stuntime_client_vm.set_template_affinity(affinity=new_pod_affinity(label=SERVER_VM_LABEL))

migrate_vm_and_verify(vm=localnet_stuntime_client_vm, client=admin_client)
measured_stuntime = measure_stuntime(active_ping=active_ping)
assert measured_stuntime <= STUNTIME_THRESHOLD_SECONDS, (
Expand Down Expand Up @@ -161,6 +163,7 @@ def test_server_migrates_off_client_node(self, admin_client, ip_family, localnet
- Measured stuntime does not exceed the global threshold.
"""
localnet_stuntime_server_vm.set_template_affinity(affinity=new_pod_anti_affinity(label=CLIENT_VM_LABEL))

migrate_vm_and_verify(vm=localnet_stuntime_server_vm, client=admin_client)
measured_stuntime = measure_stuntime(active_ping=active_ping)
assert measured_stuntime <= STUNTIME_THRESHOLD_SECONDS, (
Expand Down Expand Up @@ -190,7 +193,6 @@ def test_server_migrates_between_non_client_nodes(
Expected:
- Measured stuntime does not exceed the global threshold.
"""
localnet_stuntime_server_vm.set_template_affinity(affinity=new_pod_anti_affinity(label=CLIENT_VM_LABEL))
migrate_vm_and_verify(vm=localnet_stuntime_server_vm, client=admin_client)
measured_stuntime = measure_stuntime(active_ping=active_ping)
assert measured_stuntime <= STUNTIME_THRESHOLD_SECONDS, (
Expand Down Expand Up @@ -219,6 +221,7 @@ def test_server_migrates_to_client_node(self, admin_client, ip_family, localnet_
- Measured stuntime does not exceed the global threshold.
"""
localnet_stuntime_server_vm.set_template_affinity(affinity=new_pod_affinity(label=CLIENT_VM_LABEL))

migrate_vm_and_verify(vm=localnet_stuntime_server_vm, client=admin_client)
measured_stuntime = measure_stuntime(active_ping=active_ping)
assert measured_stuntime <= STUNTIME_THRESHOLD_SECONDS, (
Expand Down