Skip to content

Commit 21b145d

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 21b145d

File tree

1 file changed

+56
-2
lines changed

1 file changed

+56
-2
lines changed

tests/test_updater_with_simulator.py

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,18 @@
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 MagicMock, call, 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 (
22+
BadVersionNumberError,
23+
ExpiredMetadataError,
24+
UnsignedMetadataError,
25+
)
2126
from tuf.ngclient import Updater
2227

2328

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

242247
# Run refresh, top-level roles are loaded
243248
updater = self._run_refresh()
249+
244250
# Clean up calls to open during refresh()
245251
wrapped_open.reset_mock()
246252

@@ -254,6 +260,54 @@ def test_not_loading_targets_twice(self, wrapped_open: MagicMock) -> None:
254260
updater.get_targetinfo("somepath")
255261
wrapped_open.assert_not_called()
256262

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

258312
if __name__ == "__main__":
259313
if "--dump" in sys.argv:

0 commit comments

Comments
 (0)