1919
2020from utilities .constants import ModelFormat , KServeDeploymentType , ModelStoragePath , Annotations , Labels
2121from utilities .inference_utils import create_isvc
22- from utilities .infra import create_inference_token , create_inference_graph_view_role
22+ from utilities .infra import (
23+ create_inference_token ,
24+ create_inference_graph_view_role ,
25+ get_services_by_isvc_label ,
26+ )
2327
2428
2529@pytest .fixture (scope = "class" )
@@ -35,50 +39,51 @@ def kserve_raw_headless_service_config(
3539
3640 logger .info (msg = f"Current rawDeploymentServiceConfig: { current_config } " )
3741
38- # If already headed (case-insensitive), skip the patch
42+ # If already Headed, keep the existing mode. For tests we want Headed even if the
43+ # cluster is explicitly configured as Headless.
3944 if current_config and current_config .lower () == "headed" :
40- logger .info (msg = "rawDeploymentServiceConfig is already Headed, skipping patch" )
41- yield dsc_resource
42- else :
43- logger .info (msg = f"Patching rawDeploymentServiceConfig from '{ current_config } ' to 'Headed'" )
44- # Patch DSC to set rawDeploymentServiceConfig to Headed
45- with ResourceEditor (
46- patches = {dsc_resource : {"spec" : {"components" : {"kserve" : {"rawDeploymentServiceConfig" : "Headed" }}}}}
47- ):
48- logger .info (msg = "Waiting for DSC to become ready after patch..." )
49- dsc_resource .wait_for_condition (
50- condition = dsc_resource .Condition .READY ,
51- status = dsc_resource .Condition .Status .TRUE ,
52- timeout = 300 ,
53- )
54- # Verify the patch was applied
55- new_config = dsc_resource .instance .spec .components .kserve .rawDeploymentServiceConfig
56- logger .info (msg = f"After patch, rawDeploymentServiceConfig is: { new_config } " )
57-
58- logger .info (msg = "Waiting for KServe controller to be ready and configuration to propagate..." )
59- kserve_deployments = list (
60- Deployment .get (
61- dyn_client = admin_client ,
62- namespace = "redhat-ods-applications" ,
63- label_selector = "control-plane=kserve-controller-manager" ,
64- )
45+ logger .info (
46+ msg = (
47+ "rawDeploymentServiceConfig is already set to "
48+ f"'{ current_config } ', reusing existing configuration"
6549 )
50+ )
51+ yield dsc_resource
52+ return
6653
67- if kserve_deployments :
68- for deployment in kserve_deployments :
69- deployment .wait_for_replicas (timeout = 180 )
54+ logger .info (msg = f"Patching rawDeploymentServiceConfig from '{ current_config } ' to 'Headed'" )
55+ # Patch DSC to set rawDeploymentServiceConfig to Headed when not explicitly configured
56+ with ResourceEditor (
57+ patches = {dsc_resource : {"spec" : {"components" : {"kserve" : {"rawDeploymentServiceConfig" : "Headed" }}}}}
58+ ):
59+ logger .info (msg = "Waiting for DSC to become ready after patch..." )
60+ dsc_resource .wait_for_condition (
61+ condition = dsc_resource .Condition .READY ,
62+ status = dsc_resource .Condition .Status .TRUE ,
63+ timeout = 300 ,
64+ )
65+ # Verify the patch was applied
66+ new_config = dsc_resource .instance .spec .components .kserve .rawDeploymentServiceConfig
67+ logger .info (msg = f"After patch, rawDeploymentServiceConfig is: { new_config } " )
7068
71- # Wait for configuration to be picked up by the controller
72- # The KServe controller reads DSC configuration at runtime but doesn't have an observable
73- # status to wait on. A grace period is required for the controller to reload and apply the
74- # new rawDeploymentServiceConfig before creating InferenceServices.
75- # TODO: Consider creating a canary InferenceService to verify config was applied
76- logger .info (msg = "Waiting for KServe controller to process configuration change..." )
77- time .sleep (60 )
78- else :
79- logger .warning (msg = "No KServe controller deployment found, skipping wait" )
69+ logger .info (msg = "Waiting for KServe controller to be ready and configuration to propagate..." )
70+ kserve_deployments = list (
71+ Deployment .get (
72+ dyn_client = admin_client ,
73+ namespace = "redhat-ods-applications" ,
74+ label_selector = "control-plane=kserve-controller-manager" ,
75+ )
76+ )
77+
78+ if kserve_deployments :
79+ for deployment in kserve_deployments :
80+ deployment .wait_for_replicas (timeout = 180 )
81+ else :
82+ logger .warning (msg = "No KServe controller deployment found" )
83+ logger .info (msg = "Waiting for KServe controller to process configuration change..." )
84+ time .sleep (60 )
8085
81- yield dsc_resource
86+ yield dsc_resource
8287
8388
8489@pytest .fixture
@@ -164,6 +169,21 @@ def dog_cat_inference_service(
164169 deployment_mode = KServeDeploymentType .RAW_DEPLOYMENT ,
165170 protocol_version = "v2" ,
166171 ) as isvc :
172+ # Canary check: verify RawDeployment is using a headed service (non-headless).
173+ services = get_services_by_isvc_label (
174+ client = admin_client ,
175+ isvc = isvc ,
176+ runtime_name = ovms_kserve_serving_runtime .name ,
177+ )
178+ is_headed = any (
179+ getattr (svc .instance .spec , "clusterIP" , None )
180+ and svc .instance .spec .clusterIP != "None"
181+ for svc in services
182+ )
183+ assert is_headed , (
184+ "Expected Headed RawDeployment for dog-cat-classifier, but predictor Service is headless. "
185+ "Check rawDeploymentServiceConfig in DataScienceCluster."
186+ )
167187 yield isvc
168188
169189
0 commit comments