1212import sys
1313import unittest
1414
15+ from securesystemslib .signer import Signature
16+
1517from tests import utils
1618from tuf .api .metadata import (
1719 DelegatedRole ,
1820 Delegations ,
1921 Key ,
22+ Metadata ,
2023 MetaFile ,
2124 Role ,
2225 Root ,
2528 Targets ,
2629 Timestamp ,
2730)
31+ from tuf .api .serialization import DeserializationError
2832
2933logger = logging .getLogger (__name__ )
3034
3135
36+ # pylint: disable=too-many-public-methods
3237class TestSerialization (unittest .TestCase ):
3338 """Test serialization for all classes in 'tuf/api/metadata.py'."""
3439
40+ invalid_metadata : utils .DataSet = {
41+ "no signatures field" : b'{"signed": \
42+ { "_type": "timestamp", "spec_version": "1.0.0", "version": 1, "expires": "2030-01-01T00:00:00Z", \
43+ "meta": {"snapshot.json": {"hashes": {"sha256" : "abc"}, "version": 1}}} \
44+ }' ,
45+ "non unique duplicating signatures" : b'{"signed": \
46+ { "_type": "timestamp", "spec_version": "1.0.0", "version": 1, "expires": "2030-01-01T00:00:00Z", \
47+ "meta": {"snapshot.json": {"hashes": {"sha256" : "abc"}, "version": 1}}}, \
48+ "signatures": [{"keyid": "id", "sig": "b"}, {"keyid": "id", "sig": "b"}] \
49+ }' ,
50+ }
51+
52+ @utils .run_sub_tests_with_dataset (invalid_metadata )
53+ def test_invalid_metadata_serialization (self , test_data : bytes ) -> None :
54+ # We expect a DeserializationError reraised from ValueError or KeyError.
55+ with self .assertRaises (DeserializationError ):
56+ Metadata .from_bytes (test_data )
57+
58+ valid_metadata : utils .DataSet = {
59+ "multiple signatures" : b'{ \
60+ "signed": \
61+ { "_type": "timestamp", "spec_version": "1.0.0", "version": 1, "expires": "2030-01-01T00:00:00Z", \
62+ "meta": {"snapshot.json": {"hashes": {"sha256" : "abc"}, "version": 1}}}, \
63+ "signatures": [{ "keyid": "id", "sig": "b"}, {"keyid": "id2", "sig": "d" }] \
64+ }' ,
65+ "no signatures" : b'{ \
66+ "signed": \
67+ { "_type": "timestamp", "spec_version": "1.0.0", "version": 1, "expires": "2030-01-01T00:00:00Z", \
68+ "meta": {"snapshot.json": {"hashes": {"sha256" : "abc"}, "version": 1}}}, \
69+ "signatures": [] \
70+ }' ,
71+ }
72+
73+ @utils .run_sub_tests_with_dataset (valid_metadata )
74+ def test_valid_metadata_serialization (self , test_case_data : bytes ) -> None :
75+ md = Metadata .from_bytes (test_case_data )
76+ input_dict = json .loads (test_case_data )
77+ self .assertDictEqual (input_dict , md .to_dict ())
78+
79+ invalid_signatures : utils .DataSet = {
80+ "missing keyid attribute in a signature" : '{ "sig": "abc" }' ,
81+ "missing sig attribute in a signature" : '{ "keyid": "id" }' ,
82+ }
83+
84+ @utils .run_sub_tests_with_dataset (invalid_signatures )
85+ def test_invalid_signature_serialization (self , test_data : str ) -> None :
86+ case_dict = json .loads (test_data )
87+ with self .assertRaises (KeyError ):
88+ Signature .from_dict (case_dict )
89+
90+ valid_signatures : utils .DataSet = {
91+ "all" : '{ "keyid": "id", "sig": "b"}' ,
92+ "unrecognized fields" : '{ "keyid": "id", "sig": "b", "foo": "bar"}' ,
93+ }
94+
95+ @utils .run_sub_tests_with_dataset (valid_signatures )
96+ def test_signature_serialization (self , test_case_data : str ) -> None :
97+ case_dict = json .loads (test_case_data )
98+ signature = Signature .from_dict (copy .copy (case_dict ))
99+ self .assertEqual (case_dict , signature .to_dict ())
100+
35101 # Snapshot instances with meta = {} are valid, but for a full valid
36102 # repository it's required that meta has at least one element inside it.
37103 invalid_signed : utils .DataSet = {
@@ -56,7 +122,7 @@ class TestSerialization(unittest.TestCase):
56122 def test_invalid_signed_serialization (self , test_case_data : str ) -> None :
57123 case_dict = json .loads (test_case_data )
58124 with self .assertRaises ((KeyError , ValueError , TypeError )):
59- Snapshot .from_dict (copy . deepcopy ( case_dict ) )
125+ Snapshot .from_dict (case_dict )
60126
61127 valid_keys : utils .DataSet = {
62128 "all" : '{"keytype": "rsa", "scheme": "rsassa-pss-sha256", \
@@ -89,7 +155,7 @@ def test_invalid_key_serialization(self, test_case_data: str) -> None:
89155 case_dict = json .loads (test_case_data )
90156 with self .assertRaises ((TypeError , KeyError )):
91157 keyid = case_dict .pop ("keyid" )
92- Key .from_dict (keyid , copy . copy ( case_dict ) )
158+ Key .from_dict (keyid , case_dict )
93159
94160 invalid_roles : utils .DataSet = {
95161 "no threshold" : '{"keyids": ["keyid"]}' ,
@@ -103,7 +169,7 @@ def test_invalid_key_serialization(self, test_case_data: str) -> None:
103169 def test_invalid_role_serialization (self , test_case_data : str ) -> None :
104170 case_dict = json .loads (test_case_data )
105171 with self .assertRaises ((KeyError , TypeError , ValueError )):
106- Role .from_dict (copy . deepcopy ( case_dict ) )
172+ Role .from_dict (case_dict )
107173
108174 valid_roles : utils .DataSet = {
109175 "all" : '{"keyids": ["keyid"], "threshold": 3}' ,
@@ -201,7 +267,7 @@ def test_root_serialization(self, test_case_data: str) -> None:
201267 "snapshot": {"keyids": ["keyid2"], "threshold": 1}, \
202268 "foo": {"keyids": ["keyid2"], "threshold": 1}} \
203269 }' ,
204- "invalid expiry with microsecond s " : '{"_type": "root", "spec_version": "1.0.0", "version": 1, \
270+ "invalid expiry with microseconds " : '{"_type": "root", "spec_version": "1.0.0", "version": 1, \
205271 "expires": "2030-01-01T12:00:00.123456Z", "consistent_snapshot": false, \
206272 "keys": {}, "roles": {"root": {}, "timestamp": {}, "targets": {}, "snapshot": {}}}' ,
207273 }
@@ -210,7 +276,7 @@ def test_root_serialization(self, test_case_data: str) -> None:
210276 def test_invalid_root_serialization (self , test_case_data : str ) -> None :
211277 case_dict = json .loads (test_case_data )
212278 with self .assertRaises (ValueError ):
213- Root .from_dict (copy . deepcopy ( case_dict ) )
279+ Root .from_dict (case_dict )
214280
215281 invalid_metafiles : utils .DataSet = {
216282 "wrong length type" : '{"version": 1, "length": "a", "hashes": {"sha256" : "abc"}}' ,
@@ -226,7 +292,7 @@ def test_invalid_root_serialization(self, test_case_data: str) -> None:
226292 def test_invalid_metafile_serialization (self , test_case_data : str ) -> None :
227293 case_dict = json .loads (test_case_data )
228294 with self .assertRaises ((TypeError , ValueError , AttributeError )):
229- MetaFile .from_dict (copy . deepcopy ( case_dict ) )
295+ MetaFile .from_dict (case_dict )
230296
231297 valid_metafiles : utils .DataSet = {
232298 "all" : '{"hashes": {"sha256" : "abc"}, "length": 12, "version": 1}' ,
@@ -250,7 +316,7 @@ def test_metafile_serialization(self, test_case_data: str) -> None:
250316 def test_invalid_timestamp_serialization (self , test_case_data : str ) -> None :
251317 case_dict = json .loads (test_case_data )
252318 with self .assertRaises ((ValueError , KeyError )):
253- Timestamp .from_dict (copy . deepcopy ( case_dict ) )
319+ Timestamp .from_dict (case_dict )
254320
255321 valid_timestamps : utils .DataSet = {
256322 "all" : '{ "_type": "timestamp", "spec_version": "1.0.0", "version": 1, "expires": "2030-01-01T00:00:00Z", \
@@ -326,7 +392,7 @@ def test_invalid_delegated_role_serialization(
326392 ) -> None :
327393 case_dict = json .loads (test_case_data )
328394 with self .assertRaises (ValueError ):
329- DelegatedRole .from_dict (copy . copy ( case_dict ) )
395+ DelegatedRole .from_dict (case_dict )
330396
331397 invalid_delegations : utils .DataSet = {
332398 "empty delegations" : "{}" ,
@@ -387,7 +453,7 @@ def test_invalid_delegation_serialization(
387453 ) -> None :
388454 case_dict = json .loads (test_case_data )
389455 with self .assertRaises ((ValueError , KeyError , AttributeError )):
390- Delegations .from_dict (copy . deepcopy ( case_dict ) )
456+ Delegations .from_dict (case_dict )
391457
392458 valid_delegations : utils .DataSet = {
393459 "all" : '{"keys": { \
@@ -424,7 +490,7 @@ def test_invalid_targetfile_serialization(
424490 ) -> None :
425491 case_dict = json .loads (test_case_data )
426492 with self .assertRaises (KeyError ):
427- TargetFile .from_dict (copy . deepcopy ( case_dict ) , "file1.txt" )
493+ TargetFile .from_dict (case_dict , "file1.txt" )
428494
429495 valid_targetfiles : utils .DataSet = {
430496 "all" : '{"length": 12, "hashes": {"sha256" : "abc"}, \
0 commit comments