|
6 | 6 | """Test ngclient Updater using the repository simulator.
|
7 | 7 | """
|
8 | 8 |
|
| 9 | +import builtins |
9 | 10 | import os
|
10 | 11 | import sys
|
11 | 12 | import tempfile
|
12 | 13 | import unittest
|
13 | 14 | from typing import Optional, Tuple
|
| 15 | +from unittest.mock import MagicMock, Mock, patch |
14 | 16 |
|
15 | 17 | from tests import utils
|
16 | 18 | from tests.repository_simulator import RepositorySimulator
|
@@ -230,6 +232,32 @@ def test_snapshot_rollback_with_local_snapshot_hash_mismatch(self):
|
230 | 232 | with self.assertRaises(BadVersionNumberError):
|
231 | 233 | self._run_refresh()
|
232 | 234 |
|
| 235 | + @patch.object(builtins, "open", wraps=builtins.open) |
| 236 | + def test_not_loading_targets_twice(self, wrapped_open: MagicMock): |
| 237 | + # Do not load targets roles more than once when traversing |
| 238 | + # the delegations tree |
| 239 | + |
| 240 | + # Add new delegated targets, update the snapshot |
| 241 | + spec_version = ".".join(SPECIFICATION_VERSION) |
| 242 | + targets = Targets(1, spec_version, self.sim.safe_expiry, {}, None) |
| 243 | + self.sim.add_delegation("targets", "role1", targets, False, ["*"], None) |
| 244 | + self.sim.update_snapshot() |
| 245 | + |
| 246 | + # Run refresh, top-level roles are loaded |
| 247 | + updater = self._run_refresh() |
| 248 | + # Clean up calls to open during refresh() |
| 249 | + wrapped_open.reset_mock() |
| 250 | + |
| 251 | + # First time looking for "somepath", only 'role1' must be loaded |
| 252 | + updater.get_targetinfo("somepath") |
| 253 | + wrapped_open.assert_called_once_with( |
| 254 | + os.path.join(self.metadata_dir, "role1.json"), "rb" |
| 255 | + ) |
| 256 | + wrapped_open.reset_mock() |
| 257 | + # Second call to get_targetinfo, all metadata is already loaded |
| 258 | + updater.get_targetinfo("somepath") |
| 259 | + wrapped_open.assert_not_called() |
| 260 | + |
233 | 261 |
|
234 | 262 | if __name__ == "__main__":
|
235 | 263 | if "--dump" in sys.argv:
|
|
0 commit comments