diff --git a/tests/test_metadata_eq_.py b/tests/test_metadata_eq_.py index 4f21e397..e79815f0 100644 --- a/tests/test_metadata_eq_.py +++ b/tests/test_metadata_eq_.py @@ -23,11 +23,7 @@ Metadata, MetaFile, Role, - Root, - Snapshot, TargetFile, - Targets, - Timestamp, ) @@ -41,34 +37,76 @@ def setUpClass(cls) -> None: cls.repo_dir = os.path.join( utils.TESTS_DIR, "repository_data", "repository", "metadata" ) - cls.metadata = {} + + # Store class instances in this dict instead of creating them inside the + # test function in order to escape the need for reinitialization of the + # instances on each run of the test function. + cls.objects = {} for md in TOP_LEVEL_ROLE_NAMES: with open(os.path.join(cls.repo_dir, f"{md}.json"), "rb") as f: - cls.metadata[md] = f.read() + data = f.read() + cls.objects[md.capitalize()] = Metadata.from_bytes(data).signed + + cls.objects["Metadata"] = Metadata(cls.objects["Timestamp"], {}) + cls.objects["Signed"] = cls.objects["Timestamp"] + cls.objects["Key"] = Key( + "id", "rsa", "rsassa-pss-sha256", {"public": "foo"} + ) + cls.objects["Role"] = Role(["keyid1", "keyid2"], 3) + cls.objects["MetaFile"] = MetaFile(1, 12, {"sha256": "abc"}) + cls.objects["DelegatedRole"] = DelegatedRole("a", [], 1, False, ["d"]) + cls.objects["Delegations"] = Delegations( + {"keyid": cls.objects["Key"]}, {"a": cls.objects["DelegatedRole"]} + ) + cls.objects["TargetFile"] = TargetFile( + 1, {"sha256": "abc"}, "file1.txt" + ) + + # Keys are class names. + # Values are dictionaries containing attribute names and their new values. + classes_attributes_modifications: utils.DataSet = { + "Metadata": {"signed": None, "signatures": None}, + "Signed": {"version": -1, "spec_version": "0.0.0"}, + "Key": {"keyid": "a", "keytype": "foo", "scheme": "b", "keyval": "b"}, + "Role": {"keyids": [], "threshold": 10}, + "Root": {"consistent_snapshot": None, "keys": {}}, + "MetaFile": {"version": None, "length": None, "hashes": {}}, + "Timestamp": {"snapshot_meta": None}, + "Snapshot": {"meta": None}, + "DelegatedRole": { + "name": "", + "terminating": None, + "paths": [""], + "path_hash_prefixes": [""], + }, + "Delegations": {"keys": {}, "roles": {}}, + "TargetFile": {"length": 0, "hashes": {}, "path": ""}, + "Targets": {"targets": {}, "delegations": []}, + } + + @utils.run_sub_tests_with_dataset(classes_attributes_modifications) + def test_classes_eq_(self, test_case_data: Dict[str, Any]) -> None: + obj = self.objects[self.case_name] # pylint: disable=no-member - def copy_and_simple_assert(self, obj: Any) -> Any: # Assert that obj is not equal to an object from another type self.assertNotEqual(obj, "") - result_obj = copy.deepcopy(obj) + obj_2 = copy.deepcopy(obj) # Assert that __eq__ works for equal objects. - self.assertEqual(obj, result_obj) - return result_obj + self.assertEqual(obj, obj_2) - def test_metadata_eq_(self) -> None: - md = Metadata.from_bytes(self.metadata["snapshot"]) - md_2: Metadata = self.copy_and_simple_assert(md) - - for attr, value in [("signed", None), ("signatures", None)]: - setattr(md_2, attr, value) - self.assertNotEqual(md, md_2, f"Failed case: {attr}") + for attr, value in test_case_data.items(): + original_value = getattr(obj_2, attr) + setattr(obj_2, attr, value) + # Assert that the original object != modified one. + self.assertNotEqual(obj, obj_2, f"Failed case: {attr}") # Restore the old value of the attribute. - setattr(md_2, attr, getattr(md, attr)) + setattr(obj_2, attr, original_value) def test_md_eq_signatures_reversed_order(self) -> None: # Test comparing objects with same signatures but different order. # Remove all signatures and create new ones. - md = Metadata.from_bytes(self.metadata["snapshot"]) + md: Metadata = self.objects["Metadata"] md.signatures = {"a": Signature("a", "a"), "b": Signature("b", "b")} md_2 = copy.deepcopy(md) # Reverse signatures order in md_2. @@ -83,7 +121,7 @@ def test_md_eq_signatures_reversed_order(self) -> None: def test_md_eq_special_signatures_tests(self) -> None: # Test that metadata objects with different signatures are not equal. - md = Metadata.from_bytes(self.metadata["snapshot"]) + md: Metadata = self.objects["Metadata"] md_2 = copy.deepcopy(md) md_2.signatures = {} self.assertNotEqual(md, md_2) @@ -96,171 +134,6 @@ def test_md_eq_special_signatures_tests(self) -> None: md_2.signatures = "" # type: ignore self.assertNotEqual(md, md_2) - def test_signed_eq_(self) -> None: - md = Metadata.from_bytes(self.metadata["snapshot"]) - md_2: Metadata = self.copy_and_simple_assert(md) - - # We don't need to make "signed" = None as that was done when testing - # metadata attribute modifications. - for attr, value in [("version", -1), ("spec_version", "0.0.0")]: - setattr(md_2.signed, attr, value) - self.assertNotEqual(md.signed, md_2.signed, f"Failed case: {attr}") - # Restore the old value of the attribute. - setattr(md_2.signed, attr, getattr(md.signed, attr)) - - def test_key_eq_(self) -> None: - key_dict = { - "keytype": "rsa", - "scheme": "rsassa-pss-sha256", - "keyval": {"public": "foo"}, - } - key = Key.from_dict("12sa12", key_dict) - key_2: Key = self.copy_and_simple_assert(key) - for attr, value in [ - ("keyid", "a"), - ("keytype", "foo"), - ("scheme", "b"), - ("keytype", "b"), - ]: - setattr(key_2, attr, value) - self.assertNotEqual(key, key_2, f"Failed case: {attr}") - # Restore the old value of the attribute. - setattr(key_2, attr, getattr(key, attr)) - - def test_role_eq_(self) -> None: - role_dict = { - "keyids": ["keyid1", "keyid2"], - "threshold": 3, - } - role = Role.from_dict(role_dict) - role_2: Role = self.copy_and_simple_assert(role) - - for attr, value in [("keyids", []), ("threshold", 10)]: - setattr(role_2, attr, value) - self.assertNotEqual(role, role_2, f"Failed case: {attr}") - # Restore the old value of the attribute. - setattr(role_2, attr, getattr(role, attr)) - - def test_root_eq_(self) -> None: - md = Metadata.from_bytes(self.metadata["root"]) - signed_copy: Root = self.copy_and_simple_assert(md.signed) - - # Common attributes between Signed and Root doesn't need testing. - # Ignore mypy request for type annotations on attr and value - for attr, value in [ # type: ignore - ("consistent_snapshot", None), - ("keys", {}), - ("roles", {}), - ]: - - setattr(signed_copy, attr, value) - self.assertNotEqual(md.signed, signed_copy, f"Failed case: {attr}") - # Restore the old value of the attribute. - setattr(signed_copy, attr, getattr(md.signed, attr)) - - def test_metafile_eq_(self) -> None: - metafile_dict = { - "version": 1, - "length": 12, - "hashes": {"sha256": "abc"}, - } - metafile = MetaFile.from_dict(metafile_dict) - metafile_2: MetaFile = self.copy_and_simple_assert(metafile) - - # Ignore mypy request for type annotations on attr and value - for attr, value in [ # type: ignore - ("version", None), - ("length", None), - ("hashes", {}), - ]: - setattr(metafile_2, attr, value) - self.assertNotEqual(metafile, metafile_2, f"Failed case: {attr}") - # Restore the old value of the attribute. - setattr(metafile_2, attr, getattr(metafile, attr)) - - def test_timestamp_eq_(self) -> None: - md = Metadata.from_bytes(self.metadata["timestamp"]) - signed_copy: Timestamp = self.copy_and_simple_assert(md.signed) - - # Common attributes between Signed and Timestamp doesn't need testing. - setattr(signed_copy, "snapshot_meta", None) - self.assertNotEqual(md.signed, signed_copy) - - def test_snapshot_eq_(self) -> None: - md = Metadata.from_bytes(self.metadata["snapshot"]) - signed_copy: Snapshot = self.copy_and_simple_assert(md.signed) - - # Common attributes between Signed and Snapshot doesn't need testing. - setattr(signed_copy, "meta", None) - self.assertNotEqual(md.signed, signed_copy) - - def test_delegated_role_eq_(self) -> None: - delegated_role_dict = { - "keyids": ["keyid"], - "name": "a", - "terminating": False, - "threshold": 1, - "paths": ["fn1", "fn2"], - } - delegated_role = DelegatedRole.from_dict(delegated_role_dict) - delegated_role_2: DelegatedRole = self.copy_and_simple_assert( - delegated_role - ) - - # Common attributes between DelegatedRole and Role doesn't need testing. - for attr, value in [ - ("name", ""), - ("terminating", None), - ("paths", [""]), - ("path_hash_prefixes", [""]), - ]: - setattr(delegated_role_2, attr, value) - msg = f"Failed case: {attr}" - self.assertNotEqual(delegated_role, delegated_role_2, msg) - # Restore the old value of the attribute. - setattr(delegated_role_2, attr, getattr(delegated_role, attr)) - - def test_delegations_eq_(self) -> None: - delegations_dict = { - "keys": { - "keyid2": { - "keytype": "ed25519", - "scheme": "ed25519", - "keyval": {"public": "bar"}, - } - }, - "roles": [ - { - "keyids": ["keyid2"], - "name": "b", - "terminating": True, - "paths": ["fn2"], - "threshold": 4, - } - ], - } - delegations = Delegations.from_dict(delegations_dict) - delegations_2: Delegations = self.copy_and_simple_assert(delegations) - # Ignore mypy request for type annotations on attr and value - for attr, value in [("keys", {}), ("roles", {})]: # type: ignore - setattr(delegations_2, attr, value) - msg = f"Failed case: {attr}" - self.assertNotEqual(delegations, delegations_2, msg) - # Restore the old value of the attribute. - setattr(delegations_2, attr, getattr(delegations, attr)) - - def test_targetfile_eq_(self) -> None: - targetfile_dict = { - "length": 12, - "hashes": {"sha256": "abc"}, - } - targetfile = TargetFile.from_dict(targetfile_dict, "file1.txt") - targetfile_2: TargetFile = self.copy_and_simple_assert(targetfile) - - # Common attr between TargetFile and MetaFile doesn't need testing. - setattr(targetfile_2, "path", "") - self.assertNotEqual(targetfile, targetfile_2) - def test_delegations_eq_roles_reversed_order(self) -> None: # Test comparing objects with same delegated roles but different order. role_one_dict = { @@ -303,18 +176,6 @@ def test_delegations_eq_roles_reversed_order(self) -> None: self.assertEqual(delegations, delegations_2) - def test_targets_eq_(self) -> None: - md = Metadata.from_bytes(self.metadata["targets"]) - signed_copy: Targets = self.copy_and_simple_assert(md.signed) - - # Common attributes between Targets and Signed doesn't need testing. - # Ignore mypy request for type annotations on attr and value - for attr, value in [("targets", {}), ("delegations", [])]: # type: ignore - setattr(signed_copy, attr, value) - self.assertNotEqual(md.signed, signed_copy, f"Failed case: {attr}") - # Restore the old value of the attribute. - setattr(signed_copy, attr, getattr(md.signed, attr)) - # Run unit test. if __name__ == "__main__":