Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
13 changes: 13 additions & 0 deletions tests/observability/metrics/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,3 +396,16 @@ def pvc_size_bytes(vm_for_vm_disk_allocation_size_test):
name=vm_for_vm_disk_allocation_size_test.instance.spec.dataVolumeTemplates[0].metadata.name,
namespace=vm_for_vm_disk_allocation_size_test.namespace,
).instance.spec.resources.requests.storage

Comment thread
OhadRevah marked this conversation as resolved.

@pytest.fixture(scope="class")
def expected_cpu_affinity_metric_value(vm_with_cpu_spec):
"""Calculate expected kubevirt_vmi_node_cpu_affinity metric value."""
# Calculate VM CPU count
vm_cpu = vm_with_cpu_spec.vmi.instance.spec.domain.cpu
cpu_count_from_vm = (vm_cpu.threads or 1) * (vm_cpu.cores or 1) * (vm_cpu.sockets or 1)
# Get node CPU capacity
cpu_count_from_vm_node = int(vm_with_cpu_spec.privileged_vmi.node.instance.status.capacity.cpu)

# return multiplication for multi-CPU VMs
return str(cpu_count_from_vm_node * cpu_count_from_vm)
2 changes: 2 additions & 0 deletions tests/observability/metrics/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,5 @@
KUBEVIRT_VMI_MIGRATION_DATA_TOTAL_BYTES = "kubevirt_vmi_migration_data_total_bytes{{name='{vm_name}'}}"
BINDING_NAME = "binding_name"
BINDING_TYPE = "binding_type"

KUBEVIRT_VMI_NODE_CPU_AFFINITY = "kubevirt_vmi_node_cpu_affinity{{kubernetes_vmi_label_kubevirt_io_domain='{vm_name}'}}"
35 changes: 6 additions & 29 deletions tests/observability/metrics/test_general_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,9 @@
import pytest
from ocp_resources.resource import Resource
from ocp_resources.virtual_machine import VirtualMachine
from pytest_testconfig import config as py_config

from tests.observability.metrics.utils import (
validate_vmi_node_cpu_affinity_with_prometheus,
)
from tests.observability.metrics.constants import KUBEVIRT_VMI_NODE_CPU_AFFINITY
from tests.observability.utils import validate_metrics_value
from tests.os_params import RHEL_LATEST, RHEL_LATEST_LABELS, RHEL_LATEST_OS
from utilities.virt import VirtualMachineForTests, fedora_vm_body, running_vm

KUBEVIRT_VM_TAG = f"{Resource.ApiGroup.KUBEVIRT_IO}/vm"
Expand Down Expand Up @@ -41,36 +37,17 @@ def fedora_vm_without_name_in_label(
client=unprivileged_client,
run_strategy=VirtualMachine.RunStrategy.ALWAYS,
) as vm:
running_vm(vm=vm, check_ssh_connectivity=False)
running_vm(vm=vm, wait_for_interfaces=False, check_ssh_connectivity=False)
yield vm


@pytest.mark.parametrize(
"golden_image_data_volume_scope_class, vm_from_template_scope_class",
[
pytest.param(
{
"dv_name": RHEL_LATEST_OS,
"image": RHEL_LATEST["image_path"],
"storage_class": py_config["default_storage_class"],
"dv_size": RHEL_LATEST["dv_size"],
},
{
"vm_name": "rhel-latest",
"template_labels": RHEL_LATEST_LABELS,
"guest_agent": False,
"ssh": False,
},
),
],
indirect=True,
)
class TestVmiNodeCpuAffinity:
@pytest.mark.polarion("CNV-7295")
def test_kubevirt_vmi_node_cpu_affinity(self, prometheus, vm_from_template_scope_class):
validate_vmi_node_cpu_affinity_with_prometheus(
vm=vm_from_template_scope_class,
def test_kubevirt_vmi_node_cpu_affinity(self, prometheus, vm_with_cpu_spec, expected_cpu_affinity_metric_value):
validate_metrics_value(
prometheus=prometheus,
metric_name=KUBEVIRT_VMI_NODE_CPU_AFFINITY.format(vm_name=vm_with_cpu_spec.name),
expected_value=expected_cpu_affinity_metric_value,
)


Expand Down
42 changes: 1 addition & 41 deletions tests/observability/metrics/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
import re
import shlex
import time
import urllib
from datetime import datetime, timezone
from typing import Any, Optional
from typing import Any

from kubernetes.dynamic import DynamicClient
from ocp_resources.resource import Resource
Expand Down Expand Up @@ -205,45 +204,6 @@ def enable_swap_fedora_vm(vm: VirtualMachineForTests) -> None:
vm.ssh_exec.executor(sudo=True).run_cmd(cmd=shlex.split("sysctl vm.swappiness=100"))


def get_vm_cpu_info_from_prometheus(prometheus: Prometheus, vm_name: str) -> Optional[int]:
query = urllib.parse.quote_plus(
f'kubevirt_vmi_node_cpu_affinity{{kubernetes_vmi_label_kubevirt_io_domain="{vm_name}"}}'
)
samples = TimeoutSampler(
wait_timeout=TIMEOUT_1MIN,
sleep=2,
func=prometheus.query_sampler,
query=query,
)
sample = None
try:
for sample in samples:
if sample:
return int(sample[0]["value"][1])
except TimeoutExpiredError:
LOGGER.error(f"Failed to get data from query '{query}' in time. Current data: {sample}")
raise
return None


def validate_vmi_node_cpu_affinity_with_prometheus(prometheus: Prometheus, vm: VirtualMachineForTests) -> None:
vm_cpu = vm.instance.spec.template.spec.domain.cpu
cpu_count_from_vm = (vm_cpu.threads or 1) * (vm_cpu.cores or 1) * (vm_cpu.sockets or 1)
LOGGER.info(f"Cpu count from vm {vm.name}: {cpu_count_from_vm}")
cpu_info_from_prometheus = get_vm_cpu_info_from_prometheus(prometheus=prometheus, vm_name=vm.name)
LOGGER.info(f"CPU information from prometheus: {cpu_info_from_prometheus}")
cpu_count_from_vm_node = int(vm.privileged_vmi.node.instance.status.capacity.cpu)
LOGGER.info(f"Cpu count from node {vm.privileged_vmi.node.name}: {cpu_count_from_vm_node}")

if cpu_count_from_vm > 1:
cpu_count_from_vm_node = cpu_count_from_vm_node * cpu_count_from_vm

assert cpu_count_from_vm_node == cpu_info_from_prometheus, (
f"Actual CPU count {cpu_count_from_vm_node} not matching with "
f"expected CPU count {cpu_info_from_prometheus} for VM CPU {cpu_count_from_vm}"
)


def get_resource_object(
admin_client: DynamicClient, related_objects: list, resource_kind, resource_name: str
) -> Resource:
Expand Down
Loading