Skip to content

Commit a4afb16

Browse files
dbasunagadolfo-ab
andauthored
Use exitStack to support multiple resource creations (#429)
* on rebase clean commented-by- labels * Use exitStack to support multiple resource creations updates! 418c33c * Use exitStack to support multiple resource creations updates! 418c33c updates! 9e0cdf8 * Update tests/model_registry/conftest.py Co-authored-by: Adolfo Aguirrezabal <aaguirre@redhat.com> * address review comments --------- Co-authored-by: Adolfo Aguirrezabal <aaguirre@redhat.com>
1 parent b943a2b commit a4afb16

19 files changed

+697
-526
lines changed

tests/model_registry/conftest.py

Lines changed: 143 additions & 363 deletions
Large diffs are not rendered by default.

tests/model_registry/constants.py

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Any
22
from ocp_resources.resource import Resource
3-
from utilities.constants import ModelFormat, Annotations
3+
from utilities.constants import ModelFormat
44

55

66
class ModelRegistryEndpoints:
@@ -25,7 +25,8 @@ class ModelRegistryEndpoints:
2525
"str_key": "str_value",
2626
},
2727
}
28-
MR_INSTANCE_NAME: str = "model-registry"
28+
MR_INSTANCE_BASE_NAME: str = "model-registry"
29+
MR_INSTANCE_NAME: str = f"{MR_INSTANCE_BASE_NAME}0"
2930
SECURE_MR_NAME: str = "secure-db-mr"
3031
ISTIO_CONFIG_DICT: dict[str, Any] = {
3132
"gateway": {"grpc": {"tls": {}}, "rest": {"tls": {}}},
@@ -35,11 +36,12 @@ class ModelRegistryEndpoints:
3536
"routePort": 443,
3637
"serviceRoute": "enabled",
3738
}
38-
DB_RESOURCES_NAME: str = "db-model-registry"
39+
DB_BASE_RESOURCES_NAME: str = "db-model-registry"
40+
DB_RESOURCE_NAME: str = f"{DB_BASE_RESOURCES_NAME}0"
3941
MR_DB_IMAGE_DIGEST: str = (
4042
"public.ecr.aws/docker/library/mysql@sha256:9de9d54fecee6253130e65154b930978b1fcc336bcc86dfd06e89b72a2588ebe"
4143
)
42-
MODEL_REGISTRY_DB_SECRET_STR_DATA = {
44+
MODEL_REGISTRY_DB_SECRET_STR_DATA: dict[str, str] = {
4345
"database-name": "model_registry",
4446
"database-password": "TheBlurstOfTimes", # pragma: allowlist secret
4547
"database-user": "mlmduser", # pragma: allowlist secret
@@ -53,12 +55,5 @@ class ModelRegistryEndpoints:
5355
CA_CONFIGMAP_NAME = "odh-trusted-ca-bundle"
5456
CA_MOUNT_PATH = "/etc/pki/ca-trust/extracted/pem"
5557
CA_FILE_PATH = f"{CA_MOUNT_PATH}/ca-bundle.crt"
56-
57-
MODEL_REGISTRY_STANDARD_LABELS = {
58-
Annotations.KubernetesIo.NAME: MR_INSTANCE_NAME,
59-
Annotations.KubernetesIo.INSTANCE: MR_INSTANCE_NAME,
60-
Annotations.KubernetesIo.PART_OF: MR_OPERATOR_NAME,
61-
Annotations.KubernetesIo.CREATED_BY: MR_OPERATOR_NAME,
62-
}
63-
58+
NUM_RESOURCES = {"num_resources": 3}
6459
NUM_MR_INSTANCES: int = 2

tests/model_registry/image_validation/test_verify_rhoai_images.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from utilities.general import (
77
validate_container_images,
88
)
9-
from ocp_resources.model_registry_modelregistry_opendatahub_io import ModelRegistry
109
from ocp_resources.pod import Pod
1110

1211
LOGGER = get_logger(name=__name__)
@@ -15,7 +14,7 @@
1514
@pytest.mark.usefixtures(
1615
"updated_dsc_component_state_scope_class",
1716
"is_model_registry_oauth",
18-
"model_registry_mysql_metadata_db",
17+
"mysql_metadata_resources",
1918
"model_registry_instance_mysql",
2019
)
2120
@pytest.mark.downstream_only
@@ -32,7 +31,6 @@ class TestModelRegistryImages:
3231
def test_verify_model_registry_images(
3332
self: Self,
3433
admin_client: DynamicClient,
35-
model_registry_instance_mysql: ModelRegistry,
3634
model_registry_operator_pod: Pod,
3735
model_registry_instance_pod: Pod,
3836
related_images_refs: Set[str],
Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,89 @@
11
import pytest
2-
import uuid
32
from tests.model_registry.constants import (
43
MODEL_REGISTRY_DB_SECRET_STR_DATA,
54
MR_INSTANCE_NAME,
6-
DB_RESOURCES_NAME,
5+
DB_BASE_RESOURCES_NAME,
76
NUM_MR_INSTANCES,
7+
MODEL_REGISTRY_DB_SECRET_ANNOTATIONS,
8+
OAUTH_PROXY_CONFIG_DICT,
89
)
10+
from tests.model_registry.utils import (
11+
get_model_registry_db_label_dict,
12+
get_model_registry_deployment_template_dict,
13+
get_mr_standard_labels,
14+
get_mysql_config,
15+
)
16+
from utilities.general import generate_random_name
917

10-
11-
ns_name = f"{MR_INSTANCE_NAME}-ns-{str(uuid.uuid4())[:8]}"
18+
ns_name = generate_random_name(prefix=MR_INSTANCE_NAME, length=2)
1219
ns_params = {"ns_name": ns_name}
1320

14-
db_names = [f"{DB_RESOURCES_NAME}-{i + 1}-{str(uuid.uuid4())[:8]}" for i in range(NUM_MR_INSTANCES)]
21+
resource_names = [f"{DB_BASE_RESOURCES_NAME}{index}" for index in range(0, NUM_MR_INSTANCES)]
1522

16-
db_secret_params = [{"db_name": db_name, "ns_name": ns_name} for db_name in db_names]
23+
db_secret_params = [
24+
{
25+
"name": resource_name,
26+
"namespace": ns_name,
27+
"string_data": MODEL_REGISTRY_DB_SECRET_STR_DATA,
28+
"label": get_model_registry_db_label_dict(db_resource_name=resource_name),
29+
"annotations": MODEL_REGISTRY_DB_SECRET_ANNOTATIONS,
30+
}
31+
for resource_name in resource_names
32+
]
1733

1834
db_pvc_params = [
1935
{
20-
"db_name": db_name,
21-
"ns_name": ns_name,
36+
"name": resource_name,
37+
"namespace": ns_name,
2238
"accessmodes": "ReadWriteOnce",
2339
"size": "4Gi",
40+
"label": get_model_registry_db_label_dict(db_resource_name=resource_name),
2441
}
25-
for db_name in db_names
42+
for resource_name in resource_names
2643
]
27-
44+
annotation = {"template.openshift.io/expose-uri": r"mysql://{.spec.clusterIP}:{.spec.ports[?(.name==\mysql\)].port}"}
2845
db_service_params = [
2946
{
30-
"db_name": db_name,
47+
"name": resource_name,
3148
"ports": [{"name": "mysql", "port": 3306, "protocol": "TCP", "targetPort": 3306}],
32-
"ns_name": ns_name,
49+
"namespace": ns_name,
50+
"selector": {"name": resource_name},
51+
"label": get_model_registry_db_label_dict(db_resource_name=resource_name),
52+
"annotations": annotation,
3353
}
34-
for db_name in db_names
54+
for resource_name in resource_names
3555
]
3656

3757
db_deployment_params = [
3858
{
39-
"db_name": db_name,
40-
"ns_name": ns_name,
59+
"name": resource_name,
60+
"namespace": ns_name,
4161
"replicas": 1,
4262
"revision_history_limit": 0,
63+
"annotations": {
64+
"template.alpha.openshift.io/wait-for-ready": "true",
65+
},
66+
"label": get_model_registry_db_label_dict(db_resource_name=resource_name),
67+
"selector": {"matchLabels": {"name": resource_name}},
68+
"strategy": {"type": "Recreate"},
69+
"template": get_model_registry_deployment_template_dict(secret_name=resource_name, resource_name=resource_name),
70+
"wait_for_resource": True,
4371
}
44-
for db_name in db_names
72+
for resource_name in resource_names
4573
]
4674

4775
model_registry_instance_params = [
4876
{
49-
"is_model_registry_oauth": True,
50-
"mr_name": f"{MR_INSTANCE_NAME}-{i + 1}",
51-
"db_name": db_name,
52-
"ns_name": ns_name,
53-
"mysql_config": {
54-
"host": f"{db_name}.{ns_name}.svc.cluster.local",
55-
"database": MODEL_REGISTRY_DB_SECRET_STR_DATA["database-name"],
56-
"passwordSecret": {"key": "database-password", "name": db_name},
57-
"port": 3306,
58-
"skipDBCreation": False,
59-
"username": MODEL_REGISTRY_DB_SECRET_STR_DATA["database-user"],
60-
},
77+
"name": f"{MR_INSTANCE_NAME}{index}",
78+
"namespace": ns_name,
79+
"label": get_mr_standard_labels(resource_name=f"{MR_INSTANCE_NAME}{index}"),
80+
"grpc": {},
81+
"rest": {},
82+
"mysql": get_mysql_config(base_name=f"{DB_BASE_RESOURCES_NAME}{index}", namespace=ns_name),
83+
"wait_for_resource": True,
84+
"oauth_proxy": OAUTH_PROXY_CONFIG_DICT,
6185
}
62-
for i, db_name in enumerate(db_names)
86+
for index in range(0, NUM_MR_INSTANCES)
6387
]
6488

6589
# Add this complete set of parameters as a pytest.param tuple to the list.
@@ -71,6 +95,6 @@
7195
db_service_params,
7296
db_deployment_params,
7397
model_registry_instance_params,
74-
id=f"mr-scenario-{len(db_names)}-instances", # Unique ID for pytest output
98+
id=f"mr-scenario-{len(resource_names)}-instances", # Unique ID for pytest output
7599
)
76100
]

tests/model_registry/negative_tests/test_db_migration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414

1515
@pytest.mark.usefixtures(
16-
"updated_dsc_component_state_scope_class", "model_registry_mysql_metadata_db", "model_registry_instance_mysql"
16+
"updated_dsc_component_state_scope_class", "mysql_metadata_resources", "model_registry_instance_mysql"
1717
)
1818
class TestDBMigration:
1919
def test_db_migration_negative(

tests/model_registry/negative_tests/test_model_registry_creation_negative.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from tests.model_registry.constants import (
1212
MR_OPERATOR_NAME,
1313
MR_INSTANCE_NAME,
14-
DB_RESOURCES_NAME,
14+
DB_RESOURCE_NAME,
1515
OAUTH_PROXY_CONFIG_DICT,
1616
)
1717
from kubernetes.dynamic.exceptions import ForbiddenError
@@ -40,7 +40,7 @@ def test_registering_model_negative(
4040
"host": f"{model_registry_db_deployment_negative_test.name}."
4141
f"{model_registry_db_deployment_negative_test.namespace}.svc.cluster.local",
4242
"database": model_registry_db_secret_negative_test.string_data["database-name"],
43-
"passwordSecret": {"key": "database-password", "name": DB_RESOURCES_NAME},
43+
"passwordSecret": {"key": "database-password", "name": DB_RESOURCE_NAME},
4444
"port": 3306,
4545
"skipDBCreation": False,
4646
"username": model_registry_db_secret_negative_test.string_data["database-user"],

tests/model_registry/python_client/test_model_registry_creation.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,12 @@
3131
)
3232
@pytest.mark.usefixtures(
3333
"updated_dsc_component_state_scope_class",
34-
"model_registry_mysql_metadata_db",
34+
"is_model_registry_oauth",
35+
"model_registry_namespace",
36+
"model_registry_db_secret",
37+
"model_registry_db_pvc",
38+
"model_registry_db_service",
39+
"model_registry_db_deployment",
3540
"model_registry_instance_mysql",
3641
"registered_model",
3742
)
@@ -45,10 +50,10 @@ class TestModelRegistryCreation:
4550
@pytest.mark.smoke
4651
def test_registering_model(
4752
self: Self,
48-
model_registry_client: ModelRegistryClient,
53+
model_registry_client: list[ModelRegistryClient],
4954
registered_model: RegisteredModel,
5055
):
51-
model = model_registry_client.get_registered_model(name=MODEL_NAME)
56+
model = model_registry_client[0].get_registered_model(name=MODEL_NAME)
5257
expected_attrs = {
5358
"id": registered_model.id,
5459
"name": registered_model.name,
@@ -113,7 +118,7 @@ def test_model_registry_pod_log_mlmd_removal(
113118
],
114119
)
115120
def test_model_registry_endpoint_response(
116-
self, model_registry_rest_url: str, model_registry_rest_headers: dict[str, str], endpoint: str
121+
self, model_registry_rest_url: list[str], model_registry_rest_headers: dict[str, str], endpoint: str
117122
):
118123
"""
119124
RHOAIENG-26239: Test to ensure model registry endpoints are responsive
@@ -123,6 +128,6 @@ def test_model_registry_endpoint_response(
123128
Ensure endpoint is responsive via get call
124129
"""
125130
output = execute_model_registry_get_command(
126-
url=f"{model_registry_rest_url}/{endpoint}", headers=model_registry_rest_headers, json_output=False
131+
url=f"{model_registry_rest_url[0]}/{endpoint}", headers=model_registry_rest_headers, json_output=False
127132
)
128133
assert output["raw_output"] == "OK"

0 commit comments

Comments
 (0)