@@ -353,6 +353,154 @@ def test_fishy_rolenames(self) -> None:
353
353
for fname in roles_to_filenames .values ():
354
354
self .assertTrue (fname in local_metadata )
355
355
356
+ hash_bins_metadata : utils .DataSet = {
357
+ "delegated hash bins" : DelegationsTestCase (
358
+ delegations = [
359
+ TestDelegation ("targets" , "f8-ff" ),
360
+ TestDelegation ("targets" , "20-27" ),
361
+ TestDelegation ("targets" , "70-77" ),
362
+ TestDelegation ("targets" , "58-5f" ),
363
+ ],
364
+ target_files = [
365
+ TestTarget (
366
+ "f8-ff" ,
367
+ b"fff0838676c1dacb8827b02511e89f85b43814a74dd2c3ffb31d952a1db94311" ,
368
+ "test_hashed_bins.ext" ,
369
+ ),
370
+ TestTarget (
371
+ "20-27" ,
372
+ b"22992ae806e6d652835f3c84e169f05127da69e599f902e4dbdc6ff27ce46d01" ,
373
+ "delegate_1.ext" ,
374
+ ),
375
+ TestTarget (
376
+ "70-77" ,
377
+ b"77e5df355e2af6a842b47e8cb3fb0649ec29062917e6bcf0793adbf001faefc2" ,
378
+ "delegate_2.ext" ,
379
+ ),
380
+ TestTarget (
381
+ "58-5f" ,
382
+ b"5ac2ad3230b5cd7f2f0cc99ef2d0d5024a3a34f6b7bf38a4db8694a1fd953271" ,
383
+ "delegate_3.ext" ,
384
+ ),
385
+ ],
386
+ visited_order = ["f8-ff" , "20-27" , "70-77" , "58-5f" ],
387
+ ),
388
+ }
389
+
390
+ @utils .run_sub_tests_with_dataset (hash_bins_metadata )
391
+ def test_delegated_hash_bins (self , test_data : DelegationsTestCase ) -> None :
392
+ try :
393
+ self ._init_repo (test_data )
394
+ self .setup_subtest ()
395
+
396
+ updater = self ._init_updater ()
397
+ # Call explicitly refresh to simplify the expected_calls list
398
+ updater .refresh ()
399
+ self .sim .fetch_tracker .metadata .clear ()
400
+
401
+ roles_pref_map = [
402
+ (
403
+ "f8-ff" ,
404
+ [
405
+ "f8" ,
406
+ "f9" ,
407
+ "fa" ,
408
+ "fb" ,
409
+ "fc" ,
410
+ "fd" ,
411
+ "fe" ,
412
+ "ff" ,
413
+ ],
414
+ ),
415
+ (
416
+ "20-27" ,
417
+ [
418
+ "20" ,
419
+ "21" ,
420
+ "22" ,
421
+ "23" ,
422
+ "24" ,
423
+ "25" ,
424
+ "26" ,
425
+ "27" ,
426
+ ],
427
+ ),
428
+ (
429
+ "70-77" ,
430
+ [
431
+ "70" ,
432
+ "71" ,
433
+ "72" ,
434
+ "73" ,
435
+ "74" ,
436
+ "75" ,
437
+ "76" ,
438
+ "77" ,
439
+ ],
440
+ ),
441
+ (
442
+ "58-5f" ,
443
+ [
444
+ "58" ,
445
+ "59" ,
446
+ "5a" ,
447
+ "5b" ,
448
+ "5c" ,
449
+ "5d" ,
450
+ "5e" ,
451
+ "5f" ,
452
+ ],
453
+ ),
454
+ ]
455
+
456
+ delegated_role1 = DelegatedRole (
457
+ roles_pref_map [0 ][0 ], [], 1 , False , roles_pref_map [0 ][1 ]
458
+ )
459
+ delegated_role1 .path_hash_prefixes = roles_pref_map [0 ][1 ]
460
+
461
+ delegated_role2 = DelegatedRole (
462
+ roles_pref_map [1 ][0 ], [], 1 , False , roles_pref_map [1 ][1 ]
463
+ )
464
+ delegated_role2 .path_hash_prefixes = roles_pref_map [1 ][1 ]
465
+
466
+ delegated_role3 = DelegatedRole (
467
+ roles_pref_map [2 ][0 ], [], 1 , False , roles_pref_map [2 ][1 ]
468
+ )
469
+ delegated_role3 .path_hash_prefixes = roles_pref_map [2 ][1 ]
470
+
471
+ delegated_role4 = DelegatedRole (
472
+ roles_pref_map [3 ][0 ], [], 1 , False , roles_pref_map [3 ][1 ]
473
+ )
474
+ delegated_role4 .path_hash_prefixes = roles_pref_map [3 ][1 ]
475
+
476
+ spec_version = "." .join (SPECIFICATION_VERSION )
477
+ targets = Targets (1 , spec_version , self .sim .safe_expiry , {}, None )
478
+ self .sim .add_delegation ("targets" , delegated_role1 , targets )
479
+ self .sim .add_delegation ("f8-ff" , delegated_role2 , targets )
480
+ self .sim .add_delegation ("20-27" , delegated_role3 , targets )
481
+ self .sim .add_delegation ("70-77" , delegated_role4 , targets )
482
+
483
+ # verify that the target info was successfully found and the correct delegated metadata file was downloaded
484
+ target_info = updater .get_targetinfo ("test_hashed_bins.ext" )
485
+ assert target_info is not None
486
+ self .assertEqual (target_info .path , "test_hashed_bins.ext" )
487
+
488
+ target_info = updater .get_targetinfo ("delegate_1.ext" )
489
+ assert target_info is not None
490
+ self .assertEqual (target_info .path , "delegate_1.ext" )
491
+
492
+ target_info = updater .get_targetinfo ("delegate_2.ext" )
493
+ assert target_info is not None
494
+ self .assertEqual (target_info .path , "delegate_2.ext" )
495
+
496
+ target_info = updater .get_targetinfo ("delegate_3.ext" )
497
+ assert target_info is not None
498
+ self .assertEqual (target_info .path , "delegate_3.ext" )
499
+
500
+ # add any other error cases that can come to mind
501
+ finally :
502
+ self .teardown_subtest ()
503
+
356
504
357
505
class TestTargetFileSearch (TestDelegations ):
358
506
r"""
0 commit comments