forked from opendatahub-io/opendatahub-tests
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.py
More file actions
114 lines (89 loc) · 4.56 KB
/
utils.py
File metadata and controls
114 lines (89 loc) · 4.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
from typing import Any
import yaml
from kubernetes.dynamic import DynamicClient
from simple_logger.logger import get_logger
from ocp_resources.pod import Pod
from ocp_resources.config_map import ConfigMap
from tests.model_registry.model_catalog.constants import DEFAULT_CATALOGS
LOGGER = get_logger(name=__name__)
def validate_model_catalog_enabled(pod: Pod) -> bool:
for container in pod.instance.spec.containers:
for env in container.env:
if env.name == "ENABLE_MODEL_CATALOG":
return True
return False
def validate_model_catalog_resource(
kind: Any, admin_client: DynamicClient, namespace: str, expected_resource_count: int
) -> None:
resource = list(kind.get(namespace=namespace, label_selector="component=model-catalog", dyn_client=admin_client))
assert resource
LOGGER.info(f"Validating resource: {kind}: Found {len(resource)}")
assert len(resource) == expected_resource_count, (
f"Unexpected number of {kind} resources found: {[res.name for res in resource]}"
)
def validate_default_catalog(catalogs: list[dict[Any, Any]]) -> None:
errors = []
for catalog in catalogs:
expected_catalog = DEFAULT_CATALOGS.get(catalog["id"])
assert expected_catalog, f"Unexpected catalog: {catalog}"
for key, expected_value in expected_catalog.items():
actual_value = catalog.get(key)
if actual_value != expected_value:
errors.append(f"For catalog '{catalog['id']}': expected {key}={expected_value}, but got {actual_value}")
assert not errors, "\n".join(errors)
def get_validate_default_model_catalog_source(catalogs: list[dict[Any, Any]]) -> None:
assert len(catalogs) == 2, f"Expected no custom models to be present. Actual: {catalogs}"
ids_actual = [entry["id"] for entry in catalogs]
assert sorted(ids_actual) == sorted(DEFAULT_CATALOGS.keys()), (
f"Actual default catalog entries: {ids_actual},Expected: {DEFAULT_CATALOGS.keys()}"
)
def extract_schema_fields(openapi_schema: dict[Any, Any], schema_name: str) -> tuple[set[str], set[str]]:
"""
Extract all and required fields from an OpenAPI schema for validation.
Args:
openapi_schema: The parsed OpenAPI schema dictionary
schema_name: Name of the schema to extract (e.g., "CatalogModel", "CatalogModelArtifact")
Returns:
Tuple of (all_fields, required_fields) excluding server-generated fields and timestamps.
"""
def _extract_properties_and_required(schema: dict[Any, Any]) -> tuple[set[str], set[str]]:
"""Recursively extract properties and required fields from a schema."""
props = set(schema.get("properties", {}).keys())
required = set(schema.get("required", []))
# Properties from allOf (inheritance/composition)
if "allOf" in schema:
for item in schema["allOf"]:
sub_schema = item
if "$ref" in item:
# Follow reference and recursively extract
ref_schema_name = item["$ref"].split("/")[-1]
sub_schema = openapi_schema["components"]["schemas"][ref_schema_name]
sub_props, sub_required = _extract_properties_and_required(schema=sub_schema)
props.update(sub_props)
required.update(sub_required)
return props, required
target_schema = openapi_schema["components"]["schemas"][schema_name]
all_properties, required_fields = _extract_properties_and_required(schema=target_schema)
# Exclude fields that shouldn't be compared
excluded_fields = {
"id", # Server-generated
"externalId", # Server-generated
"createTimeSinceEpoch", # Timestamps may differ
"lastUpdateTimeSinceEpoch", # Timestamps may differ
"artifacts", # CatalogModel only
"source_id", # CatalogModel only
}
return all_properties - excluded_fields, required_fields - excluded_fields
def validate_model_catalog_configmap_data(configmap: ConfigMap, num_catalogs: int) -> None:
"""
Validate the model catalog configmap data.
Args:
configmap: The ConfigMap object to validate
num_catalogs: Expected number of catalogs in the configmap
"""
# Check that model catalog configmaps is created when model registry is
# enabled on data science cluster.
catalogs = yaml.safe_load(configmap.instance.data["sources.yaml"])["catalogs"]
assert len(catalogs) == num_catalogs, f"{configmap.name} should have {num_catalogs} catalog"
if num_catalogs:
validate_default_catalog(catalogs=catalogs)