Skip to content

Commit 6f5bf5a

Browse files
committed
Test expired metadata from cache
This tests that an expired timestamp/snapshot/targets when loaded from cache is not stored as final but is used to verify the new timestamp Fixes theupdateframework#1681 Signed-off-by: Ivana Atanasova <[email protected]>
1 parent bdf1cbb commit 6f5bf5a

File tree

1 file changed

+48
-2
lines changed

1 file changed

+48
-2
lines changed

tests/test_updater_with_simulator.py

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@
1111
import sys
1212
import tempfile
1313
import unittest
14+
from datetime import datetime, timedelta
1415
from typing import Optional, Tuple
15-
from unittest.mock import MagicMock, patch
16+
from unittest.mock import call, MagicMock, patch
1617

1718
from tests import utils
1819
from tests.repository_simulator import RepositorySimulator
1920
from tuf.api.metadata import SPECIFICATION_VERSION, Targets
20-
from tuf.exceptions import BadVersionNumberError, UnsignedMetadataError
21+
from tuf.exceptions import BadVersionNumberError, ExpiredMetadataError, UnsignedMetadataError
2122
from tuf.ngclient import Updater
2223

2324

@@ -241,6 +242,7 @@ def test_not_loading_targets_twice(self, wrapped_open: MagicMock) -> None:
241242

242243
# Run refresh, top-level roles are loaded
243244
updater = self._run_refresh()
245+
244246
# Clean up calls to open during refresh()
245247
wrapped_open.reset_mock()
246248

@@ -254,6 +256,50 @@ def test_not_loading_targets_twice(self, wrapped_open: MagicMock) -> None:
254256
updater.get_targetinfo("somepath")
255257
wrapped_open.assert_not_called()
256258

259+
@patch.object(builtins, "open", wraps=builtins.open)
260+
def test_expired_metadata(self, wrapped_open: MagicMock) -> None:
261+
updater = self._run_refresh()
262+
263+
past_datetime = datetime.utcnow().replace(microsecond=0) - timedelta(days=5)
264+
265+
self.sim.timestamp.expires = past_datetime
266+
self.sim.snapshot.expires = past_datetime
267+
self.sim.targets.expires = past_datetime
268+
269+
# Add targets to repository
270+
self.sim.targets.version += 1
271+
self.sim.add_target("targets", b'some content', self.targets_dir)
272+
self.sim.update_snapshot()
273+
274+
# Clean up calls to open during refresh()
275+
wrapped_open.reset_mock()
276+
277+
# Make a successful update of valid metadata which stores it in cache
278+
updater.get_targetinfo(self.targets_dir)
279+
280+
# Create a new updater and perform a second update while
281+
# the metadata is already stored in cache (metadata dir)
282+
updater = Updater(
283+
self.metadata_dir,
284+
"https://example.com/metadata/",
285+
self.targets_dir,
286+
"https://example.com/targets/",
287+
self.sim,
288+
)
289+
290+
with self.assertRaises(ExpiredMetadataError):
291+
updater.get_targetinfo(self.targets_dir)
292+
293+
# Test that an expired timestamp/snapshot/targets
294+
# when loaded from cache is not stored as final
295+
# but is used to verify the new timestamp
296+
wrapped_open.assert_has_calls([
297+
call(os.path.join(self.metadata_dir, "root.json"), "rb"),
298+
call(os.path.join(self.metadata_dir, "timestamp.json"), "rb"),
299+
])
300+
301+
wrapped_open.reset_mock()
302+
257303

258304
if __name__ == "__main__":
259305
if "--dump" in sys.argv:

0 commit comments

Comments
 (0)