1+ import os
12import pytest
3+ from pytest import Config
24import schemathesis
35from typing import Generator , Any
46from ocp_resources .pod import Pod
911from ocp_resources .data_science_cluster import DataScienceCluster
1012from ocp_resources .deployment import Deployment
1113
12- from ocp_resources .model_registry import ModelRegistry
14+ from ocp_resources .model_registry_modelregistry_opendatahub_io import ModelRegistry
1315from schemathesis .specs .openapi .schemas import BaseOpenAPISchema
1416from schemathesis .generation .stateful .state_machine import APIStateMachine
1517from schemathesis .core .transport import Response
2931 DB_RESOURCES_NAME ,
3032 MODEL_REGISTRY_DB_SECRET_STR_DATA ,
3133 MODEL_REGISTRY_DB_SECRET_ANNOTATIONS ,
34+ OAUTH_PROXY_CONFIG_DICT ,
35+ MODEL_REGISTRY_STANDARD_LABELS ,
3236)
3337from utilities .constants import Labels
3438from tests .model_registry .utils import (
3842 get_model_registry_db_label_dict ,
3943 wait_for_pods_running ,
4044)
41- from utilities .constants import Annotations , Protocols , DscComponents
45+ from utilities .constants import Protocols , DscComponents
4246from model_registry import ModelRegistry as ModelRegistryClient
4347from semver import Version
4448from utilities .infra import get_product_version
@@ -145,66 +149,94 @@ def model_registry_db_deployment(
145149
146150@pytest .fixture (scope = "class" )
147151def model_registry_instance (
148- admin_client : DynamicClient ,
149- model_registry_namespace : str ,
150- model_registry_db_deployment : Deployment ,
151- model_registry_db_secret : Secret ,
152- model_registry_db_service : Service ,
152+ model_registry_namespace : str , model_registry_mysql_config : dict [str , Any ], is_model_registry_oauth : bool
153153) -> Generator [ModelRegistry , Any , Any ]:
154+ istio_config = None
155+ oauth_config = None
156+ if is_model_registry_oauth :
157+ LOGGER .warning ("Requested Ouath Proxy configuration:" )
158+ oauth_config = OAUTH_PROXY_CONFIG_DICT
159+ else :
160+ LOGGER .warning ("Requested OSSM configuration:" )
161+ istio_config = ISTIO_CONFIG_DICT
162+ """Creates a model registry instance with oauth proxy/service mesh configuration."""
154163 with ModelRegistry (
155164 name = MR_INSTANCE_NAME ,
156165 namespace = model_registry_namespace ,
157- label = {
158- Annotations .KubernetesIo .NAME : MR_INSTANCE_NAME ,
159- Annotations .KubernetesIo .INSTANCE : MR_INSTANCE_NAME ,
160- Annotations .KubernetesIo .PART_OF : MR_OPERATOR_NAME ,
161- Annotations .KubernetesIo .CREATED_BY : MR_OPERATOR_NAME ,
162- },
166+ label = MODEL_REGISTRY_STANDARD_LABELS ,
163167 grpc = {},
164168 rest = {},
165- istio = ISTIO_CONFIG_DICT ,
166- mysql = {
167- "host" : f"{ model_registry_db_deployment .name } .{ model_registry_db_deployment .namespace } .svc.cluster.local" ,
168- "database" : model_registry_db_secret .string_data ["database-name" ],
169- "passwordSecret" : {"key" : "database-password" , "name" : DB_RESOURCES_NAME },
170- "port" : 3306 ,
171- "skipDBCreation" : False ,
172- "username" : model_registry_db_secret .string_data ["database-user" ],
173- },
169+ istio = istio_config ,
170+ oauth_proxy = oauth_config ,
171+ mysql = model_registry_mysql_config ,
174172 wait_for_resource = True ,
175173 ) as mr :
176174 mr .wait_for_condition (condition = "Available" , status = "True" )
177175 yield mr
178176
179177
178+ @pytest .fixture (scope = "class" )
179+ def model_registry_mysql_config (
180+ model_registry_db_deployment : Deployment , model_registry_db_secret : Secret
181+ ) -> dict [str , Any ]:
182+ return {
183+ "host" : f"{ model_registry_db_deployment .name } .{ model_registry_db_deployment .namespace } .svc.cluster.local" ,
184+ "database" : model_registry_db_secret .string_data ["database-name" ],
185+ "passwordSecret" : {"key" : "database-password" , "name" : model_registry_db_deployment .name },
186+ "port" : 3306 ,
187+ "skipDBCreation" : False ,
188+ "username" : model_registry_db_secret .string_data ["database-user" ],
189+ }
190+
191+
180192@pytest .fixture (scope = "class" )
181193def model_registry_instance_service (
182194 admin_client : DynamicClient ,
183195 model_registry_namespace : str ,
184196 model_registry_instance : ModelRegistry ,
185197) -> Service :
198+ """
199+ Get the service for the regular model registry instance.
200+ Args:
201+ admin_client: The admin client
202+ model_registry_namespace: The namespace where the model registry is deployed
203+ model_registry_instance: The model registry instance to get the service for
204+ Returns:
205+ Service: The service for the model registry instance
206+ """
186207 return get_mr_service_by_label (
187- client = admin_client , ns = Namespace (name = model_registry_namespace ), mr_instance = model_registry_instance
208+ client = admin_client ,
209+ ns = Namespace (name = model_registry_namespace ),
210+ mr_instance = model_registry_instance ,
188211 )
189212
190213
191214@pytest .fixture (scope = "class" )
192215def model_registry_instance_rest_endpoint (
193216 model_registry_instance_service : Service ,
194217) -> str :
218+ """
219+ Get the REST endpoint for the model registry instance.
220+ Args:
221+ model_registry_instance_service: The service for the model registry instance
222+ Returns:
223+ str: The REST endpoint for the model registry instance
224+ """
195225 return get_endpoint_from_mr_service (svc = model_registry_instance_service , protocol = Protocols .REST )
196226
197227
198228@pytest .fixture (scope = "class" )
199- def generated_schema (model_registry_instance_rest_endpoint : str ) -> BaseOpenAPISchema :
229+ def generated_schema (pytestconfig : Config , model_registry_instance_rest_endpoint : str ) -> BaseOpenAPISchema :
230+ os .environ ["API_HOST" ] = model_registry_instance_rest_endpoint
231+ config = schemathesis .config .SchemathesisConfig .from_path (f"{ pytestconfig .rootpath } /schemathesis.toml" )
200232 schema = schemathesis .openapi .from_url (
201- url = "https://raw.githubusercontent.com/kubeflow/model-registry/main/api/openapi/model-registry.yaml"
233+ url = "https://raw.githubusercontent.com/kubeflow/model-registry/main/api/openapi/model-registry.yaml" ,
234+ config = config ,
202235 )
203- schema .configure (base_url = f"https://{ model_registry_instance_rest_endpoint } /" )
204236 return schema
205237
206238
207- @pytest .fixture
239+ @pytest .fixture ()
208240def state_machine (generated_schema : BaseOpenAPISchema , current_client_token : str ) -> APIStateMachine :
209241 BaseAPIWorkflow = generated_schema .as_state_machine ()
210242
@@ -214,12 +246,18 @@ class APIWorkflow(BaseAPIWorkflow): # type: ignore
214246 def setup (self ) -> None :
215247 self .headers = {"Authorization" : f"Bearer { current_client_token } " , "Content-Type" : "application/json" }
216248
249+ def before_call (self , case : Case ) -> None :
250+ LOGGER .info (f"Checking: { case .method } { case .path } " )
251+
217252 # these kwargs are passed to requests.request()
218253 def get_call_kwargs (self , case : Case ) -> dict [str , Any ]:
219254 return {"verify" : False , "headers" : self .headers }
220255
221256 def after_call (self , response : Response , case : Case ) -> None :
222- LOGGER .info (f"{ case .method } { case .path } -> { response .status_code } " )
257+ LOGGER .info (
258+ f"Method tested: { case .method } , API: { case .path } , response code:{ response .status_code } ,"
259+ f" Full Response:{ response .text } "
260+ )
223261
224262 return APIWorkflow
225263
@@ -263,11 +301,18 @@ def updated_dsc_component_state_scope_class(
263301
264302@pytest .fixture (scope = "class" )
265303def model_registry_client (current_client_token : str , model_registry_instance_rest_endpoint : str ) -> ModelRegistryClient :
266- # address and port need to be split in the client instantiation
304+ """
305+ Get a client for the model registry instance.
306+ Args:
307+ request: The pytest request object
308+ current_client_token: The current client token
309+ Returns:
310+ ModelRegistryClient: A client for the model registry instance
311+ """
267312 server , port = model_registry_instance_rest_endpoint .split (":" )
268313 return ModelRegistryClient (
269314 server_address = f"{ Protocols .HTTPS } ://{ server } " ,
270- port = port ,
315+ port = int ( port ) ,
271316 author = "opendatahub-test" ,
272317 user_token = current_client_token ,
273318 is_secure = False ,
@@ -350,3 +395,8 @@ def validate_authorino_operator_version_channel(admin_client: DynamicClient) ->
350395 validate_operator_subscription_channel (
351396 client = admin_client , namespace = "openshift-operators" , operator_name = operator_name , channel_name = "stable"
352397 )
398+
399+
400+ @pytest .fixture (scope = "class" )
401+ def is_model_registry_oauth (request : FixtureRequest ) -> bool :
402+ return getattr (request , "param" , {}).get ("use_oauth_proxy" , False )
0 commit comments