|
13 | 13 | import unittest
|
14 | 14 | from datetime import datetime, timedelta
|
15 | 15 | from typing import Optional, Tuple
|
16 |
| -from unittest.mock import MagicMock, call, patch |
| 16 | +from unittest.mock import MagicMock, Mock, patch |
17 | 17 |
|
18 | 18 | from tests import utils
|
19 | 19 | from tests.repository_simulator import RepositorySimulator
|
@@ -257,74 +257,31 @@ def test_not_loading_targets_twice(self, wrapped_open: MagicMock) -> None:
|
257 | 257 | updater.get_targetinfo("somepath")
|
258 | 258 | wrapped_open.assert_not_called()
|
259 | 259 |
|
260 |
| - @patch.object(builtins, "open", wraps=builtins.open) |
261 |
| - def test_expired_metadata(self, wrapped_open: MagicMock) -> None: |
262 |
| - # Test that expired timestamp/snapshot can be used to verify the next |
263 |
| - # version of timestamp/snapshot respectively. |
264 |
| - # If there is an expired local targets it won't be verified and the |
265 |
| - # updater will try to fetch and verify the next version without using |
266 |
| - # any information from the old expired targets file. |
| 260 | + def test_expired_metadata(self) -> None: |
| 261 | + # Test that expired local timestamp/snapshot can be used for updating |
| 262 | + # from remote |
267 | 263 |
|
268 | 264 | # Make a successful update of valid metadata which stores it in cache
|
269 | 265 | self._run_refresh()
|
270 | 266 |
|
271 |
| - past_datetime = datetime.utcnow().replace(microsecond=0) - timedelta( |
272 |
| - days=5 |
273 |
| - ) |
274 |
| - |
275 |
| - # Store the future_datetime for future reference |
276 |
| - future_datetime = self.sim.timestamp.expires |
277 |
| - |
278 |
| - # Make version 1 stored metadata in the simulator expired. |
279 |
| - past_datetime = datetime.utcnow().replace(microsecond=0) - timedelta( |
280 |
| - weeks=52 |
281 |
| - ) |
282 |
| - self.sim.timestamp.expires = past_datetime |
283 |
| - self.sim.snapshot.expires = past_datetime |
284 |
| - self.sim.targets.expires = past_datetime |
285 |
| - |
286 |
| - # Serializer is used to serialize JSON in a human readable format. |
287 |
| - seriazer = JSONSerializer() |
288 |
| - |
289 |
| - # Replace current version 1 roles with expired ones. |
290 |
| - for role in ["timestamp", "snapshot"]: |
291 |
| - md = Metadata.from_bytes(self.sim.fetch_metadata(role)) |
292 |
| - md.to_file(f"{self.metadata_dir}/{role}.json", seriazer) |
293 |
| - |
294 |
| - # Make version 2 of the roles valid by using a future expiry date |
295 |
| - self.sim.timestamp.expires = future_datetime |
296 |
| - self.sim.snapshot.expires = future_datetime |
297 |
| - self.sim.targets.expires = future_datetime |
298 |
| - |
299 |
| - self.sim.targets.version += 1 |
300 |
| - self.sim.update_snapshot() |
301 |
| - |
302 |
| - # Clean up calls to open during refresh() |
303 |
| - wrapped_open.reset_mock() |
304 |
| - |
305 |
| - # Create a new updater and perform a second update while |
306 |
| - # the metadata is already stored in cache (metadata dir) |
307 |
| - self._run_refresh() |
308 |
| - |
309 |
| - # Test that an expired timestamp/snapshot when loaded from cache is not |
310 |
| - # stored as final but is used to verify the new timestamp |
311 |
| - wrapped_open.assert_has_calls( |
312 |
| - [ |
313 |
| - call(os.path.join(self.metadata_dir, "root.json"), "rb"), |
314 |
| - call(os.path.join(self.metadata_dir, "timestamp.json"), "rb"), |
315 |
| - call(os.path.join(self.metadata_dir, "snapshot.json"), "rb"), |
316 |
| - call(os.path.join(self.metadata_dir, "targets.json"), "rb"), |
317 |
| - ] |
| 267 | + # Simulate expired local metadata by mocking system time one second ahead |
| 268 | + mock_time = Mock() |
| 269 | + mock_time.return_value = ( |
| 270 | + int(self.sim.timestamp.expires.strftime("%Y%m%d%H%M%S")) + 1 |
318 | 271 | )
|
| 272 | + with patch("time.time", mock_time): |
| 273 | + self.sim.targets.version += 1 |
| 274 | + self.sim.update_snapshot() |
| 275 | + # Create a new updater and perform a second update while |
| 276 | + # the metadata is already stored in cache (metadata dir) |
| 277 | + self._run_refresh() |
319 | 278 |
|
320 |
| - # Assert that the final version of timestamp/snapshot is version 2 with |
321 |
| - # a future expiry date. |
| 279 | + # Assert that the final version of timestamp/snapshot is version 2 |
| 280 | + # which means a successful refresh is performed |
| 281 | + # with expired local metadata |
322 | 282 | for role in ["timestamp", "snapshot", "targets"]:
|
323 | 283 | md = Metadata.from_file(f"{self.metadata_dir}/{role}.json")
|
324 | 284 | self.assertEqual(md.signed.version, 2)
|
325 |
| - self.assertEqual(md.signed.expires, future_datetime) |
326 |
| - |
327 |
| - wrapped_open.reset_mock() |
328 | 285 |
|
329 | 286 |
|
330 | 287 | if __name__ == "__main__":
|
|
0 commit comments