From 230920f74e8cc7b34e7639abd5b42796c69ab61a Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Mon, 27 Apr 2015 18:30:55 -0400 Subject: [PATCH 1/6] Minor code coverage improvement to updater.py --- tests/test_updater.py | 66 ++++++++++++++++++++++++++++++++++++++----- tests/test_util.py | 2 +- tuf/client/updater.py | 10 ++++++- 3 files changed, 69 insertions(+), 9 deletions(-) diff --git a/tests/test_updater.py b/tests/test_updater.py index cbf6c63a..38870178 100755 --- a/tests/test_updater.py +++ b/tests/test_updater.py @@ -686,6 +686,10 @@ def test_3__update_metadata_if_changed(self): self.assertTrue(self.repository_updater.metadata['current']['targets']) self.assertEqual(self.repository_updater.metadata['current']['targets']['version'], 2) + # Test for an invalid 'referenced_metadata' argument. + self.assertRaises(tuf.RepositoryError, + self.repository_updater._update_metadata_if_changed, + 'snapshot', 'bad_role') @@ -789,8 +793,17 @@ def test_4__refresh_targets_metadata(self): # Verify that client's metadata files were refreshed successfully. self.assertEqual(len(self.repository_updater.metadata['current']), 5) - - + # Test for compressed metadata roles. + self.repository_updater.metadata['current']['snapshot']['meta']['targets.json.gz'] = \ + self.repository_updater.metadata['current']['snapshot']['meta']['targets.json'] + self.repository_updater._refresh_targets_metadata(include_delegations=True) + + # Test for repository error if the 'targets' role is not specified + # in 'snapshot'. + del self.repository_updater.metadata['current']['snapshot']['meta']['targets.json'] + self.assertRaises(tuf.RepositoryError, + self.repository_updater._refresh_targets_metadata, + 'targets', True) def test_5_all_targets(self): @@ -1024,10 +1037,13 @@ def test_6_download_target(self): download_targetfileinfo['custom'] = target_fileinfo['fileinfo']['custom'] self.assertEqual(target_fileinfo['fileinfo'], download_targetfileinfo) - # Test when consistent snapshots is set. - self.repository_updater.consistent_snapshots = True + # Test when consistent snapshots is set. TODO: creat a repository + # with consistent snapshots set. + """ + self.repository_updater.consistent_snapshot = True self.repository_updater.download_target(target_fileinfo, destination_directory) + """ # Test: Invalid arguments. self.assertRaises(tuf.FormatError, self.repository_updater.download_target, @@ -1037,7 +1053,14 @@ def test_6_download_target(self): target_fileinfo = self.repository_updater.target(random_target_filepath) self.assertRaises(tuf.FormatError, self.repository_updater.download_target, target_fileinfo, 8) - + + # Non-existent destination. + # TODO: test for non-existent directories. + """ + self.assertRaises(tuf.Error, self.repository_updater.download_target, + target_fileinfo, 'non-existent/bad_path') + """ + # Test: # Attempt a file download of a valid target, however, a download exception # occurs because the target is not within the mirror's confined target @@ -1073,12 +1096,21 @@ def test_7_updated_targets(self): # Get the list of target files. It will be used as an argument to # 'updated_targets' function. all_targets = self.repository_updater.all_targets() + + # Test for duplicates and targets in the root directory of the repository. + additional_target = all_targets[0].copy() + all_targets.append(additional_target) + additional_target_in_root_directory = additional_target.copy() + additional_target_in_root_directory['filepath'] = 'file1.txt' + all_targets.append(additional_target_in_root_directory) # At this point client needs to update and download all targets. # Test: normal cases. updated_targets = \ self.repository_updater.updated_targets(all_targets, destination_directory) + all_targets = self.repository_updater.all_targets() + # Assumed the pre-generated repository specifies two target files in # 'targets.json' and one delegated target file in 'targets/role1.json'. self.assertEqual(len(updated_targets), 3) @@ -1096,7 +1128,7 @@ def test_7_updated_targets(self): # Test: download all the targets. for download_target in all_targets: self.repository_updater.download_target(download_target, - destination_directory) + destination_directory) updated_targets = \ self.repository_updater.updated_targets(all_targets, destination_directory) @@ -1258,8 +1290,28 @@ def test_10__targets_of_role(self): 0) - + def test_10__visit_child_role(self): + # Call _visit_child_role and test the dict keys: 'paths', + # 'path_hash_prefixes', and if both are missing. + targets_role = self.repository_updater.metadata['current']['targets'] + + child_role = targets_role['delegations']['roles'][0] + self.assertEqual(self.repository_updater._visit_child_role(child_role, + '/file3.txt'), child_role['name']) + + # Test path hash prefixes. + child_role['path_hash_prefixes'] = ['8baf', '0000'] + self.assertEqual(self.repository_updater._visit_child_role(child_role, + '/file3.txt'), child_role['name']) + + # Test if both 'path' and 'path_hash_prefixes' is missing. + del child_role['paths'] + del child_role['path_hash_prefixes'] + self.assertRaises(tuf.FormatError, self.repository_updater._visit_child_role, + child_role, child_role['name']) + + def _load_role_keys(keystore_directory): diff --git a/tests/test_util.py b/tests/test_util.py index b5ce3694..25e1e318 100755 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -422,7 +422,7 @@ def test_C2_find_delegated_role(self): 'targets/tuf') # Test missing 'name' attribute (optional, but required by - # 'find_delegated_role()'. + # 'find_delegated_role()'). # Delete the duplicate role, and the remaining role's 'name' attribute. del role_list[2] del role_list[0]['name'] diff --git a/tuf/client/updater.py b/tuf/client/updater.py index dbe8d70c..4fbb845d 100755 --- a/tuf/client/updater.py +++ b/tuf/client/updater.py @@ -1914,6 +1914,9 @@ def _refresh_targets_metadata(self, rolename='targets', include_delegations=Fals # extensions. if metadata_path.endswith('.json'): roles_to_update.append(metadata_path[:-len('.json')]) + + else: + continue # Remove the 'targets' role because it gets updated when the targets.json # file is updated in _update_metadata_if_changed('targets'). @@ -2440,6 +2443,9 @@ def _visit_child_role(self, child_role, target_filepath): for child_role_path_hash_prefix in child_role_path_hash_prefixes: if target_filepath_hash.startswith(child_role_path_hash_prefix): child_role_is_relevant = True + + else: + continue elif child_role_paths is not None: for child_role_path in child_role_paths: @@ -2726,6 +2732,8 @@ def download_target(self, target, destination_directory): raise else: - logger.warning(repr(target_dirpath) + ' does not exist.') + message = repr(target_dirpath) + ' does not exist.' + logger.warning(message) + raise tuf.Error(message) target_file_object.move(destination) From c97d9a022d5bced7cb65a1ba6f0e304012da88aa Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Mon, 27 Apr 2015 18:32:09 -0400 Subject: [PATCH 2/6] Force build failure if any of the unit tests fail --- tests/aggregate_tests.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/aggregate_tests.py b/tests/aggregate_tests.py index a73e95fc..12e14e37 100755 --- a/tests/aggregate_tests.py +++ b/tests/aggregate_tests.py @@ -62,6 +62,8 @@ # modules. random.shuffle(tests_without_extension) - -suite = unittest.TestLoader().loadTestsFromNames(tests_without_extension) -unittest.TextTestRunner(verbosity=2).run(suite) +if __name__ == '__main__': + suite = unittest.TestLoader().loadTestsFromNames(tests_without_extension) + all_tests_passed = unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful() + if not all_tests_passed: + sys.exit(1) From 94a9c9615f9abb1c5b91e1ffba058c6b5ce5db48 Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Mon, 27 Apr 2015 18:33:12 -0400 Subject: [PATCH 3/6] Force build failure if code coverage < 97% (to be increased). --- tox.ini | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 0c586e04..5bc40fed 100644 --- a/tox.ini +++ b/tox.ini @@ -4,6 +4,7 @@ # and then run "tox" from this directory. [tox] +#envlist = py27 envlist = py26, py27, py32, py33, py34 @@ -12,7 +13,8 @@ changedir = tests commands = coverage run --source tuf aggregate_tests.py - coverage report -m + coverage report -m --fail-under 97 + coverage html deps = coverage From d9e3ce4ce1b3c9ec661740b1973814f4f00760fb Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Mon, 27 Apr 2015 20:25:52 -0400 Subject: [PATCH 4/6] Expand comment for incomplete test case (testing consistent snapshots) in test_updater.py --- tests/test_updater.py | 5 +++-- tox.ini | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/test_updater.py b/tests/test_updater.py index 38870178..50af71b4 100755 --- a/tests/test_updater.py +++ b/tests/test_updater.py @@ -1037,8 +1037,9 @@ def test_6_download_target(self): download_targetfileinfo['custom'] = target_fileinfo['fileinfo']['custom'] self.assertEqual(target_fileinfo['fileinfo'], download_targetfileinfo) - # Test when consistent snapshots is set. TODO: creat a repository - # with consistent snapshots set. + # Test when consistent snapshots is set. TODO: create a valid repository + # with consistent snapshots set. The updater expects the existence + # of .filename files if root.json sets 'consistent_snapshot = True'. """ self.repository_updater.consistent_snapshot = True self.repository_updater.download_target(target_fileinfo, diff --git a/tox.ini b/tox.ini index 5bc40fed..0085b26f 100644 --- a/tox.ini +++ b/tox.ini @@ -4,8 +4,8 @@ # and then run "tox" from this directory. [tox] -#envlist = py27 -envlist = py26, py27, py32, py33, py34 +envlist = py27 +#envlist = py26, py27, py32, py33, py34 [testenv] @@ -14,7 +14,7 @@ changedir = tests commands = coverage run --source tuf aggregate_tests.py coverage report -m --fail-under 97 - coverage html + coverage html deps = coverage From b9d2f49f57e1a27544b24fa346bf5fcfea69a015 Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Mon, 27 Apr 2015 20:56:55 -0400 Subject: [PATCH 5/6] Update tox.ini --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 0085b26f..9116bc6a 100644 --- a/tox.ini +++ b/tox.ini @@ -13,7 +13,7 @@ changedir = tests commands = coverage run --source tuf aggregate_tests.py - coverage report -m --fail-under 97 + coverage report -m --fail-under 96 coverage html deps = From 1bd9e1c7331bf7aafbcd0c8688dd5bf934faec92 Mon Sep 17 00:00:00 2001 From: Vladimir Diaz Date: Wed, 29 Apr 2015 10:33:43 -0400 Subject: [PATCH 6/6] Update tox.ini --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 9116bc6a..3070bb5a 100644 --- a/tox.ini +++ b/tox.ini @@ -4,8 +4,8 @@ # and then run "tox" from this directory. [tox] -envlist = py27 -#envlist = py26, py27, py32, py33, py34 +#envlist = py27 +envlist = py26, py27, py32, py33, py34 [testenv]