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
Empty file.
34 changes: 34 additions & 0 deletions tests/storage/cdi_config/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
Comment thread
ema-aka-young marked this conversation as resolved.
Comment thread
ema-aka-young marked this conversation as resolved.
Comment thread
ema-aka-young marked this conversation as resolved.
Comment thread
ema-aka-young marked this conversation as resolved.
Comment thread
ema-aka-young marked this conversation as resolved.

"""
Pytest conftest file for CNV CDI Config tests
"""

import pytest
from ocp_resources.cdi import CDI

from utilities.hco import ResourceEditorValidateHCOReconcile
from utilities.storage import cdi_feature_gate_list_with_added_feature


@pytest.fixture()
def cdi_with_extra_non_existent_feature_gate(cdi):
with ResourceEditorValidateHCOReconcile(
patches={
cdi: {
"spec": {
"config": {
"featureGates": cdi_feature_gate_list_with_added_feature(feature="ExtraNonExistentFeature")
}
},
},
},
list_resource_reconcile=[CDI],
wait_for_reconcile_post_update=True,
):
yield cdi
Comment thread
ema-aka-young marked this conversation as resolved.


@pytest.fixture()
def initial_cdi_config_from_cr(cdi):
return cdi.instance.to_dict()["spec"]["config"]
161 changes: 161 additions & 0 deletions tests/storage/cdi_config/test_cdi_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
"""CDIConfig tests"""

import pytest
from ocp_resources.cdi import CDI
from ocp_resources.route import Route
from timeout_sampler import TimeoutSampler

from tests.storage.utils import LOGGER
from utilities.constants import CDI_UPLOADPROXY
from utilities.hco import ResourceEditorValidateHCOReconcile

pytestmark = pytest.mark.post_upgrade

STORAGE_WORKLOADS_DICT = {
"limits": {"cpu": "505m", "memory": "2Gi"},
"requests": {"cpu": "252m", "memory": "1Gi"},
}
NON_EXISTENT_SCRATCH_SC_DICT = {"scratchSpaceStorageClass": "NonExistentSC"}
INSECURE_REGISTRIES_LIST = ["added-private-registry:5000"]


@pytest.mark.sno
@pytest.mark.gating
@pytest.mark.polarion("CNV-2208")
@pytest.mark.s390x
def test_cdi_config_exists(cdi_config, upload_proxy_route):
"""
Test that CDIConfig exists and has the expected upload_proxy_url
"""
assert cdi_config.upload_proxy_url == upload_proxy_route.host, (
f"Expected upload_proxy_url to match upload-proxy route host {upload_proxy_route.host},"
f"got {cdi_config.upload_proxy_url}"
)


@pytest.mark.destructive
@pytest.mark.polarion("CNV-2209")
def test_different_route_for_upload_proxy(hco_namespace, cdi_config, uploadproxy_route_deleted):
"""
Test that CDIConfig's upload_proxy_url changes when the upload-proxy route is deleted
and recreated with a different host
"""
with Route(
namespace=hco_namespace.name,
name="new-route-uploadproxy",
service=CDI_UPLOADPROXY,
) as new_route:
cdi_config.wait_until_upload_url_changed(uploadproxy_url=new_route.host)


@pytest.mark.sno
@pytest.mark.polarion("CNV-2215")
@pytest.mark.s390x
def test_route_for_different_service(admin_client, cdi_config, upload_proxy_route):
"""
Test that CDIConfig's upload_proxy_url does not change when a route for a different service is created
"""
with Route(
namespace=upload_proxy_route.namespace, name="cdi-api", service="cdi-api", client=admin_client
) as cdi_api_route:
assert cdi_config.upload_proxy_url != cdi_api_route.host, (
f"upload_proxy_url unexpectedly changed to cdi-api route host {cdi_api_route.host}"
)
assert cdi_config.upload_proxy_url == upload_proxy_route.host, (
f"Expected upload_proxy_url to remain {upload_proxy_route.host}, got {cdi_config.upload_proxy_url}"
)


@pytest.mark.sno
@pytest.mark.polarion("CNV-2216")
@pytest.mark.s390x
def test_upload_proxy_url_overridden(admin_client, cdi_config, namespace, cdi_config_upload_proxy_overridden):
"""
Test that CDIConfig's upload_proxy_url does not change when overridden
and a new route is created for upload-proxy service
"""
with Route(namespace=namespace.name, name="my-route", service=CDI_UPLOADPROXY, client=admin_client) as new_route:
assert cdi_config.upload_proxy_url != new_route.host, (
f"upload_proxy_url should remain overridden and not switch to route host {new_route.host}"
)


@pytest.mark.sno
@pytest.mark.polarion("CNV-6312")
@pytest.mark.s390x
def test_cdi_spec_reconciled_by_hco(initial_cdi_config_from_cr, cdi_with_extra_non_existent_feature_gate):
"""
Test that added feature gate on the CDI CR does not persist
(HCO Should reconcile back changes on the CDI CR)
"""
assert (
cdi_with_extra_non_existent_feature_gate.instance.to_dict()["spec"]["config"] == initial_cdi_config_from_cr
), "HCO should have reconciled back changes"


@pytest.mark.sno
@pytest.mark.parametrize(
("hco_updated_spec_stanza", "expected_in_cdi_config_from_cr"),
[
pytest.param(
{"resourceRequirements": {"storageWorkloads": STORAGE_WORKLOADS_DICT}},
{"podResourceRequirements": STORAGE_WORKLOADS_DICT},
marks=(pytest.mark.polarion("CNV-6000")),
id="test_storage_workloads_in_hco_propagated_to_cdi_cr",
),
pytest.param(
NON_EXISTENT_SCRATCH_SC_DICT,
NON_EXISTENT_SCRATCH_SC_DICT,
marks=(pytest.mark.polarion("CNV-6001")),
id="test_scratch_sc_in_hco_propagated_to_cdi_cr",
),
pytest.param(
{"storageImport": {"insecureRegistries": INSECURE_REGISTRIES_LIST}},
{"insecureRegistries": INSECURE_REGISTRIES_LIST},
marks=(pytest.mark.polarion("CNV-6092")),
id="test_insecure_registries_in_hco_propagated_to_cdi_cr",
),
],
)
@pytest.mark.s390x
def test_cdi_tunables_in_hco_propagated_to_cr(
hyperconverged_resource_scope_module,
cdi,
namespace,
expected_in_cdi_config_from_cr,
hco_updated_spec_stanza,
):
"""
Test that the exposed CDI-related tunables in HCO are propagated to the CDI CR
"""
initial_cdi_config_from_cr = cdi.instance.to_dict()["spec"]["config"]

def _verify_propagation():
current_cdi_config_from_cr = cdi.instance.to_dict()["spec"]["config"]
return {
**initial_cdi_config_from_cr,
**expected_in_cdi_config_from_cr,
} == current_cdi_config_from_cr
Comment thread
coderabbitai[bot] marked this conversation as resolved.

def _verify_revert() -> bool:
current_cdi_config_from_cr = cdi.instance.to_dict()["spec"]["config"]
return current_cdi_config_from_cr == initial_cdi_config_from_cr

with ResourceEditorValidateHCOReconcile(
patches={hyperconverged_resource_scope_module: {"spec": hco_updated_spec_stanza}},
list_resource_reconcile=[CDI],
):
propagated = False
for sample in TimeoutSampler(wait_timeout=20, sleep=1, func=_verify_propagation):
if sample:
propagated = True
break
assert propagated, "CDI config was not updated from HCO tunables within timeout"

LOGGER.info("Check values revert back to original")
reverted = False
for sample in TimeoutSampler(wait_timeout=20, sleep=1, func=_verify_revert):
if sample:
reverted = True
break
assert reverted, "CDI config did not revert to the original values after restore"
54 changes: 0 additions & 54 deletions tests/storage/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@
from ocp_resources.data_source import DataSource
from ocp_resources.deployment import Deployment
from ocp_resources.exceptions import ExecOnPodError
from ocp_resources.resource import ResourceEditor
from ocp_resources.route import Route
from ocp_resources.secret import Secret
from ocp_resources.storage_class import StorageClass
from ocp_resources.virtual_machine_cluster_instancetype import (
VirtualMachineClusterInstancetype,
)
Expand Down Expand Up @@ -316,48 +314,6 @@ def default_fs_overhead(cdi_config):
return float(cdi_config.instance.status.filesystemOverhead["global"])


@pytest.fixture()
def unset_predefined_scratch_sc(hyperconverged_resource_scope_module, cdi_config):
if cdi_config.instance.spec.scratchSpaceStorageClass:
empty_scratch_space_spec = {"spec": {"scratchSpaceStorageClass": ""}}
with ResourceEditorValidateHCOReconcile(
patches={hyperconverged_resource_scope_module: empty_scratch_space_spec},
list_resource_reconcile=[CDI],
):
LOGGER.info(f"wait for {empty_scratch_space_spec} in CDIConfig")
for sample in TimeoutSampler(
wait_timeout=20,
sleep=1,
func=lambda: not cdi_config.instance.spec.scratchSpaceStorageClass,
):
if sample:
break
yield
else:
yield


@pytest.fixture()
def default_sc_as_fallback_for_scratch(unset_predefined_scratch_sc, admin_client, cdi_config, default_sc):
# Based on py_config["default_storage_class"], update default SC, if needed
if default_sc:
yield default_sc
else:
for sc in StorageClass.get(client=admin_client, name=py_config["default_storage_class"]):
assert sc, f"The cluster does not include {py_config['default_storage_class']} storage class"
with ResourceEditor(
patches={
sc: {
"metadata": {
"annotations": {StorageClass.Annotations.IS_DEFAULT_CLASS: "true"},
"name": sc.name,
}
}
}
):
yield sc


@pytest.fixture()
def router_cert_secret(admin_client):
router_secret = "router-certs-default"
Expand Down Expand Up @@ -429,16 +385,6 @@ def rhel_vm_name(request):
return request.param["vm_name"]


@pytest.fixture(scope="session")
def available_hpp_storage_class(skip_test_if_no_hpp_sc, cluster_storage_classes):
"""
Get an HPP storage class if there is any in the cluster
"""
for storage_class in cluster_storage_classes:
if storage_class.name in HPP_STORAGE_CLASSES:
return storage_class


@pytest.fixture(scope="module")
def artifactory_secret_scope_module(namespace):
artifactory_secret = get_artifactory_secret(namespace=namespace.name)
Expand Down
Loading
Loading