def test_5_all_targets(self): # As with '_refresh_targets_metadata()', tuf.roledb._roledb_dict # has to be populated. The 'tuf.download.safe_download' method # should be patched. The 'self.all_role_paths' argument is passed so that # the top-level roles and delegations may be all "downloaded" when # Repository.refresh() is called below. '_mock_download_url_to_tempfileobj' # returns each filepath listed in 'self.all_role_paths' in the listed # order. self._mock_download_url_to_tempfileobj(self.all_role_paths) setup.build_server_repository(self.server_repo_dir, self.targets_dir) # Update top-level metadata. self.Repository.refresh() # Test: normal case. all_targets = self.Repository.all_targets() # Verify format of 'all_targets', it should correspond to # 'TARGETFILES_SCHEMA'. self.assertTrue(tuf.formats.TARGETFILES_SCHEMA.matches(all_targets)) # Verify that there is a correct number of records in 'all_targets' list. # On the repository there are 4 target files, 2 of which are delegated. # The targets role lists all targets, for a total of 4. The two delegated # roles each list 1 of the already listed targets in 'targets.txt', for a # total of 2 (the delegated targets are listed twice). The total number of # targets in 'all_targets' should then be 6. self.assertTrue(len(all_targets) is 6)
def _remove_target_from_targets_dir(self, target_filename, remove_all=True): """ Remove a target 'target_filename' from server's targets directory and rebuild 'targets', 'release', 'timestamp' metadata files. 'target_filename' is relative to targets directory. Example of 'target_filename': 'targets_sub_dir/somefile.txt'. If 'remove_all' is set to True, then the sub directory 'targets_sub_dir' (with all added targets) is removed. All listed metadata files are rebuilt. """ targets_sub_dir = os.path.join(self.targets_dir, 'targets_sub_dir') if remove_all: shutil.rmtree(targets_sub_dir) else: target_path = os.path.join(targets_dir, target_filename) os.remove(target_path) # In order to rebuild metadata, keystore's dictionary must be loaded. keystore._keystore = self.rsa_keystore setup.build_server_repository(self.server_repo_dir, self.targets_dir) # Synchronise client's repository with server's repository. shutil.rmtree(self.client_meta_dir) shutil.copytree(self.server_meta_dir, self.client_current_dir) shutil.copytree(self.server_meta_dir, self.client_previous_dir) keystore._keystore = {}
def test_4_refresh(self): # This unit test is based on adding an extra target file to the # server and rebuilding all server-side metadata. When 'refresh' # function is called by the client all top level metadata should # be updated. target_fullpath = self._add_file_to_directory(self.targets_dir) target_relpath = os.path.split(target_fullpath) # Reference 'self.Repository.metadata['current']['targets']'. targets_meta = self.Repository.metadata['current']['targets'] self.assertFalse(target_relpath[1] in targets_meta['targets'].keys()) # Rebuild metadata at the server side. self._mock_download_url_to_tempfileobj(self.all_role_paths) setup.build_server_repository(self.server_repo_dir, self.targets_dir) # Test: normal case. self.Repository.refresh() # Verify that clients metadata was updated. targets_meta = self.Repository.metadata['current']['targets'] self.assertTrue(target_relpath[1] in targets_meta['targets'].keys()) # Restore server's repository to initial state. self._remove_filepath(target_fullpath) # Rebuild metadata at the server side. self._mock_download_url_to_tempfileobj(self.all_role_paths) setup.build_server_repository(self.server_repo_dir, self.targets_dir)
def _remove_target_from_targets_dir(self, target_filename, remove_all=True): """ Remove a target 'target_filename' from server's targets directory and rebuild 'targets', 'release', 'timestamp' metadata files. 'target_filename' is relative to targets directory. Example of 'target_filename': 'targets_sub_dir/somefile.txt'. If 'remove_all' is set to True, then the sub directory 'targets_sub_dir' (with all added targets) is removed. All listed metadata files are rebuilt. """ targets_sub_dir = os.path.join(self.targets_dir, 'targets_sub_dir') if remove_all: shutil.rmtree(targets_sub_dir) else: target_path = os.path.join(targets_dir, target_filename) os.remove(target_path) # In order to rebuild metadata, keystore's dictionary must be loaded. keystore._keystore = self.rsa_keystore setup.build_server_repository(self.server_repo_dir, self.targets_dir) # Synchronise client's repository with server's repository. shutil.rmtree(self.client_meta_dir) shutil.copytree(self.server_meta_dir, self.client_current_dir) shutil.copytree(self.server_meta_dir, self.client_previous_dir) keystore._keystore = {}
def test_8_remove_obsolete_targets(self): # Setup: original_download = tuf.download.download_url_to_tempfileobj # This unit test should be last, because it removes target files from the # server's targets directory. It is done to avoid adding files, rebuilding # and updating metadata. target_rel_paths_src = self._get_list_of_target_paths(self.targets_dir) # Create temporary directory which will hold client's target files. dest_dir = self.make_temp_directory() # Populate 'dest_dir' with all target files. for target_path in target_rel_paths_src: _target_info = self.Repository.target(target_path) _target_path = os.path.join(self.targets_dir, target_path) self._mock_download_url_to_tempfileobj(_target_path) self.Repository.download_target(_target_info, dest_dir) # Remove few target files from the server's repository. os.remove(os.path.join(self.targets_dir, target_rel_paths_src[0])) os.remove(os.path.join(self.targets_dir, target_rel_paths_src[3])) # Rebuild server's metadata and update client's metadata. setup.build_server_repository(self.server_repo_dir, self.targets_dir) self._update_top_level_roles() # Get the list of target files. It will be used as an argument to # 'updated_targets' function. delegated_roles = [] delegated_roles = self.all_role_paths[4:] self._mock_download_url_to_tempfileobj(delegated_roles) all_targets = self.Repository.all_targets() # Test: normal case. # Verify number of target files in the 'dest_dir' (should be 4), # and execute 'remove_obsolete_targets' function. self.assertTrue(os.listdir(dest_dir), 4) self.Repository.remove_obsolete_targets(dest_dir) # Verify that number of target files in the 'dest_dir' is now 2, since # two files were previously removed. self.assertTrue(os.listdir(dest_dir), 2) self.assertTrue(os.path.join(dest_dir), target_rel_paths_src[1]) self.assertTrue(os.path.join(dest_dir), target_rel_paths_src[2]) # Verify that if there are no obsolete files, the number of files, # in the 'dest_dir' remains the same. self.Repository.remove_obsolete_targets(dest_dir) self.assertTrue(os.listdir(dest_dir), 2) # RESTORE tuf.download.download_url_to_tempfileobj = original_download
def test_4__refresh_targets_metadata(self): # To test this method a target file would be added to a delegated role, # and metadata on the server side would be rebuilt. targets_deleg_dir1 = os.path.join(self.targets_dir, 'delegated_level1') targets_deleg_dir2 = os.path.join(targets_deleg_dir1, 'delegated_level2') shutil.rmtree(self.server_meta_dir) shutil.rmtree(os.path.join(self.server_repo_dir, 'keystore')) tuf.roledb._roledb_dict['targets/delegated_role1'] = \ self.semi_roledict['targets/delegated_role1'] tuf.roledb._roledb_dict['targets/delegated_role1/delegated_role2'] = \ self.semi_roledict['targets/delegated_role1/delegated_role2'] # Delegated roles paths. role1_dir = os.path.join(self.server_meta_dir, 'targets') role1_filepath = os.path.join(role1_dir, 'delegated_role1.txt') role2_dir = os.path.join(role1_dir, 'delegated_role1') role2_filepath = os.path.join(role2_dir, 'delegated_role2.txt') # Create a file in the delegated targets directory. deleg_target_filepath2 = self._add_file_to_directory( targets_deleg_dir2) junk, deleg_target_file2 = os.path.split(deleg_target_filepath2) # Rebuild server's metadata and update client's metadata. setup.build_server_repository(self.server_repo_dir, self.targets_dir) self._update_top_level_roles() # Patching 'download.download_url_to_tempfilepbj' function. delegated_roles = [role1_filepath, role2_filepath] self._mock_download_url_to_tempfileobj(delegated_roles) # Test: normal case. self.Repository._refresh_targets_metadata(include_delegations=True) # References deleg_role = 'targets/delegated_role1/delegated_role2' deleg_metadata = self.Repository.metadata['current'][deleg_role] # Verify that client's metadata files were refreshed successfully by # checking that the added target file is listed in the client's metadata. # 'targets_list' is the list of included targets from client's metadata. targets_list = [] for target in deleg_metadata['targets']: junk, target_file = os.path.split(target) targets_list.append(target_file) self.assertTrue(deleg_target_file2 in targets_list) # Clean up. self._remove_filepath(deleg_target_filepath2) shutil.rmtree(os.path.join(self.server_repo_dir, 'metadata')) shutil.rmtree(os.path.join(self.server_repo_dir, 'keystore')) setup.build_server_repository(self.server_repo_dir, self.targets_dir)
def test_8_remove_obsolete_targets(self): # Setup: original_download = tuf.download.download_url_to_tempfileobj # This unit test should be last, because it removes target files from the # server's targets directory. It is done to avoid adding files, rebuilding # and updating metadata. target_rel_paths_src = self._get_list_of_target_paths(self.targets_dir) # Create temporary directory which will hold client's target files. dest_dir = self.make_temp_directory() # Populate 'dest_dir' with all target files. for target_path in target_rel_paths_src: _target_info = self.Repository.target(target_path) _target_path = os.path.join(self.targets_dir, target_path) self._mock_download_url_to_tempfileobj(_target_path) self.Repository.download_target(_target_info, dest_dir) # Remove few target files from the server's repository. os.remove(os.path.join(self.targets_dir, target_rel_paths_src[0])) os.remove(os.path.join(self.targets_dir, target_rel_paths_src[3])) # Rebuild server's metadata and update client's metadata. setup.build_server_repository(self.server_repo_dir, self.targets_dir) self._update_top_level_roles() # Get the list of target files. It will be used as an argument to # 'updated_targets' function. delegated_roles = [] delegated_roles = self.all_role_paths[4:] self._mock_download_url_to_tempfileobj(delegated_roles) all_targets = self.Repository.all_targets() # Test: normal case. # Verify number of target files in the 'dest_dir' (should be 4), # and execute 'remove_obsolete_targets' function. self.assertTrue(os.listdir(dest_dir), 4) self.Repository.remove_obsolete_targets(dest_dir) # Verify that number of target files in the 'dest_dir' is now 2, since # two files were previously removed. self.assertTrue(os.listdir(dest_dir), 2) self.assertTrue(os.path.join(dest_dir), target_rel_paths_src[1]) self.assertTrue(os.path.join(dest_dir), target_rel_paths_src[2]) # Verify that if there are no obsolete files, the number of files, # in the 'dest_dir' remains the same. self.Repository.remove_obsolete_targets(dest_dir) self.assertTrue(os.listdir(dest_dir), 2) # RESTORE tuf.download.download_url_to_tempfileobj = original_download
def _add_target_to_targets_dir(self, targets_keyids): """ Adds a file to server's 'targets' directory and rebuilds targets metadata (targets.txt). """ targets_sub_dir = os.path.join(self.targets_dir, 'targets_sub_dir') if not os.path.exists(targets_sub_dir): os.mkdir(targets_sub_dir) file_path = tempfile.mkstemp(suffix='.txt', dir=targets_sub_dir) data = self.random_string() file_object = open(file_path[1], 'wb') file_object.write(data) file_object.close() # In order to rebuild metadata, keystore's dictionary must be loaded. # Fortunately, 'unittest_toolbox.rsa_keystore' dictionary stores all keys. keystore._keystore = self.rsa_keystore setup.build_server_repository(self.server_repo_dir, self.targets_dir) keystore._keystore = {} junk, target_filename = os.path.split(file_path[1]) return os.path.join('targets_sub_dir', target_filename)
def _add_target_to_targets_dir(self, targets_keyids): """ Adds a file to server's 'targets' directory and rebuilds targets metadata (targets.txt). """ targets_sub_dir = os.path.join(self.targets_dir, 'targets_sub_dir') if not os.path.exists(targets_sub_dir): os.mkdir(targets_sub_dir) file_path = tempfile.mkstemp(suffix='.txt', dir=targets_sub_dir) data = self.random_string() file_object = open(file_path[1], 'wb') file_object.write(data) file_object.close() # In order to rebuild metadata, keystore's dictionary must be loaded. # Fortunately, 'unittest_toolbox.rsa_keystore' dictionary stores all keys. keystore._keystore = self.rsa_keystore setup.build_server_repository(self.server_repo_dir, self.targets_dir) keystore._keystore = {} junk, target_filename = os.path.split(file_path[1]) return os.path.join('targets_sub_dir', target_filename)
def test_4_refresh(self): # Setup. original_download = tuf.download.download_url_to_tempfileobj # This unit test is based on adding an extra target file to the # server and rebuilding all server-side metadata. When 'refresh' # function is called by the client all top level metadata should # be updated. target_fullpath = self._add_file_to_directory(self.targets_dir) target_relpath = os.path.split(target_fullpath) # Reference 'self.Repository.metadata['current']['targets']'. targets_meta = self.Repository.metadata['current']['targets'] self.assertFalse(target_relpath[1] in targets_meta['targets'].keys()) # Rebuild metadata at the server side. self._mock_download_url_to_tempfileobj(self.all_role_paths) setup.build_server_repository(self.server_repo_dir, self.targets_dir) # Test: normal case. self.Repository.refresh() # Verify that clients metadata was updated. targets_meta = self.Repository.metadata['current']['targets'] self.assertTrue(target_relpath[1] in targets_meta['targets'].keys()) # Restore server's repository to initial state. self._remove_filepath(target_fullpath) # Rebuild metadata at the server side. self._mock_download_url_to_tempfileobj(self.all_role_paths) setup.build_server_repository(self.server_repo_dir, self.targets_dir) # RESTORE tuf.download.download_url_to_tempfileobj = original_download
def test_4__refresh_targets_metadata(self): # Setup original_download = tuf.download.download_url_to_tempfileobj # To test this method a target file would be added to a delegated role, # and metadata on the server side would be rebuilt. targets_deleg_dir1 = os.path.join(self.targets_dir, 'delegated_level1') targets_deleg_dir2 = os.path.join(targets_deleg_dir1, 'delegated_level2') shutil.rmtree(self.server_meta_dir) shutil.rmtree(os.path.join(self.server_repo_dir, 'keystore')) tuf.roledb._roledb_dict['targets/delegated_role1'] = \ self.semi_roledict['targets/delegated_role1'] tuf.roledb._roledb_dict['targets/delegated_role1/delegated_role2'] = \ self.semi_roledict['targets/delegated_role1/delegated_role2'] # Delegated roles paths. role1_dir = os.path.join(self.server_meta_dir, 'targets') role1_filepath = os.path.join(role1_dir, 'delegated_role1.txt') role2_dir = os.path.join(role1_dir, 'delegated_role1') role2_filepath = os.path.join(role2_dir, 'delegated_role2.txt') # Create a file in the delegated targets directory. deleg_target_filepath2 = self._add_file_to_directory(targets_deleg_dir2) junk, deleg_target_file2 = os.path.split(deleg_target_filepath2) # Rebuild server's metadata and update client's metadata. setup.build_server_repository(self.server_repo_dir, self.targets_dir) self._update_top_level_roles() # Patching 'download.download_url_to_tempfilepbj' function. delegated_roles = [role1_filepath, role2_filepath] self._mock_download_url_to_tempfileobj(delegated_roles) # Test: normal case. self.Repository._refresh_targets_metadata(include_delegations=True) # References deleg_role = 'targets/delegated_role1/delegated_role2' deleg_metadata = self.Repository.metadata['current'][deleg_role] # Verify that client's metadata files were refreshed successfully by # checking that the added target file is listed in the client's metadata. # 'targets_list' is the list of included targets from client's metadata. targets_list = [] for target in deleg_metadata['targets']: junk, target_file = os.path.split(target) targets_list.append(target_file) self.assertTrue(deleg_target_file2 in targets_list) # Clean up. self._remove_filepath(deleg_target_filepath2) shutil.rmtree(os.path.join(self.server_repo_dir, 'metadata')) shutil.rmtree(os.path.join(self.server_repo_dir, 'keystore')) setup.build_server_repository(self.server_repo_dir, self.targets_dir) # RESTORE tuf.download.download_url_to_tempfileobj = original_download
def test_7_updated_targets(self): # Setup: original_download = tuf.download.download_url_to_tempfileobj # In this test, client will have two target files. Server will modify # one of them. As with 'all_targets' function, tuf.roledb._roledb_dict # has to be populated. 'tuf.download.download_url_to_tempfileobj' method # should be patched. target_rel_paths_src = self._get_list_of_target_paths(self.targets_dir) # Create temporary directory which will hold client's target files. dest_dir = self.make_temp_directory() target_info = [] for target_path in target_rel_paths_src: target_info.append(self.Repository.target(target_path)) # Populate 'dest_dir' with few target files. target_path0 = os.path.join(self.targets_dir, target_info[0]['filepath']) self._mock_download_url_to_tempfileobj(target_path0) self.Repository.download_target(target_info[0], dest_dir) target_path1 = os.path.join(self.targets_dir, target_info[1]['filepath']) self._mock_download_url_to_tempfileobj(target_path1) self.Repository.download_target(target_info[1], dest_dir) # Modify one of the above downloaded target files at the server side. file_obj = open(target_path0, 'wb') file_obj.write(2*self.random_string()) file_obj.close() # Rebuild server's metadata and update client's metadata. setup.build_server_repository(self.server_repo_dir, self.targets_dir) self._update_top_level_roles() # Get the list of target files. It will be used as an argument to # 'updated_targets' function. delegated_roles = [] delegated_roles = self.all_role_paths[4:] self._mock_download_url_to_tempfileobj(delegated_roles) all_targets = self.Repository.all_targets() # At this point client needs to update modified target and download # two other targets. As a result of calling 'update_targets' method, # a list of updated/new targets (that will need to be downloaded) # should be returned. # Test: normal cases. updated_targets = self.Repository.updated_targets(all_targets, dest_dir) # Verify that list contains all files that need to be updated, these # files include modified and new target files. Also, confirm that files # than need not to be updated are absent from the list. # 'updated_targets' list should contains 5 target files i.e. one - that # was modified, two - that are absent from the client's repository and # same two - belonging to delegated roles. self.assertTrue(len(updated_targets) is 5) for updated_target in updated_targets: if target_info[1]['filepath'] == updated_target['filepath']: msg = 'A file that need not to be updated is indicated as updated.' self.fail(msg) # RESTORE tuf.download.download_url_to_tempfileobj = original_download
def test_7_updated_targets(self): # In this test, client will have two target files. Server will modify # one of them. As with 'all_targets' function, tuf.roledb._roledb_dict # has to be populated. 'tuf.download.safe_download' method # should be patched. target_rel_paths_src = self._get_list_of_target_paths(self.targets_dir) # Create temporary directory which will hold client's target files. dest_dir = self.make_temp_directory() target_info = [] for target_path in target_rel_paths_src: target_info.append(self.Repository.target(target_path)) # Populate 'dest_dir' with few target files. target_path0 = os.path.join(self.targets_dir, target_info[0]['filepath']) self._mock_download_url_to_tempfileobj(target_path0) self.Repository.download_target(target_info[0], dest_dir) target_path1 = os.path.join(self.targets_dir, target_info[1]['filepath']) self._mock_download_url_to_tempfileobj(target_path1) self.Repository.download_target(target_info[1], dest_dir) # Modify one of the above downloaded target files at the server side. file_obj = open(target_path0, 'wb') file_obj.write(2 * self.random_string()) file_obj.close() # Rebuild server's metadata and update client's metadata. setup.build_server_repository(self.server_repo_dir, self.targets_dir) self._update_top_level_roles() # Get the list of target files. It will be used as an argument to # 'updated_targets' function. delegated_roles = [] delegated_roles = self.all_role_paths[4:] self._mock_download_url_to_tempfileobj(delegated_roles) all_targets = self.Repository.all_targets() # At this point client needs to update modified target and download # two other targets. As a result of calling 'update_targets' method, # a list of updated/new targets (that will need to be downloaded) # should be returned. # Test: normal cases. updated_targets = self.Repository.updated_targets( all_targets, dest_dir) # Verify that list contains all files that need to be updated, these # files include modified and new target files. Also, confirm that files # than need not to be updated are absent from the list. # 'updated_targets' list should contains 5 target files i.e. one - that # was modified, two - that are absent from the client's repository and # same two - belonging to delegated roles. self.assertTrue(len(updated_targets) is 5) for updated_target in updated_targets: if target_info[1]['filepath'] == updated_target['filepath']: msg = 'A file that need not to be updated is indicated as updated.' self.fail(msg)