@@ -32,7 +32,7 @@ class TestDelegation:
32
32
keyids : List [str ] = field (default_factory = list )
33
33
threshold : int = 1
34
34
terminating : bool = False
35
- paths : List [str ] = field (default_factory = lambda : ["*" ])
35
+ paths : Optional [ List [str ] ] = field (default_factory = lambda : ["*" ])
36
36
path_hash_prefixes : Optional [List [str ]] = None
37
37
38
38
@@ -362,6 +362,132 @@ def test_safely_encoded_rolenames(self) -> None:
362
362
exp_calls = [(quoted [:- 5 ], 1 ) for quoted in roles_to_filenames .values ()]
363
363
self .assertListEqual (self .sim .fetch_tracker .metadata , exp_calls )
364
364
365
+ hash_bins_metadata : utils .DataSet = {
366
+ "delegated hash bins" : DelegationsTestCase (
367
+ delegations = [
368
+ TestDelegation (
369
+ "targets" ,
370
+ "f8-ff" ,
371
+ paths = None ,
372
+ path_hash_prefixes = [
373
+ "f8" ,
374
+ "f9" ,
375
+ "fa" ,
376
+ "fb" ,
377
+ "fc" ,
378
+ "fd" ,
379
+ "fe" ,
380
+ "ff" ,
381
+ ],
382
+ ),
383
+ TestDelegation (
384
+ "targets" ,
385
+ "20-27" ,
386
+ paths = None ,
387
+ path_hash_prefixes = [
388
+ "20" ,
389
+ "21" ,
390
+ "22" ,
391
+ "23" ,
392
+ "24" ,
393
+ "25" ,
394
+ "26" ,
395
+ "27" ,
396
+ ],
397
+ ),
398
+ ],
399
+ target_files = [
400
+ TestTarget (
401
+ "f8-ff" ,
402
+ b"fff0838676c1dacb8827b02511e89f85b43814a74dd2c3ffb31d952a1db94311" ,
403
+ "non_matching_path_to_prefix.ext" ,
404
+ ),
405
+ TestTarget (
406
+ "20-27" ,
407
+ b"22992ae806e6d652835f3c84e169f05127da69e599f902e4dbdc6ff27ce46d01" ,
408
+ "delegate_1.ext" ,
409
+ ),
410
+ ],
411
+ visited_order = ["f8-ff" , "20-27" ],
412
+ ),
413
+ }
414
+
415
+ @utils .run_sub_tests_with_dataset (hash_bins_metadata )
416
+ def test_delegated_hash_bins (self , test_data : DelegationsTestCase ) -> None :
417
+ try :
418
+ self ._init_repo (test_data )
419
+ self .setup_subtest ()
420
+
421
+ updater = self ._init_updater ()
422
+ # Call explicitly refresh to simplify the expected_calls list
423
+ updater .refresh ()
424
+ self .sim .fetch_tracker .metadata .clear ()
425
+
426
+ roles_pref_map = [
427
+ (
428
+ "f8-ff" ,
429
+ [
430
+ "f8" ,
431
+ "f9" ,
432
+ "fa" ,
433
+ "fb" ,
434
+ "fc" ,
435
+ "fd" ,
436
+ "fe" ,
437
+ "ff" ,
438
+ ],
439
+ ),
440
+ (
441
+ "20-27" ,
442
+ [
443
+ "20" ,
444
+ "21" ,
445
+ "22" ,
446
+ "23" ,
447
+ "24" ,
448
+ "25" ,
449
+ "26" ,
450
+ "27" ,
451
+ ],
452
+ ),
453
+ ]
454
+
455
+ delegated_role1 = DelegatedRole (
456
+ roles_pref_map [0 ][0 ], [], 1 , False , roles_pref_map [0 ][1 ]
457
+ )
458
+ delegated_role1 .path_hash_prefixes = roles_pref_map [0 ][1 ]
459
+
460
+ delegated_role2 = DelegatedRole (
461
+ roles_pref_map [1 ][0 ], [], 1 , False , roles_pref_map [1 ][1 ]
462
+ )
463
+ delegated_role2 .path_hash_prefixes = roles_pref_map [1 ][1 ]
464
+
465
+ spec_version = "." .join (SPECIFICATION_VERSION )
466
+ targets = Targets (1 , spec_version , self .sim .safe_expiry , {}, None )
467
+ self .sim .add_delegation ("targets" , delegated_role1 , targets )
468
+ self .sim .add_delegation ("f8-ff" , delegated_role2 , targets )
469
+
470
+ # verify that no metadata file was downloaded as expected
471
+ # for non-existing path
472
+ target_info = updater .get_targetinfo ("missingpath" )
473
+ self .assertIsNone (target_info )
474
+
475
+ # verify that no metadata file was downloaded for existing
476
+ # path that doesn't match correct prefix
477
+ target_info = updater .get_targetinfo (
478
+ "non_matching_path_to_prefix.ext"
479
+ )
480
+ self .assertIsNone (target_info )
481
+
482
+ # verify that the target info was successfully found
483
+ # and the correct delegated metadata file was downloaded
484
+ target_info = updater .get_targetinfo ("delegate_1.ext" )
485
+ assert target_info is not None
486
+ self .assertEqual (target_info .path , "delegate_1.ext" )
487
+
488
+ finally :
489
+ self .teardown_subtest ()
490
+
365
491
366
492
class TestTargetFileSearch (TestDelegations ):
367
493
r"""
0 commit comments