Skip to content

Commit a65796b

Browse files
committed
[model registry] update namespace code and rearrange tests (opendatahub-io#247)
* updates to test_registering_model() based on previous review comments * update namespace code and rearrange tests
1 parent f77d1cd commit a65796b

File tree

11 files changed

+317
-198
lines changed

11 files changed

+317
-198
lines changed

tests/model_registry/conftest.py

Lines changed: 36 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -25,49 +25,39 @@
2525
from pytest_testconfig import config as py_config
2626
from model_registry.types import RegisteredModel
2727
from tests.model_registry.constants import (
28-
MR_NAMESPACE,
2928
MR_OPERATOR_NAME,
3029
MR_INSTANCE_NAME,
3130
ISTIO_CONFIG_DICT,
3231
DB_RESOURCES_NAME,
33-
MR_DB_IMAGE_DIGEST,
32+
MODEL_REGISTRY_DB_SECRET_STR_DATA,
33+
MODEL_REGISTRY_DB_SECRET_ANNOTATIONS,
34+
)
35+
from tests.model_registry.utils import (
36+
get_endpoint_from_mr_service,
37+
get_mr_service_by_label,
38+
get_model_registry_deployment_template_dict,
39+
get_model_registry_db_label_dict,
3440
)
35-
from tests.model_registry.utils import get_endpoint_from_mr_service, get_mr_service_by_label
36-
from utilities.infra import create_ns
3741
from utilities.constants import Annotations, Protocols, DscComponents
3842
from model_registry import ModelRegistry as ModelRegistryClient
3943

4044

4145
LOGGER = get_logger(name=__name__)
4246

43-
DEFAULT_LABEL_DICT_DB: dict[str, str] = {
44-
Annotations.KubernetesIo.NAME: DB_RESOURCES_NAME,
45-
Annotations.KubernetesIo.INSTANCE: DB_RESOURCES_NAME,
46-
Annotations.KubernetesIo.PART_OF: DB_RESOURCES_NAME,
47-
}
48-
4947

5048
@pytest.fixture(scope="class")
51-
def model_registry_namespace(request: FixtureRequest, admin_client: DynamicClient) -> Generator[Namespace, Any, Any]:
52-
# TODO: model_registry_namespace fixture should basically be doing this 1) check the ns exists, 2) it is in ACTIVE
53-
# state and return. But it should not create the ns. If DSC manages registriesNamespace, and namespace was not
54-
# created when mr is updated to Managed state, it would be a bug and we should catch it
55-
# To be handled in upcoming PR.
56-
with create_ns(
57-
name=request.param.get("namespace_name", MR_NAMESPACE),
58-
admin_client=admin_client,
59-
) as ns:
60-
yield ns
49+
def model_registry_namespace(updated_dsc_component_state_scope_class: DataScienceCluster) -> str:
50+
return updated_dsc_component_state_scope_class.instance.spec.components.modelregistry.registriesNamespace
6151

6252

6353
@pytest.fixture(scope="class")
6454
def model_registry_db_service(
65-
admin_client: DynamicClient, model_registry_namespace: Namespace
55+
admin_client: DynamicClient, model_registry_namespace: str
6656
) -> Generator[Service, Any, Any]:
6757
with Service(
6858
client=admin_client,
6959
name=DB_RESOURCES_NAME,
70-
namespace=model_registry_namespace.name,
60+
namespace=model_registry_namespace,
7161
ports=[
7262
{
7363
"name": "mysql",
@@ -81,7 +71,7 @@ def model_registry_db_service(
8171
selector={
8272
"name": DB_RESOURCES_NAME,
8373
},
84-
label=DEFAULT_LABEL_DICT_DB,
74+
label=get_model_registry_db_label_dict(db_resource_name=DB_RESOURCES_NAME),
8575
annotations={
8676
"template.openshift.io/expose-uri": r"mysql://{.spec.clusterIP}:{.spec.ports[?(.name==\mysql\)].port}",
8777
},
@@ -91,163 +81,57 @@ def model_registry_db_service(
9181

9282
@pytest.fixture(scope="class")
9383
def model_registry_db_pvc(
94-
admin_client: DynamicClient,
95-
model_registry_namespace: Namespace,
84+
admin_client: DynamicClient, model_registry_namespace: str
9685
) -> Generator[PersistentVolumeClaim, Any, Any]:
9786
with PersistentVolumeClaim(
9887
accessmodes="ReadWriteOnce",
9988
name=DB_RESOURCES_NAME,
100-
namespace=model_registry_namespace.name,
89+
namespace=model_registry_namespace,
10190
client=admin_client,
10291
size="5Gi",
103-
label=DEFAULT_LABEL_DICT_DB,
92+
label=get_model_registry_db_label_dict(db_resource_name=DB_RESOURCES_NAME),
10493
) as pvc:
10594
yield pvc
10695

10796

10897
@pytest.fixture(scope="class")
10998
def model_registry_db_secret(
11099
admin_client: DynamicClient,
111-
model_registry_namespace: Namespace,
100+
model_registry_namespace: str,
112101
) -> Generator[Secret, Any, Any]:
113102
with Secret(
114103
client=admin_client,
115104
name=DB_RESOURCES_NAME,
116-
namespace=model_registry_namespace.name,
117-
string_data={
118-
"database-name": "model_registry",
119-
"database-password": "TheBlurstOfTimes", # pragma: allowlist secret
120-
"database-user": "mlmduser", # pragma: allowlist secret
121-
},
122-
label=DEFAULT_LABEL_DICT_DB,
123-
annotations={
124-
"template.openshift.io/expose-database_name": "'{.data[''database-name'']}'",
125-
"template.openshift.io/expose-password": "'{.data[''database-password'']}'",
126-
"template.openshift.io/expose-username": "'{.data[''database-user'']}'",
127-
},
105+
namespace=model_registry_namespace,
106+
string_data=MODEL_REGISTRY_DB_SECRET_STR_DATA,
107+
label=get_model_registry_db_label_dict(db_resource_name=DB_RESOURCES_NAME),
108+
annotations=MODEL_REGISTRY_DB_SECRET_ANNOTATIONS,
128109
) as mr_db_secret:
129110
yield mr_db_secret
130111

131112

132113
@pytest.fixture(scope="class")
133114
def model_registry_db_deployment(
134115
admin_client: DynamicClient,
135-
model_registry_namespace: Namespace,
116+
model_registry_namespace: str,
136117
model_registry_db_secret: Secret,
137118
model_registry_db_pvc: PersistentVolumeClaim,
138119
model_registry_db_service: Service,
139120
) -> Generator[Deployment, Any, Any]:
140121
with Deployment(
141122
name=DB_RESOURCES_NAME,
142-
namespace=model_registry_namespace.name,
123+
namespace=model_registry_namespace,
143124
annotations={
144125
"template.alpha.openshift.io/wait-for-ready": "true",
145126
},
146-
label=DEFAULT_LABEL_DICT_DB,
127+
label=get_model_registry_db_label_dict(db_resource_name=DB_RESOURCES_NAME),
147128
replicas=1,
148129
revision_history_limit=0,
149130
selector={"matchLabels": {"name": DB_RESOURCES_NAME}},
150131
strategy={"type": "Recreate"},
151-
template={
152-
"metadata": {
153-
"labels": {
154-
"name": DB_RESOURCES_NAME,
155-
"sidecar.istio.io/inject": "false",
156-
}
157-
},
158-
"spec": {
159-
"containers": [
160-
{
161-
"env": [
162-
{
163-
"name": "MYSQL_USER",
164-
"valueFrom": {
165-
"secretKeyRef": {
166-
"key": "database-user",
167-
"name": f"{model_registry_db_secret.name}",
168-
}
169-
},
170-
},
171-
{
172-
"name": "MYSQL_PASSWORD",
173-
"valueFrom": {
174-
"secretKeyRef": {
175-
"key": "database-password",
176-
"name": f"{model_registry_db_secret.name}",
177-
}
178-
},
179-
},
180-
{
181-
"name": "MYSQL_ROOT_PASSWORD",
182-
"valueFrom": {
183-
"secretKeyRef": {
184-
"key": "database-password",
185-
"name": f"{model_registry_db_secret.name}",
186-
}
187-
},
188-
},
189-
{
190-
"name": "MYSQL_DATABASE",
191-
"valueFrom": {
192-
"secretKeyRef": {
193-
"key": "database-name",
194-
"name": f"{model_registry_db_secret.name}",
195-
}
196-
},
197-
},
198-
],
199-
"args": [
200-
"--datadir",
201-
"/var/lib/mysql/datadir",
202-
"--default-authentication-plugin=mysql_native_password",
203-
],
204-
"image": MR_DB_IMAGE_DIGEST,
205-
"imagePullPolicy": "IfNotPresent",
206-
"livenessProbe": {
207-
"exec": {
208-
"command": [
209-
"/bin/bash",
210-
"-c",
211-
"mysqladmin -u${MYSQL_USER} -p${MYSQL_ROOT_PASSWORD} ping",
212-
]
213-
},
214-
"initialDelaySeconds": 15,
215-
"periodSeconds": 10,
216-
"timeoutSeconds": 5,
217-
},
218-
"name": "mysql",
219-
"ports": [{"containerPort": 3306, "protocol": "TCP"}],
220-
"readinessProbe": {
221-
"exec": {
222-
"command": [
223-
"/bin/bash",
224-
"-c",
225-
'mysql -D ${MYSQL_DATABASE} -u${MYSQL_USER} -p${MYSQL_ROOT_PASSWORD} -e "SELECT 1"',
226-
]
227-
},
228-
"initialDelaySeconds": 10,
229-
"timeoutSeconds": 5,
230-
},
231-
"securityContext": {"capabilities": {}, "privileged": False},
232-
"terminationMessagePath": "/dev/termination-log",
233-
"volumeMounts": [
234-
{
235-
"mountPath": "/var/lib/mysql",
236-
"name": f"{DB_RESOURCES_NAME}-data",
237-
}
238-
],
239-
}
240-
],
241-
"dnsPolicy": "ClusterFirst",
242-
"restartPolicy": "Always",
243-
"volumes": [
244-
{
245-
"name": f"{DB_RESOURCES_NAME}-data",
246-
"persistentVolumeClaim": {"claimName": DB_RESOURCES_NAME},
247-
}
248-
],
249-
},
250-
},
132+
template=get_model_registry_deployment_template_dict(
133+
secret_name=model_registry_db_secret.name, resource_name=DB_RESOURCES_NAME
134+
),
251135
wait_for_resource=True,
252136
) as mr_db_deployment:
253137
mr_db_deployment.wait_for_replicas(deployed=True)
@@ -257,14 +141,14 @@ def model_registry_db_deployment(
257141
@pytest.fixture(scope="class")
258142
def model_registry_instance(
259143
admin_client: DynamicClient,
260-
model_registry_namespace: Namespace,
144+
model_registry_namespace: str,
261145
model_registry_db_deployment: Deployment,
262146
model_registry_db_secret: Secret,
263147
model_registry_db_service: Service,
264148
) -> Generator[ModelRegistry, Any, Any]:
265149
with ModelRegistry(
266150
name=MR_INSTANCE_NAME,
267-
namespace=model_registry_namespace.name,
151+
namespace=model_registry_namespace,
268152
label={
269153
Annotations.KubernetesIo.NAME: MR_INSTANCE_NAME,
270154
Annotations.KubernetesIo.INSTANCE: MR_INSTANCE_NAME,
@@ -291,11 +175,11 @@ def model_registry_instance(
291175
@pytest.fixture(scope="class")
292176
def model_registry_instance_service(
293177
admin_client: DynamicClient,
294-
model_registry_namespace: Namespace,
178+
model_registry_namespace: str,
295179
model_registry_instance: ModelRegistry,
296180
) -> Service:
297181
return get_mr_service_by_label(
298-
client=admin_client, ns=model_registry_namespace, mr_instance=model_registry_instance
182+
client=admin_client, ns=Namespace(name=model_registry_namespace), mr_instance=model_registry_instance
299183
)
300184

301185

@@ -341,13 +225,17 @@ def after_call(self, response: Response, case: Case) -> None:
341225
@pytest.fixture(scope="class")
342226
def updated_dsc_component_state_scope_class(
343227
request: FixtureRequest,
344-
model_registry_namespace: Namespace,
345228
dsc_resource: DataScienceCluster,
346229
) -> Generator[DataScienceCluster, Any, Any]:
347230
original_components = dsc_resource.instance.spec.components
348231
with ResourceEditor(patches={dsc_resource: {"spec": {"components": request.param["component_patch"]}}}):
349232
for component_name in request.param["component_patch"]:
350233
dsc_resource.wait_for_condition(condition=DscComponents.COMPONENT_MAPPING[component_name], status="True")
234+
if request.param["component_patch"].get(DscComponents.MODELREGISTRY):
235+
namespace = Namespace(
236+
name=dsc_resource.instance.spec.components.modelregistry.registriesNamespace, ensure_exists=True
237+
)
238+
namespace.wait_for_status(status=Namespace.Status.ACTIVE)
351239
yield dsc_resource
352240

353241
for component_name, value in request.param["component_patch"].items():

tests/model_registry/constants.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from typing import Any
2-
2+
from ocp_resources.resource import Resource
33
from utilities.constants import ModelFormat
44

55

@@ -35,3 +35,13 @@ class ModelRegistryEndpoints:
3535
MR_DB_IMAGE_DIGEST: str = (
3636
"public.ecr.aws/docker/library/mysql@sha256:9de9d54fecee6253130e65154b930978b1fcc336bcc86dfd06e89b72a2588ebe"
3737
)
38+
MODEL_REGISTRY_DB_SECRET_STR_DATA = {
39+
"database-name": "model_registry",
40+
"database-password": "TheBlurstOfTimes", # pragma: allowlist secret
41+
"database-user": "mlmduser", # pragma: allowlist secret
42+
}
43+
MODEL_REGISTRY_DB_SECRET_ANNOTATIONS = {
44+
f"{Resource.ApiGroup.TEMPLATE_OPENSHIFT_IO}/expose-database_name": "'{.data[''database-name'']}'",
45+
f"{Resource.ApiGroup.TEMPLATE_OPENSHIFT_IO}/expose-password": "'{.data[''database-password'']}'",
46+
f"{Resource.ApiGroup.TEMPLATE_OPENSHIFT_IO}/expose-username": "'{.data[''database-user'']}'",
47+
}

tests/model_registry/negative_tests/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)