Skip to content

Commit c5d0970

Browse files
Merge pull request #1 from theupdateframework/develop
Merge from main branch
2 parents ffe2384 + 0ce016b commit c5d0970

11 files changed

+290
-386
lines changed

tests/test_repository_lib.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -755,14 +755,18 @@ def test_write_metadata_file(self):
755755
compression_algorithms,
756756
consistent_snapshot=False)
757757

758-
# Try to wirte a consistent metadate file. An exception is not raised in this case.
758+
# Try to write a consistent metadate file. An exception is not raised in
759+
# this case. For testing purposes, root.json should be a hard link to the
760+
# consistent metadata file. We should verify that root.json points to
761+
# the latest consistent files.
759762
tuf.conf.CONSISTENT_METHOD = 'hard_link'
760763
repo_lib.write_metadata_file(root_signable, output_filename,
761764
version_number,
762765
compression_algorithms,
763766
consistent_snapshot=True)
764767

765-
# Test if the consistent files are properly named (<version number>.rolename.json) or not
768+
# Test if the consistent files are properly named
769+
# Filename format of a consistent file: <version number>.rolename.json
766770
version_and_filename = str(version_number) + '.' + 'root.json'
767771
first_version_output_file = os.path.join(temporary_directory, version_and_filename)
768772
self.assertTrue(os.path.exists(first_version_output_file))
@@ -775,23 +779,34 @@ def test_write_metadata_file(self):
775779
consistent_snapshot=True)
776780

777781
# Test if the the latest root.json points to the expected consistent file
778-
# and
779-
# consistent metadata do not all point to the same root.json
782+
# and consistent metadata do not all point to the same root.json
780783
version_and_filename = str(version_number) + '.' + 'root.json'
781784
second_version_output_file = os.path.join(temporary_directory, version_and_filename)
782785
self.assertTrue(os.path.exists(second_version_output_file))
783786
self.assertNotEqual(os.stat(output_filename).st_ino, os.stat(first_version_output_file).st_ino)
784787
self.assertEqual(os.stat(output_filename).st_ino, os.stat(second_version_output_file).st_ino)
785788

786-
# Test improper Consistent_METHOD configuration
789+
# Test for an improper tuf.conf.CONSISTENT_METHOD string value.
787790
tuf.conf.CONSISTENT_METHOD = 'somebadidea'
788791
self.assertRaises(tuf.InvalidConfigurationError, repo_lib.write_metadata_file,
789792
root_signable, output_filename,
790793
version_number,
791794
compression_algorithms,
792795
consistent_snapshot=True)
793796

794-
# Test unknown compression algorithm.
797+
# Try to create a link to root.json when root.json doesn't exist locally.
798+
# repository_lib should log a message if this is the case.
799+
tuf.conf.CONSISTENT_METHOD = 'hard_link'
800+
os.remove(output_filename)
801+
repo_lib.write_metadata_file(root_signable, output_filename,
802+
version_number,
803+
compression_algorithms,
804+
consistent_snapshot=True)
805+
806+
# Reset CONSISTENT_METHOD so that subsequent tests work as expected.
807+
tuf.conf.CONSISTENT_METHOD = 'copy'
808+
809+
# Test for unknown compression algorithm.
795810
self.assertRaises(tuf.FormatError, repo_lib.write_metadata_file,
796811
root_signable, output_filename,
797812
version_number,

tests/test_repository_tool.py

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,13 @@ def test_writeall(self):
194194

195195

196196
# (3) Load top-level signing keys.
197+
repository.status()
197198
repository.root.load_signing_key(root_privkey)
199+
repository.status()
198200
repository.targets.load_signing_key(targets_privkey)
201+
repository.status()
199202
repository.snapshot.load_signing_key(snapshot_privkey)
203+
repository.status()
200204

201205
# Verify that repository.writeall() fails for insufficient threshold
202206
# of signatures (default threshold = 1).
@@ -343,6 +347,19 @@ def test_writeall(self):
343347
# successfully.
344348
repo_tool.load_repository(repository_directory)
345349

350+
# Verify the behavior of marking and unmarking roles as dirty.
351+
# We begin by ensuring that writeall() cleared the list of dirty roles..
352+
self.assertEqual([], tuf.roledb.get_dirty_roles())
353+
354+
repository.mark_dirty(['root', 'timestamp'])
355+
self.assertEqual(['root', 'timestamp'], sorted(tuf.roledb.get_dirty_roles()))
356+
repository.unmark_dirty(['root'])
357+
self.assertEqual(['timestamp'], tuf.roledb.get_dirty_roles())
358+
359+
# Ensure status() does not leave behind any dirty roles.
360+
repository.status()
361+
self.assertEqual(['timestamp'], tuf.roledb.get_dirty_roles())
362+
346363
# Test improperly formatted arguments.
347364
self.assertRaises(tuf.FormatError, repository.writeall, 3, False)
348365
self.assertRaises(tuf.FormatError, repository.writeall, False, 3)
@@ -1538,9 +1555,26 @@ def test_load_repository(self):
15381555
temporary_directory = tempfile.mkdtemp(dir=self.temporary_directory)
15391556
original_repository_directory = os.path.join('repository_data',
15401557
'repository')
1558+
15411559
repository_directory = os.path.join(temporary_directory, 'repository')
1560+
metadata_directory = os.path.join(repository_directory, 'metadata.staged')
15421561
shutil.copytree(original_repository_directory, repository_directory)
1543-
1562+
1563+
# For testing purposes, add a metadata file with an extension that is
1564+
# not supported, and another with invalid JSON content.
1565+
invalid_metadata_file = os.path.join(metadata_directory, 'root.xml')
1566+
root_file = os.path.join(metadata_directory, 'root.json')
1567+
shutil.copyfile(root_file, invalid_metadata_file)
1568+
bad_root_content = os.path.join(metadata_directory, 'root_bad.json')
1569+
1570+
with open(bad_root_content, 'wb') as file_object:
1571+
file_object.write(b'bad')
1572+
1573+
# Remove the compressed version of role1 to test whether the
1574+
# load_repository() complains or not (it logs a message).
1575+
role1_path = os.path.join(metadata_directory, 'role1.json.gz')
1576+
os.remove(role1_path)
1577+
15441578
repository = repo_tool.load_repository(repository_directory)
15451579
self.assertTrue(isinstance(repository, repo_tool.Repository))
15461580

@@ -1557,8 +1591,8 @@ def test_load_repository(self):
15571591
self.assertTrue(len(repository.timestamp.keys))
15581592
self.assertEqual(1, repository.targets('role1').version)
15591593

1560-
# Assumed the targets (tuf/tests/repository_data/) role contains 'file1.txt'
1561-
# and 'file2.txt'.
1594+
# It is assumed that the targets (tuf/tests/repository_data/) role contains
1595+
# 'file1.txt' and 'file2.txt'.
15621596
self.assertTrue('/file1.txt' in repository.targets.target_files)
15631597
self.assertTrue('/file2.txt' in repository.targets.target_files)
15641598
self.assertTrue('/file3.txt' in repository.targets('role1').target_files)

tests/test_roledb.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,36 @@ def test_mark_dirty(self):
701701
self.assertRaises(tuf.InvalidNameError, tuf.roledb.mark_dirty,
702702
['dirty_role'], 'non-existent')
703703

704+
705+
706+
def test_unmark_dirty(self):
707+
# Add a dirty role to roledb.
708+
rolename = 'targets'
709+
roleinfo1 = {'keyids': ['123'], 'threshold': 1}
710+
tuf.roledb.add_role(rolename, roleinfo1)
711+
rolename2 = 'dirty_role'
712+
roleinfo2 = {'keyids': ['123'], 'threshold': 2}
713+
tuf.roledb.add_role(rolename2, roleinfo2)
714+
mark_role_as_dirty = True
715+
tuf.roledb.update_roleinfo(rolename, roleinfo1, mark_role_as_dirty)
716+
# Note: The 'default' repository is searched if the repository name is
717+
# not given to get_dirty_roles().
718+
self.assertEqual([rolename], tuf.roledb.get_dirty_roles())
719+
tuf.roledb.update_roleinfo(rolename2, roleinfo2, mark_role_as_dirty)
720+
721+
tuf.roledb.unmark_dirty(['dirty_role'])
722+
self.assertEqual([rolename], sorted(tuf.roledb.get_dirty_roles()))
723+
tuf.roledb.unmark_dirty(['targets'])
724+
self.assertEqual([], sorted(tuf.roledb.get_dirty_roles()))
725+
726+
# What happens for a role that isn't dirty? unmark_dirty() should just
727+
# log a message.
728+
tuf.roledb.unmark_dirty(['unknown_role'])
729+
730+
# Verify that a role cannot be unmarked as dirty for a non-existent
731+
# repository.
732+
self.assertRaises(tuf.InvalidNameError, tuf.roledb.unmark_dirty,
733+
['dirty_role'], 'non-existent')
704734

705735

706736
def _test_rolename(self, test_function):

tests/test_sig.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,16 @@ def test_get_signature_status_single_key(self):
177177
self.assertEqual([], sig_status['unknown_method_sigs'])
178178

179179
self.assertTrue(tuf.sig.verify(signable, 'Root'))
180+
181+
# Test for an unknown signature when 'role' is left unspecified.
182+
sig_status = tuf.sig.get_signature_status(signable)
183+
184+
self.assertEqual(0, sig_status['threshold'])
185+
self.assertEqual([], sig_status['good_sigs'])
186+
self.assertEqual([], sig_status['bad_sigs'])
187+
self.assertEqual([KEYS[0]['keyid']], sig_status['unknown_sigs'])
188+
self.assertEqual([], sig_status['untrusted_sigs'])
189+
self.assertEqual([], sig_status['unknown_method_sigs'])
180190

181191
# Done. Let's remove the added key(s) from the key database.
182192
tuf.keydb.remove_key(KEYS[0]['keyid'])
@@ -281,6 +291,9 @@ def test_get_signature_status_below_threshold_unauthorized_sigs(self):
281291
self.assertEqual([], sig_status['unknown_method_sigs'])
282292

283293
self.assertFalse(tuf.sig.verify(signable, 'Root'))
294+
295+
self.assertRaises(tuf.UnknownRoleError,
296+
tuf.sig.get_signature_status, signable, 'unknown_role')
284297

285298
# Done. Let's remove the added key(s) from the key database.
286299
tuf.keydb.remove_key(KEYS[0]['keyid'])

0 commit comments

Comments
 (0)