23
23
TEST_COMMIT ,
24
24
TEST_FEATURE_SET ,
25
25
TEST_VERSION ,
26
+ TEST_VERSION_STABLE ,
26
27
TEST_PLATFORMS ,
27
28
TEST_FEATURE_STRINGS_SHORT ,
28
29
TEST_ARCHITECTURES ,
@@ -53,7 +54,6 @@ def push_manifest(runner, version, arch, cname, additional_tags=None):
53
54
"manifests/manifest.json" ,
54
55
]
55
56
56
- # Add additional tags if provided
57
57
if additional_tags :
58
58
for tag in additional_tags :
59
59
cmd .extend (["--additional_tag" , tag ])
@@ -71,23 +71,35 @@ def push_manifest(runner, version, arch, cname, additional_tags=None):
71
71
return False
72
72
73
73
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 """
76
76
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
91
103
92
104
93
105
def get_catalog (client ):
@@ -181,14 +193,84 @@ def verify_combined_tag_manifest(manifest, arch, cname, version, feature_set, co
181
193
), f"Manifest should have commit { commit } "
182
194
183
195
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
+
184
259
@pytest .mark .usefixtures ("zot_session" )
185
260
@pytest .mark .parametrize (
186
- "version, cname, arch, additional_tags " ,
261
+ "version, cname, arch, additional_tags_index, additional_tags_manifest " ,
187
262
[
188
263
(
189
264
TEST_VERSION ,
190
265
f"{ platform } -{ feature_string } " ,
191
266
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
+ ],
192
274
[
193
275
f"{ TEST_VERSION } -patch-{ platform } -{ feature_string } -{ arch } " ,
194
276
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
200
282
for arch in TEST_ARCHITECTURES
201
283
],
202
284
)
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
+ ):
204
288
print (f"\n \n === Starting test for { cname } { arch } { version } ===" )
205
289
runner = CliRunner ()
206
290
registry_url = "http://127.0.0.1:18081"
207
291
repo_name = "gardenlinux-example"
208
292
combined_tag = f"{ version } -{ cname } -{ arch } "
209
293
210
294
# 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
+ )
212
298
assert push_successful , "Manifest push should succeed"
213
299
214
300
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"
216
303
217
304
# Verify registry contents
218
305
print (f"\n === Verifying registry for { cname } { arch } { version } ===" )
@@ -234,54 +321,44 @@ def test_push_manifest_and_index(version, arch, cname, additional_tags):
234
321
tags = get_tags (client , repo_name )
235
322
print (f"Tags for { repo_name } : { tags } " )
236
323
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 } ===" )
247
326
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 } " )
253
329
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 ,
255
341
)
256
342
else :
257
343
pytest .fail (f"Combined tag { combined_tag } not found in repository { repo_name } " )
258
344
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 )
276
351
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 ,
281
360
)
282
- for tag in missing_tags :
283
- print (f" - { tag } " )
284
361
else :
285
- print ( " \n All additional tags were successfully pushed! " )
362
+ pytest . fail ( f"Tag { version } not found in repository { repo_name } " )
286
363
287
364
print ("\n === Registry verification completed ===" )
0 commit comments