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,24 +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 } " )
9177
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
92103
93104def get_catalog (client ):
94105 """Get catalog from registry and return repositories list"""
@@ -181,14 +192,78 @@ def verify_combined_tag_manifest(manifest, arch, cname, version, feature_set, co
181192 ), f"Manifest should have commit { commit } "
182193
183194
195+ def verify_additional_tags (client , repo , additional_tags , reference_digest = None , fail_on_missing = True ):
196+ """
197+ Verify that all additional tags exist and match the reference digest if provided.
198+
199+ Args:
200+ client: Reggie client
201+ repo: Repository name
202+ additional_tags: List of tags to verify
203+ reference_digest: Optional digest to compare against
204+ fail_on_missing: If True, fail the test when tags are missing
205+
206+ Returns:
207+ List of missing tags
208+ """
209+ missing_tags = []
210+
211+ for tag in additional_tags :
212+ print (f"Verifying additional tag: { tag } " )
213+ try :
214+ # Create a simple request for the manifest
215+ tag_req = client .NewRequest ("GET" , f"/v2/{ repo } /manifests/{ tag } " )
216+ tag_req .headers .update (
217+ {
218+ "Accept" : "application/vnd.oci.image.manifest.v1+json,application/vnd.docker.distribution.manifest.v2+json,application/vnd.oci.image.index.v1+json"
219+ }
220+ )
221+
222+ tag_resp = client .Do (tag_req )
223+
224+ if tag_resp .status_code != 200 :
225+ print (f"✗ Could not find additional tag { tag } : status { tag_resp .status_code } " )
226+ missing_tags .append (tag )
227+ continue
228+
229+ # Get the digest
230+ digest = tag_resp .headers .get ("Docker-Content-Digest" )
231+
232+ # Check digest if reference provided
233+ if reference_digest and digest != reference_digest :
234+ print (f"✗ Tag { tag } has different digest: { digest } (expected { reference_digest } )" )
235+ missing_tags .append (tag )
236+ continue
237+
238+ print (f"✓ Successfully verified additional tag { tag } with digest: { digest } " )
239+
240+ except Exception as e :
241+ print (f"✗ Error verifying tag { tag } : { str (e )} " )
242+ missing_tags .append (tag )
243+
244+ # If any tags are missing and fail_on_missing is True, fail the test
245+ if missing_tags and fail_on_missing :
246+ missing_tags_str = "\n - " .join (missing_tags )
247+ pytest .fail (f"Missing tags:\n - { missing_tags_str } " )
248+
249+ return missing_tags
250+
251+
184252@pytest .mark .usefixtures ("zot_session" )
185253@pytest .mark .parametrize (
186- "version, cname, arch, additional_tags " ,
254+ "version, cname, arch, additional_tags_index, additional_tags_manifest " ,
187255 [
188256 (
189257 TEST_VERSION ,
190258 f"{ platform } -{ feature_string } " ,
191259 arch ,
260+ [
261+ f"{ TEST_VERSION } -patch" ,
262+ f"{ TEST_VERSION } -patch-{ TEST_COMMIT } " ,
263+ f"{ TEST_VERSION_STABLE } " ,
264+ f"{ TEST_VERSION_STABLE } -stable" ,
265+ f"latest" ,
266+ ],
192267 [
193268 f"{ TEST_VERSION } -patch-{ platform } -{ feature_string } -{ arch } " ,
194269 f"{ TEST_VERSION } -{ TEST_COMMIT } -patch-{ platform } -{ feature_string } -{ arch } " ,
@@ -200,19 +275,20 @@ def verify_combined_tag_manifest(manifest, arch, cname, version, feature_set, co
200275 for arch in TEST_ARCHITECTURES
201276 ],
202277)
203- def test_push_manifest_and_index (version , arch , cname , additional_tags ):
278+ def test_push_manifest_and_index (version , arch , cname , additional_tags_index , additional_tags_manifest ):
204279 print (f"\n \n === Starting test for { cname } { arch } { version } ===" )
205280 runner = CliRunner ()
206281 registry_url = "http://127.0.0.1:18081"
207282 repo_name = "gardenlinux-example"
208283 combined_tag = f"{ version } -{ cname } -{ arch } "
209284
210285 # Push manifest and update index
211- push_successful = push_manifest (runner , version , arch , cname , additional_tags )
286+ push_successful = push_manifest (runner , version , arch , cname , additional_tags_manifest )
212287 assert push_successful , "Manifest push should succeed"
213288
214289 if push_successful :
215- update_index (runner , version )
290+ update_index_successful = update_index (runner , version , additional_tags_index )
291+ assert update_index_successful , "Index update should succeed"
216292
217293 # Verify registry contents
218294 print (f"\n === Verifying registry for { cname } { arch } { version } ===" )
@@ -234,54 +310,36 @@ def test_push_manifest_and_index(version, arch, cname, additional_tags):
234310 tags = get_tags (client , repo_name )
235311 print (f"Tags for { repo_name } : { tags } " )
236312
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
313+ # FIRST: Verify manifest with combined tag (the actual artifact)
314+ print (f"\n === Verifying manifest with combined tag { combined_tag } ===" )
247315 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 } " )
316+ manifest , manifest_digest = get_manifest (client , repo_name , combined_tag )
317+ print (f"Successfully retrieved manifest with digest: { manifest_digest } " )
253318 verify_combined_tag_manifest (
254- combined_manifest , arch , cname , version , TEST_FEATURE_SET , TEST_COMMIT
319+ manifest , arch , cname , version , TEST_FEATURE_SET , TEST_COMMIT
255320 )
321+
322+ # Verify additional tags for manifest
323+ print ("\n === Verifying additional tags for manifest ===" )
324+ verify_additional_tags (client , repo_name , additional_tags_manifest ,
325+ reference_digest = manifest_digest ,
326+ fail_on_missing = True )
256327 else :
257328 pytest .fail (f"Combined tag { combined_tag } not found in repository { repo_name } " )
258329
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 )
330+ # SECOND: Verify index (the collection of manifests)
331+ print (f"\n === Verifying index with tag { version } ===" )
332+ if version in tags :
333+ index_manifest , index_digest = get_manifest (client , repo_name , version )
334+ print (f"Successfully retrieved index with digest: { index_digest } " )
335+ verify_index_manifest (index_manifest , arch )
276336
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:"
281- )
282- for tag in missing_tags :
283- print (f" - { tag } " )
337+ # Verify additional tags for index
338+ print ("\n === Verifying additional tags for index ===" )
339+ verify_additional_tags (client , repo_name , additional_tags_index ,
340+ reference_digest = index_digest ,
341+ fail_on_missing = True )
284342 else :
285- print ( " \n All additional tags were successfully pushed! " )
343+ pytest . fail ( f"Tag { version } not found in repository { repo_name } " )
286344
287345 print ("\n === Registry verification completed ===" )
0 commit comments