55
66import builtins
77import datetime
8+ import logging
89import os
910import sys
1011import tempfile
@@ -58,10 +59,6 @@ def setUp(self) -> None:
5859
5960 self .sim = RepositorySimulator ()
6061
61- # boostrap client with initial root metadata
62- with open (os .path .join (self .metadata_dir , "root.json" ), "bw" ) as f :
63- f .write (self .sim .signed_roots [0 ])
64-
6562 if self .dump_dir is not None :
6663 # create test specific dump directory
6764 name = self .id ().split ("." )[- 1 ]
@@ -71,22 +68,13 @@ def setUp(self) -> None:
7168 def tearDown (self ) -> None :
7269 self .temp_dir .cleanup ()
7370
74- def _run_refresh (self ) -> Updater :
71+ def _run_refresh (self , skip_bootstrap : bool = False ) -> Updater :
7572 """Create a new Updater instance and refresh"""
76- if self .dump_dir is not None :
77- self .sim .write ()
78-
79- updater = Updater (
80- self .metadata_dir ,
81- "https://example.com/metadata/" ,
82- self .targets_dir ,
83- "https://example.com/targets/" ,
84- self .sim ,
85- )
73+ updater = self ._init_updater (skip_bootstrap )
8674 updater .refresh ()
8775 return updater
8876
89- def _init_updater (self ) -> Updater :
77+ def _init_updater (self , skip_bootstrap : bool = False ) -> Updater :
9078 """Create a new Updater instance"""
9179 if self .dump_dir is not None :
9280 self .sim .write ()
@@ -97,6 +85,7 @@ def _init_updater(self) -> Updater:
9785 self .targets_dir ,
9886 "https://example.com/targets/" ,
9987 self .sim ,
88+ bootstrap = None if skip_bootstrap else self .sim .signed_roots [0 ]
10089 )
10190
10291 def _assert_files_exist (self , roles : Iterable [str ]) -> None :
@@ -120,9 +109,6 @@ def _assert_version_equals(self, role: str, expected_version: int) -> None:
120109 self .assertEqual (md .signed .version , expected_version )
121110
122111 def test_first_time_refresh (self ) -> None :
123- # Metadata dir contains only the mandatory initial root.json
124- self ._assert_files_exist ([Root .type ])
125-
126112 # Add one more root version to repository so that
127113 # refresh() updates from local trusted root (v1) to
128114 # remote root (v2)
@@ -136,10 +122,11 @@ def test_first_time_refresh(self) -> None:
136122 version = 2 if role == Root .type else None
137123 self ._assert_content_equals (role , version )
138124
139- def test_trusted_root_missing (self ) -> None :
140- os .remove (os .path .join (self .metadata_dir , "root.json" ))
125+ def test_cached_root_missing_without_bootstrap (self ) -> None :
126+ # Run update without a bootstrap, with empty cache: this fails since there is no
127+ # trusted root
141128 with self .assertRaises (OSError ):
142- self ._run_refresh ()
129+ self ._run_refresh (skip_bootstrap = True )
143130
144131 # Metadata dir is empty
145132 self .assertFalse (os .listdir (self .metadata_dir ))
@@ -172,15 +159,15 @@ def test_trusted_root_expired(self) -> None:
172159 self ._assert_files_exist (TOP_LEVEL_ROLE_NAMES )
173160 self ._assert_content_equals (Root .type , 3 )
174161
175- def test_trusted_root_unsigned (self ) -> None :
176- # Local trusted root is not signed
162+ def test_trusted_root_unsigned_without_bootstrap (self ) -> None :
163+ # Cached root is not signed, bootstrap root is not used
177164 root_path = os .path .join (self .metadata_dir , "root.json" )
178- md_root = Metadata .from_file ( root_path )
165+ md_root = Metadata .from_bytes ( self . sim . signed_roots [ 0 ] )
179166 md_root .signatures .clear ()
180167 md_root .to_file (root_path )
181168
182169 with self .assertRaises (UnsignedMetadataError ):
183- self ._run_refresh ()
170+ self ._run_refresh (skip_bootstrap = True )
184171
185172 # The update failed, no changes in metadata
186173 self ._assert_files_exist ([Root .type ])
@@ -198,10 +185,7 @@ def test_max_root_rotations(self) -> None:
198185 self .sim .root .version += 1
199186 self .sim .publish_root ()
200187
201- md_root = Metadata .from_file (
202- os .path .join (self .metadata_dir , "root.json" )
203- )
204- initial_root_version = md_root .signed .version
188+ initial_root_version = 1
205189
206190 updater .refresh ()
207191
@@ -706,26 +690,18 @@ def test_load_metadata_from_cache(self, wrapped_open: MagicMock) -> None:
706690 updater = self ._run_refresh ()
707691 updater .get_targetinfo ("non_existent_target" )
708692
709- # Clean up calls to open during refresh()
693+ # Clear statistics for calls and metadata requests
710694 wrapped_open .reset_mock ()
711- # Clean up fetch tracker metadata
712695 self .sim .fetch_tracker .metadata .clear ()
713696
714697 # Create a new updater and perform a second update while
715698 # the metadata is already stored in cache (metadata dir)
716- updater = Updater (
717- self .metadata_dir ,
718- "https://example.com/metadata/" ,
719- self .targets_dir ,
720- "https://example.com/targets/" ,
721- self .sim ,
722- )
699+ updater = self ._init_updater ()
723700 updater .get_targetinfo ("non_existent_target" )
724701
725702 # Test that metadata is loaded from cache and not downloaded
726703 wrapped_open .assert_has_calls (
727704 [
728- call (os .path .join (self .metadata_dir , "root.json" ), "rb" ),
729705 call (os .path .join (self .metadata_dir , "root_history/2.root.json" ), "rb" ),
730706 call (os .path .join (self .metadata_dir , "timestamp.json" ), "rb" ),
731707 call (os .path .join (self .metadata_dir , "snapshot.json" ), "rb" ),
0 commit comments