88 REDHAT_AI_VALIDATED_FILTER ,
99 REDHAT_AI_CATALOG_ID ,
1010 VALIDATED_CATALOG_ID ,
11+ MODEL_ARTIFACT_TYPE ,
12+ METRICS_ARTIFACT_TYPE ,
1113)
1214from tests .model_registry .model_catalog .utils import (
13- get_models_from_api ,
15+ get_models_from_catalog_api ,
16+ fetch_all_artifacts_with_dynamic_paging ,
1417)
18+ from kubernetes .dynamic .exceptions import ResourceNotFoundError
1519
1620LOGGER = get_logger (name = __name__ )
1721pytestmark = [
@@ -28,20 +32,20 @@ def test_search_model_catalog_source_label(
2832 RHOAIENG-33656: Validate search model catalog by source label
2933 """
3034
31- redhat_ai_filter_moldels_size = get_models_from_api (
35+ redhat_ai_filter_moldels_size = get_models_from_catalog_api (
3236 model_catalog_rest_url = model_catalog_rest_url ,
3337 model_registry_rest_headers = model_registry_rest_headers ,
3438 source_label = REDHAT_AI_FILTER ,
3539 )["size" ]
36- redhat_ai_validated_filter_models_size = get_models_from_api (
40+ redhat_ai_validated_filter_models_size = get_models_from_catalog_api (
3741 model_catalog_rest_url = model_catalog_rest_url ,
3842 model_registry_rest_headers = model_registry_rest_headers ,
3943 source_label = REDHAT_AI_VALIDATED_FILTER ,
4044 )["size" ]
41- no_filtered_models_size = get_models_from_api (
45+ no_filtered_models_size = get_models_from_catalog_api (
4246 model_catalog_rest_url = model_catalog_rest_url , model_registry_rest_headers = model_registry_rest_headers
4347 )["size" ]
44- both_filtered_models_size = get_models_from_api (
48+ both_filtered_models_size = get_models_from_catalog_api (
4549 model_catalog_rest_url = model_catalog_rest_url ,
4650 model_registry_rest_headers = model_registry_rest_headers ,
4751 source_label = f"{ REDHAT_AI_VALIDATED_FILTER } ,{ REDHAT_AI_FILTER } " ,
@@ -58,13 +62,13 @@ def test_search_model_catalog_invalid_source_label(
5862 Validate search model catalog by invalid source label
5963 """
6064
61- null_size = get_models_from_api (
65+ null_size = get_models_from_catalog_api (
6266 model_catalog_rest_url = model_catalog_rest_url ,
6367 model_registry_rest_headers = model_registry_rest_headers ,
6468 source_label = "null" ,
6569 )["size" ]
6670
67- invalid_size = get_models_from_api (
71+ invalid_size = get_models_from_catalog_api (
6872 model_catalog_rest_url = model_catalog_rest_url ,
6973 model_registry_rest_headers = model_registry_rest_headers ,
7074 source_label = "invalid" ,
@@ -75,33 +79,35 @@ def test_search_model_catalog_invalid_source_label(
7579 )
7680
7781 @pytest .mark .parametrize (
78- "randomly_picked_model ,source_filter" ,
82+ "randomly_picked_model_from_catalog_api_by_source ,source_filter" ,
7983 [
8084 pytest .param (
81- {"source" : VALIDATED_CATALOG_ID },
85+ {"source" : VALIDATED_CATALOG_ID , "header_type" : "registry" },
8286 REDHAT_AI_VALIDATED_FILTER ,
8387 id = "test_search_model_catalog_redhat_ai_validated" ,
8488 ),
8589 pytest .param (
86- {"source" : REDHAT_AI_CATALOG_ID }, REDHAT_AI_FILTER , id = "test_search_model_catalog_redhat_ai_default"
90+ {"source" : REDHAT_AI_CATALOG_ID , "header_type" : "registry" },
91+ REDHAT_AI_FILTER ,
92+ id = "test_search_model_catalog_redhat_ai_default" ,
8793 ),
8894 ],
89- indirect = ["randomly_picked_model " ],
95+ indirect = ["randomly_picked_model_from_catalog_api_by_source " ],
9096 )
9197 def test_search_model_catalog_match (
9298 self : Self ,
9399 model_catalog_rest_url : list [str ],
94100 model_registry_rest_headers : dict [str , str ],
95- randomly_picked_model : dict [Any , Any ],
101+ randomly_picked_model_from_catalog_api_by_source : dict [Any , Any ],
96102 source_filter : str ,
97103 ):
98104 """
99105 RHOAIENG-33656: Validate search model catalog by match
100106 """
101- random_model = randomly_picked_model
107+ random_model = randomly_picked_model_from_catalog_api_by_source
102108 random_model_name = random_model ["name" ]
103109 LOGGER .info (f"random_model_name: { random_model_name } " )
104- result = get_models_from_api (
110+ result = get_models_from_catalog_api (
105111 model_catalog_rest_url = model_catalog_rest_url ,
106112 model_registry_rest_headers = model_registry_rest_headers ,
107113 source_label = source_filter ,
@@ -113,3 +119,180 @@ def test_search_model_catalog_match(
113119 differences = list (diff (random_model , result ["items" ][0 ]))
114120 assert not differences , f"Expected no differences in model information for { random_model_name } : { differences } "
115121 LOGGER .info ("Model information matches" )
122+
123+
124+ # All the tests in this class are failing for RHOAIENG-36938, there are two problems:
125+ # 1. The filter parameter is setup to use artifact_type instead of artifactType
126+ # 2. The filter with multiple artifact types is not working as expected
127+ class TestSearchModelArtifact :
128+ @pytest .mark .parametrize (
129+ "randomly_picked_model_from_catalog_api_by_source, artifact_type" ,
130+ [
131+ pytest .param (
132+ {"catalog_id" : REDHAT_AI_CATALOG_ID , "header_type" : "registry" },
133+ MODEL_ARTIFACT_TYPE ,
134+ id = "redhat_ai_model_artifact" ,
135+ ),
136+ pytest .param (
137+ {"catalog_id" : REDHAT_AI_CATALOG_ID , "header_type" : "registry" },
138+ METRICS_ARTIFACT_TYPE ,
139+ id = "redhat_ai_metrics_artifact" ,
140+ ),
141+ pytest .param (
142+ {"catalog_id" : VALIDATED_CATALOG_ID , "header_type" : "registry" },
143+ MODEL_ARTIFACT_TYPE ,
144+ id = "validated_model_artifact" ,
145+ ),
146+ pytest .param (
147+ {"catalog_id" : VALIDATED_CATALOG_ID , "header_type" : "registry" },
148+ METRICS_ARTIFACT_TYPE ,
149+ id = "validated_metrics_artifact" ,
150+ ),
151+ ],
152+ indirect = ["randomly_picked_model_from_catalog_api_by_source" ],
153+ )
154+ def test_validate_model_artifacts_by_artifact_type (
155+ self : Self ,
156+ model_catalog_rest_url : list [str ],
157+ model_registry_rest_headers : dict [str , str ],
158+ randomly_picked_model_from_catalog_api_by_source : dict [Any , Any ],
159+ artifact_type : str ,
160+ ):
161+ """
162+ RHOAIENG-33659: Validates that the model artifacts returned by the artifactType filter
163+ match the complete set of artifacts for a random model.
164+ """
165+ model_name = randomly_picked_model_from_catalog_api_by_source .get ("name" )
166+ catalog_id = randomly_picked_model_from_catalog_api_by_source .get ("source_id" )
167+ assert model_name and catalog_id , "Model name or catalog ID not found in random model"
168+ LOGGER .info (f"Testing model '{ model_name } ' from catalog '{ catalog_id } ' for artifact type '{ artifact_type } '" )
169+
170+ # Fetch all artifacts with dynamic page size adjustment
171+ all_model_artifacts = fetch_all_artifacts_with_dynamic_paging (
172+ url_with_pagesize = f"{ model_catalog_rest_url [0 ]} sources/{ catalog_id } /models/{ model_name } /artifacts?pageSize" ,
173+ headers = model_registry_rest_headers ,
174+ page_size = 100 ,
175+ )["items" ]
176+
177+ # Fetch filtered artifacts by type with dynamic page size adjustment
178+ artifact_type_artifacts = fetch_all_artifacts_with_dynamic_paging (
179+ url_with_pagesize = (
180+ f"{ model_catalog_rest_url [0 ]} sources/{ catalog_id } /models/{ model_name } /artifacts?"
181+ f"artifactType={ artifact_type } &pageSize"
182+ ),
183+ headers = model_registry_rest_headers ,
184+ page_size = 50 ,
185+ )["items" ]
186+
187+ # Create lookup for validation
188+ all_artifacts_by_id = {artifact ["id" ]: artifact for artifact in all_model_artifacts }
189+
190+ # Verify all filtered artifacts exist
191+ for artifact in artifact_type_artifacts :
192+ artifact_id = artifact ["id" ]
193+ assert artifact_id in all_artifacts_by_id , (
194+ f"Filtered artifact { artifact_id } not found in complete artifact list for { model_name } "
195+ )
196+
197+ differences = list (diff (artifact , all_artifacts_by_id [artifact_id ]))
198+ assert not differences , f"Artifact { artifact_id } mismatch for { model_name } : { differences } "
199+
200+ # Verify the filter didn't miss any artifacts of the type
201+ artifacts_of_type_in_all = [
202+ artifact for artifact in all_model_artifacts if artifact .get ("artifactType" ) == artifact_type
203+ ]
204+ assert len (artifact_type_artifacts ) == len (artifacts_of_type_in_all ), (
205+ f"Filter returned { len (artifact_type_artifacts )} { artifact_type } artifacts, "
206+ f"but found { len (artifacts_of_type_in_all )} in complete list for { model_name } "
207+ )
208+
209+ LOGGER .info (f"Validated { len (artifact_type_artifacts )} { artifact_type } artifacts for { model_name } " )
210+
211+ @pytest .mark .parametrize (
212+ "randomly_picked_model_from_catalog_api_by_source" ,
213+ [
214+ pytest .param (
215+ {"header_type" : "registry" },
216+ id = "invalid_artifact_type" ,
217+ ),
218+ ],
219+ indirect = ["randomly_picked_model_from_catalog_api_by_source" ],
220+ )
221+ def test_error_handled_for_invalid_artifact_type (
222+ self : Self ,
223+ model_catalog_rest_url : list [str ],
224+ model_registry_rest_headers : dict [str , str ],
225+ randomly_picked_model_from_catalog_api_by_source : dict [Any , Any ],
226+ ):
227+ """
228+ RHOAIENG-33659: Validates that the API returns the correct error when an invalid artifactType
229+ is provided regardless of catalog or model.
230+ """
231+ model_name = randomly_picked_model_from_catalog_api_by_source .get ("name" )
232+ catalog_id = randomly_picked_model_from_catalog_api_by_source .get ("source_id" )
233+ assert model_name and catalog_id , "Model name or catalog ID not found in random model"
234+
235+ invalid_artifact_type = "invalid"
236+
237+ with pytest .raises (ResourceNotFoundError , match = f"unsupported catalog artifact type: { invalid_artifact_type } " ):
238+ fetch_all_artifacts_with_dynamic_paging (
239+ url_with_pagesize = (
240+ f"{ model_catalog_rest_url [0 ]} sources/{ catalog_id } /models/{ model_name } /artifacts?"
241+ f"artifactType={ invalid_artifact_type } &pageSize"
242+ ),
243+ headers = model_registry_rest_headers ,
244+ page_size = 1 ,
245+ )
246+
247+ LOGGER .info (f"Successfully validated that invalid artifact type '{ invalid_artifact_type } ' raises an error" )
248+
249+ @pytest .mark .parametrize (
250+ "randomly_picked_model_from_catalog_api_by_source" ,
251+ [
252+ pytest .param (
253+ {"catalog_id" : REDHAT_AI_CATALOG_ID , "header_type" : "registry" },
254+ id = "redhat_ai_catalog" ,
255+ ),
256+ pytest .param (
257+ {"catalog_id" : VALIDATED_CATALOG_ID , "header_type" : "registry" },
258+ id = "validated_catalog" ,
259+ ),
260+ ],
261+ indirect = ["randomly_picked_model_from_catalog_api_by_source" ],
262+ )
263+ def test_multiple_artifact_type_filtering (
264+ self : Self ,
265+ model_catalog_rest_url : list [str ],
266+ model_registry_rest_headers : dict [str , str ],
267+ randomly_picked_model_from_catalog_api_by_source : dict [Any , Any ],
268+ ):
269+ """
270+ RHOAIENG-33659: Validates that the API returns all artifacts of a random model
271+ when filtering by multiple artifact types.
272+ """
273+ model_name = randomly_picked_model_from_catalog_api_by_source .get ("name" )
274+ catalog_id = randomly_picked_model_from_catalog_api_by_source .get ("source_id" )
275+ assert model_name and catalog_id , "Model name or catalog ID not found in random model"
276+ LOGGER .info (f"Testing model '{ model_name } ' from catalog '{ catalog_id } ' for multiple artifact types" )
277+ artifact_types = f"{ METRICS_ARTIFACT_TYPE } ,{ MODEL_ARTIFACT_TYPE } "
278+ # Fetch all artifacts with dynamic page size adjustment
279+ all_model_artifacts = fetch_all_artifacts_with_dynamic_paging (
280+ url_with_pagesize = f"{ model_catalog_rest_url [0 ]} sources/{ catalog_id } /models/{ model_name } /artifacts?pageSize" ,
281+ headers = model_registry_rest_headers ,
282+ page_size = 100 ,
283+ )["items" ]
284+
285+ # Fetch filtered artifacts by type with dynamic page size adjustment
286+ artifact_type_artifacts = fetch_all_artifacts_with_dynamic_paging (
287+ url_with_pagesize = (
288+ f"{ model_catalog_rest_url [0 ]} sources/{ catalog_id } /models/{ model_name } /artifacts?"
289+ f"artifactType={ artifact_types } &pageSize"
290+ ),
291+ headers = model_registry_rest_headers ,
292+ page_size = 100 ,
293+ )["items" ]
294+
295+ assert len (artifact_type_artifacts ) == len (all_model_artifacts ), (
296+ f"Filter returned { len (artifact_type_artifacts )} artifacts, "
297+ f"but found { len (all_model_artifacts )} in complete list for { model_name } "
298+ )
0 commit comments