2323 TEST_COMMIT ,
2424 TEST_FEATURE_SET ,
2525 TEST_VERSION ,
26+ TEST_VERSION_STABLE ,
2627 TEST_PLATFORMS ,
2728 TEST_FEATURE_STRINGS_SHORT ,
2829 TEST_ARCHITECTURES ,
@@ -53,7 +54,6 @@ def push_manifest(runner, version, arch, cname, additional_tags=None):
5354 "manifests/manifest.json" ,
5455 ]
5556
56- # Add additional tags if provided
5757 if additional_tags :
5858 for tag in additional_tags :
5959 cmd .extend (["--additional_tag" , tag ])
@@ -71,23 +71,35 @@ def push_manifest(runner, version, arch, cname, additional_tags=None):
7171 return False
7272
7373
74- def update_index (runner , version ):
75- """Update index in registry"""
74+ def update_index (runner , version , additional_tags = None ):
75+ """Update index in registry and return success status """
7676 print ("Updating index" )
77- result = runner .invoke (
78- gl_oci ,
79- [
80- "update-index" ,
81- "--container" ,
82- CONTAINER_NAME_ZOT_EXAMPLE ,
83- "--version" ,
84- version ,
85- "--insecure" ,
86- "True" ,
87- ],
88- catch_exceptions = False ,
89- )
90- print (f"Update index output: { result .output } " )
77+
78+ cmd = [
79+ "update-index" ,
80+ "--container" ,
81+ CONTAINER_NAME_ZOT_EXAMPLE ,
82+ "--version" ,
83+ version ,
84+ "--insecure" ,
85+ "True" ,
86+ ]
87+
88+ if additional_tags :
89+ for tag in additional_tags :
90+ cmd .extend (["--additional_tag" , tag ])
91+
92+ try :
93+ result = runner .invoke (
94+ gl_oci ,
95+ cmd ,
96+ catch_exceptions = False ,
97+ )
98+ print (f"Update index output: { result .output } " )
99+ return result .exit_code == 0
100+ except Exception as e :
101+ print (f"Error during update index: { str (e )} " )
102+ return False
91103
92104
93105def get_catalog (client ):
@@ -181,14 +193,84 @@ def verify_combined_tag_manifest(manifest, arch, cname, version, feature_set, co
181193 ), f"Manifest should have commit { commit } "
182194
183195
196+ def verify_additional_tags (
197+ client , repo , additional_tags , reference_digest = None , fail_on_missing = True
198+ ):
199+ """
200+ Verify that all additional tags exist and match the reference digest if provided.
201+
202+ Args:
203+ client: Reggie client
204+ repo: Repository name
205+ additional_tags: List of tags to verify
206+ reference_digest: Optional digest to compare against
207+ fail_on_missing: If True, fail the test when tags are missing
208+
209+ Returns:
210+ List of missing tags
211+ """
212+ missing_tags = []
213+
214+ for tag in additional_tags :
215+ print (f"Verifying additional tag: { tag } " )
216+ try :
217+ # Create a simple request for the manifest
218+ tag_req = client .NewRequest ("GET" , f"/v2/{ repo } /manifests/{ tag } " )
219+ tag_req .headers .update (
220+ {
221+ "Accept" : "application/vnd.oci.image.manifest.v1+json,application/vnd.docker.distribution.manifest.v2+json,application/vnd.oci.image.index.v1+json"
222+ }
223+ )
224+
225+ tag_resp = client .Do (tag_req )
226+
227+ if tag_resp .status_code != 200 :
228+ print (
229+ f"✗ Could not find additional tag { tag } : status { tag_resp .status_code } "
230+ )
231+ missing_tags .append (tag )
232+ continue
233+
234+ # Get the digest
235+ digest = tag_resp .headers .get ("Docker-Content-Digest" )
236+
237+ # Check digest if reference provided
238+ if reference_digest and digest != reference_digest :
239+ print (
240+ f"✗ Tag { tag } has different digest: { digest } (expected { reference_digest } )"
241+ )
242+ missing_tags .append (tag )
243+ continue
244+
245+ print (f"✓ Successfully verified additional tag { tag } with digest: { digest } " )
246+
247+ except Exception as e :
248+ print (f"✗ Error verifying tag { tag } : { str (e )} " )
249+ missing_tags .append (tag )
250+
251+ # If any tags are missing and fail_on_missing is True, fail the test
252+ if missing_tags and fail_on_missing :
253+ missing_tags_str = "\n - " .join (missing_tags )
254+ pytest .fail (f"Missing tags:\n - { missing_tags_str } " )
255+
256+ return missing_tags
257+
258+
184259@pytest .mark .usefixtures ("zot_session" )
185260@pytest .mark .parametrize (
186- "version, cname, arch, additional_tags " ,
261+ "version, cname, arch, additional_tags_index, additional_tags_manifest " ,
187262 [
188263 (
189264 TEST_VERSION ,
190265 f"{ platform } -{ feature_string } " ,
191266 arch ,
267+ [
268+ f"{ TEST_VERSION } -patch" ,
269+ f"{ TEST_VERSION } -patch-{ TEST_COMMIT } " ,
270+ f"{ TEST_VERSION_STABLE } " ,
271+ f"{ TEST_VERSION_STABLE } -stable" ,
272+ f"latest" ,
273+ ],
192274 [
193275 f"{ TEST_VERSION } -patch-{ platform } -{ feature_string } -{ arch } " ,
194276 f"{ TEST_VERSION } -{ TEST_COMMIT } -patch-{ platform } -{ feature_string } -{ arch } " ,
@@ -200,19 +282,24 @@ def verify_combined_tag_manifest(manifest, arch, cname, version, feature_set, co
200282 for arch in TEST_ARCHITECTURES
201283 ],
202284)
203- def test_push_manifest_and_index (version , arch , cname , additional_tags ):
285+ def test_push_manifest_and_index (
286+ version , arch , cname , additional_tags_index , additional_tags_manifest
287+ ):
204288 print (f"\n \n === Starting test for { cname } { arch } { version } ===" )
205289 runner = CliRunner ()
206290 registry_url = "http://127.0.0.1:18081"
207291 repo_name = "gardenlinux-example"
208292 combined_tag = f"{ version } -{ cname } -{ arch } "
209293
210294 # Push manifest and update index
211- push_successful = push_manifest (runner , version , arch , cname , additional_tags )
295+ push_successful = push_manifest (
296+ runner , version , arch , cname , additional_tags_manifest
297+ )
212298 assert push_successful , "Manifest push should succeed"
213299
214300 if push_successful :
215- update_index (runner , version )
301+ update_index_successful = update_index (runner , version , additional_tags_index )
302+ assert update_index_successful , "Index update should succeed"
216303
217304 # Verify registry contents
218305 print (f"\n === Verifying registry for { cname } { arch } { version } ===" )
@@ -234,54 +321,44 @@ def test_push_manifest_and_index(version, arch, cname, additional_tags):
234321 tags = get_tags (client , repo_name )
235322 print (f"Tags for { repo_name } : { tags } " )
236323
237- # Verify version tag (index)
238- if version in tags :
239- print (f"\n Verifying index with tag { version } ..." )
240- index_manifest , index_digest = get_manifest (client , repo_name , version )
241- print (f"Successfully retrieved index with digest: { index_digest } " )
242- verify_index_manifest (index_manifest , arch )
243- else :
244- pytest .fail (f"Tag { version } not found in repository { repo_name } " )
245-
246- # Verify combined tag
324+ # FIRST: Verify manifest with combined tag (the actual artifact)
325+ print (f"\n === Verifying manifest with combined tag { combined_tag } ===" )
247326 if combined_tag in tags :
248- print (f"\n Verifying manifest with combined tag { combined_tag } ..." )
249- combined_manifest , combined_digest = get_manifest (
250- client , repo_name , combined_tag
251- )
252- print (f"Successfully retrieved manifest with digest: { combined_digest } " )
327+ manifest , manifest_digest = get_manifest (client , repo_name , combined_tag )
328+ print (f"Successfully retrieved manifest with digest: { manifest_digest } " )
253329 verify_combined_tag_manifest (
254- combined_manifest , arch , cname , version , TEST_FEATURE_SET , TEST_COMMIT
330+ manifest , arch , cname , version , TEST_FEATURE_SET , TEST_COMMIT
331+ )
332+
333+ # Verify additional tags for manifest
334+ print ("\n === Verifying additional tags for manifest ===" )
335+ verify_additional_tags (
336+ client ,
337+ repo_name ,
338+ additional_tags_manifest ,
339+ reference_digest = manifest_digest ,
340+ fail_on_missing = True ,
255341 )
256342 else :
257343 pytest .fail (f"Combined tag { combined_tag } not found in repository { repo_name } " )
258344
259- print ("\n === Verifying additional tags in main repository ===" )
260- # Force update the tags list to ensure it's current
261- updated_tags = get_tags (client , repo_name )
262- print (f"Updated tags for { repo_name } : { updated_tags } " )
263-
264- # Now try each additional tag but don't fail the test if not found
265- missing_tags = []
266- for tag in additional_tags :
267- print (f"Verifying additional tag: { tag } " )
268- try :
269- tag_manifest , tag_digest = get_manifest (client , repo_name , tag )
270- print (
271- f"✓ Successfully retrieved additional tag { tag } with digest: { tag_digest } "
272- )
273- except Exception as e :
274- print (f"✗ Could not find additional tag { tag } : { str (e )} " )
275- missing_tags .append (tag )
345+ # SECOND: Verify index (the collection of manifests)
346+ print (f"\n === Verifying index with tag { version } ===" )
347+ if version in tags :
348+ index_manifest , index_digest = get_manifest (client , repo_name , version )
349+ print (f"Successfully retrieved index with digest: { index_digest } " )
350+ verify_index_manifest (index_manifest , arch )
276351
277- # Report missing tags but don't fail the test
278- if missing_tags :
279- print (
280- f"\n Warning: { len (missing_tags )} additional tags were not found in the registry:"
352+ # Verify additional tags for index
353+ print ("\n === Verifying additional tags for index ===" )
354+ verify_additional_tags (
355+ client ,
356+ repo_name ,
357+ additional_tags_index ,
358+ reference_digest = index_digest ,
359+ fail_on_missing = True ,
281360 )
282- for tag in missing_tags :
283- print (f" - { tag } " )
284361 else :
285- print ( " \n All additional tags were successfully pushed! " )
362+ pytest . fail ( f"Tag { version } not found in repository { repo_name } " )
286363
287364 print ("\n === Registry verification completed ===" )
0 commit comments