diff --git a/swh/model/hypothesis_strategies.py b/swh/model/hypothesis_strategies.py --- a/swh/model/hypothesis_strategies.py +++ b/swh/model/hypothesis_strategies.py @@ -188,15 +188,16 @@ )) if not only_objects: - # Make sure aliases point to actual branches + # Make sure aliases point to actual branches and no cycles exist unresolved_aliases = { - target.target - for target in branches.values() - if (target - and target.target_type == 'alias' - and target.target not in branches) - } - + branch.target + for name, branch in branches.items() + if (branch + and branch.target_type == 'alias' + and (branch.target not in branches or + (branches[branch.target] and + branches[branch.target].target == name))) + } for alias in unresolved_aliases: branches[alias] = draw(branch_targets(only_objects=True)) diff --git a/swh/model/tests/test_hypothesis_strategies.py b/swh/model/tests/test_hypothesis_strategies.py --- a/swh/model/tests/test_hypothesis_strategies.py +++ b/swh/model/tests/test_hypothesis_strategies.py @@ -9,7 +9,7 @@ from hypothesis import given from swh.model.hashutil import DEFAULT_ALGORITHMS -from swh.model.hypothesis_strategies import objects, object_dicts +from swh.model.hypothesis_strategies import objects, object_dicts, snapshots target_types = ( @@ -60,3 +60,12 @@ elif obj_type == 'snapshot': for branch in object_['branches'].values(): assert branch is None or branch['target_type'] in target_types + + +@given(snapshots(min_size=4)) +def test_generated_snapshot_branch_alias(snapshot): + for name, branch in snapshot.branches.items(): + if branch and branch.target_type == 'alias': + assert branch.target in snapshot.branches + alias_target = snapshot.branches[branch.target] + assert not alias_target or alias_target.target != name