12
12
import unittest
13
13
import copy
14
14
15
- from typing import Dict , Callable
15
+ from typing import Dict , Callable , Optional , Mapping , Any
16
+ from datetime import datetime
16
17
17
18
from tests import utils
18
19
19
20
from tuf .api .metadata import (
21
+ Signed ,
20
22
Root ,
21
23
Snapshot ,
22
24
Timestamp ,
@@ -50,6 +52,44 @@ def wrapper(test_cls: "TestSerialization"):
50
52
51
53
class TestSerialization (unittest .TestCase ):
52
54
55
+ # Snapshot instances with meta = {} are valid, but for a full valid
56
+ # repository it's required that meta has at least one element inside it.
57
+ invalid_signed : DataSet = {
58
+ "no _type" : '{"spec_version": "1.0.0", "expires": "2030-01-01T00:00:00Z", "meta": {}}' ,
59
+ "no spec_version" : '{"_type": "signed", "version": 1, "expires": "2030-01-01T00:00:00Z", "meta": {}}' ,
60
+ "no version" : '{"_type": "signed", "spec_version": "1.0.0", "expires": "2030-01-01T00:00:00Z", "meta": {}}' ,
61
+ "no expires" : '{"_type": "signed", "spec_version": "1.0.0", "version": 1, "meta": {}}' ,
62
+ "empty str _type" :
63
+ '{"_type": "", "spec_version": "1.0.0", "version": 1, "expires": "2030-01-01T00:00:00Z", "meta": {}}' ,
64
+ "empty str spec_version" :
65
+ '{"_type": "signed", "spec_version": "", "version": 1, "expires": "2030-01-01T00:00:00Z", "meta": {}}' ,
66
+ "_type wrong type" :
67
+ '{"_type": "foo", "spec_version": "1.0.0", "version": 1, "expires": "2030-01-01T00:00:00Z", "meta": {}}' ,
68
+ "version wrong type" :
69
+ '{"_type": "signed", "spec_version": "1.0.0", "version": "a", "expires": "2030-01-01T00:00:00Z", "meta": {}}' ,
70
+ "invalid spec_version str" :
71
+ '{"_type": "signed", "spec_version": "abc", "version": 1, "expires": "2030-01-01T00:00:00Z", "meta": {}}' ,
72
+ "two digit spec_version" :
73
+ '{"_type": "signed", "spec_version": "1.2.a", "version": 1, "expires": "2030-01-01T00:00:00Z", "meta": {}}' ,
74
+ "no digit spec_version" :
75
+ '{"_type": "signed", "spec_version": "a.b.c", "version": 1, "expires": "2030-01-01T00:00:00Z", "meta": {}}' ,
76
+ "different major spec_version" :
77
+ '{"_type": "signed", "spec_version": "0.0.0", "version": 1, "expires": "2030-01-01T00:00:00Z", "meta": {}}' ,
78
+ "version 0" :
79
+ '{"_type": "signed", "spec_version": "1.0.0", "version": 0, "expires": "2030-01-01T00:00:00Z", "meta": {}}' ,
80
+ "version below 0" :
81
+ '{"_type": "signed", "spec_version": "1.0.0", "version": -1, "expires": "2030-01-01T00:00:00Z", "meta": {}}' ,
82
+ "wrong datetime string" :
83
+ '{"_type": "signed", "spec_version": "1.0.0", "version": 1, "expires": "abc", "meta": {}}' ,
84
+ }
85
+
86
+ @run_sub_tests_with_dataset (invalid_signed )
87
+ def test_invalid_signed_serialization (self , test_case_data : Dict [str , str ]):
88
+ case_dict = json .loads (test_case_data )
89
+ with self .assertRaises ((KeyError , ValueError , TypeError )):
90
+ Snapshot .from_dict (copy .deepcopy (case_dict ))
91
+
92
+
53
93
valid_keys : DataSet = {
54
94
"all" : '{"keytype": "rsa", "scheme": "rsassa-pss-sha256", \
55
95
"keyval": {"public": "foo"}}' ,
@@ -60,12 +100,45 @@ class TestSerialization(unittest.TestCase):
60
100
}
61
101
62
102
@run_sub_tests_with_dataset (valid_keys )
63
- def test_key_serialization (self , test_case_data : str ):
103
+ def test_valid_key_serialization (self , test_case_data : str ):
64
104
case_dict = json .loads (test_case_data )
65
105
key = Key .from_dict ("id" , copy .copy (case_dict ))
66
106
self .assertDictEqual (case_dict , key .to_dict ())
67
107
68
108
109
+ invalid_keys : DataSet = {
110
+ "no keyid" : '{"keytype": "rsa", "scheme": "rsassa-pss-sha256", "keyval": {"public": "abc"}}' ,
111
+ "no keytype" : '{"keyid": "id", "scheme": "rsassa-pss-sha256", "keyval": {"public": "foo"}}' ,
112
+ "no scheme" : '{"keyid": "id", "keytype": "rsa", "keyval": {"public": "foo"}}' ,
113
+ "no keyval" : '{"keyid": "id", "keytype": "rsa", "scheme": "rsassa-pss-sha256"}' ,
114
+ "keyid wrong type" : '{"keyid": 1, "keytype": "rsa", "scheme": "rsassa-pss-sha256", "keyval": {"public": "abc"}}' ,
115
+ "keytype wrong type" : '{"keyid": "id", "keytype": 1, "scheme": "rsassa-pss-sha256", "keyval": {"public": "abc"}}' ,
116
+ "scheme wrong type" : '{"keyid": "id", "keytype": "rsa", "scheme": 1, "keyval": {"public": "abc"}}' ,
117
+ "keyval wrong type" : '{"keyid": "id", "keytype": "rsa", "scheme": "rsassa-pss-sha256", "keyval": 1}' ,
118
+ }
119
+
120
+ @run_sub_tests_with_dataset (invalid_keys )
121
+ def test_invalid_key_serialization (self , test_case_data : Dict [str , str ]):
122
+ case_dict = json .loads (test_case_data )
123
+ with self .assertRaises ((TypeError , KeyError )):
124
+ keyid = case_dict .pop ("keyid" )
125
+ Key .from_dict (keyid , copy .copy (case_dict ))
126
+
127
+ invalid_roles : DataSet = {
128
+ "no threshold" : '{"keyids": ["keyid"]}' ,
129
+ "no keyids" : '{"threshold": 3}' ,
130
+ "wrong threshold type" : '{"keyids": ["keyid"], "threshold": "a"}' ,
131
+ "threshold below 1" : '{"keyids": ["keyid"], "threshold": 0}' ,
132
+ "duplicate keyids" : '{"keyids": ["keyid", "keyid"], "threshold": 3}' ,
133
+ }
134
+
135
+ @run_sub_tests_with_dataset (invalid_roles )
136
+ def test_invalid_role_serialization (self , test_case_data : Dict [str , str ]):
137
+ case_dict = json .loads (test_case_data )
138
+ with self .assertRaises ((KeyError , TypeError , ValueError )):
139
+ Role .from_dict (copy .deepcopy (case_dict ))
140
+
141
+
69
142
valid_roles : DataSet = {
70
143
"all" : '{"keyids": ["keyid"], "threshold": 3}' ,
71
144
"unrecognized field" : '{"keyids": ["keyid"], "threshold": 3, "foo": "bar"}' ,
@@ -102,12 +175,28 @@ def test_root_serialization(self, test_case_data: str):
102
175
root = Root .from_dict (copy .deepcopy (case_dict ))
103
176
self .assertDictEqual (case_dict , root .to_dict ())
104
177
178
+
179
+ invalid_metafiles : DataSet = {
180
+ "wrong length type" : '{"version": 1, "length": "a", "hashes": {"sha256" : "abc"}}' ,
181
+ "length 0" : '{"version": 1, "length": 0, "hashes": {"sha256" : "abc"}}' ,
182
+ "length below 0" : '{"version": 1, "length": -1, "hashes": {"sha256" : "abc"}}' ,
183
+ "empty hashes dict" : '{"version": 1, "length": 1, "hashes": {}}' ,
184
+ "hashes wrong type" : '{"version": 1, "length": 1, "hashes": 1}' ,
185
+ "hashes values wrong type" : '{"version": 1, "length": 1, "hashes": {"sha256": 1}}' ,
186
+ }
187
+
188
+ @run_sub_tests_with_dataset (invalid_metafiles )
189
+ def test_invalid_metafile_serialization (self , test_case_data : Dict [str , str ]):
190
+ case_dict = json .loads (test_case_data )
191
+ with self .assertRaises ((TypeError , ValueError , AttributeError )):
192
+ MetaFile .from_dict (copy .deepcopy (case_dict ))
193
+
194
+
105
195
valid_metafiles : DataSet = {
106
196
"all" : '{"hashes": {"sha256" : "abc"}, "length": 12, "version": 1}' ,
107
197
"no length" : '{"hashes": {"sha256" : "abc"}, "version": 1 }' ,
108
198
"no hashes" : '{"length": 12, "version": 1}' ,
109
- "unrecognized field" : '{"hashes": {"sha256" : "abc"}, "length": 12, "version": 1, \
110
- "foo": "bar"}' ,
199
+ "unrecognized field" : '{"hashes": {"sha256" : "abc"}, "length": 12, "version": 1, "foo": "bar"}' ,
111
200
}
112
201
113
202
@run_sub_tests_with_dataset (valid_metafiles )
@@ -181,6 +270,20 @@ def test_delegation_serialization(self, test_case_data: str):
181
270
self .assertDictEqual (case_dict , delegation .to_dict ())
182
271
183
272
273
+ invalid_targetfiles : DataSet = {
274
+ "no hashes" : '{"length": 1}' ,
275
+ "no length" : '{"hashes": {"sha256": "abc"}}'
276
+ # The remaining cases are the same as for invalid_hashes and
277
+ # invalid_length datasets.
278
+ }
279
+
280
+ @run_sub_tests_with_dataset (invalid_targetfiles )
281
+ def test_invalid_targetfile_serialization (self , test_case_data : Dict [str , str ]):
282
+ case_dict = json .loads (test_case_data )
283
+ with self .assertRaises (KeyError ):
284
+ TargetFile .from_dict (copy .deepcopy (case_dict ))
285
+
286
+
184
287
valid_targetfiles : DataSet = {
185
288
"all" : '{"length": 12, "hashes": {"sha256" : "abc"}, \
186
289
"custom" : {"foo": "bar"} }' ,
0 commit comments