diff --git a/tests/repository_simulator.py b/tests/repository_simulator.py index e50886d7..f7d31578 100644 --- a/tests/repository_simulator.py +++ b/tests/repository_simulator.py @@ -44,11 +44,11 @@ updater.refresh() """ +import datetime import logging import os import tempfile from dataclasses import dataclass, field -from datetime import datetime, timedelta from typing import Dict, Iterator, List, Optional, Tuple from urllib import parse @@ -125,8 +125,10 @@ def __init__(self) -> None: self.fetch_tracker = FetchTracker() - now = datetime.utcnow() - self.safe_expiry = now.replace(microsecond=0) + timedelta(days=30) + now = datetime.datetime.utcnow() + self.safe_expiry = now.replace(microsecond=0) + datetime.timedelta( + days=30 + ) self._initialize() diff --git a/tests/test_updater_top_level_update.py b/tests/test_updater_top_level_update.py index 94ec348c..04994dbf 100644 --- a/tests/test_updater_top_level_update.py +++ b/tests/test_updater_top_level_update.py @@ -6,11 +6,11 @@ """Test ngclient Updater top-level metadata update workflow""" import builtins +import datetime import os import sys import tempfile import unittest -from datetime import datetime, timedelta from typing import Iterable, Optional from unittest.mock import MagicMock, Mock, call, patch @@ -43,7 +43,9 @@ class TestRefresh(unittest.TestCase): # set dump_dir to trigger repository state dumps dump_dir: Optional[str] = None - past_datetime = datetime.utcnow().replace(microsecond=0) - timedelta(days=5) + past_datetime = datetime.datetime.utcnow().replace( + microsecond=0 + ) - datetime.timedelta(days=5) def setUp(self) -> None: # pylint: disable=consider-using-with @@ -306,32 +308,32 @@ def test_new_timestamp_unsigned(self) -> None: self._assert_files_exist([Root.type]) - def test_expired_timestamp_version_rollback(self) -> None: + @patch.object(datetime, "datetime", wraps=datetime.datetime) + def test_expired_timestamp_version_rollback(self, mock_time: Mock) -> None: self._run_refresh() - mock_time = Mock() - mock_time.return_value = ( - int(self.sim.timestamp.expires.strftime("%Y%m%d%H%M%S")) + 1 + mock_time.utcnow.return_value = ( + datetime.datetime.utcnow() + datetime.timedelta(seconds=1) ) - with patch("time.time", mock_time): + with patch("datetime.datetime", mock_time): # Check for a rollback attack self.sim.timestamp.version = 2 self._run_refresh() self.sim.timestamp.version = 1 - with self.assertRaises(ReplayedMetadataError): + with self.assertRaises(BadVersionNumberError): self._run_refresh() self._assert_version_equals(Timestamp.type, 2) - def test_expired_timestamp_snapshot_rollback(self) -> None: + @patch.object(datetime, "datetime", wraps=datetime.datetime) + def test_expired_timestamp_snapshot_rollback(self, mock_time: Mock) -> None: self._run_refresh() - mock_time = Mock() - mock_time.return_value = ( - int(self.sim.timestamp.expires.strftime("%Y%m%d%H%M%S")) + 1 + mock_time.utcnow.return_value = ( + datetime.datetime.utcnow() + datetime.timedelta(seconds=1) ) - with patch("time.time", mock_time): + with patch("datetime.datetime", mock_time): # Check for a rollback attack. self.sim.snapshot.version = 2 self.sim.update_timestamp() # timestamp v2 @@ -341,7 +343,7 @@ def test_expired_timestamp_snapshot_rollback(self) -> None: self.sim.timestamp.snapshot_meta.version = 1 self.sim.timestamp.version += 1 # timestamp v3 - with self.assertRaises(ReplayedMetadataError): + with self.assertRaises(BadVersionNumberError): self._run_refresh() self._assert_version_equals(Timestamp.type, 2) @@ -419,7 +421,7 @@ def test_new_snapshot_hash_mismatch(self) -> None: # Modify snapshot contents without updating # timestamp's snapshot hash - self.sim.snapshot.expires += timedelta(days=1) + self.sim.snapshot.expires += datetime.timedelta(days=1) self.sim.snapshot.version += 1 # snapshot v2 self.sim.timestamp.snapshot_meta.version = self.sim.snapshot.version self.sim.timestamp.version += 1 # timestamp v3 @@ -702,7 +704,8 @@ def test_load_metadata_from_cache(self, wrapped_open: MagicMock) -> None: expected_calls = [("root", 2), ("timestamp", None)] self.assertListEqual(self.sim.fetch_tracker.metadata, expected_calls) - def test_expired_metadata(self) -> None: + @patch.object(datetime, "datetime", wraps=datetime.datetime) + def test_expired_metadata(self, mock_time: Mock) -> None: # Test that expired local timestamp/snapshot can be used for updating # from remote @@ -710,16 +713,15 @@ def test_expired_metadata(self) -> None: self._run_refresh() # Simulate expired local metadata by mocking system time one second ahead - mock_time = Mock() - mock_time.return_value = ( - int(self.sim.timestamp.expires.strftime("%Y%m%d%H%M%S")) + 1 + mock_time.utcnow.return_value = ( + datetime.datetime.utcnow() + datetime.timedelta(seconds=1) ) - with patch("time.time", mock_time): + with patch("datetime.datetime", mock_time): self.sim.targets.version += 1 self.sim.update_snapshot() - # Create a new updater and perform a second update while - # the metadata is already stored in cache (metadata dir) - self._run_refresh() + # Create a new updater and perform a second update while + # the metadata is already stored in cache (metadata dir) + self._run_refresh() # Assert that the final version of timestamp/snapshot is version 2 # which means a successful refresh is performed diff --git a/tuf/ngclient/_internal/trusted_metadata_set.py b/tuf/ngclient/_internal/trusted_metadata_set.py index 754fb896..d08694f0 100644 --- a/tuf/ngclient/_internal/trusted_metadata_set.py +++ b/tuf/ngclient/_internal/trusted_metadata_set.py @@ -59,9 +59,9 @@ >>> trusted_set.update_snapshot(f.read()) """ +import datetime import logging from collections import abc -from datetime import datetime from typing import Dict, Iterator, Optional from tuf.api import exceptions @@ -91,7 +91,7 @@ def __init__(self, root_data: bytes): error type and content will contain more details. """ self._trusted_set: Dict[str, Metadata] = {} - self.reference_time = datetime.utcnow() + self.reference_time = datetime.datetime.utcnow() # Load and validate the local root metadata. Valid initial trusted root # metadata is required