Skip to content

Commit fe62290

Browse files
authored
add separate commandline option for custom namespace tests (#480)
1 parent e33c4ad commit fe62290

16 files changed

+59
-200
lines changed

conftest.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from typing import Optional, Any
2424
from pytest_testconfig import config as py_config
2525

26-
from utilities.constants import KServeDeploymentType
26+
from utilities.constants import KServeDeploymentType, MODEL_REGISTRY_CUSTOM_NAMESPACE
2727
from utilities.database import Database
2828
from utilities.logger import separator, setup_logging
2929
from utilities.must_gather_collector import (
@@ -53,7 +53,7 @@ def pytest_addoption(parser: Parser) -> None:
5353
serving_arguments_group = parser.getgroup(name="Serving arguments")
5454
model_validation_automation_group = parser.getgroup(name="Model Validation Automation")
5555
hf_group = parser.getgroup(name="Hugging Face")
56-
56+
model_registry_group = parser.getgroup(name="Model Registry options")
5757
# AWS config and credentials options
5858
aws_group.addoption(
5959
"--aws-secret-access-key",
@@ -190,6 +190,13 @@ def pytest_addoption(parser: Parser) -> None:
190190

191191
# HuggingFace options
192192
hf_group.addoption("--hf-access-token", default=os.environ.get("HF_ACCESS_TOKEN"), help="HF access token")
193+
# Model Registry options
194+
model_registry_group.addoption(
195+
"--custom-namespace",
196+
default=False,
197+
action="store_true",
198+
help="Indicates if the model registry tests are to be run against custom namespace",
199+
)
193200

194201

195202
def pytest_cmdline_main(config: Any) -> None:
@@ -285,10 +292,10 @@ def pytest_sessionstart(session: Session) -> None:
285292
if config.getoption("--collect-only") or config.getoption("--setup-plan"):
286293
LOGGER.info("Skipping global config update for collect-only or setup-plan")
287294
return
288-
updated_global_config(admin_client=get_client())
295+
updated_global_config(admin_client=get_client(), config=config)
289296

290297

291-
def updated_global_config(admin_client: DynamicClient) -> None:
298+
def updated_global_config(admin_client: DynamicClient, config: Config) -> None:
292299
"""
293300
Updates the global config with the distribution, applications namespace, and model registry namespace.
294301
Args:
@@ -308,9 +315,15 @@ def updated_global_config(admin_client: DynamicClient) -> None:
308315
pytest.exit(f"Unknown distribution: {distribution}")
309316

310317
py_config["applications_namespace"] = get_dsci_applications_namespace(client=admin_client)
311-
py_config["model_registry_namespace"] = get_data_science_cluster(
312-
client=admin_client
313-
).instance.spec.components.modelregistry.registriesNamespace
318+
319+
if config.getoption("--custom-namespace"):
320+
LOGGER.info(f"Running model registry tests against custom namespace: {MODEL_REGISTRY_CUSTOM_NAMESPACE}")
321+
py_config["model_registry_namespace"] = MODEL_REGISTRY_CUSTOM_NAMESPACE
322+
else:
323+
LOGGER.info("Running model registry tests against default namespace")
324+
py_config["model_registry_namespace"] = get_data_science_cluster(
325+
client=admin_client
326+
).instance.spec.components.modelregistry.registriesNamespace
314327

315328

316329
def pytest_fixture_setup(fixturedef: FixtureDef[Any], request: FixtureRequest) -> None:

pytest.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ markers =
3232
multinode: Mark tests which require multiple nodes
3333
keda: Mark tests which are testing KEDA scaling
3434

35+
# Model Registry:
36+
custom_namespace: mark tests that are to be run with custom namespace
37+
3538
addopts =
3639
-s
3740
-p no:logging

tests/model_registry/conftest.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -290,18 +290,21 @@ def updated_dsc_component_state_scope_class(
290290
yield dsc_resource
291291
else:
292292
original_components = dsc_resource.instance.spec.components
293-
component_patch = request.param["component_patch"]
293+
component_patch = {
294+
DscComponents.MODELREGISTRY: {
295+
"managementState": DscComponents.ManagementState.MANAGED,
296+
"registriesNamespace": py_config["model_registry_namespace"],
297+
},
298+
}
299+
LOGGER.info(f"Applying patch {component_patch}")
294300

295301
with ResourceEditor(patches={dsc_resource: {"spec": {"components": component_patch}}}):
296302
for component_name in component_patch:
297303
dsc_resource.wait_for_condition(
298304
condition=DscComponents.COMPONENT_MAPPING[component_name], status="True"
299305
)
300-
if component_patch.get(DscComponents.MODELREGISTRY):
301-
namespace = Namespace(
302-
name=dsc_resource.instance.spec.components.modelregistry.registriesNamespace, ensure_exists=True
303-
)
304-
namespace.wait_for_status(status=Namespace.Status.ACTIVE)
306+
namespace = Namespace(name=py_config["model_registry_namespace"], ensure_exists=True)
307+
namespace.wait_for_status(status=Namespace.Status.ACTIVE)
305308
wait_for_pods_running(
306309
admin_client=admin_client,
307310
namespace_name=py_config["applications_namespace"],
@@ -321,7 +324,7 @@ def updated_dsc_component_state_scope_class(
321324
):
322325
# Since namespace specified in registriesNamespace is automatically created after setting
323326
# managementStateto Managed. We need to explicitly delete it on clean up.
324-
namespace = Namespace(name=value["registriesNamespace"], ensure_exists=True)
327+
namespace = Namespace(name=py_config["model_registry_namespace"], ensure_exists=True)
325328
if namespace:
326329
namespace.delete(wait=True)
327330

tests/model_registry/image_validation/test_verify_rhoai_images.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
from typing import Self, Set
33
from simple_logger.logger import get_logger
44
from kubernetes.dynamic import DynamicClient
5-
from pytest_testconfig import config as py_config
65

7-
from utilities.constants import DscComponents
86
from utilities.general import (
97
validate_container_images,
108
)
@@ -14,20 +12,6 @@
1412
LOGGER = get_logger(name=__name__)
1513

1614

17-
@pytest.mark.parametrize(
18-
"updated_dsc_component_state_scope_class",
19-
[
20-
{
21-
"component_patch": {
22-
DscComponents.MODELREGISTRY: {
23-
"managementState": DscComponents.ManagementState.MANAGED,
24-
"registriesNamespace": py_config["model_registry_namespace"],
25-
}
26-
}
27-
}
28-
],
29-
indirect=True,
30-
)
3115
@pytest.mark.usefixtures(
3216
"updated_dsc_component_state_scope_class",
3317
"is_model_registry_oauth",

tests/model_registry/negative_tests/conftest.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,40 @@
11
import pytest
22
from typing import Generator, Any
3+
4+
from _pytest.config import Config
5+
6+
from ocp_resources.data_science_cluster import DataScienceCluster
37
from ocp_resources.secret import Secret
48
from ocp_resources.namespace import Namespace
59
from ocp_resources.service import Service
610
from ocp_resources.persistent_volume_claim import PersistentVolumeClaim
711
from ocp_resources.deployment import Deployment
812

9-
from pytest import FixtureRequest
1013
from kubernetes.dynamic import DynamicClient
1114

1215

1316
from tests.model_registry.constants import (
1417
MODEL_REGISTRY_DB_SECRET_STR_DATA,
1518
MODEL_REGISTRY_DB_SECRET_ANNOTATIONS,
1619
)
17-
from tests.model_registry.negative_tests.constants import CUSTOM_NEGATIVE_NS
1820
from tests.model_registry.utils import get_model_registry_deployment_template_dict, get_model_registry_db_label_dict
21+
from utilities.constants import MODEL_REGISTRY_CUSTOM_NAMESPACE
1922
from utilities.infra import create_ns
2023

2124
DB_RESOURCES_NAME_NEGATIVE = "db-model-registry-negative"
2225

2326

2427
@pytest.fixture(scope="class")
2528
def model_registry_namespace_for_negative_tests(
26-
request: FixtureRequest, admin_client: DynamicClient
29+
dsc_resource: DataScienceCluster,
30+
admin_client: DynamicClient,
31+
pytestconfig: Config,
2732
) -> Generator[Namespace, Any, Any]:
33+
namespace_name = MODEL_REGISTRY_CUSTOM_NAMESPACE
34+
if pytestconfig.option.custom_namespace:
35+
namespace_name = "rhoai-model-registries"
2836
with create_ns(
29-
name=request.param.get("namespace_name", CUSTOM_NEGATIVE_NS),
37+
name=namespace_name,
3038
admin_client=admin_client,
3139
) as ns:
3240
yield ns

tests/model_registry/negative_tests/constants.py

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/model_registry/negative_tests/test_db_migration.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
from pytest_testconfig import config as py_config
55

66
from ocp_resources.pod import Pod
7-
from utilities.constants import DscComponents
87
from tests.model_registry.constants import MR_INSTANCE_NAME
98
from kubernetes.dynamic.client import DynamicClient
109
from utilities.general import wait_for_container_status
@@ -13,20 +12,6 @@
1312
LOGGER = get_logger(name=__name__)
1413

1514

16-
@pytest.mark.parametrize(
17-
"updated_dsc_component_state_scope_class",
18-
[
19-
pytest.param({
20-
"component_patch": {
21-
DscComponents.MODELREGISTRY: {
22-
"managementState": DscComponents.ManagementState.MANAGED,
23-
"registriesNamespace": py_config["model_registry_namespace"],
24-
},
25-
}
26-
}),
27-
],
28-
indirect=True,
29-
)
3015
@pytest.mark.usefixtures(
3116
"updated_dsc_component_state_scope_class", "model_registry_mysql_metadata_db", "model_registry_instance_mysql"
3217
)

tests/model_registry/negative_tests/test_model_registry_creation_negative.py

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
from pytest_testconfig import config as py_config
88
from ocp_resources.namespace import Namespace
99
from ocp_resources.secret import Secret
10-
from tests.model_registry.negative_tests.constants import CUSTOM_NEGATIVE_NS
11-
from utilities.constants import DscComponents, Annotations
10+
from utilities.constants import Annotations
1211
from tests.model_registry.constants import (
1312
MR_OPERATOR_NAME,
1413
MR_INSTANCE_NAME,
@@ -21,42 +20,13 @@
2120
LOGGER = get_logger(name=__name__)
2221

2322

24-
@pytest.mark.parametrize(
25-
"model_registry_namespace_for_negative_tests, updated_dsc_component_state_scope_class, expected_namespace",
26-
[
27-
pytest.param(
28-
{"namespace_name": CUSTOM_NEGATIVE_NS},
29-
{
30-
"component_patch": {
31-
DscComponents.MODELREGISTRY: {
32-
"managementState": DscComponents.ManagementState.MANAGED,
33-
"registriesNamespace": py_config["model_registry_namespace"],
34-
},
35-
}
36-
},
37-
py_config["model_registry_namespace"],
38-
),
39-
pytest.param(
40-
{"namespace_name": py_config["model_registry_namespace"]},
41-
{
42-
"component_patch": {
43-
DscComponents.MODELREGISTRY: {
44-
"managementState": DscComponents.ManagementState.MANAGED,
45-
"registriesNamespace": CUSTOM_NEGATIVE_NS,
46-
},
47-
},
48-
},
49-
CUSTOM_NEGATIVE_NS,
50-
),
51-
],
52-
indirect=["model_registry_namespace_for_negative_tests", "updated_dsc_component_state_scope_class"],
53-
)
5423
@pytest.mark.usefixtures(
5524
"model_registry_namespace_for_negative_tests",
5625
"updated_dsc_component_state_scope_class",
5726
"model_registry_db_secret_negative_test",
5827
"model_registry_db_deployment_negative_test",
5928
)
29+
@pytest.mark.custom_namespace
6030
class TestModelRegistryCreationNegative:
6131
def test_registering_model_negative(
6232
self: Self,
@@ -65,7 +35,6 @@ def test_registering_model_negative(
6535
updated_dsc_component_state_scope_class: DataScienceCluster,
6636
model_registry_db_secret_negative_test: Secret,
6737
model_registry_db_deployment_negative_test: Deployment,
68-
expected_namespace: str,
6938
):
7039
my_sql_dict: dict[str, str] = {
7140
"host": f"{model_registry_db_deployment_negative_test.name}."
@@ -78,7 +47,7 @@ def test_registering_model_negative(
7847
}
7948
with pytest.raises(
8049
ForbiddenError, # UnprocessibleEntityError
81-
match=f"namespace must be {expected_namespace}",
50+
match=f"namespace must be {py_config['model_registry_namespace']}",
8251
):
8352
with ModelRegistry(
8453
name=MR_INSTANCE_NAME,

tests/model_registry/python_client/test_model_registry_creation.py

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import pytest
22
from typing import Self, Any
33
from simple_logger.logger import get_logger
4-
from pytest_testconfig import config as py_config
54

65
# ocp_resources imports
76
from ocp_resources.pod import Pod
@@ -11,7 +10,6 @@
1110
validate_no_grpc_container,
1211
validate_mlmd_removal_in_model_registry_pod_log,
1312
)
14-
from utilities.constants import DscComponents
1513
from tests.model_registry.constants import MODEL_NAME, MODEL_DICT
1614
from model_registry import ModelRegistry as ModelRegistryClient
1715
from model_registry.types import RegisteredModel
@@ -23,28 +21,9 @@
2321

2422

2523
@pytest.mark.parametrize(
26-
"updated_dsc_component_state_scope_class, registered_model",
24+
"registered_model",
2725
[
2826
pytest.param(
29-
{
30-
"component_patch": {
31-
DscComponents.MODELREGISTRY: {
32-
"managementState": DscComponents.ManagementState.MANAGED,
33-
"registriesNamespace": CUSTOM_NAMESPACE,
34-
},
35-
}
36-
},
37-
MODEL_DICT,
38-
),
39-
pytest.param(
40-
{
41-
"component_patch": {
42-
DscComponents.MODELREGISTRY: {
43-
"managementState": DscComponents.ManagementState.MANAGED,
44-
"registriesNamespace": py_config["model_registry_namespace"],
45-
},
46-
},
47-
},
4827
MODEL_DICT,
4928
),
5029
],
@@ -56,6 +35,7 @@
5635
"model_registry_instance_mysql",
5736
"registered_model",
5837
)
38+
@pytest.mark.custom_namespace
5939
class TestModelRegistryCreation:
6040
"""
6141
Tests the creation of a model registry. If the component is set to 'Removed' it will be switched to 'Managed'

tests/model_registry/rbac/test_mr_rbac.py

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
"""
1010

1111
import pytest
12-
from pytest_testconfig import config as py_config
1312
from typing import Self, Generator, List
1413
from simple_logger.logger import get_logger
1514

@@ -25,7 +24,6 @@
2524
from ocp_resources.deployment import Deployment
2625
from tests.model_registry.rbac.utils import build_mr_client_args, assert_positive_mr_registry, assert_forbidden_access
2726
from utilities.infra import get_openshift_token
28-
from utilities.constants import DscComponents
2927
from mr_openapi.exceptions import ForbiddenException
3028
from utilities.user_utils import UserTestSession
3129
from kubernetes.dynamic import DynamicClient
@@ -36,26 +34,13 @@
3634
pytestmark = [pytest.mark.usefixtures("original_user", "test_idp_user")]
3735

3836

39-
@pytest.mark.parametrize(
40-
"updated_dsc_component_state_scope_class",
41-
[
42-
pytest.param({
43-
"component_patch": {
44-
DscComponents.MODELREGISTRY: {
45-
"managementState": DscComponents.ManagementState.MANAGED,
46-
"registriesNamespace": py_config["model_registry_namespace"],
47-
},
48-
}
49-
}),
50-
],
51-
indirect=True,
52-
)
5337
@pytest.mark.usefixtures(
5438
"updated_dsc_component_state_scope_class",
5539
"is_model_registry_oauth",
5640
"model_registry_mysql_metadata_db",
5741
"model_registry_instance_mysql",
5842
)
43+
@pytest.mark.custom_namespace
5944
class TestUserPermission:
6045
@pytest.mark.sanity
6146
def test_user_permission_non_admin_user(

0 commit comments

Comments
 (0)