|
12 | 12 | import unittest
|
13 | 13 | from datetime import datetime, timedelta
|
14 | 14 | from typing import Iterable, Optional
|
15 |
| -from unittest.mock import MagicMock, call, patch |
| 15 | +from unittest.mock import MagicMock, Mock, call, patch |
16 | 16 |
|
17 | 17 | from tests import utils
|
18 | 18 | from tests.repository_simulator import RepositorySimulator
|
@@ -662,6 +662,32 @@ def test_load_metadata_from_cache(self, wrapped_open: MagicMock) -> None:
|
662 | 662 | expected_calls = [("root", 2), ("timestamp", None)]
|
663 | 663 | self.assertListEqual(self.sim.fetch_tracker.metadata, expected_calls)
|
664 | 664 |
|
| 665 | + def test_expired_metadata(self) -> None: |
| 666 | + # Test that expired local timestamp/snapshot can be used for updating |
| 667 | + # from remote |
| 668 | + |
| 669 | + # Make a successful update of valid metadata which stores it in cache |
| 670 | + self._run_refresh() |
| 671 | + |
| 672 | + # Simulate expired local metadata by mocking system time one second ahead |
| 673 | + mock_time = Mock() |
| 674 | + mock_time.return_value = ( |
| 675 | + int(self.sim.timestamp.expires.strftime("%Y%m%d%H%M%S")) + 1 |
| 676 | + ) |
| 677 | + with patch("time.time", mock_time): |
| 678 | + self.sim.targets.version += 1 |
| 679 | + self.sim.update_snapshot() |
| 680 | + # Create a new updater and perform a second update while |
| 681 | + # the metadata is already stored in cache (metadata dir) |
| 682 | + self._run_refresh() |
| 683 | + |
| 684 | + # Assert that the final version of timestamp/snapshot is version 2 |
| 685 | + # which means a successful refresh is performed |
| 686 | + # with expired local metadata |
| 687 | + for role in ["timestamp", "snapshot", "targets"]: |
| 688 | + md = Metadata.from_file(f"{self.metadata_dir}/{role}.json") |
| 689 | + self.assertEqual(md.signed.version, 2) |
| 690 | + |
665 | 691 |
|
666 | 692 | if __name__ == "__main__":
|
667 | 693 | if "--dump" in sys.argv:
|
|
0 commit comments