Skip to content
Open
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
11 changes: 11 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from utilities.bitwarden import get_cnv_tests_secret_by_name
from utilities.constants import (
AMD_64,
MULTIARCH,
QUARANTINED,
SETUP_ERROR,
TIMEOUT_5MIN,
Expand Down Expand Up @@ -558,6 +559,15 @@ def filter_sno_only_tests(items: list[Item], config: Config) -> list[Item]:
return items


def filter_multiarch_tests(items: list[Item], config: Config) -> list[Item]:
if py_config.get("cluster_type") == MULTIARCH:
return items
discard_tests, items_to_return = remove_tests_from_list(items=items, filter_str="multiarch")
if discard_tests:
config.hook.pytest_deselected(items=discard_tests)
return items_to_return


def remove_tests_from_list(items: list[Item], filter_str: str) -> tuple[list[Item], list[Item]]:
discard_tests: list[Item] = []
items_to_return: list[Item] = []
Expand Down Expand Up @@ -635,6 +645,7 @@ def pytest_collection_modifyitems(session, config, items):
config.hook.pytest_deselected(items=discard)
items[:] = filter_deprecated_api_tests(items=items, config=config)
items[:] = filter_sno_only_tests(items=items, config=config)
items[:] = filter_multiarch_tests(items=items, config=config)
items[:] = mark_nmstate_dependent_tests(items=items)


Expand Down
8 changes: 5 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
from libs.net.ip import filter_link_local_addresses, random_ipv4_address, random_ipv6_address
from libs.net.vmspec import lookup_iface_status
from tests.utils import download_and_extract_tar
from utilities.architecture import get_cluster_architecture
from utilities.artifactory import get_artifactory_header, get_http_image_url, get_test_artifact_server_url
from utilities.bitwarden import get_cnv_tests_secret_by_name
from utilities.cluster import cache_admin_client, get_oc_whoami_username
Expand Down Expand Up @@ -446,6 +447,7 @@ def schedulable_nodes(nodes):
"""
schedulable_label = "kubevirt.io/schedulable"
cpu_arch = py_config.get("cpu_arch")
cpu_archs = [cpu_arch] if isinstance(cpu_arch, str) else cpu_arch
schedulable = [
node
for node in nodes
Expand All @@ -454,7 +456,7 @@ def schedulable_nodes(nodes):
and not node.instance.spec.unschedulable
and not kubernetes_taint_exists(node)
and node.kubelet_ready
and (not cpu_arch or node.labels.get(KUBERNETES_ARCH_LABEL) == cpu_arch)
and (not cpu_archs or node.labels.get(KUBERNETES_ARCH_LABEL) in cpu_archs)
]

LOGGER.info(f"Schedulable nodes: {[node.name for node in schedulable]}, node architecture: {cpu_arch or 'all'}")
Expand Down Expand Up @@ -1026,7 +1028,7 @@ def mac_pool(admin_client, hco_namespace):

@pytest.fixture(scope="session")
def nodes_cpu_architecture():
return py_config["cpu_arch"]
return py_config.get("cpu_arch")


@pytest.fixture(scope="session")
Expand Down Expand Up @@ -1478,7 +1480,7 @@ def cluster_info(
f"\tOCS version: {ocs_current_version}\n"
f"\tCNI type: {get_cluster_cni_type(admin_client=admin_client)}\n"
f"\tWorkers type: {workers_type}\n"
f"\tCluster CPU Architecture: {nodes_cpu_architecture}\n"
f"\tCluster CPU Architecture: {nodes_cpu_architecture or ', '.join(sorted(get_cluster_architecture()))}\n"
f"\tIPv4 cluster: {ipv4_supported_cluster()}\n"
f"\tIPv6 cluster: {ipv6_supported_cluster()}\n"
f"\tVirtctl version: \n\t{virtctl_client_version}\n\t{virtctl_server_version}\n"
Expand Down
6 changes: 6 additions & 0 deletions tests/install_upgrade_operators/constants.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
from ocp_resources.cdi import CDI
from ocp_resources.kubevirt import KubeVirt
from ocp_resources.network_addons_config import NetworkAddonsConfig
from ocp_resources.ssp import SSP

SECTION_TITLE = "section_title"
FILE_SUFFIX = "file_suffix"
HCO_CR_CERT_CONFIG_CA_KEY = "ca"
Expand Down Expand Up @@ -58,6 +63,7 @@
"containerPathVolumes": FG_DISABLED,
}
CUSTOM_DATASOURCE_NAME = "custom-datasource"
MANAGED_CRS_LIST = [KubeVirt, CDI, NetworkAddonsConfig, SSP]
WORKLOAD_UPDATE_STRATEGY_KEY_NAME = "workloadUpdateStrategy"
KUBEMACPOOL_SERVICE = "kubemacpool-service"

Expand Down
3 changes: 1 addition & 2 deletions tests/install_upgrade_operators/crypto_policy/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@
from ocp_resources.network_addons_config import NetworkAddonsConfig
from ocp_resources.ssp import SSP

from tests.install_upgrade_operators.constants import KEY_PATH_SEPARATOR
from tests.install_upgrade_operators.constants import KEY_PATH_SEPARATOR, MANAGED_CRS_LIST
from utilities.constants import TLS_CUSTOM_POLICY, TLS_OLD_POLICY

MANAGED_CRS_LIST = [KubeVirt, CDI, NetworkAddonsConfig, SSP]
MANAGED_CRS_LIST_WITH_AAQ = [*MANAGED_CRS_LIST, AAQ]

TLS_MODERN_POLICY = "modern"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
import pytest
from ocp_resources.data_import_cron import DataImportCron
from ocp_resources.data_source import DataSource
from ocp_resources.image_stream import ImageStream
from ocp_resources.pod import Pod
from ocp_utilities.infra import get_pods_by_name_prefix

from tests.install_upgrade_operators.constants import ENABLE_MULTI_ARCH_BOOT_IMAGE_IMPORT
from tests.install_upgrade_operators.hco_enablement_golden_image_updates.utils import (
COMMON_TEMPLATE,
CUSTOM_TEMPLATE,
HCO_CR_DATA_IMPORT_SCHEDULE_KEY,
get_modifed_common_template_names,
get_random_minutes_hours_fields_from_data_import_schedule,
get_templates_by_type_from_hco_status,
get_templates_resources_names_dict,
)
from utilities.constants import (
COMMON_TEMPLATES_KEY_NAME,
FEATURE_GATES,
HCO_OPERATOR,
KUBERNETES_ARCH_LABEL,
SSP_CR_COMMON_TEMPLATES_LIST_KEY_NAME,
)
from utilities.ssp import get_ssp_resource
Expand Down Expand Up @@ -113,3 +120,50 @@ def ssp_spec_templates_scope_function(ssp_resource_scope_function):
@pytest.fixture(scope="session")
def common_templates_scope_session(hyperconverged_status_scope_session):
return hyperconverged_status_scope_session[SSP_CR_COMMON_TEMPLATES_LIST_KEY_NAME]


@pytest.fixture(scope="session")
def worker_architectures(schedulable_nodes):
return {node.labels[KUBERNETES_ARCH_LABEL] for node in schedulable_nodes}


@pytest.fixture(scope="class")
def default_common_template_hco_status(hyperconverged_status_templates_scope_class):
return get_templates_by_type_from_hco_status(
hco_status_templates=hyperconverged_status_templates_scope_class, template_type=COMMON_TEMPLATE
)


@pytest.fixture(scope="class")
def default_common_templates_related_resources(
default_common_template_hco_status,
hyperconverged_resource_scope_class,
worker_architectures,
):
"""Return expected golden image resource names for the current cluster state.

When enableMultiArchBootImageImport is enabled:
- DataImportCrons: arch-specific only (base names are replaced)
- DataSources: both arch-specific and agnostic pointers
- ImageStreams: always base names
When disabled: all base names.
"""
base_resources = get_templates_resources_names_dict(templates=default_common_template_hco_status)

feature_gate_enabled = hyperconverged_resource_scope_class.instance.spec.get(FEATURE_GATES, {}).get(
ENABLE_MULTI_ARCH_BOOT_IMAGE_IMPORT, False
)

if not feature_gate_enabled:
return base_resources

result = {}
for kind, base_names in base_resources.items():
arch_names = {f"{name}-{arch}" for name in base_names for arch in worker_architectures}
if kind == DataImportCron.kind:
result[kind] = arch_names
elif kind == DataSource.kind:
result[kind] = base_names | arch_names
else:
result[kind] = base_names
return result
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import logging

import pytest
from ocp_resources.cdi import CDI
from ocp_resources.kubevirt import KubeVirt
from ocp_resources.ssp import SSP

from tests.install_upgrade_operators.constants import ENABLE_MULTI_ARCH_BOOT_IMAGE_IMPORT, MANAGED_CRS_LIST
from tests.install_upgrade_operators.hco_enablement_golden_image_updates.multiarch.utils import (
CUSTOM_MULTIARCH_DATASOURCE_NAME,
get_control_plane_architecture,
get_no_arch_annotation_template,
get_unsupported_arch_template,
)
from utilities.constants import (
FEATURE_GATES,
KUBERNETES_ARCH_LABEL,
)
from utilities.hco import (
ResourceEditorValidateHCOReconcile,
update_hco_templates_spec,
)

LOGGER = logging.getLogger(__name__)

_MULTIARCH_MANAGED_CRS = [SSP, KubeVirt, CDI]


@pytest.fixture(scope="class")
def disabled_multiarch_feature_gate(hyperconverged_resource_scope_class):
with ResourceEditorValidateHCOReconcile(
patches={
hyperconverged_resource_scope_class: {"spec": {FEATURE_GATES: {ENABLE_MULTI_ARCH_BOOT_IMAGE_IMPORT: False}}}
},
list_resource_reconcile=_MULTIARCH_MANAGED_CRS,
wait_for_reconcile_post_update=True,
):
yield


@pytest.fixture(scope="class")
def enabled_multiarch_feature_gate(hyperconverged_resource_scope_class):
feature_gates = hyperconverged_resource_scope_class.instance.spec.get(FEATURE_GATES, {})
if feature_gates.get(ENABLE_MULTI_ARCH_BOOT_IMAGE_IMPORT):
yield
else:
with ResourceEditorValidateHCOReconcile(
patches={
hyperconverged_resource_scope_class: {
"spec": {FEATURE_GATES: {ENABLE_MULTI_ARCH_BOOT_IMAGE_IMPORT: True}}
}
},
list_resource_reconcile=_MULTIARCH_MANAGED_CRS,
wait_for_reconcile_post_update=True,
):
yield


@pytest.fixture(scope="class")
def control_plane_architecture(control_plane_nodes):
return get_control_plane_architecture(control_plane_nodes=control_plane_nodes)


@pytest.fixture()
def single_arch_node_placement(hyperconverged_resource_scope_function, worker_architectures):
single_arch = sorted(worker_architectures)[0]
LOGGER.info(f"Restricting workloads nodePlacement to single architecture: {single_arch}")
placement = {"nodePlacement": {"nodeSelector": {KUBERNETES_ARCH_LABEL: single_arch}}}
with ResourceEditorValidateHCOReconcile(
patches={hyperconverged_resource_scope_function: {"spec": {"workloads": placement}}},
list_resource_reconcile=MANAGED_CRS_LIST,
wait_for_reconcile_post_update=True,
):
yield


@pytest.fixture()
def hco_with_custom_unsupported_arch_template(
admin_client,
hco_namespace,
hyperconverged_resource_scope_function,
hyperconverged_status_templates_scope_function,
golden_images_namespace,
):
yield from update_hco_templates_spec(
admin_client=admin_client,
hco_namespace=hco_namespace,
hyperconverged_resource=hyperconverged_resource_scope_function,
updated_template=get_unsupported_arch_template(
common_templates=hyperconverged_status_templates_scope_function,
),
custom_datasource_name=CUSTOM_MULTIARCH_DATASOURCE_NAME,
golden_images_namespace=golden_images_namespace,
)


@pytest.fixture()
def hco_with_custom_no_arch_annotation_template(
admin_client,
hco_namespace,
hyperconverged_resource_scope_function,
hyperconverged_status_templates_scope_function,
golden_images_namespace,
):
yield from update_hco_templates_spec(
admin_client=admin_client,
hco_namespace=hco_namespace,
hyperconverged_resource=hyperconverged_resource_scope_function,
updated_template=get_no_arch_annotation_template(
common_templates=hyperconverged_status_templates_scope_function,
),
custom_datasource_name=CUSTOM_MULTIARCH_DATASOURCE_NAME,
golden_images_namespace=golden_images_namespace,
)
Loading
Loading