Skip to content

Commit 3d4df87

Browse files
author
Jussi Kukkonen
authored
Merge pull request #1741 from sechkova/remove-updater-with-sim
Remove test_updater_with_simulator.py
2 parents d8591e7 + 672df74 commit 3d4df87

3 files changed

+86
-218
lines changed

tests/test_updater_delegation_graphs.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,31 @@ def test_invalid_metadata(self, test_data: DelegationsTestCase) -> None:
328328
finally:
329329
self.teardown_subtest()
330330

331+
def test_fishy_rolenames(self) -> None:
332+
# Test that delegated roles filenames are safely encoded
333+
# when persisted to the file system.
334+
335+
roles_to_filenames = {
336+
"../a": "..%2Fa.json",
337+
".": "..json",
338+
"/": "%2F.json",
339+
"ö": "%C3%B6.json",
340+
}
341+
342+
delegations = []
343+
for rolename in roles_to_filenames:
344+
delegations.append(TestDelegation("targets", rolename))
345+
346+
fishy_rolenames = DelegationsTestCase(delegations)
347+
self._init_repo(fishy_rolenames)
348+
updater = self._init_updater()
349+
350+
# trigger updater to fetch the delegated metadata, check filenames
351+
updater.get_targetinfo("anything")
352+
local_metadata = os.listdir(self.metadata_dir)
353+
for fname in roles_to_filenames.values():
354+
self.assertTrue(fname in local_metadata)
355+
331356

332357
class TestTargetFileSearch(TestDelegations):
333358
r"""
@@ -382,7 +407,6 @@ def setUp(self) -> None:
382407
def test_targetfile_search(self, test_data: TargetTestCase) -> None:
383408
try:
384409
self.setup_subtest()
385-
# targetpath, found, visited_order = test_data
386410
exp_files = [*TOP_LEVEL_ROLE_NAMES, *test_data.visited_order]
387411
exp_calls = [(role, 1) for role in test_data.visited_order]
388412
exp_target = self.sim.target_files[test_data.targetpath].target_file

tests/test_updater_top_level_update.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,21 @@
55

66
"""Test ngclient Updater top-level metadata update workflow"""
77

8+
import builtins
89
import os
910
import sys
1011
import tempfile
1112
import unittest
1213
from datetime import datetime, timedelta
1314
from typing import Iterable, Optional
15+
from unittest.mock import MagicMock, patch
1416

1517
from tests import utils
1618
from tests.repository_simulator import RepositorySimulator
1719
from tuf.api.metadata import (
20+
SPECIFICATION_VERSION,
1821
TOP_LEVEL_ROLE_NAMES,
22+
DelegatedRole,
1923
Metadata,
2024
Root,
2125
Snapshot,
@@ -575,6 +579,63 @@ def test_new_targets_fast_forward_recovery(self) -> None:
575579
self._run_refresh()
576580
self._assert_version_equals(Targets.type, 1)
577581

582+
@patch.object(builtins, "open", wraps=builtins.open)
583+
def test_not_loading_targets_twice(self, wrapped_open: MagicMock) -> None:
584+
# Do not load targets roles more than once when traversing
585+
# the delegations tree
586+
587+
# Add new delegated targets, update the snapshot
588+
spec_version = ".".join(SPECIFICATION_VERSION)
589+
targets = Targets(1, spec_version, self.sim.safe_expiry, {}, None)
590+
role = DelegatedRole("role1", [], 1, False, ["*"], None)
591+
self.sim.add_delegation("targets", role, targets)
592+
self.sim.update_snapshot()
593+
594+
# Run refresh, top-level roles are loaded
595+
updater = self._run_refresh()
596+
# Clean up calls to open during refresh()
597+
wrapped_open.reset_mock()
598+
599+
# First time looking for "somepath", only 'role1' must be loaded
600+
updater.get_targetinfo("somepath")
601+
wrapped_open.assert_called_once_with(
602+
os.path.join(self.metadata_dir, "role1.json"), "rb"
603+
)
604+
wrapped_open.reset_mock()
605+
# Second call to get_targetinfo, all metadata is already loaded
606+
updater.get_targetinfo("somepath")
607+
wrapped_open.assert_not_called()
608+
609+
def test_snapshot_rollback_with_local_snapshot_hash_mismatch(self) -> None:
610+
# Test triggering snapshot rollback check on a newly downloaded snapshot
611+
# when the local snapshot is loaded even when there is a hash mismatch
612+
# with timestamp.snapshot_meta.
613+
614+
# By raising this flag on timestamp update the simulator would:
615+
# 1) compute the hash of the new modified version of snapshot
616+
# 2) assign the hash to timestamp.snapshot_meta
617+
# The purpose is to create a hash mismatch between timestamp.meta and
618+
# the local snapshot, but to have hash match between timestamp.meta and
619+
# the next snapshot version.
620+
self.sim.compute_metafile_hashes_length = True
621+
622+
# Initialize all metadata and assign targets version higher than 1.
623+
self.sim.targets.version = 2
624+
self.sim.update_snapshot()
625+
self._run_refresh()
626+
627+
# The new targets must have a lower version than the local trusted one.
628+
self.sim.targets.version = 1
629+
self.sim.update_snapshot()
630+
631+
# During the snapshot update, the local snapshot will be loaded even if
632+
# there is a hash mismatch with timestamp.snapshot_meta, because it will
633+
# be considered as trusted.
634+
# Should fail as a new version of snapshot will be fetched which lowers
635+
# the snapshot.meta["targets.json"] version by 1 and throws an error.
636+
with self.assertRaises(BadVersionNumberError):
637+
self._run_refresh()
638+
578639

579640
if __name__ == "__main__":
580641
if "--dump" in sys.argv:

tests/test_updater_with_simulator.py

Lines changed: 0 additions & 217 deletions
This file was deleted.

0 commit comments

Comments
 (0)