@@ -425,6 +425,91 @@ def test_hash_bins_graph_traversal(
425425 finally :
426426 self .teardown_subtest ()
427427
428+ @dataclass
429+ class SuccinctRolesTestCase :
430+ bit_length : int
431+ target_path : str
432+ expected_target_bin : str
433+
434+ # By setting the bit_length the total number of bins is 2^bit_length.
435+ # In each test case target_path is a path to a random target we want to
436+ # fetch and expected_target_bin is the bin we are expecting to visit.
437+ succinct_bins_graph : utils .DataSet = {
438+ "bin amount = 2, taget bin index 0" : SuccinctRolesTestCase (
439+ bit_length = 1 ,
440+ target_path = "boo" ,
441+ expected_target_bin = "bin-0" ,
442+ ),
443+ "bin amount = 2, taget bin index 1" : SuccinctRolesTestCase (
444+ bit_length = 1 ,
445+ target_path = "too" ,
446+ expected_target_bin = "bin-1" ,
447+ ),
448+ "bin amount = 4, taget bin index 0" : SuccinctRolesTestCase (
449+ bit_length = 2 ,
450+ target_path = "foo" ,
451+ expected_target_bin = "bin-0" ,
452+ ),
453+ "bin amount = 4, taget bin index 1" : SuccinctRolesTestCase (
454+ bit_length = 2 ,
455+ target_path = "doo" ,
456+ expected_target_bin = "bin-1" ,
457+ ),
458+ "bin amount = 4, taget bin index 2" : SuccinctRolesTestCase (
459+ bit_length = 2 ,
460+ target_path = "too" ,
461+ expected_target_bin = "bin-2" ,
462+ ),
463+ "bin amount = 4, taget bin index 3" : SuccinctRolesTestCase (
464+ bit_length = 2 ,
465+ target_path = "bar" ,
466+ expected_target_bin = "bin-3" ,
467+ ),
468+ "bin amount = 256, taget bin index fc" : SuccinctRolesTestCase (
469+ bit_length = 8 ,
470+ target_path = "bar" ,
471+ expected_target_bin = "bin-fc" ,
472+ ),
473+ }
474+
475+ @utils .run_sub_tests_with_dataset (succinct_bins_graph )
476+ def test_succinct_roles_graph_traversal (
477+ self , test_data : SuccinctRolesTestCase
478+ ) -> None :
479+ # Test traversing the delegation tree when succinct roles is used. For a
480+ # successful traversal all top level metadata files plus the expected
481+ # bin should exist locally and only one bin must be downloaded.
482+
483+ try :
484+ exp_files = [* TOP_LEVEL_ROLE_NAMES , test_data .expected_target_bin ]
485+ exp_calls = [(test_data .expected_target_bin , 1 )]
486+
487+ self .sim = RepositorySimulator ()
488+ self .sim .add_succinct_roles ("targets" , test_data .bit_length , "bin" )
489+ self .sim .update_snapshot ()
490+
491+ self .setup_subtest ()
492+
493+ updater = self ._init_updater ()
494+ # Call explicitly refresh to simplify the expected_calls list.
495+ updater .refresh ()
496+ self .sim .fetch_tracker .metadata .clear ()
497+ # Check that metadata dir contains only top-level roles
498+ self ._assert_files_exist (TOP_LEVEL_ROLE_NAMES )
499+
500+ # Looking for a non-existing targetpath forces updater
501+ # to visit a corresponding delegated role.
502+ targetfile = updater .get_targetinfo (test_data .target_path )
503+ self .assertIsNone (targetfile )
504+
505+ # Check that the delegated roles were visited in the expected
506+ # order and the corresponding metadata files were persisted.
507+ self .assertListEqual (self .sim .fetch_tracker .metadata , exp_calls )
508+ self ._assert_files_exist (exp_files )
509+
510+ finally :
511+ self .teardown_subtest ()
512+
428513
429514class TestTargetFileSearch (TestDelegations ):
430515 r"""
0 commit comments