Skip to content

Commit 8d4d9af

Browse files
committed
Update expired metadata tests logic
This change improves the logic of expired metadata tests, so that it is explicitly visible what the expiry time and the versions are and when update/refresh is called in that period Signed-off-by: Ivana Atanasova <[email protected]>
1 parent d8d0486 commit 8d4d9af

File tree

1 file changed

+74
-27
lines changed

1 file changed

+74
-27
lines changed

tests/test_updater_top_level_update.py

Lines changed: 74 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -310,43 +310,78 @@ def test_new_timestamp_unsigned(self) -> None:
310310

311311
@patch.object(datetime, "datetime", wraps=datetime.datetime)
312312
def test_expired_timestamp_version_rollback(self, mock_time: Mock) -> None:
313+
"""Verifies that local timestamp is used in rollback checks even if it is expired.
314+
315+
The timestamp updates and rollback checks are performed
316+
with the following timing:
317+
- Timestamp v1 expiry set to day 7
318+
- First updater refresh performed on day 0
319+
- Repository publishes timestamp v2 on day 0
320+
- Timestamp v2 expiry set to day 21
321+
- Second updater refresh performed on day 18:
322+
assert that rollback check uses expired timestamp v1"""
323+
324+
now = datetime.datetime.utcnow()
325+
self.sim.timestamp.expires = now + datetime.timedelta(days=7)
326+
327+
self.sim.timestamp.version = 2
328+
329+
# Make a successful update of valid metadata which stores it in cache
313330
self._run_refresh()
314331

332+
self.sim.timestamp.expires = now + datetime.timedelta(days=21)
333+
334+
self.sim.timestamp.version = 1
335+
315336
mock_time.utcnow.return_value = (
316-
datetime.datetime.utcnow() + datetime.timedelta(seconds=1)
337+
datetime.datetime.utcnow() + datetime.timedelta(days=18)
317338
)
318339
with patch("datetime.datetime", mock_time):
319-
# Check for a rollback attack
320-
self.sim.timestamp.version = 2
321-
self._run_refresh()
322-
323-
self.sim.timestamp.version = 1
340+
# Check that a rollback protection is performed even if
341+
# local timestamp has expired
324342
with self.assertRaises(BadVersionNumberError):
325343
self._run_refresh()
326344

327-
self._assert_version_equals(Timestamp.type, 2)
345+
self._assert_version_equals(Timestamp.type, 2)
328346

329347
@patch.object(datetime, "datetime", wraps=datetime.datetime)
330348
def test_expired_timestamp_snapshot_rollback(self, mock_time: Mock) -> None:
349+
"""Verifies that rollback protection is done even if local timestamp has expired.
350+
351+
The snapshot updates and rollback protection checks are performed
352+
with the following timing:
353+
- Timestamp v1 expiry set to day 7
354+
- Repository bumps snapshot to v3 on day 0
355+
- First updater refresh performed on day 0
356+
- Timestamp v2 expiry set to day 21
357+
- Second updater refresh performed on day 18:
358+
assert that rollback protection is done with expired timestamp v1"""
359+
360+
now = datetime.datetime.utcnow()
361+
self.sim.timestamp.expires = now + datetime.timedelta(days=7)
362+
363+
# Bump the snapshot version number to 3
364+
self.sim.update_snapshot()
365+
self.sim.update_snapshot()
366+
367+
# Make a successful update of valid metadata which stores it in cache
331368
self._run_refresh()
332369

370+
self.sim.snapshot.version = 1
371+
# Snapshot version number is set to 2, which is still less than 3
372+
self.sim.update_snapshot()
373+
self.sim.timestamp.expires = now + datetime.timedelta(days=21)
374+
333375
mock_time.utcnow.return_value = (
334-
datetime.datetime.utcnow() + datetime.timedelta(seconds=1)
376+
datetime.datetime.utcnow() + datetime.timedelta(days=18)
335377
)
336378
with patch("datetime.datetime", mock_time):
337-
# Check for a rollback attack.
338-
self.sim.snapshot.version = 2
339-
self.sim.update_timestamp() # timestamp v2
340-
self._run_refresh()
341-
342-
# Snapshot meta version is smaller than previous
343-
self.sim.timestamp.snapshot_meta.version = 1
344-
self.sim.timestamp.version += 1 # timestamp v3
345-
379+
# Assert that rollback protection is done even if
380+
# local timestamp has expired
346381
with self.assertRaises(BadVersionNumberError):
347382
self._run_refresh()
348383

349-
self._assert_version_equals(Timestamp.type, 2)
384+
self._assert_version_equals(Timestamp.type, 3)
350385

351386
def test_new_timestamp_version_rollback(self) -> None:
352387
# Check for a rollback attack
@@ -706,22 +741,34 @@ def test_load_metadata_from_cache(self, wrapped_open: MagicMock) -> None:
706741

707742
@patch.object(datetime, "datetime", wraps=datetime.datetime)
708743
def test_expired_metadata(self, mock_time: Mock) -> None:
709-
# Test that expired local timestamp/snapshot can be used for updating
710-
# from remote
744+
"""Verifies that expired local timestamp/snapshot can be used for
745+
updating from remote.
746+
747+
The updates and verifications are performed with the following timing:
748+
- Timestamp v1 expiry set to day 7
749+
- First updater refresh performed on day 0
750+
- Repository bumps snapshot and targets to v2 on day 0
751+
- Timestamp v2 expiry set to day 21
752+
- Second updater refresh performed on day 18,
753+
it is successful and timestamp/snaphot final versions are v2"""
754+
755+
now = datetime.datetime.utcnow()
756+
self.sim.timestamp.expires = now + datetime.timedelta(days=7)
711757

712758
# Make a successful update of valid metadata which stores it in cache
713759
self._run_refresh()
714760

715-
# Simulate expired local metadata by mocking system time one second ahead
761+
self.sim.targets.version += 1
762+
self.sim.update_snapshot()
763+
self.sim.timestamp.expires = now + datetime.timedelta(days=21)
764+
765+
# Mocking time so that local timestam has expired
766+
# but the new timestamp has not
716767
mock_time.utcnow.return_value = (
717-
datetime.datetime.utcnow() + datetime.timedelta(seconds=1)
768+
datetime.datetime.utcnow() + datetime.timedelta(days=18)
718769
)
719770
with patch("datetime.datetime", mock_time):
720-
self.sim.targets.version += 1
721-
self.sim.update_snapshot()
722-
# Create a new updater and perform a second update while
723-
# the metadata is already stored in cache (metadata dir)
724-
self._run_refresh()
771+
self._run_refresh()
725772

726773
# Assert that the final version of timestamp/snapshot is version 2
727774
# which means a successful refresh is performed

0 commit comments

Comments
 (0)