Skip to content

Commit 7927545

Browse files
rnetserdbasunag
authored andcommitted
feat: add upgrade tests (opendatahub-io#258)
1 parent e8694e0 commit 7927545

File tree

3 files changed

+179
-10
lines changed

3 files changed

+179
-10
lines changed

tests/model_serving/model_server/upgrade/test_upgrade.py

Lines changed: 109 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import pytest
22

3+
from tests.model_serving.model_server.upgrade.utils import (
4+
verify_inference_generation,
5+
verify_pod_containers_not_restarted,
6+
verify_serving_runtime_generation,
7+
)
38
from tests.model_serving.model_server.utils import verify_inference_response
49
from utilities.constants import ModelName, Protocols
510
from utilities.inference_utils import Inference
@@ -8,7 +13,11 @@
813
from utilities.manifests.openvino import OPENVINO_INFERENCE_CONFIG
914

1015

11-
# TODO: add auth, external route and grpc tests
16+
TEST_SERVERLESS_ONNX_POST_UPGRADE_INFERENCE_SERVICE_EXISTS: str = (
17+
"test_serverless_onnx_post_upgrade_inference_service_exists"
18+
)
19+
TEST_RAW_CAIKIT_BGE_POST_UPGRADE_INFERENCE_EXISTS: str = "test_raw_caikit_bge_post_upgrade_inference_exists"
20+
TEST_MODEL_MESH_OPENVINO_POST_UPGRADE_INFERENCE_EXISTS: str = "test_model_mesh_openvino_post_upgrade_inference_exists"
1221

1322

1423
@pytest.mark.usefixtures("valid_aws_config")
@@ -53,7 +62,9 @@ def test_model_mesh_openvino_pre_upgrade_inference(self, openvino_model_mesh_inf
5362
@pytest.mark.pre_upgrade
5463
@pytest.mark.serverless
5564
def test_serverless_authenticated_onnx_pre_upgrade_inference(
56-
self, ovms_authenticated_serverless_inference_service_scope_session, http_inference_token_scope_session
65+
self,
66+
ovms_authenticated_serverless_inference_service_scope_session,
67+
http_inference_token_scope_session,
5768
):
5869
"""Verify that kserve Serverless with auth ONNX model can be queried using REST before upgrade"""
5970
verify_inference_response(
@@ -69,7 +80,7 @@ def test_serverless_authenticated_onnx_pre_upgrade_inference(
6980
class TestPostUpgradeModelServer:
7081
@pytest.mark.post_upgrade
7182
@pytest.mark.serverless
72-
@pytest.mark.dependency(name="test_serverless_onnx_post_upgrade_inference_service_exists")
83+
@pytest.mark.dependency(name=TEST_SERVERLESS_ONNX_POST_UPGRADE_INFERENCE_SERVICE_EXISTS)
7384
def test_serverless_onnx_post_upgrade_inference_service_exists(
7485
self, ovms_serverless_inference_service_scope_session
7586
):
@@ -78,7 +89,23 @@ def test_serverless_onnx_post_upgrade_inference_service_exists(
7889

7990
@pytest.mark.post_upgrade
8091
@pytest.mark.serverless
81-
@pytest.mark.dependency(depends=["test_serverless_onnx_post_upgrade_inference_service_exists"])
92+
@pytest.mark.dependency(depends=[TEST_SERVERLESS_ONNX_POST_UPGRADE_INFERENCE_SERVICE_EXISTS])
93+
def test_serverless_onnx_post_upgrade_inference_service_not_modified(
94+
self, ovms_serverless_inference_service_scope_session
95+
):
96+
"""Test that the serverless inference service is not modified in upgrade"""
97+
verify_inference_generation(isvc=ovms_serverless_inference_service_scope_session, expected_generation=1)
98+
99+
@pytest.mark.post_upgrade
100+
@pytest.mark.serverless
101+
@pytest.mark.dependency(depends=[TEST_SERVERLESS_ONNX_POST_UPGRADE_INFERENCE_SERVICE_EXISTS])
102+
def test_serverless_onnx_post_upgrade_runtime_not_modified(self, ovms_serverless_inference_service_scope_session):
103+
"""Test that the serverless runtime is not modified in upgrade"""
104+
verify_serving_runtime_generation(isvc=ovms_serverless_inference_service_scope_session, expected_generation=1)
105+
106+
@pytest.mark.post_upgrade
107+
@pytest.mark.serverless
108+
@pytest.mark.dependency(depends=[TEST_SERVERLESS_ONNX_POST_UPGRADE_INFERENCE_SERVICE_EXISTS])
82109
def test_serverless_onnx_post_upgrade_inference(self, ovms_serverless_inference_service_scope_session):
83110
"""Verify that kserve Serverless ONNX model can be queried using REST after upgrade"""
84111
verify_inference_response(
@@ -91,14 +118,28 @@ def test_serverless_onnx_post_upgrade_inference(self, ovms_serverless_inference_
91118

92119
@pytest.mark.post_upgrade
93120
@pytest.mark.rawdeployment
94-
@pytest.mark.dependency(name="test_raw_caikit_bge_post_upgrade_inference_exists")
121+
@pytest.mark.dependency(name=TEST_RAW_CAIKIT_BGE_POST_UPGRADE_INFERENCE_EXISTS)
95122
def test_raw_caikit_bge_post_upgrade_inference_exists(self, caikit_raw_inference_service_scope_session):
96123
"""Test that raw deployment inference service exists after upgrade"""
97124
assert caikit_raw_inference_service_scope_session.exists
98125

99126
@pytest.mark.post_upgrade
100127
@pytest.mark.rawdeployment
101-
@pytest.mark.dependency(depends=["test_raw_caikit_bge_post_upgrade_inference_exists"])
128+
@pytest.mark.dependency(depends=[TEST_RAW_CAIKIT_BGE_POST_UPGRADE_INFERENCE_EXISTS])
129+
def test_raw_caikit_bge_post_upgrade_inference_not_modified(self, caikit_raw_inference_service_scope_session):
130+
"""Test that the raw deployment inference service is not modified in upgrade"""
131+
verify_inference_generation(isvc=caikit_raw_inference_service_scope_session, expected_generation=1)
132+
133+
@pytest.mark.post_upgrade
134+
@pytest.mark.rawdeployment
135+
@pytest.mark.dependency(depends=[TEST_RAW_CAIKIT_BGE_POST_UPGRADE_INFERENCE_EXISTS])
136+
def test_raw_caikit_bge_post_upgrade_runtime_not_modified(self, caikit_raw_inference_service_scope_session):
137+
"""Test that the raw deployment runtime is not modified in upgrade"""
138+
verify_serving_runtime_generation(isvc=caikit_raw_inference_service_scope_session, expected_generation=1)
139+
140+
@pytest.mark.post_upgrade
141+
@pytest.mark.rawdeployment
142+
@pytest.mark.dependency(depends=[TEST_RAW_CAIKIT_BGE_POST_UPGRADE_INFERENCE_EXISTS])
102143
def test_raw_caikit_bge_post_upgrade_inference(self, caikit_raw_inference_service_scope_session):
103144
"""Test Caikit bge-large-en embedding model inference using internal route after upgrade"""
104145
verify_inference_response(
@@ -112,7 +153,7 @@ def test_raw_caikit_bge_post_upgrade_inference(self, caikit_raw_inference_servic
112153

113154
@pytest.mark.post_upgrade
114155
@pytest.mark.modelmesh
115-
@pytest.mark.dependency(name="test_model_mesh_openvino_post_upgrade_inference_exists")
156+
@pytest.mark.dependency(name=TEST_MODEL_MESH_OPENVINO_POST_UPGRADE_INFERENCE_EXISTS)
116157
def test_model_mesh_openvino_post_upgrade_inference_exists(
117158
self, openvino_model_mesh_inference_service_scope_session
118159
):
@@ -121,7 +162,31 @@ def test_model_mesh_openvino_post_upgrade_inference_exists(
121162

122163
@pytest.mark.post_upgrade
123164
@pytest.mark.modelmesh
124-
@pytest.mark.dependency(depends=["test_model_mesh_openvino_post_upgrade_inference_exists"])
165+
@pytest.mark.dependency(depends=[TEST_MODEL_MESH_OPENVINO_POST_UPGRADE_INFERENCE_EXISTS])
166+
def test_model_mesh_openvino_post_upgrade_inference_not_modified(
167+
self, openvino_model_mesh_inference_service_scope_session
168+
):
169+
"""Test that the model mesh deployment inference service is not modified in upgrade"""
170+
verify_inference_generation(
171+
isvc=openvino_model_mesh_inference_service_scope_session,
172+
expected_generation=1,
173+
)
174+
175+
@pytest.mark.post_upgrade
176+
@pytest.mark.modelmesh
177+
@pytest.mark.dependency(depends=[TEST_MODEL_MESH_OPENVINO_POST_UPGRADE_INFERENCE_EXISTS])
178+
def test_model_mesh_openvino_post_upgrade_runtime_not_modified(
179+
self, openvino_model_mesh_inference_service_scope_session
180+
):
181+
"""Test that the model mesh deployment runtime is not modified in upgrade"""
182+
verify_serving_runtime_generation(
183+
isvc=openvino_model_mesh_inference_service_scope_session,
184+
expected_generation=1,
185+
)
186+
187+
@pytest.mark.post_upgrade
188+
@pytest.mark.modelmesh
189+
@pytest.mark.dependency(depends=[TEST_MODEL_MESH_OPENVINO_POST_UPGRADE_INFERENCE_EXISTS])
125190
def test_model_mesh_openvino_post_upgrade_inference(self, openvino_model_mesh_inference_service_scope_session):
126191
"""Test OpenVINO ModelMesh inference with internal route after upgrade"""
127192
verify_inference_response(
@@ -145,7 +210,9 @@ def test_serverless_authenticated_onnx_post_upgrade_inference_service_exists(
145210
@pytest.mark.serverless
146211
@pytest.mark.dependency(depends=["test_serverless_authenticated_onnx_post_upgrade_inference_service_exists"])
147212
def test_serverless_authenticated_onnx_post_upgrade_inference(
148-
self, ovms_authenticated_serverless_inference_service_scope_session, http_inference_token_scope_session
213+
self,
214+
ovms_authenticated_serverless_inference_service_scope_session,
215+
http_inference_token_scope_session,
149216
):
150217
"""Verify that kserve Serverless with auth ONNX model can be queried using REST before upgrade"""
151218
verify_inference_response(
@@ -156,3 +223,36 @@ def test_serverless_authenticated_onnx_post_upgrade_inference(
156223
token=http_inference_token_scope_session,
157224
use_default_query=True,
158225
)
226+
227+
@pytest.mark.post_upgrade
228+
@pytest.mark.serverless
229+
@pytest.mark.rawdeployment
230+
@pytest.mark.modelmesh
231+
def test_verify_odh_model_controller_pod_not_restarted_post_upgrade(self, admin_client):
232+
"""Verify that ODH Model Controller pod is not restarted after upgrade"""
233+
verify_pod_containers_not_restarted(
234+
client=admin_client,
235+
component_name="odh-model-controller",
236+
)
237+
238+
@pytest.mark.post_upgrade
239+
@pytest.mark.serverless
240+
@pytest.mark.rawdeployment
241+
def test_verify_kserve_pod_not_restarted_post_upgrade(self, admin_client):
242+
"""Verify that KServe pod is not restarted after upgrade"""
243+
verify_pod_containers_not_restarted(
244+
client=admin_client,
245+
component_name="kserve",
246+
)
247+
248+
@pytest.mark.post_upgrade
249+
@pytest.mark.modelmesh
250+
def test_verify_model_mesh_pod_not_restarted_post_upgrade(
251+
self,
252+
admin_client,
253+
):
254+
"""Verify that Model Mesh pods are not restarted after upgrade"""
255+
verify_pod_containers_not_restarted(
256+
client=admin_client,
257+
component_name="model-mesh",
258+
)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
from kubernetes.dynamic import DynamicClient
2+
from ocp_resources.inference_service import InferenceService
3+
from ocp_resources.pod import Pod
4+
from pytest_testconfig import config as py_config
5+
6+
from utilities.exceptions import PodContainersRestartError, ResourceMismatchError
7+
from utilities.infra import get_inference_serving_runtime
8+
9+
10+
def verify_pod_containers_not_restarted(client: DynamicClient, component_name: str) -> None:
11+
"""
12+
Verify pod containers not restarted.
13+
14+
Args:
15+
client (DynamicClient): DynamicClient instance
16+
component_name (str): Name of the component
17+
18+
Raises:
19+
AssertionError: If pod containers are restarted
20+
21+
"""
22+
restarted_containers = {}
23+
24+
for pod in Pod.get(
25+
dyn_client=client,
26+
namespace=py_config["applications_namespace"],
27+
label_selector=f"{Pod.ApiGroup.APP_KUBERNETES_IO}/part-of={component_name}",
28+
):
29+
if _restarted_containers := [
30+
container.name for container in pod.instance.status.containerStatuses if container.restartCount > 0
31+
]:
32+
restarted_containers[pod.name] = _restarted_containers
33+
34+
if restarted_containers:
35+
raise PodContainersRestartError(f"Containers {restarted_containers} restarted")
36+
37+
38+
def verify_inference_generation(isvc: InferenceService, expected_generation: int) -> None:
39+
"""
40+
Verify that inference generation is equal to expected generation.
41+
42+
Args:
43+
isvc (InferenceService): InferenceService instance
44+
expected_generation (int): Expected generation
45+
46+
Raises:
47+
ResourceMismatch: If inference generation is not equal to expected generation
48+
"""
49+
if isvc.instance.status.observedGeneration != expected_generation:
50+
ResourceMismatchError(f"Inference service {isvc.name} was modified")
51+
52+
53+
def verify_serving_runtime_generation(isvc: InferenceService, expected_generation: int) -> None:
54+
"""
55+
Verify that serving runtime generation is equal to expected generation.
56+
Args:
57+
isvc (InferenceService): InferenceService instance
58+
expected_generation (int): Expected generation
59+
60+
Raises:
61+
ResourceMismatch: If serving runtime generation is not equal to expected generation
62+
"""
63+
runtime = get_inference_serving_runtime(isvc=isvc)
64+
if runtime.instance.metadata.generation != expected_generation:
65+
ResourceMismatchError(f"Serving runtime {runtime.name} was modified")

utilities/exceptions.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class PodLogMissMatchError(Exception):
8484
pass
8585

8686

87-
class ResourceMismatch(Exception):
87+
class ResourceMismatchError(Exception):
8888
pass
8989

9090

@@ -117,3 +117,7 @@ class UnexpectedFailureError(Exception):
117117

118118
class ResourceNotReadyError(Exception):
119119
pass
120+
121+
122+
class PodContainersRestartError(Exception):
123+
pass

0 commit comments

Comments
 (0)