@@ -63,133 +63,181 @@ def model_registry_namespace(updated_dsc_component_state_scope_class: DataScienc
6363
6464@pytest .fixture (scope = "class" )
6565def model_registry_db_service (
66- admin_client : DynamicClient , model_registry_namespace : str , is_model_registry_oauth : bool
66+ pytestconfig : Config ,
67+ admin_client : DynamicClient ,
68+ model_registry_namespace : str ,
69+ is_model_registry_oauth : bool ,
70+ teardown_resources : bool ,
6771) -> Generator [Service , Any , Any ]:
68- with Service (
69- client = admin_client ,
70- name = DB_RESOURCES_NAME ,
71- namespace = model_registry_namespace ,
72- ports = [
73- {
74- "name" : "mysql" ,
75- "nodePort" : 0 ,
76- "port" : 3306 ,
77- "protocol" : "TCP" ,
78- "appProtocol" : "tcp" ,
79- "targetPort" : 3306 ,
80- }
81- ],
82- selector = {
83- "name" : DB_RESOURCES_NAME ,
84- },
85- label = get_model_registry_db_label_dict (db_resource_name = DB_RESOURCES_NAME ),
86- annotations = {
87- "template.openshift.io/expose-uri" : r"mysql://{.spec.clusterIP}:{.spec.ports[?(.name==\mysql\)].port}" ,
88- },
89- ) as mr_db_service :
72+ if pytestconfig .option .post_upgrade :
73+ mr_db_service = Service (name = DB_RESOURCES_NAME , namespace = model_registry_namespace , ensure_exists = True )
9074 yield mr_db_service
75+ mr_db_service .delete (wait = True )
76+ else :
77+ with Service (
78+ client = admin_client ,
79+ name = DB_RESOURCES_NAME ,
80+ namespace = model_registry_namespace ,
81+ ports = [
82+ {
83+ "name" : "mysql" ,
84+ "nodePort" : 0 ,
85+ "port" : 3306 ,
86+ "protocol" : "TCP" ,
87+ "appProtocol" : "tcp" ,
88+ "targetPort" : 3306 ,
89+ }
90+ ],
91+ selector = {
92+ "name" : DB_RESOURCES_NAME ,
93+ },
94+ label = get_model_registry_db_label_dict (db_resource_name = DB_RESOURCES_NAME ),
95+ annotations = {
96+ "template.openshift.io/expose-uri" : r"mysql://{.spec.clusterIP}:{.spec.ports[?(.name==\mysql\)].port}" ,
97+ },
98+ teardown = teardown_resources ,
99+ ) as mr_db_service :
100+ yield mr_db_service
91101
92102
93103@pytest .fixture (scope = "class" )
94104def model_registry_db_pvc (
95- admin_client : DynamicClient , model_registry_namespace : str , is_model_registry_oauth : bool
105+ pytestconfig : Config ,
106+ admin_client : DynamicClient ,
107+ model_registry_namespace : str ,
108+ is_model_registry_oauth : bool ,
109+ teardown_resources : bool ,
96110) -> Generator [PersistentVolumeClaim , Any , Any ]:
97- with PersistentVolumeClaim (
98- accessmodes = "ReadWriteOnce" ,
99- name = DB_RESOURCES_NAME ,
100- namespace = model_registry_namespace ,
101- client = admin_client ,
102- size = "5Gi" ,
103- label = get_model_registry_db_label_dict (db_resource_name = DB_RESOURCES_NAME ),
104- ) as pvc :
105- yield pvc
111+ if pytestconfig .option .post_upgrade :
112+ mr_db_pvc = PersistentVolumeClaim (
113+ name = DB_RESOURCES_NAME , namespace = model_registry_namespace , ensure_exists = True
114+ )
115+ yield mr_db_pvc
116+ mr_db_pvc .delete (wait = True )
117+ else :
118+ with PersistentVolumeClaim (
119+ accessmodes = "ReadWriteOnce" ,
120+ name = DB_RESOURCES_NAME ,
121+ namespace = model_registry_namespace ,
122+ client = admin_client ,
123+ size = "5Gi" ,
124+ label = get_model_registry_db_label_dict (db_resource_name = DB_RESOURCES_NAME ),
125+ teardown = teardown_resources ,
126+ ) as pvc :
127+ yield pvc
106128
107129
108130@pytest .fixture (scope = "class" )
109131def model_registry_db_secret (
132+ pytestconfig : Config ,
110133 admin_client : DynamicClient ,
111134 model_registry_namespace : str ,
112135 is_model_registry_oauth : bool ,
136+ teardown_resources : bool ,
113137) -> Generator [Secret , Any , Any ]:
114- with Secret (
115- client = admin_client ,
116- name = DB_RESOURCES_NAME ,
117- namespace = model_registry_namespace ,
118- string_data = MODEL_REGISTRY_DB_SECRET_STR_DATA ,
119- label = get_model_registry_db_label_dict (db_resource_name = DB_RESOURCES_NAME ),
120- annotations = MODEL_REGISTRY_DB_SECRET_ANNOTATIONS ,
121- ) as mr_db_secret :
138+ if pytestconfig .option .post_upgrade :
139+ mr_db_secret = Secret (name = DB_RESOURCES_NAME , namespace = model_registry_namespace , ensure_exists = True )
122140 yield mr_db_secret
141+ mr_db_secret .delete (wait = True )
142+ else :
143+ with Secret (
144+ client = admin_client ,
145+ name = DB_RESOURCES_NAME ,
146+ namespace = model_registry_namespace ,
147+ string_data = MODEL_REGISTRY_DB_SECRET_STR_DATA ,
148+ label = get_model_registry_db_label_dict (db_resource_name = DB_RESOURCES_NAME ),
149+ annotations = MODEL_REGISTRY_DB_SECRET_ANNOTATIONS ,
150+ teardown = teardown_resources ,
151+ ) as mr_db_secret :
152+ yield mr_db_secret
123153
124154
125155@pytest .fixture (scope = "class" )
126156def model_registry_db_deployment (
157+ pytestconfig : Config ,
127158 admin_client : DynamicClient ,
128159 model_registry_namespace : str ,
129160 model_registry_db_secret : Secret ,
130161 model_registry_db_pvc : PersistentVolumeClaim ,
131162 model_registry_db_service : Service ,
132163 is_model_registry_oauth : bool ,
164+ teardown_resources : bool ,
133165) -> Generator [Deployment , Any , Any ]:
134- with Deployment (
135- name = DB_RESOURCES_NAME ,
136- namespace = model_registry_namespace ,
137- annotations = {
138- "template.alpha.openshift.io/wait-for-ready" : "true" ,
139- },
140- label = get_model_registry_db_label_dict (db_resource_name = DB_RESOURCES_NAME ),
141- replicas = 1 ,
142- revision_history_limit = 0 ,
143- selector = {"matchLabels" : {"name" : DB_RESOURCES_NAME }},
144- strategy = {"type" : "Recreate" },
145- template = get_model_registry_deployment_template_dict (
146- secret_name = model_registry_db_secret .name , resource_name = DB_RESOURCES_NAME
147- ),
148- wait_for_resource = True ,
149- ) as mr_db_deployment :
150- mr_db_deployment .wait_for_replicas (deployed = True )
151- yield mr_db_deployment
166+ if pytestconfig .option .post_upgrade :
167+ db_deployment = Deployment (name = DB_RESOURCES_NAME , namespace = model_registry_namespace , ensure_exists = True )
168+ yield db_deployment
169+ db_deployment .delete (wait = True )
170+ else :
171+ with Deployment (
172+ name = DB_RESOURCES_NAME ,
173+ namespace = model_registry_namespace ,
174+ annotations = {
175+ "template.alpha.openshift.io/wait-for-ready" : "true" ,
176+ },
177+ label = get_model_registry_db_label_dict (db_resource_name = DB_RESOURCES_NAME ),
178+ replicas = 1 ,
179+ revision_history_limit = 0 ,
180+ selector = {"matchLabels" : {"name" : DB_RESOURCES_NAME }},
181+ strategy = {"type" : "Recreate" },
182+ template = get_model_registry_deployment_template_dict (
183+ secret_name = model_registry_db_secret .name , resource_name = DB_RESOURCES_NAME
184+ ),
185+ wait_for_resource = True ,
186+ teardown = teardown_resources ,
187+ ) as mr_db_deployment :
188+ mr_db_deployment .wait_for_replicas (deployed = True )
189+ yield mr_db_deployment
152190
153191
154192@pytest .fixture (scope = "class" )
155193def model_registry_instance (
156- model_registry_namespace : str , model_registry_mysql_config : dict [str , Any ], is_model_registry_oauth : bool
194+ pytestconfig : Config ,
195+ model_registry_namespace : str ,
196+ model_registry_mysql_config : dict [str , Any ],
197+ is_model_registry_oauth : bool ,
198+ teardown_resources : bool ,
157199) -> Generator [ModelRegistry , Any , Any ]:
158- istio_config = None
159- oauth_config = None
160- if is_model_registry_oauth :
161- LOGGER .warning ("Requested Ouath Proxy configuration:" )
162- oauth_config = OAUTH_PROXY_CONFIG_DICT
200+ if pytestconfig .option .post_upgrade :
201+ mr_instance = ModelRegistry (name = MR_INSTANCE_NAME , namespace = model_registry_namespace , ensure_exists = True )
202+ yield mr_instance
203+ mr_instance .delete (wait = True )
163204 else :
164- LOGGER .warning ("Requested OSSM configuration:" )
165- istio_config = ISTIO_CONFIG_DICT
166- """Creates a model registry instance with oauth proxy/service mesh configuration."""
167- with ModelRegistry (
168- name = MR_INSTANCE_NAME ,
169- namespace = model_registry_namespace ,
170- label = MODEL_REGISTRY_STANDARD_LABELS ,
171- grpc = {},
172- rest = {},
173- istio = istio_config ,
174- oauth_proxy = oauth_config ,
175- mysql = model_registry_mysql_config ,
176- wait_for_resource = True ,
177- ) as mr :
178- mr .wait_for_condition (condition = "Available" , status = "True" )
179- yield mr
205+ istio_config = None
206+ oauth_config = None
207+ if is_model_registry_oauth :
208+ LOGGER .warning ("Requested Ouath Proxy configuration:" )
209+ oauth_config = OAUTH_PROXY_CONFIG_DICT
210+ else :
211+ LOGGER .warning ("Requested OSSM configuration:" )
212+ istio_config = ISTIO_CONFIG_DICT
213+ """Creates a model registry instance with oauth proxy/service mesh configuration."""
214+ with ModelRegistry (
215+ name = MR_INSTANCE_NAME ,
216+ namespace = model_registry_namespace ,
217+ label = MODEL_REGISTRY_STANDARD_LABELS ,
218+ grpc = {},
219+ rest = {},
220+ istio = istio_config ,
221+ oauth_proxy = oauth_config ,
222+ mysql = model_registry_mysql_config ,
223+ wait_for_resource = True ,
224+ teardown = teardown_resources ,
225+ ) as mr :
226+ mr .wait_for_condition (condition = "Available" , status = "True" )
227+ yield mr
180228
181229
182230@pytest .fixture (scope = "class" )
183231def model_registry_mysql_config (
184- model_registry_db_deployment : Deployment , model_registry_db_secret : Secret
232+ model_registry_db_deployment : Deployment ,
185233) -> dict [str , Any ]:
186234 return {
187235 "host" : f"{ model_registry_db_deployment .name } .{ model_registry_db_deployment .namespace } .svc.cluster.local" ,
188- "database" : model_registry_db_secret . string_data ["database-name" ],
236+ "database" : MODEL_REGISTRY_DB_SECRET_STR_DATA ["database-name" ],
189237 "passwordSecret" : {"key" : "database-password" , "name" : model_registry_db_deployment .name },
190238 "port" : 3306 ,
191239 "skipDBCreation" : False ,
192- "username" : model_registry_db_secret . string_data ["database-user" ],
240+ "username" : MODEL_REGISTRY_DB_SECRET_STR_DATA ["database-user" ],
193241 }
194242
195243
@@ -267,41 +315,52 @@ def after_call(self, response: Response, case: Case) -> None:
267315@pytest .fixture (scope = "class" )
268316def updated_dsc_component_state_scope_class (
269317 request : FixtureRequest ,
318+ pytestconfig : Config ,
270319 dsc_resource : DataScienceCluster ,
271320 admin_client : DynamicClient ,
272321 is_model_registry_oauth : bool ,
322+ teardown_resources : bool ,
273323) -> Generator [DataScienceCluster , Any , Any ]:
274- original_components = dsc_resource .instance .spec .components
275- component_patch = request .param ["component_patch" ]
276-
277- with ResourceEditor (patches = {dsc_resource : {"spec" : {"components" : component_patch }}}):
278- for component_name in component_patch :
279- dsc_resource .wait_for_condition (condition = DscComponents .COMPONENT_MAPPING [component_name ], status = "True" )
280- if component_patch .get (DscComponents .MODELREGISTRY ):
281- namespace = Namespace (
282- name = dsc_resource .instance .spec .components .modelregistry .registriesNamespace , ensure_exists = True
283- )
284- namespace .wait_for_status (status = Namespace .Status .ACTIVE )
285- wait_for_pods_running (
286- admin_client = admin_client ,
287- namespace_name = py_config ["applications_namespace" ],
288- number_of_consecutive_checks = 6 ,
289- )
324+ if not teardown_resources or pytestconfig .option .post_upgrade :
325+ # if we are not tearing down resources or we are in post upgrade, we don't need to do anything
326+ # the pre_upgrade/post_upgrade fixtures will handle the rest
290327 yield dsc_resource
291-
292- for component_name , value in component_patch .items ():
293- LOGGER .info (f"Waiting for component { component_name } to be updated." )
294- if original_components [component_name ]["managementState" ] == DscComponents .ManagementState .MANAGED :
295- dsc_resource .wait_for_condition (condition = DscComponents .COMPONENT_MAPPING [component_name ], status = "True" )
296- if (
297- component_name == DscComponents .MODELREGISTRY
298- and value .get ("managementState" ) == DscComponents .ManagementState .MANAGED
299- ):
300- # Since namespace specified in registriesNamespace is automatically created after setting
301- # managementStateto Managed. We need to explicitly delete it on clean up.
302- namespace = Namespace (name = value ["registriesNamespace" ], ensure_exists = True )
303- if namespace :
304- namespace .delete (wait = True )
328+ else :
329+ original_components = dsc_resource .instance .spec .components
330+ component_patch = request .param ["component_patch" ]
331+
332+ with ResourceEditor (patches = {dsc_resource : {"spec" : {"components" : component_patch }}}):
333+ for component_name in component_patch :
334+ dsc_resource .wait_for_condition (
335+ condition = DscComponents .COMPONENT_MAPPING [component_name ], status = "True"
336+ )
337+ if component_patch .get (DscComponents .MODELREGISTRY ):
338+ namespace = Namespace (
339+ name = dsc_resource .instance .spec .components .modelregistry .registriesNamespace , ensure_exists = True
340+ )
341+ namespace .wait_for_status (status = Namespace .Status .ACTIVE )
342+ wait_for_pods_running (
343+ admin_client = admin_client ,
344+ namespace_name = py_config ["applications_namespace" ],
345+ number_of_consecutive_checks = 6 ,
346+ )
347+ yield dsc_resource
348+
349+ for component_name , value in component_patch .items ():
350+ LOGGER .info (f"Waiting for component { component_name } to be updated." )
351+ if original_components [component_name ]["managementState" ] == DscComponents .ManagementState .MANAGED :
352+ dsc_resource .wait_for_condition (
353+ condition = DscComponents .COMPONENT_MAPPING [component_name ], status = "True"
354+ )
355+ if (
356+ component_name == DscComponents .MODELREGISTRY
357+ and value .get ("managementState" ) == DscComponents .ManagementState .MANAGED
358+ ):
359+ # Since namespace specified in registriesNamespace is automatically created after setting
360+ # managementStateto Managed. We need to explicitly delete it on clean up.
361+ namespace = Namespace (name = value ["registriesNamespace" ], ensure_exists = True )
362+ if namespace :
363+ namespace .delete (wait = True )
305364
306365
307366@pytest .fixture (scope = "class" )
0 commit comments