10
10
import sys
11
11
import tempfile
12
12
import unittest
13
- from typing import Optional , Tuple
13
+ from dataclasses import dataclass
14
+ from typing import Optional
14
15
15
16
from tests import utils
16
17
from tests .repository_simulator import RepositorySimulator
17
18
from tuf .exceptions import RepositoryError
18
19
from tuf .ngclient import Updater
19
20
20
21
22
+ @dataclass
23
+ class TestTarget :
24
+ path : str
25
+ content : bytes
26
+ encoded_path : str
27
+
28
+
21
29
class TestFetchTarget (unittest .TestCase ):
22
30
"""Test ngclient downloading and caching target files."""
23
31
@@ -61,32 +69,39 @@ def _init_updater(self) -> Updater:
61
69
return updater
62
70
63
71
targets : utils .DataSet = {
64
- "standard case" : ("targetpath" , b"content" , "targetpath" ),
65
- "non-asci case" : ("åäö" , b"more content" , "%C3%A5%C3%A4%C3%B6" ),
66
- "subdirectory case" : (
67
- "a/b/c/targetpath" ,
68
- b"dir target content" ,
69
- "a%2Fb%2Fc%2Ftargetpath" ,
72
+ "standard case" : TestTarget (
73
+ path = "targetpath" ,
74
+ content = b"target content" ,
75
+ encoded_path = "targetpath" ,
76
+ ),
77
+ "non-asci case" : TestTarget (
78
+ path = "åäö" ,
79
+ content = b"more content" ,
80
+ encoded_path = "%C3%A5%C3%A4%C3%B6" ,
81
+ ),
82
+ "subdirectory case" : TestTarget (
83
+ path = "a/b/c/targetpath" ,
84
+ content = b"dir target content" ,
85
+ encoded_path = "a%2Fb%2Fc%2Ftargetpath" ,
70
86
),
71
87
}
72
88
73
89
@utils .run_sub_tests_with_dataset (targets )
74
- def test_fetch_target (self , test_case_data : Tuple [str , bytes , str ]) -> None :
75
- targetpath , content , encoded_path = test_case_data
76
- path = os .path .join (self .targets_dir , encoded_path )
90
+ def test_fetch_target (self , target : TestTarget ) -> None :
91
+ path = os .path .join (self .targets_dir , target .encoded_path )
77
92
78
93
updater = self ._init_updater ()
79
94
# target does not exist yet
80
- self .assertIsNone (updater .get_targetinfo (targetpath ))
95
+ self .assertIsNone (updater .get_targetinfo (target . path ))
81
96
82
97
# Add targets to repository
83
98
self .sim .targets .version += 1
84
- self .sim .add_target ("targets" , content , targetpath )
99
+ self .sim .add_target ("targets" , target . content , target . path )
85
100
self .sim .update_snapshot ()
86
101
87
102
updater = self ._init_updater ()
88
103
# target now exists, is not in cache yet
89
- info = updater .get_targetinfo (targetpath )
104
+ info = updater .get_targetinfo (target . path )
90
105
assert info is not None
91
106
# Test without and with explicit local filepath
92
107
self .assertIsNone (updater .find_cached_target (info ))
@@ -98,7 +113,7 @@ def test_fetch_target(self, test_case_data: Tuple[str, bytes, str]) -> None:
98
113
self .assertEqual (path , updater .find_cached_target (info , path ))
99
114
100
115
with open (path , "rb" ) as f :
101
- self .assertEqual (f .read (), content )
116
+ self .assertEqual (f .read (), target . content )
102
117
103
118
# download using explicit filepath as well
104
119
os .remove (path )
@@ -107,61 +122,62 @@ def test_fetch_target(self, test_case_data: Tuple[str, bytes, str]) -> None:
107
122
self .assertEqual (path , updater .find_cached_target (info , path ))
108
123
109
124
def test_invalid_target_download (self ) -> None :
110
- targetpath = "targetpath"
125
+ target = TestTarget ("targetpath" , b"content" , "targetpath" )
126
+
111
127
# Add target to repository
112
128
self .sim .targets .version += 1
113
- self .sim .add_target ("targets" , b" content" , targetpath )
129
+ self .sim .add_target ("targets" , target . content , target . path )
114
130
self .sim .update_snapshot ()
115
131
116
132
updater = self ._init_updater ()
117
- info = updater .get_targetinfo (targetpath )
133
+ info = updater .get_targetinfo (target . path )
118
134
assert info is not None
119
135
120
136
# Corrupt the file content to not match the hash
121
- self .sim .target_files [targetpath ].data = b"conten@"
137
+ self .sim .target_files [target . path ].data = b"conten@"
122
138
with self .assertRaises (RepositoryError ):
123
139
updater .download_target (info )
124
140
125
141
# Corrupt the file content to not match the length
126
- self .sim .target_files [targetpath ].data = b"cont"
142
+ self .sim .target_files [target . path ].data = b"cont"
127
143
with self .assertRaises (RepositoryError ):
128
144
updater .download_target (info )
129
145
130
146
# Verify the file is not persisted in cache
131
147
self .assertIsNone (updater .find_cached_target (info ))
132
148
133
149
def test_invalid_target_cache (self ) -> None :
134
- targetpath = "targetpath"
135
- content = b"content"
150
+ target = TestTarget ( "targetpath" , b"content" , "targetpath" )
151
+
136
152
# Add target to repository
137
153
self .sim .targets .version += 1
138
- self .sim .add_target ("targets" , content , targetpath )
154
+ self .sim .add_target ("targets" , target . content , target . path )
139
155
self .sim .update_snapshot ()
140
156
141
157
# Download the target
142
158
updater = self ._init_updater ()
143
- info = updater .get_targetinfo (targetpath )
159
+ info = updater .get_targetinfo (target . path )
144
160
assert info is not None
145
161
path = updater .download_target (info )
146
162
self .assertEqual (path , updater .find_cached_target (info ))
147
163
148
164
# Add newer content to the same targetpath
149
- content = b"contentv2"
165
+ target . content = b"contentv2"
150
166
self .sim .targets .version += 1
151
- self .sim .add_target ("targets" , content , targetpath )
167
+ self .sim .add_target ("targets" , target . content , target . path )
152
168
self .sim .update_snapshot ()
153
169
154
170
# Newer content is detected, old cached version is not used
155
171
updater = self ._init_updater ()
156
- info = updater .get_targetinfo (targetpath )
172
+ info = updater .get_targetinfo (target . path )
157
173
assert info is not None
158
174
self .assertIsNone (updater .find_cached_target (info ))
159
175
160
176
# Download target, assert it is in cache and content is the newer
161
177
path = updater .download_target (info )
162
178
self .assertEqual (path , updater .find_cached_target (info ))
163
179
with open (path , "rb" ) as f :
164
- self .assertEqual (f .read (), content )
180
+ self .assertEqual (f .read (), target . content )
165
181
166
182
167
183
if __name__ == "__main__" :
0 commit comments