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 @@ -34,6 +34,7 @@ Content, Directory, DirectoryEntry, + ExtID, ObjectType, Origin, OriginVisit, @@ -287,6 +288,20 @@ return one_of(present_contents(), skipped_contents()) +def extids_d(): + return builds( + dict, + target_type=sampled_from([x.value for x in ObjectType]), + target=sha1_git(), + extid_type=sampled_from(["hg", "git", "bzr"]), + extid=sha1(), + ) + + +def extids(): + return extids_d().map(ExtID.from_dict) + + def present_contents_d(): return builds( dict, @@ -421,6 +436,7 @@ ("release", releases), ("revision", revisions), ("directory", directories), + ("extid", extids), ] if split_content: strategies.append(("content", present_contents)) @@ -454,6 +470,7 @@ ("release", releases_d), ("revision", revisions_d), ("directory", directories_d), + ("extid", extids_d), ] if split_content: strategies.append(("content", present_contents_d)) diff --git a/swh/model/model.py b/swh/model/model.py --- a/swh/model/model.py +++ b/swh/model/model.py @@ -35,7 +35,7 @@ pass -KeyType = Union[Dict[str, str], Dict[str, bytes], bytes] +KeyType = Union[Dict[str, str], Dict[str, bytes], Tuple[Union[str, bytes], ...], bytes] """The type returned by BaseModel.unique_key().""" @@ -1072,3 +1072,25 @@ "fetcher_name": self.fetcher.name, "fetcher_version": self.fetcher.version, } + + +@attr.s(frozen=True, slots=True) +class ExtID(BaseModel): + object_type: Final = "extid" + + extid = attr.ib(type=bytes, validator=type_validator()) + extid_type = attr.ib(type=str, validator=type_validator()) + target = attr.ib(type=Sha1Git, validator=type_validator()) + target_type = attr.ib(type=ObjectType, validator=type_validator()) + + @classmethod + def from_dict(cls, d): + return cls( + extid=d["extid"], + extid_type=d["extid_type"], + target=d["target"], + target_type=ObjectType(d["target_type"]), + ) + + def unique_key(self) -> KeyType: + return attr.astuple(self) diff --git a/swh/model/tests/test_model.py b/swh/model/tests/test_model.py --- a/swh/model/tests/test_model.py +++ b/swh/model/tests/test_model.py @@ -1224,3 +1224,16 @@ ), **_common_metadata_fields, ) + + +@given(strategies.extids()) +def test_extid(extid): + assert extid + assert extid.unique_key() + assert extid.target_type.value in ( + "content", + "directory", + "revision", + "release", + "snapshot", + )