-
Notifications
You must be signed in to change notification settings - Fork 278
experimental client: Add MetadataBundle #1355
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
jku
merged 33 commits into
theupdateframework:experimental-client
from
jku:experimental-metadata-bundle
May 18, 2021
Merged
Changes from all commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
3b161bf
experimental client: Add MetadataBundle
5e1fe0d
MetadataBundle: Update outdated docstring
3f7c405
MetadataBundle: Modify state handling
6228454
MetadataBundle: implement delegates support
f503ebe
MetadataBundle: use Metadata.from_bytes()
c1afe57
MetadataBundle: Require load_local_metadata()
e7a0feb
Improve loading rules checks
cadbd84
Comment and variable name improvements
7e457ec
Exceptions refactoring
53f5ccb
MetadataBundle: Exception refactor
71793b6
Update MetadataBundle with named methods
5596f77
MetadataBundle: Handle targets like delegated targets
766f494
MetadataBundle: Avoid loading targets twice
9051358
MetadataBundle: fix import name
1d22d5a
MetadataBundle: Improve hints and docs
e26772c
Remove unnecessary directory check at startup
800b088
MetadataBundle: Fix loads of linting issues
b681788
Improve documentation
66fa37b
MetadataBundle: Update to API changes
0bbfe03
tests: Add minimal test case for Bundle
112b333
Metadata API: Fix DelegatedRole serialization issue
f8b714d
Metadata API: Don't do equality comparisons on containers
2d155fa
MetadataBundle: Change ValueErrors to RuntimeErrors
eb648d1
MetadataBundle: Save original files on disk
3b30d08
MetadataBundle: Store reference time earlier
8d0245a
MetadataBundle: Use type, not _type
876fda1
MetadataBundle: Add comments about the process
112f3b6
MetadataBundle: Handle Deserialization errors
b86d1f7
MetadataBundle: Raise instead of returning bool
a371258
MetadataBundle: Use builtin errors when possible
6b53ac7
Make BadHashError derive from RepositoryError
f2cff95
MetadataBundle: Don't do any file IO
377eac1
MetadataBundle: Improve docstrings
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import json | ||
import logging | ||
import os | ||
import shutil | ||
import sys | ||
import tempfile | ||
import unittest | ||
|
||
from tuf import exceptions | ||
from tuf.api.metadata import Metadata | ||
from tuf.client_rework.metadata_bundle import MetadataBundle | ||
|
||
from tests import utils | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
class TestMetadataBundle(unittest.TestCase): | ||
|
||
def test_update(self): | ||
repo_dir = os.path.join(os.getcwd(), 'repository_data', 'repository', 'metadata') | ||
|
||
with open(os.path.join(repo_dir, "root.json"), "rb") as f: | ||
bundle = MetadataBundle(f.read()) | ||
bundle.root_update_finished() | ||
|
||
with open(os.path.join(repo_dir, "timestamp.json"), "rb") as f: | ||
bundle.update_timestamp(f.read()) | ||
with open(os.path.join(repo_dir, "snapshot.json"), "rb") as f: | ||
bundle.update_snapshot(f.read()) | ||
with open(os.path.join(repo_dir, "targets.json"), "rb") as f: | ||
bundle.update_targets(f.read()) | ||
with open(os.path.join(repo_dir, "role1.json"), "rb") as f: | ||
bundle.update_delegated_targets(f.read(), "role1", "targets") | ||
with open(os.path.join(repo_dir, "role2.json"), "rb") as f: | ||
bundle.update_delegated_targets(f.read(), "role2", "role1") | ||
|
||
def test_out_of_order_ops(self): | ||
repo_dir = os.path.join(os.getcwd(), 'repository_data', 'repository', 'metadata') | ||
data={} | ||
for md in ["root", "timestamp", "snapshot", "targets", "role1"]: | ||
with open(os.path.join(repo_dir, f"{md}.json"), "rb") as f: | ||
data[md] = f.read() | ||
|
||
bundle = MetadataBundle(data["root"]) | ||
|
||
# Update timestamp before root is finished | ||
with self.assertRaises(RuntimeError): | ||
bundle.update_timestamp(data["timestamp"]) | ||
|
||
bundle.root_update_finished() | ||
with self.assertRaises(RuntimeError): | ||
bundle.root_update_finished() | ||
|
||
# Update snapshot before timestamp | ||
with self.assertRaises(RuntimeError): | ||
bundle.update_snapshot(data["snapshot"]) | ||
|
||
bundle.update_timestamp(data["timestamp"]) | ||
|
||
# Update targets before snapshot | ||
with self.assertRaises(RuntimeError): | ||
bundle.update_targets(data["targets"]) | ||
|
||
bundle.update_snapshot(data["snapshot"]) | ||
|
||
#update timestamp after snapshot | ||
with self.assertRaises(RuntimeError): | ||
bundle.update_timestamp(data["timestamp"]) | ||
|
||
# Update delegated targets before targets | ||
with self.assertRaises(RuntimeError): | ||
bundle.update_delegated_targets(data["role1"], "role1", "targets") | ||
|
||
bundle.update_targets(data["targets"]) | ||
bundle.update_delegated_targets(data["role1"], "role1", "targets") | ||
|
||
def test_update_with_invalid_json(self): | ||
repo_dir = os.path.join(os.getcwd(), 'repository_data', 'repository', 'metadata') | ||
data={} | ||
for md in ["root", "timestamp", "snapshot", "targets", "role1"]: | ||
with open(os.path.join(repo_dir, f"{md}.json"), "rb") as f: | ||
data[md] = f.read() | ||
|
||
# root.json not a json file at all | ||
with self.assertRaises(exceptions.RepositoryError): | ||
MetadataBundle(b"") | ||
# root.json is invalid | ||
root = Metadata.from_bytes(data["root"]) | ||
root.signed.version += 1 | ||
with self.assertRaises(exceptions.RepositoryError): | ||
MetadataBundle(json.dumps(root.to_dict()).encode()) | ||
|
||
bundle = MetadataBundle(data["root"]) | ||
bundle.root_update_finished() | ||
|
||
top_level_md = [ | ||
(data["timestamp"], bundle.update_timestamp), | ||
(data["snapshot"], bundle.update_snapshot), | ||
(data["targets"], bundle.update_targets), | ||
] | ||
for metadata, update_func in top_level_md: | ||
# metadata is not json | ||
with self.assertRaises(exceptions.RepositoryError): | ||
update_func(b"") | ||
# metadata is invalid | ||
md = Metadata.from_bytes(metadata) | ||
md.signed.version += 1 | ||
with self.assertRaises(exceptions.RepositoryError): | ||
update_func(json.dumps(md.to_dict()).encode()) | ||
|
||
# metadata is of wrong type | ||
with self.assertRaises(exceptions.RepositoryError): | ||
update_func(data["root"]) | ||
|
||
update_func(metadata) | ||
|
||
|
||
# TODO test updating over initial metadata (new keys, newer timestamp, etc) | ||
# TODO test the actual specification checks | ||
|
||
|
||
if __name__ == '__main__': | ||
utils.configure_test_logging(sys.argv) | ||
unittest.main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note:
assertDictEqual()
gives more meaningful messages when this fails.