43
43
44
44
import tuf
45
45
import tuf .download as download
46
+ import tuf .requests_fetcher
46
47
import tuf .log
47
48
import tuf .unittest_toolbox as unittest_toolbox
48
49
import tuf .exceptions
@@ -76,7 +77,7 @@ def setUp(self):
76
77
self .server_process_handler = utils .TestServerProcess (log = logger )
77
78
78
79
rel_target_filepath = os .path .basename (target_filepath )
79
- self .url = 'http://localhost :' \
80
+ self .url = 'http://' + utils . TEST_HOST_ADDRESS + ' :' \
80
81
+ str (self .server_process_handler .port ) + '/' + rel_target_filepath
81
82
82
83
# Computing hash of target file data.
@@ -85,6 +86,10 @@ def setUp(self):
85
86
digest = m .hexdigest ()
86
87
self .target_hash = {'md5' :digest }
87
88
89
+ # Initialize the default fetcher for the download
90
+ self .fetcher = tuf .requests_fetcher .RequestsFetcher ()
91
+
92
+
88
93
89
94
# Stop server process and perform clean up.
90
95
def tearDown (self ):
@@ -100,13 +105,36 @@ def tearDown(self):
100
105
def test_download_url_to_tempfileobj (self ):
101
106
102
107
download_file = download .safe_download
103
- with download_file (self .url , self .target_data_length ) as temp_fileobj :
108
+ with download_file (self .url , self .target_data_length , self . fetcher ) as temp_fileobj :
104
109
temp_fileobj .seek (0 )
105
110
temp_file_data = temp_fileobj .read ().decode ('utf-8' )
106
111
self .assertEqual (self .target_data , temp_file_data )
107
112
self .assertEqual (self .target_data_length , len (temp_file_data ))
108
113
109
114
115
+ # Test: Download url in more than one chunk.
116
+ def test_download_url_in_chunks (self ):
117
+
118
+ # Set smaller chunk size to ensure that the file will be downloaded
119
+ # in more than one chunk
120
+ default_chunk_size = tuf .settings .CHUNK_SIZE
121
+ tuf .settings .CHUNK_SIZE = 4
122
+ # We don't have access to chunks from download_file()
123
+ # so we just confirm that the expectation of more than one chunk is
124
+ # correct and verify that no errors are raised during download
125
+ chunks_count = self .target_data_length / tuf .settings .CHUNK_SIZE
126
+ self .assertGreater (chunks_count , 1 )
127
+
128
+ download_file = download .safe_download
129
+ with download_file (self .url , self .target_data_length , self .fetcher ) as temp_fileobj :
130
+ temp_fileobj .seek (0 )
131
+ temp_file_data = temp_fileobj .read ().decode ('utf-8' )
132
+ self .assertEqual (self .target_data , temp_file_data )
133
+ self .assertEqual (self .target_data_length , len (temp_file_data ))
134
+
135
+ # Restore default settings
136
+ tuf .settings .CHUNK_SIZE = default_chunk_size
137
+
110
138
111
139
# Test: Incorrect lengths.
112
140
def test_download_url_to_tempfileobj_and_lengths (self ):
@@ -118,18 +146,18 @@ def test_download_url_to_tempfileobj_and_lengths(self):
118
146
# the server-reported length of the file does not match the
119
147
# required_length. 'updater.py' *does* verify the hashes of downloaded
120
148
# content.
121
- download .safe_download (self .url , self .target_data_length - 4 ).close ()
122
- download .unsafe_download (self .url , self .target_data_length - 4 ).close ()
149
+ download .safe_download (self .url , self .target_data_length - 4 , self . fetcher ).close ()
150
+ download .unsafe_download (self .url , self .target_data_length - 4 , self . fetcher ).close ()
123
151
124
152
# We catch 'tuf.exceptions.DownloadLengthMismatchError' for safe_download()
125
153
# because it will not download more bytes than requested (in this case, a
126
154
# length greater than the size of the target file).
127
155
self .assertRaises (tuf .exceptions .DownloadLengthMismatchError ,
128
- download .safe_download , self .url , self .target_data_length + 1 )
156
+ download .safe_download , self .url , self .target_data_length + 1 , self . fetcher )
129
157
130
158
# Calling unsafe_download() with a mismatched length should not raise an
131
159
# exception.
132
- download .unsafe_download (self .url , self .target_data_length + 1 ).close ()
160
+ download .unsafe_download (self .url , self .target_data_length + 1 , self . fetcher ).close ()
133
161
134
162
135
163
@@ -164,32 +192,26 @@ def test_download_url_to_tempfileobj_and_urls(self):
164
192
download_file = download .safe_download
165
193
unsafe_download_file = download .unsafe_download
166
194
167
- self .assertRaises (securesystemslib .exceptions .FormatError ,
168
- download_file , None , self .target_data_length )
169
-
170
- self .assertRaises (tuf .exceptions .URLParsingError ,
171
- download_file ,
172
- self .random_string (), self .target_data_length )
195
+ with self .assertRaises (securesystemslib .exceptions .FormatError ):
196
+ download_file (None , self .target_data_length , self .fetcher )
173
197
174
- url = 'http://localhost :' \
198
+ url = 'http://' + utils . TEST_HOST_ADDRESS + ' :' \
175
199
+ str (self .server_process_handler .port ) + '/' + self .random_string ()
176
- self .assertRaises (requests .exceptions .HTTPError ,
177
- download_file ,
178
- url ,
179
- self . target_data_length )
180
- url1 = 'http://localhost :' \
200
+ with self .assertRaises (tuf .exceptions .FetcherHTTPError ) as cm :
201
+ download_file ( url , self . target_data_length , self . fetcher )
202
+ self . assertEqual ( cm . exception . status_code , 404 )
203
+
204
+ url1 = 'http://' + utils . TEST_HOST_ADDRESS + ' :' \
181
205
+ str (self .server_process_handler .port + 1 ) + '/' + self .random_string ()
182
- self .assertRaises (requests .exceptions .ConnectionError ,
183
- download_file ,
184
- url1 ,
185
- self .target_data_length )
206
+ with self .assertRaises (requests .exceptions .ConnectionError ):
207
+ download_file (url1 , self .target_data_length , self .fetcher )
186
208
187
209
# Specify an unsupported URI scheme.
188
210
url_with_unsupported_uri = self .url .replace ('http' , 'file' )
189
211
self .assertRaises (requests .exceptions .InvalidSchema , download_file , url_with_unsupported_uri ,
190
- self .target_data_length )
212
+ self .target_data_length , self . fetcher )
191
213
self .assertRaises (requests .exceptions .InvalidSchema , unsafe_download_file ,
192
- url_with_unsupported_uri , self .target_data_length )
214
+ url_with_unsupported_uri , self .target_data_length , self . fetcher )
193
215
194
216
195
217
@@ -290,7 +312,7 @@ def test_https_connection(self):
290
312
os .environ ['REQUESTS_CA_BUNDLE' ] = bad_cert_fname
291
313
# Clear sessions to ensure that the certificate we just specified is used.
292
314
# TODO: Confirm necessity of this session clearing and lay out mechanics.
293
- tuf . download ._sessions = {}
315
+ self . fetcher ._sessions = {}
294
316
295
317
# Try connecting to the server process with the bad cert while trusting
296
318
# the bad cert. Expect failure because even though we trust it, the
@@ -302,41 +324,41 @@ def test_https_connection(self):
302
324
category = urllib3 .exceptions .SubjectAltNameWarning )
303
325
304
326
with self .assertRaises (requests .exceptions .SSLError ):
305
- download .safe_download (bad_https_url , target_data_length )
327
+ download .safe_download (bad_https_url , target_data_length , self . fetcher )
306
328
with self .assertRaises (requests .exceptions .SSLError ):
307
- download .unsafe_download (bad_https_url , target_data_length )
329
+ download .unsafe_download (bad_https_url , target_data_length , self . fetcher )
308
330
309
331
# Try connecting to the server processes with the good certs while not
310
332
# trusting the good certs (trusting the bad cert instead). Expect failure
311
333
# because even though the server's cert file is otherwise OK, we don't
312
334
# trust it.
313
335
logger .info ('Trying HTTPS download of target file: ' + good_https_url )
314
336
with self .assertRaises (requests .exceptions .SSLError ):
315
- download .safe_download (good_https_url , target_data_length )
337
+ download .safe_download (good_https_url , target_data_length , self . fetcher )
316
338
with self .assertRaises (requests .exceptions .SSLError ):
317
- download .unsafe_download (good_https_url , target_data_length )
339
+ download .unsafe_download (good_https_url , target_data_length , self . fetcher )
318
340
319
341
logger .info ('Trying HTTPS download of target file: ' + good2_https_url )
320
342
with self .assertRaises (requests .exceptions .SSLError ):
321
- download .safe_download (good2_https_url , target_data_length )
343
+ download .safe_download (good2_https_url , target_data_length , self . fetcher )
322
344
with self .assertRaises (requests .exceptions .SSLError ):
323
- download .unsafe_download (good2_https_url , target_data_length )
345
+ download .unsafe_download (good2_https_url , target_data_length , self . fetcher )
324
346
325
347
326
348
# Configure environment to now trust the certfile that is expired.
327
349
os .environ ['REQUESTS_CA_BUNDLE' ] = expired_cert_fname
328
350
# Clear sessions to ensure that the certificate we just specified is used.
329
351
# TODO: Confirm necessity of this session clearing and lay out mechanics.
330
- tuf . download ._sessions = {}
352
+ self . fetcher ._sessions = {}
331
353
332
354
# Try connecting to the server process with the expired cert while
333
355
# trusting the expired cert. Expect failure because even though we trust
334
356
# it, it is expired.
335
357
logger .info ('Trying HTTPS download of target file: ' + expired_https_url )
336
358
with self .assertRaises (requests .exceptions .SSLError ):
337
- download .safe_download (expired_https_url , target_data_length )
359
+ download .safe_download (expired_https_url , target_data_length , self . fetcher )
338
360
with self .assertRaises (requests .exceptions .SSLError ):
339
- download .unsafe_download (expired_https_url , target_data_length )
361
+ download .unsafe_download (expired_https_url , target_data_length , self . fetcher )
340
362
341
363
342
364
# Try connecting to the server processes with the good certs while
@@ -346,18 +368,18 @@ def test_https_connection(self):
346
368
os .environ ['REQUESTS_CA_BUNDLE' ] = good_cert_fname
347
369
# Clear sessions to ensure that the certificate we just specified is used.
348
370
# TODO: Confirm necessity of this session clearing and lay out mechanics.
349
- tuf . download ._sessions = {}
371
+ self . fetcher ._sessions = {}
350
372
logger .info ('Trying HTTPS download of target file: ' + good_https_url )
351
- download .safe_download (good_https_url , target_data_length ).close ()
352
- download .unsafe_download (good_https_url , target_data_length ).close ()
373
+ download .safe_download (good_https_url , target_data_length , self . fetcher ).close ()
374
+ download .unsafe_download (good_https_url , target_data_length , self . fetcher ).close ()
353
375
354
376
os .environ ['REQUESTS_CA_BUNDLE' ] = good2_cert_fname
355
377
# Clear sessions to ensure that the certificate we just specified is used.
356
378
# TODO: Confirm necessity of this session clearing and lay out mechanics.
357
- tuf . download ._sessions = {}
379
+ self . fetcher ._sessions = {}
358
380
logger .info ('Trying HTTPS download of target file: ' + good2_https_url )
359
- download .safe_download (good2_https_url , target_data_length ).close ()
360
- download .unsafe_download (good2_https_url , target_data_length ).close ()
381
+ download .safe_download (good2_https_url , target_data_length , self . fetcher ).close ()
382
+ download .unsafe_download (good2_https_url , target_data_length , self . fetcher ).close ()
361
383
362
384
finally :
363
385
for proc_handler in [
0 commit comments