Fix expired metadata tests

This change fixes the expired metadata tests to mock `datetime`
as previously they mocked `time` incorrectly, which did not affect
update methods, as they use `datetime.datetime.utcnow()` to
calculate now

Signed-off-by: Ivana Atanasova <iyovcheva@vmware.com>
This commit is contained in:
Ivana Atanasova 2022-02-04 00:14:02 +02:00
parent cab99f58b6
commit d8d0486514
3 changed files with 32 additions and 28 deletions

View file

@ -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()

View file

@ -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

View file

@ -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