Skip to content

Commit cb2738d

Browse files
authored
Merge branch 'main' into multi_ns
2 parents 0b53f4d + e91a879 commit cb2738d

68 files changed

Lines changed: 7955 additions & 1213 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ repos:
3333
rev: v1.5.0
3434
hooks:
3535
- id: detect-secrets
36-
exclude: .*/__snapshots__/.*
36+
exclude: .*/__snapshots__/.*|.*-input\.json$
3737

3838
- repo: https://github.com/astral-sh/ruff-pre-commit
3939
rev: v0.12.3

conftest.py

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import datetime
66
import traceback
77

8+
import pytest
89
import shortuuid
910
from _pytest.runner import CallInfo
1011
from _pytest.reports import TestReport
@@ -35,7 +36,7 @@
3536
from kubernetes.dynamic import DynamicClient
3637
from utilities.infra import get_operator_distribution, get_dsci_applications_namespace, get_data_science_cluster
3738
from ocp_resources.resource import get_client
38-
39+
from ocp_resources.cluster_service_version import ClusterServiceVersion
3940

4041
LOGGER = logging.getLogger(name=__name__)
4142
BASIC_LOGGER = logging.getLogger(name="basic")
@@ -48,6 +49,9 @@ def pytest_addoption(parser: Parser) -> None:
4849
upgrade_group = parser.getgroup(name="Upgrade options")
4950
must_gather_group = parser.getgroup(name="MustGather")
5051
cluster_sanity_group = parser.getgroup(name="ClusterSanity")
52+
ociregistry_group = parser.getgroup(name="OCI Registry")
53+
serving_arguments_group = parser.getgroup(name="Serving arguments")
54+
model_validation_automation_group = parser.getgroup(name="Model Validation Automation")
5155
hf_group = parser.getgroup(name="Hugging Face")
5256

5357
# AWS config and credentials options
@@ -118,6 +122,32 @@ def pytest_addoption(parser: Parser) -> None:
118122
help="Specify the runtime image to use for the tests",
119123
)
120124

125+
# OCI Registry options
126+
ociregistry_group.addoption(
127+
"--registry-pull-secret",
128+
default=os.environ.get("OCI_REGISTRY_PULL_SECRET"),
129+
help="Registry pull secret to pull oci container images",
130+
)
131+
ociregistry_group.addoption(
132+
"--registry-host",
133+
default=os.environ.get("REGISTRY_HOST"),
134+
help="Registry host to pull oci container images",
135+
)
136+
137+
# Serving arguments options
138+
serving_arguments_group.addoption(
139+
"--serving-argument",
140+
default=os.environ.get("SERVING_ARGUMENTS"),
141+
help="Serving arguments to use for the tests",
142+
)
143+
144+
# Model Validation Automation options
145+
model_validation_automation_group.addoption(
146+
"--model_car_yaml_path",
147+
default=os.environ.get("MODEL_YAML_PATH"),
148+
help="Path to the modelcar yaml file",
149+
)
150+
121151
# Upgrade options
122152
upgrade_group.addoption(
123153
"--pre-upgrade",
@@ -412,3 +442,37 @@ def pytest_exception_interact(node: Item | Collector, call: CallInfo[Any], repor
412442

413443
except Exception as current_exception:
414444
LOGGER.warning(f"Failed to collect logs: {test_name}: {current_exception} {traceback.format_exc()}")
445+
446+
447+
@pytest.fixture(scope="package")
448+
def fail_if_missing_dependent_operators(admin_client: DynamicClient) -> None:
449+
if dependent_operators := py_config.get("dependent_operators"):
450+
missing_operators: list[str] = []
451+
452+
for operator_name in dependent_operators.split(","):
453+
csvs = list(
454+
ClusterServiceVersion.get(
455+
dyn_client=admin_client,
456+
namespace=py_config["applications_namespace"],
457+
)
458+
)
459+
460+
LOGGER.info(f"Verifying if {operator_name} is installed")
461+
for csv in csvs:
462+
if csv.name.startswith(operator_name):
463+
if csv.status == csv.Status.SUCCEEDED:
464+
break
465+
466+
else:
467+
missing_operators.append(
468+
f"Operator {operator_name} is installed but CSV is not in {csv.Status.SUCCEEDED} state"
469+
)
470+
471+
else:
472+
missing_operators.append(f"{operator_name} is not installed")
473+
474+
if missing_operators:
475+
pytest.fail(str(missing_operators))
476+
477+
else:
478+
LOGGER.info("No dependent operators to verify")

tests/conftest.py

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from ocp_resources.resource import get_client
3232
from pytest_testconfig import config as py_config
3333
from simple_logger.logger import get_logger
34+
import json
3435

3536
from ocp_utilities.operators import uninstall_operator, install_operator
3637
from utilities.certificates_utils import create_ca_bundle_file
@@ -110,7 +111,7 @@ def model_namespace(
110111
ns.clean_up()
111112
else:
112113
with create_ns(
113-
client=admin_client,
114+
admin_client=admin_client,
114115
pytest_request=request,
115116
teardown=teardown_resources,
116117
) as ns:
@@ -139,6 +140,28 @@ def aws_secret_access_key(pytestconfig: Config) -> str:
139140
return secret_access_key
140141

141142

143+
@pytest.fixture(scope="session")
144+
def registry_pull_secret(pytestconfig: Config) -> str:
145+
registry_pull_secret = pytestconfig.option.registry_pull_secret
146+
if not registry_pull_secret:
147+
raise ValueError(
148+
"Registry pull secret is not set. "
149+
"Either pass with `--registry_pull_secret` or set `OCI_REGISTRY_PULL_SECRET` environment variable"
150+
)
151+
return registry_pull_secret
152+
153+
154+
@pytest.fixture(scope="session")
155+
def registry_host(pytestconfig: pytest.Config) -> str | None:
156+
registry_host = pytestconfig.option.registry_host
157+
if not registry_host:
158+
raise ValueError(
159+
"Registry host for OCI images is not set. "
160+
"Either pass with `--registry_host` or set `REGISTRY_HOST` environment variable"
161+
)
162+
return registry_host
163+
164+
142165
@pytest.fixture(scope="session")
143166
def valid_aws_config(aws_access_key_id: str, aws_secret_access_key: str) -> tuple[str, str]:
144167
return aws_access_key_id, aws_secret_access_key
@@ -177,6 +200,40 @@ def ci_s3_bucket_endpoint(pytestconfig: pytest.Config) -> str:
177200
return ci_bucket_endpoint
178201

179202

203+
@pytest.fixture(scope="session")
204+
def serving_argument(pytestconfig: pytest.Config, modelcar_yaml_config: dict[str, Any] | None) -> list[str]:
205+
if modelcar_yaml_config:
206+
arg = modelcar_yaml_config.get("serving_argument", [])
207+
return arg if isinstance(arg, list) else [arg]
208+
209+
raw_arg = pytestconfig.option.serving_argument
210+
try:
211+
return json.loads(raw_arg)
212+
except json.JSONDecodeError:
213+
raise ValueError(
214+
"Serving arguments should be a valid JSON list. "
215+
"Either pass with `--serving-argument` or set it correctly in modelcar.yaml"
216+
)
217+
218+
219+
@pytest.fixture(scope="session")
220+
def modelcar_yaml_config(pytestconfig: pytest.Config) -> dict[str, Any] | None:
221+
"""
222+
Fixture to get the path to the modelcar.yaml file.
223+
"""
224+
config_path = pytestconfig.option.model_car_yaml_path
225+
if not config_path:
226+
return None
227+
with open(config_path, "r") as file:
228+
try:
229+
modelcar_yaml = yaml.safe_load(file)
230+
if not isinstance(modelcar_yaml, dict):
231+
raise ValueError("modelcar.yaml should contain a dictionary.")
232+
return modelcar_yaml
233+
except yaml.YAMLError as e:
234+
raise ValueError(f"Error parsing modelcar.yaml: {e}") from e
235+
236+
180237
@pytest.fixture(scope="session")
181238
def models_s3_bucket_name(pytestconfig: pytest.Config) -> str:
182239
models_bucket = pytestconfig.option.models_s3_bucket_name
@@ -407,12 +464,12 @@ def cluster_monitoring_config(
407464

408465
@pytest.fixture(scope="class")
409466
def unprivileged_model_namespace(
410-
request: FixtureRequest, unprivileged_client: DynamicClient
467+
request: FixtureRequest, admin_client: DynamicClient, unprivileged_client: DynamicClient
411468
) -> Generator[Namespace, Any, Any]:
412469
if request.param.get("modelmesh-enabled"):
413470
request.getfixturevalue(argname="enabled_modelmesh_in_dsc")
414471

415-
with create_ns(unprivileged_client=unprivileged_client, pytest_request=request) as ns:
472+
with create_ns(admin_client=admin_client, unprivileged_client=unprivileged_client, pytest_request=request) as ns:
416473
yield ns
417474

418475

@@ -421,7 +478,7 @@ def unprivileged_model_namespace(
421478
def minio_namespace(admin_client: DynamicClient) -> Generator[Namespace, Any, Any]:
422479
with create_ns(
423480
name=f"{MinIo.Metadata.NAME}-{shortuuid.uuid().lower()}",
424-
client=admin_client,
481+
admin_client=admin_client,
425482
) as ns:
426483
yield ns
427484

tests/model_explainability/trustyai_service/service/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
RmcvTXlNWW9CZUNrUVRWdS9rUkIwK2N2Qy9RMDB4NExvVGpJaQpGdCtKMGc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0t\
3131
LS0t" # pragma: allowlist secret
3232

33+
3334
@pytest.fixture(scope="class")
3435
def trustyai_service_with_invalid_db_cert(
3536
admin_client: DynamicClient,

0 commit comments

Comments
 (0)