diff --git a/tests/test_trusted_metadata_set.py b/tests/test_trusted_metadata_set.py index aa2d39e4..64b2bd77 100644 --- a/tests/test_trusted_metadata_set.py +++ b/tests/test_trusted_metadata_set.py @@ -131,6 +131,13 @@ def test_update(self): # the 4 top level metadata objects + 2 additional delegated targets self.assertTrue(len(self.trusted_set), 6) + count = 0 + for md in self.trusted_set: + self.assertIsInstance(md, Metadata) + count += 1 + + self.assertTrue(count, 6) + def test_out_of_order_ops(self): # Update timestamp before root is finished with self.assertRaises(RuntimeError): @@ -214,6 +221,13 @@ def test_update_with_invalid_json(self): update_func(metadata) + def test_update_root_new_root(self): + # test that root can be updated with a new valid version + def root_new_version_modifier(root: Root) -> None: + root.version += 1 + + root = self.modify_metadata("root", root_new_version_modifier) + self.trusted_set.update_root(root) def test_update_root_new_root_cannot_be_verified_with_threshold(self): # new_root data with threshold which cannot be verified. @@ -227,7 +241,6 @@ def test_update_root_new_root_ver_same_as_trusted_root_ver(self): with self.assertRaises(exceptions.ReplayedMetadataError): self.trusted_set.update_root(self.metadata["root"]) - def test_root_update_finished_expired(self): def root_expired_modifier(root: Root) -> None: root.expires = datetime(1970, 1, 1) @@ -249,13 +262,15 @@ def version_modifier(timestamp: Timestamp) -> None: with self.assertRaises(exceptions.ReplayedMetadataError): self.trusted_set.update_timestamp(self.metadata["timestamp"]) - def test_update_timestamp_snapshot_ver_below_trusted_snapshot_ver(self): - def version_modifier(timestamp: Timestamp) -> None: - timestamp.version = 3 + def test_update_timestamp_snapshot_ver_below_current(self): + def bump_snapshot_version(timestamp: Timestamp) -> None: + timestamp.meta["snapshot.json"].version = 2 - modified_timestamp = self.modify_metadata("timestamp", version_modifier) - self._root_updated_and_update_timestamp(modified_timestamp) - # new_timestamp.snapshot.version < trusted_timestamp.snapshot.version + # set current known snapshot.json version to 2 + timestamp = self.modify_metadata("timestamp", bump_snapshot_version) + self._root_updated_and_update_timestamp(timestamp) + + # newtimestamp.meta["snapshot.json"].version < trusted_timestamp.meta["snapshot.json"].version with self.assertRaises(exceptions.ReplayedMetadataError): self.trusted_set.update_timestamp(self.metadata["timestamp"]) @@ -269,6 +284,16 @@ def timestamp_expired_modifier(timestamp: Timestamp) -> None: with self.assertRaises(exceptions.ExpiredMetadataError): self.trusted_set.update_timestamp(timestamp) + def test_update_snapshot_length_or_hash_mismatch(self): + def modify_snapshot_length(timestamp: Timestamp) -> None: + timestamp.meta["snapshot.json"].length = 1 + + # set known snapshot.json length to 1 + timestamp = self.modify_metadata("timestamp", modify_snapshot_length) + self._root_updated_and_update_timestamp(timestamp) + + with self.assertRaises(exceptions.RepositoryError): + self.trusted_set.update_snapshot(self.metadata["snapshot"]) def test_update_snapshot_cannot_verify_snapshot_with_threshold(self): self._root_updated_and_update_timestamp(self.metadata["timestamp"]) @@ -323,7 +348,6 @@ def snapshot_expired_modifier(snapshot: Snapshot) -> None: with self.assertRaises(exceptions.ExpiredMetadataError): self.trusted_set.update_snapshot(snapshot) - def test_update_targets_no_meta_in_snapshot(self): def no_meta_modifier(snapshot: Snapshot) -> None: snapshot.meta = {} diff --git a/tuf/ngclient/_internal/trusted_metadata_set.py b/tuf/ngclient/_internal/trusted_metadata_set.py index 25c46cb1..369b5255 100644 --- a/tuf/ngclient/_internal/trusted_metadata_set.py +++ b/tuf/ngclient/_internal/trusted_metadata_set.py @@ -116,7 +116,7 @@ def __len__(self) -> int: def __iter__(self) -> Iterator[Metadata]: """Returns iterator over all Metadata objects in TrustedMetadataSet""" - return iter(self._trusted_set) + return iter(self._trusted_set.values()) # Helper properties for top level metadata @property