Skip to content

Commit cf1f7d8

Browse files
authored
Merge branch 'main' into bug_template
2 parents d15052c + 84eb111 commit cf1f7d8

26 files changed

+318
-70
lines changed

tests/model_explainability/evalhub/test_evalhub_health.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
import pytest
22
from ocp_resources.route import Route
33

4-
from tests.model_explainability.evalhub.utils import validate_evalhub_health
4+
from tests.model_explainability.evalhub.utils import validate_evalhub_health, validate_evalhub_providers
55

66

77
@pytest.mark.parametrize(
88
"model_namespace",
99
[
1010
pytest.param(
11-
{"name": "test-evalhub-health"},
11+
{"name": "test-evalhub-health-providers"},
1212
),
1313
],
1414
indirect=True,
1515
)
1616
@pytest.mark.smoke
1717
@pytest.mark.model_explainability
18-
class TestEvalHubHealth:
19-
"""Tests for basic EvalHub service health and availability."""
18+
class TestEvalHub:
19+
"""Tests for basic EvalHub service health and providers."""
2020

2121
def test_evalhub_health_endpoint(
2222
self,
@@ -30,3 +30,19 @@ def test_evalhub_health_endpoint(
3030
token=current_client_token,
3131
ca_bundle_file=evalhub_ca_bundle_file,
3232
)
33+
34+
def test_evalhub_providers_list(
35+
self,
36+
current_client_token: str,
37+
evalhub_ca_bundle_file: str,
38+
evalhub_route: Route,
39+
model_namespace,
40+
) -> None:
41+
"""Test that the evaluations providers endpoint returns a non-empty list."""
42+
43+
validate_evalhub_providers(
44+
host=evalhub_route.host,
45+
token=current_client_token,
46+
ca_bundle_file=evalhub_ca_bundle_file,
47+
tenant=model_namespace.name,
48+
)

tests/model_explainability/evalhub/utils.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,31 @@
33
from tests.model_explainability.evalhub.constants import (
44
EVALHUB_HEALTH_PATH,
55
EVALHUB_HEALTH_STATUS_HEALTHY,
6+
EVALHUB_PROVIDERS_PATH,
67
)
78
from utilities.guardrails import get_auth_headers
89
from utilities.opendatahub_logger import get_logger
910

1011
LOGGER = get_logger(name=__name__)
1112

13+
TENANT_HEADER: str = "X-Tenant"
14+
15+
16+
def _build_headers(token: str, tenant: str | None = None) -> dict[str, str]:
17+
"""Build request headers with auth and optional tenant.
18+
19+
Args:
20+
token: Bearer token for authentication.
21+
tenant: Namespace for the X-Tenant header. Omitted if None.
22+
23+
Returns:
24+
Headers dict.
25+
"""
26+
headers = get_auth_headers(token=token)
27+
if tenant is not None:
28+
headers[TENANT_HEADER] = tenant
29+
return headers
30+
1231

1332
def validate_evalhub_health(
1433
host: str,
@@ -45,3 +64,26 @@ def validate_evalhub_health(
4564
f"Expected status '{EVALHUB_HEALTH_STATUS_HEALTHY}', got '{data['status']}'"
4665
)
4766
assert "timestamp" in data, "Health response missing 'timestamp' field"
67+
68+
69+
def validate_evalhub_providers(
70+
host: str,
71+
token: str,
72+
ca_bundle_file: str,
73+
tenant: str | None = None,
74+
) -> dict:
75+
"""Smoke test for the EvalHub providers endpoint."""
76+
url = f"https://{host}{EVALHUB_PROVIDERS_PATH}"
77+
78+
response = requests.get(
79+
url=url,
80+
headers=_build_headers(token=token, tenant=tenant),
81+
verify=ca_bundle_file,
82+
timeout=10,
83+
)
84+
response.raise_for_status()
85+
86+
data = response.json()
87+
assert data.get("items"), f"Smoke test failed: Providers list is empty for tenant {tenant}"
88+
89+
return data

tests/model_serving/model_server/kserve/authentication/conftest.py

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,16 @@
2121
ModelName,
2222
Protocols,
2323
RuntimeTemplates,
24+
Timeout,
2425
)
2526
from utilities.inference_utils import create_isvc
2627
from utilities.infra import (
2728
create_inference_token,
2829
create_isvc_view_role,
29-
get_pods_by_isvc_label,
3030
)
31-
from utilities.jira import is_jira_open
3231
from utilities.logger import RedactedString
33-
from utilities.opendatahub_logger import get_logger
3432
from utilities.serving_runtime import ServingRuntimeFromTemplate
3533

36-
LOGGER = get_logger(name=__name__)
37-
3834

3935
# HTTP/REST model serving
4036
@pytest.fixture(scope="class")
@@ -77,15 +73,9 @@ def http_raw_inference_token(model_service_account: ServiceAccount, http_raw_rol
7773

7874
@pytest.fixture()
7975
def patched_remove_raw_authentication_isvc(
80-
admin_client: DynamicClient,
8176
unprivileged_client: DynamicClient,
8277
http_s3_ovms_raw_inference_service: InferenceService,
8378
) -> Generator[InferenceService, Any, Any]:
84-
predictor_pod = get_pods_by_isvc_label(
85-
client=unprivileged_client,
86-
isvc=http_s3_ovms_raw_inference_service,
87-
)[0]
88-
8979
with ResourceEditor(
9080
patches={
9181
http_s3_ovms_raw_inference_service: {
@@ -95,12 +85,20 @@ def patched_remove_raw_authentication_isvc(
9585
}
9686
}
9787
):
98-
if is_jira_open(jira_id="RHOAIENG-52129", admin_client=admin_client):
99-
LOGGER.info("RHOAIENG-52129 is open; waiting for predictor pod rollout after auth toggle")
100-
predictor_pod.wait_deleted()
101-
88+
http_s3_ovms_raw_inference_service.wait_for_condition(
89+
condition=http_s3_ovms_raw_inference_service.Condition.READY,
90+
status=http_s3_ovms_raw_inference_service.Condition.Status.TRUE,
91+
timeout=Timeout.TIMEOUT_2MIN,
92+
)
10293
yield http_s3_ovms_raw_inference_service
10394

95+
# ResourceEditor restores auth on exit; wait for ISVC to reconcile before next test
96+
http_s3_ovms_raw_inference_service.wait_for_condition(
97+
condition=http_s3_ovms_raw_inference_service.Condition.READY,
98+
status=http_s3_ovms_raw_inference_service.Condition.Status.TRUE,
99+
timeout=Timeout.TIMEOUT_2MIN,
100+
)
101+
104102

105103
@pytest.fixture(scope="class")
106104
def model_service_account_2(

tests/model_serving/model_server/kserve/authentication/test_kserve_token_authentication_raw.py

Lines changed: 11 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
import pytest
2-
from ocp_resources.resource import ResourceEditor
32

43
from tests.model_serving.model_server.utils import verify_inference_response
5-
from utilities.constants import Annotations, Protocols
4+
from utilities.constants import Protocols
65
from utilities.inference_utils import Inference
7-
from utilities.infra import check_pod_status_in_time, get_pods_by_isvc_label
8-
from utilities.jira import is_jira_issue_open
96
from utilities.manifests.onnx import ONNX_INFERENCE_CONFIG
107

118
pytestmark = pytest.mark.usefixtures("valid_aws_config")
@@ -24,6 +21,16 @@
2421
indirect=True,
2522
)
2623
class TestKserveTokenAuthenticationRawForRest:
24+
"""Validate KServe raw deployment token-based authentication for REST inference.
25+
26+
Steps:
27+
1. Deploy an OVMS model with authentication enabled in a raw deployment namespace.
28+
2. Query the model with a valid token and verify a successful REST inference response.
29+
3. Disable authentication and verify the model is still queryable without a token.
30+
4. Re-enable authentication and verify the model requires a valid token again.
31+
5. Attempt cross-model authentication using another model's token and verify access is denied.
32+
"""
33+
2734
@pytest.mark.smoke
2835
@pytest.mark.ocp_interop
2936
@pytest.mark.dependency(name="test_model_authentication_using_rest_raw")
@@ -49,40 +56,6 @@ def test_disabled_raw_model_authentication(self, patched_remove_raw_authenticati
4956
use_default_query=True,
5057
)
5158

52-
@pytest.mark.smoke
53-
@pytest.mark.xfail(condition=is_jira_issue_open(jira_id="RHOAIENG-52129"), reason="RHOAIENG-52129", run=False)
54-
def test_raw_disable_enable_authentication_no_pod_rollout(self, http_s3_ovms_raw_inference_service):
55-
"""Verify no pod rollout when disabling and enabling authentication"""
56-
pod = get_pods_by_isvc_label(
57-
client=http_s3_ovms_raw_inference_service.client,
58-
isvc=http_s3_ovms_raw_inference_service,
59-
)[0]
60-
61-
ResourceEditor(
62-
patches={
63-
http_s3_ovms_raw_inference_service: {
64-
"metadata": {
65-
"annotations": {Annotations.KserveAuth.SECURITY: "false"},
66-
}
67-
}
68-
}
69-
).update()
70-
71-
check_pod_status_in_time(pod=pod, status={pod.Status.RUNNING})
72-
73-
ResourceEditor(
74-
patches={
75-
http_s3_ovms_raw_inference_service: {
76-
"metadata": {
77-
"annotations": {Annotations.KserveAuth.SECURITY: "true"},
78-
}
79-
}
80-
}
81-
).update()
82-
83-
check_pod_status_in_time(pod=pod, status={pod.Status.RUNNING})
84-
85-
@pytest.mark.dependency(depends=["test_disabled_raw_model_authentication"])
8659
def test_re_enabled_raw_model_authentication(self, http_s3_ovms_raw_inference_service, http_raw_inference_token):
8760
"""Verify model query after authentication is re-enabled"""
8861
verify_inference_response(

tests/model_serving/model_server/kserve/authentication/test_non_admin_users.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@
2121
@pytest.mark.smoke
2222
@pytest.mark.rawdeployment
2323
class TestRawUnprivilegedUser:
24+
"""Validate that a non-admin user can deploy and query a KServe raw deployment model.
25+
26+
Steps:
27+
1. Create a namespace with unprivileged user credentials.
28+
2. Deploy an OVMS model as a raw deployment using the non-admin user.
29+
3. Query the deployed model via REST and verify a successful inference response.
30+
"""
31+
2432
def test_non_admin_deploy_raw_and_query_model(
2533
self,
2634
unprivileged_s3_ovms_raw_inference_service,

tests/model_serving/model_server/kserve/inference_graph/test_inference_graph_raw.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,22 @@
1919
indirect=True,
2020
)
2121
class TestInferenceGraphRaw:
22+
"""Validate KServe InferenceGraph functionality in raw deployment mode.
23+
24+
Steps:
25+
1. Deploy an OVMS serving runtime with ONNX support in the test namespace.
26+
2. Create inference graphs with various configurations (public, private, auth-enabled).
27+
3. Send inference requests through each graph and verify correct routing and responses.
28+
4. Verify authentication enforcement by testing with privileged and unprivileged tokens.
29+
"""
30+
2231
@pytest.mark.parametrize(
2332
"dog_breed_inference_graph",
2433
[{"name": "dog-breed-raw-pipeline", "deployment-mode": KServeDeploymentType.RAW_DEPLOYMENT}],
2534
indirect=True,
2635
)
2736
def test_inference_graph_raw_deployment(self, dog_breed_inference_graph):
37+
"""Verify inference through a public raw deployment inference graph."""
2838
verify_inference_response(
2939
inference_service=dog_breed_inference_graph,
3040
inference_config=ONNX_INFERENCE_CONFIG,
@@ -46,6 +56,7 @@ def test_inference_graph_raw_deployment(self, dog_breed_inference_graph):
4656
indirect=True,
4757
)
4858
def test_private_inference_graph_raw_deployment(self, dog_breed_inference_graph):
59+
"""Verify inference through a private (no external route) raw deployment inference graph."""
4960
verify_inference_response(
5061
inference_service=dog_breed_inference_graph,
5162
inference_config=ONNX_INFERENCE_CONFIG,
@@ -69,6 +80,7 @@ def test_private_inference_graph_raw_deployment(self, dog_breed_inference_graph)
6980
indirect=True,
7081
)
7182
def test_inference_graph_raw_authentication(self, dog_breed_inference_graph, inference_graph_sa_token_with_access):
83+
"""Verify inference through an auth-enabled inference graph using an authorized service account token."""
7284
verify_inference_response(
7385
inference_service=dog_breed_inference_graph,
7486
inference_config=ONNX_INFERENCE_CONFIG,
@@ -94,6 +106,7 @@ def test_inference_graph_raw_authentication(self, dog_breed_inference_graph, inf
94106
def test_private_inference_graph_raw_authentication(
95107
self, dog_breed_inference_graph, inference_graph_sa_token_with_access
96108
):
109+
"""Verify inference through a private auth-enabled inference graph using an authorized token."""
97110
verify_inference_response(
98111
inference_service=dog_breed_inference_graph,
99112
inference_config=ONNX_INFERENCE_CONFIG,
@@ -119,6 +132,7 @@ def test_private_inference_graph_raw_authentication(
119132
def test_inference_graph_raw_authentication_without_privileges(
120133
self, dog_breed_inference_graph, inference_graph_unprivileged_sa_token
121134
):
135+
"""Verify that an unprivileged token is denied access to an auth-enabled inference graph."""
122136
verify_inference_response(
123137
inference_service=dog_breed_inference_graph,
124138
inference_config=ONNX_INFERENCE_CONFIG,
@@ -145,6 +159,7 @@ def test_inference_graph_raw_authentication_without_privileges(
145159
def test_private_inference_graph_raw_authentication_without_privileges(
146160
self, dog_breed_inference_graph, inference_graph_unprivileged_sa_token
147161
):
162+
"""Verify that an unprivileged token is denied access to a private auth-enabled inference graph."""
148163
verify_inference_response(
149164
inference_service=dog_breed_inference_graph,
150165
inference_config=ONNX_INFERENCE_CONFIG,

tests/model_serving/model_server/kserve/inference_service_lifecycle/test_isvc_env_vars_updates.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@
4343
indirect=True,
4444
)
4545
class TestRawISVCEnvVarsUpdates:
46+
"""Validate adding and removing environment variables on a KServe raw deployment ISVC.
47+
48+
Steps:
49+
1. Deploy an OVMS inference service with custom environment variables.
50+
2. Verify the environment variables are present in the predictor pods.
51+
3. Remove the environment variables from the inference service.
52+
4. Verify the environment variables are no longer present in the predictor pods.
53+
"""
54+
4655
def test_raw_with_isvc_env_vars(self, ovms_kserve_inference_service):
4756
"""Test adding environment variables to the inference service"""
4857
verify_env_vars_in_isvc_pods(isvc=ovms_kserve_inference_service, env_vars=ISVC_ENV_VARS, vars_exist=True)

tests/model_serving/model_server/kserve/inference_service_lifecycle/test_isvc_pull_secret_updates.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@
2424
indirect=True,
2525
)
2626
class TestISVCPullSecretUpdate:
27+
"""Validate pull secret lifecycle operations on a KServe model car inference service.
28+
29+
Steps:
30+
1. Deploy a model car ISVC with an initial pull secret attached.
31+
2. Verify the initial pull secret is correctly set in the predictor pod.
32+
3. Update the pull secret to a new value and verify it is reflected in the new pod.
33+
4. Remove the pull secret and verify it is no longer present in the pod.
34+
"""
35+
2736
@pytest.mark.tier1
2837
def test_initial_pull_secret_set(self, model_car_raw_inference_service_with_pull_secret):
2938
"""Ensure initial pull secret is correctly set in the pod"""
@@ -36,4 +45,5 @@ def test_update_pull_secret(self, updated_isvc_pull_secret):
3645
verify_pull_secret(isvc=updated_isvc_pull_secret, pull_secret=UPDATED_PULL_SECRET, secret_exists=True)
3746

3847
def test_remove_pull_secret(self, updated_isvc_remove_pull_secret):
48+
"""Remove the pull secret and verify it is no longer present in the pod."""
3949
verify_pull_secret(isvc=updated_isvc_remove_pull_secret, pull_secret=UPDATED_PULL_SECRET, secret_exists=False)

tests/model_serving/model_server/kserve/inference_service_lifecycle/test_isvc_replicas_update.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@
3939
indirect=True,
4040
)
4141
class TestRawISVCReplicasUpdates:
42+
"""Validate scaling replica count up and down on a KServe raw deployment ISVC.
43+
44+
Steps:
45+
1. Deploy an OVMS inference service with 2 min-replicas and 4 max-replicas.
46+
2. Verify that 2 predictor pods are running after deployment.
47+
3. Run inference to confirm the model responds correctly with multiple replicas.
48+
4. Patch the ISVC to scale down to 1 replica and verify only 1 pod remains.
49+
5. Run inference again to confirm the model responds correctly after scale-down.
50+
"""
51+
4252
@pytest.mark.dependency(name="test_raw_increase_isvc_replicas")
4353
def test_raw_increase_isvc_replicas(self, isvc_pods, ovms_kserve_inference_service):
4454
"""Test replicas increase"""

0 commit comments

Comments
 (0)