4
4
import string
5
5
import random
6
6
import tempfile
7
+ import hashlib
7
8
from imp import reload
8
9
9
10
import requests
@@ -55,21 +56,43 @@ def rand_string(length):
55
56
return '' .join ([random .choice (lib ) for i in range (0 , length )])
56
57
57
58
58
- def create_temp_file (size ):
59
- t = tempfile .mktemp ()
60
- f = open (t , 'wb' )
61
- f .seek (size - 1 )
62
- f .write (b ('0' ))
63
- f .close ()
64
- return t
65
-
59
+ def create_temp_file (size , rand = True ):
60
+ fd , path = tempfile .mkstemp ()
61
+ with os .fdopen (fd , "wb" ) as f :
62
+ if rand :
63
+ rest = size
64
+ while rest > 0 :
65
+ to_write = min (rest , 1 << 22 )
66
+ f .write (os .urandom (to_write ))
67
+ rest -= to_write
68
+ else :
69
+ f .seek (size - 1 )
70
+ f .write (b ('0' ))
71
+ f .close ()
72
+ return path
73
+
74
+ def hash_of_file (path , hash_factory = hashlib .md5 , chunk_num_blocks = 128 ):
75
+ h = hash_factory ()
76
+ with open (path , 'rb' ) as f :
77
+ for chunk in iter (lambda : f .read (chunk_num_blocks * h .block_size ), b'' ):
78
+ h .update (chunk )
79
+ return h .digest ()
80
+
81
+ def hash_of_io (io , hash_factory = hashlib .md5 , chunk_num_blocks = 128 ):
82
+ h = hash_factory ()
83
+ for chunk in iter (lambda : io .read (chunk_num_blocks * h .block_size ), b'' ):
84
+ h .update (chunk )
85
+ return h .digest ()
66
86
67
87
def remove_temp_file (file ):
68
88
try :
69
89
os .remove (file )
70
90
except OSError :
71
91
pass
72
92
93
+ def get_qiniu_file (key ):
94
+ url = "http://" + os .getenv ('QINIU_TEST_DOMAIN' ) + '/' + key + '?t=' + str (random .randint (0 , 1 << 63 - 1 ))
95
+ return urlopen (url )
73
96
74
97
def is_travis ():
75
98
return os .environ ['QINIU_TEST_ENV' ] == 'travis'
@@ -276,6 +299,7 @@ def test_delete_after_days(self):
276
299
class UploaderTestCase (unittest .TestCase ):
277
300
mime_type = "text/plain"
278
301
params = {'x:a' : 'a' }
302
+ policy = { 'returnBody' : '{"hash":$(etag),"key":$(key),"fname":$(fname),"a":$(x:a)}' }
279
303
q = Auth (access_key , secret_key )
280
304
281
305
def test_put (self ):
@@ -285,6 +309,7 @@ def test_put(self):
285
309
ret , info = put_data (token , key , data )
286
310
print (info )
287
311
assert ret ['key' ] == key
312
+ assert get_qiniu_file (key ).getcode () == 200
288
313
289
314
def test_put_crc (self ):
290
315
key = ''
@@ -293,16 +318,22 @@ def test_put_crc(self):
293
318
ret , info = put_data (token , key , data , check_crc = True )
294
319
print (info )
295
320
assert ret ['key' ] == key
321
+ assert get_qiniu_file (key ).getcode () == 200
296
322
297
323
def test_putfile (self ):
298
- localfile = __file__
324
+ localfile = create_temp_file ( 1024 * 1024 )
299
325
key = 'test_file'
300
326
301
- token = self .q .upload_token (bucket_name , key )
327
+ token = self .q .upload_token (bucket_name , key , 3600 , self . policy )
302
328
ret , info = put_file (token , key , localfile , mime_type = self .mime_type , check_crc = True )
303
329
print (info )
304
330
assert ret ['key' ] == key
305
331
assert ret ['hash' ] == etag (localfile )
332
+ assert ret ['fname' ] == os .path .basename (localfile )
333
+ resp = get_qiniu_file (key )
334
+ assert resp .getcode () == 200
335
+ assert resp .headers ['content-type' ] == self .mime_type
336
+ assert hash_of_file (localfile ) == hash_of_io (resp )
306
337
307
338
def test_putInvalidCrc (self ):
308
339
key = 'test_invalid'
@@ -321,6 +352,7 @@ def test_putWithoutKey(self):
321
352
ret , info = put_data (token , key , data )
322
353
print (info )
323
354
assert ret ['hash' ] == ret ['key' ]
355
+ assert get_qiniu_file (ret ['key' ]).getcode () == 200
324
356
325
357
data = 'hello bubby!'
326
358
token = self .q .upload_token (bucket_name , 'nokey2' )
@@ -338,6 +370,7 @@ def test_withoutRead_withoutSeek_retry(self):
338
370
print (info )
339
371
assert ret ['key' ] == key
340
372
assert ret ['hash' ] == 'FlYu0iBR1WpvYi4whKXiBuQpyLLk'
373
+ assert get_qiniu_file (key ).getcode () == 200
341
374
342
375
def test_putData_without_fname (self ):
343
376
if is_travis ():
@@ -349,17 +382,23 @@ def test_putData_without_fname(self):
349
382
ret , info = put_data (token , key , input_stream )
350
383
print (info )
351
384
assert ret is not None
385
+ resp = get_qiniu_file (key )
386
+ assert resp .getcode () == 200
387
+ assert hash_of_file (localfile ) == hash_of_io (resp )
352
388
353
389
def test_putData_without_fname1 (self ):
354
390
if is_travis ():
355
391
return
356
392
localfile = create_temp_file (30 * 1024 * 1024 )
357
393
key = 'test_putData_without_fname1'
358
394
with open (localfile , 'rb' ) as input_stream :
359
- token = self .q .upload_token (bucket_name )
395
+ token = self .q .upload_token (bucket_name , None , 3600 , self . policy )
360
396
ret , info = put_data (token , key , input_stream , self .params , self .mime_type , False , None , "" )
361
397
print (info )
362
- assert ret is not None
398
+ assert ret ['fname' ] == ''
399
+ resp = get_qiniu_file (key )
400
+ assert resp .getcode () == 200
401
+ assert hash_of_file (localfile ) == hash_of_io (resp )
363
402
364
403
def test_putData_without_fname2 (self ):
365
404
if is_travis ():
@@ -371,99 +410,144 @@ def test_putData_without_fname2(self):
371
410
ret , info = put_data (token , key , input_stream , self .params , self .mime_type , False , None , " " )
372
411
print (info )
373
412
assert ret is not None
413
+ resp = get_qiniu_file (key )
414
+ assert resp .getcode () == 200
415
+ assert hash_of_file (localfile ) == hash_of_io (resp )
374
416
375
417
376
418
class ResumableUploaderTestCase (unittest .TestCase ):
377
419
mime_type = "text/plain"
378
420
params = {'x:a' : 'a' }
379
421
q = Auth (access_key , secret_key )
422
+ policy = { 'returnBody' : '{"hash":$(etag),"key":$(key),"fname":$(fname),"a":$(x:a)}' }
380
423
381
424
def test_put_stream (self ):
382
- localfile = __file__
425
+ localfile = create_temp_file ( 1024 * 1024 )
383
426
key = 'test_file_r'
384
427
size = os .stat (localfile ).st_size
385
428
set_default (default_zone = Zone ('http://upload.qiniup.com' ))
386
429
with open (localfile , 'rb' ) as input_stream :
387
- token = self .q .upload_token (bucket_name , key )
388
- ret , info = put_stream (token , key , input_stream , os .path .basename (__file__ ), size , hostscache_dir ,
430
+ token = self .q .upload_token (bucket_name , key , 3600 , self .policy )
431
+ file_name = os .path .basename (localfile )
432
+ ret , info = put_stream (token , key , input_stream , file_name , size , hostscache_dir ,
389
433
self .params ,
390
434
self .mime_type , part_size = None , version = None , bucket_name = None )
391
435
assert ret ['key' ] == key
436
+ assert ret ['a' ] == 'a'
437
+ assert ret ['fname' ] == file_name
438
+ resp = get_qiniu_file (key )
439
+ assert resp .getcode () == 200
440
+ assert resp .headers ['content-type' ] == self .mime_type
441
+ assert hash_of_file (localfile ) == hash_of_io (resp )
392
442
393
443
def test_put_stream_v2_without_bucket_name (self ):
394
444
localfile = __file__
395
445
key = 'test_file_r'
396
446
size = os .stat (localfile ).st_size
397
447
set_default (default_zone = Zone ('http://upload.qiniup.com' ))
398
448
with open (localfile , 'rb' ) as input_stream :
399
- token = self .q .upload_token (bucket_name , key )
400
- ret , info = put_stream (token , key , input_stream , os .path .basename (__file__ ), size , hostscache_dir ,
449
+ token = self .q .upload_token (bucket_name , key , 3600 , self .policy )
450
+ file_name = os .path .basename (localfile )
451
+ ret , info = put_stream (token , key , input_stream , file_name , size , hostscache_dir ,
401
452
self .params ,
402
453
self .mime_type , part_size = 1024 * 1024 * 10 , version = 'v2' )
403
454
assert ret ['key' ] == key
455
+ assert ret ['a' ] == 'a'
456
+ assert ret ['fname' ] == file_name
457
+ resp = get_qiniu_file (key )
458
+ assert resp .getcode () == 200
459
+ assert resp .headers ['content-type' ] == self .mime_type
460
+ assert hash_of_file (localfile ) == hash_of_io (resp )
404
461
405
462
def test_put_2m_stream_v2 (self ):
406
463
localfile = create_temp_file (2 * 1024 * 1024 + 1 )
407
464
key = 'test_file_r'
408
465
size = os .stat (localfile ).st_size
409
466
set_default (default_zone = Zone ('http://upload.qiniup.com' ))
410
467
with open (localfile , 'rb' ) as input_stream :
411
- token = self .q .upload_token (bucket_name , key )
412
- ret , info = put_stream (token , key , input_stream , os .path .basename (localfile ), size , hostscache_dir ,
468
+ token = self .q .upload_token (bucket_name , key , 3600 , self .policy )
469
+ file_name = os .path .basename (localfile )
470
+ ret , info = put_stream (token , key , input_stream , file_name , size , hostscache_dir ,
413
471
self .params ,
414
472
self .mime_type , part_size = 1024 * 1024 * 4 , version = 'v2' , bucket_name = bucket_name )
415
473
assert ret ['key' ] == key
416
- remove_temp_file (localfile )
474
+ assert ret ['a' ] == 'a'
475
+ assert ret ['fname' ] == file_name
476
+ resp = get_qiniu_file (key )
477
+ assert resp .getcode () == 200
478
+ assert resp .headers ['content-type' ] == self .mime_type
479
+ assert hash_of_file (localfile ) == hash_of_io (resp )
417
480
418
481
def test_put_4m_stream_v2 (self ):
419
482
localfile = create_temp_file (4 * 1024 * 1024 )
420
483
key = 'test_file_r'
421
484
size = os .stat (localfile ).st_size
422
485
set_default (default_zone = Zone ('http://upload.qiniup.com' ))
423
486
with open (localfile , 'rb' ) as input_stream :
424
- token = self .q .upload_token (bucket_name , key )
425
- ret , info = put_stream (token , key , input_stream , os .path .basename (localfile ), size , hostscache_dir ,
487
+ token = self .q .upload_token (bucket_name , key , 3600 , self .policy )
488
+ file_name = os .path .basename (localfile )
489
+ ret , info = put_stream (token , key , input_stream , file_name , size , hostscache_dir ,
426
490
self .params ,
427
491
self .mime_type , part_size = 1024 * 1024 * 4 , version = 'v2' , bucket_name = bucket_name )
428
492
assert ret ['key' ] == key
429
- remove_temp_file (localfile )
493
+ assert ret ['a' ] == 'a'
494
+ assert ret ['fname' ] == file_name
495
+ resp = get_qiniu_file (key )
496
+ assert resp .getcode () == 200
497
+ assert resp .headers ['content-type' ] == self .mime_type
498
+ assert hash_of_file (localfile ) == hash_of_io (resp )
430
499
431
500
def test_put_10m_stream_v2 (self ):
432
501
localfile = create_temp_file (10 * 1024 * 1024 + 1 )
433
502
key = 'test_file_r'
434
503
size = os .stat (localfile ).st_size
435
504
set_default (default_zone = Zone ('http://upload.qiniup.com' ))
436
505
with open (localfile , 'rb' ) as input_stream :
437
- token = self .q .upload_token (bucket_name , key )
438
- ret , info = put_stream (token , key , input_stream , os .path .basename (localfile ), size , hostscache_dir ,
506
+ token = self .q .upload_token (bucket_name , key , 3600 , self .policy )
507
+ file_name = os .path .basename (localfile )
508
+ ret , info = put_stream (token , key , input_stream , file_name , size , hostscache_dir ,
439
509
self .params ,
440
510
self .mime_type , part_size = 1024 * 1024 * 4 , version = 'v2' , bucket_name = bucket_name )
441
511
assert ret ['key' ] == key
442
- remove_temp_file (localfile )
512
+ assert ret ['a' ] == 'a'
513
+ assert ret ['fname' ] == file_name
514
+ resp = get_qiniu_file (key )
515
+ assert resp .getcode () == 200
516
+ assert resp .headers ['content-type' ] == self .mime_type
517
+ assert hash_of_file (localfile ) == hash_of_io (resp )
443
518
444
519
def test_big_file (self ):
445
520
key = 'big'
446
- token = self .q .upload_token (bucket_name , key )
521
+ token = self .q .upload_token (bucket_name , key , 3600 , self . policy )
447
522
localfile = create_temp_file (4 * 1024 * 1024 + 1 )
448
523
progress_handler = lambda progress , total : progress
449
524
qiniu .set_default (default_zone = Zone ('http://a' , 'http://upload.qiniup.com' ))
450
525
ret , info = put_file (token , key , localfile , self .params , self .mime_type , progress_handler = progress_handler )
451
526
print (info )
452
527
assert ret ['key' ] == key
453
- remove_temp_file (localfile )
528
+ assert ret ['a' ] == 'a'
529
+ assert ret ['fname' ] == os .path .basename (localfile )
530
+ resp = get_qiniu_file (key )
531
+ assert resp .getcode () == 200
532
+ assert resp .headers ['content-type' ] == self .mime_type
533
+ assert hash_of_file (localfile ) == hash_of_io (resp )
454
534
455
535
def test_retry (self ):
456
- localfile = __file__
536
+ localfile = create_temp_file ( 1024 * 1024 - 1 )
457
537
key = 'test_file_r_retry'
458
538
qiniu .set_default (default_zone = Zone ('http://a' , 'http://upload.qiniup.com' ))
459
539
token = self .q .upload_token (bucket_name , key )
460
540
ret , info = put_file (token , key , localfile , self .params , self .mime_type )
461
541
print (info )
462
542
assert ret ['key' ] == key
463
543
assert ret ['hash' ] == etag (localfile )
544
+ resp = get_qiniu_file (key )
545
+ assert resp .getcode () == 200
546
+ assert resp .headers ['content-type' ] == self .mime_type
547
+ assert hash_of_file (localfile ) == hash_of_io (resp )
464
548
465
549
def test_put_stream_with_key_limits (self ):
466
- localfile = __file__
550
+ localfile = create_temp_file ( 1024 * 1024 - 2 )
467
551
key = 'test_file_r'
468
552
size = os .stat (localfile ).st_size
469
553
set_default (default_zone = Zone ('http://upload.qiniup.com' ))
@@ -478,6 +562,9 @@ def test_put_stream_with_key_limits(self):
478
562
self .params ,
479
563
self .mime_type )
480
564
assert info .status_code == 200
565
+ resp = get_qiniu_file (key )
566
+ assert resp .getcode () == 200
567
+ assert hash_of_file (localfile ) == hash_of_io (resp )
481
568
482
569
483
570
class DownloadTestCase (unittest .TestCase ):
@@ -513,13 +600,13 @@ def test_zero_size(self):
513
600
remove_temp_file ("x" )
514
601
515
602
def test_small_size (self ):
516
- localfile = create_temp_file (1024 * 1024 )
603
+ localfile = create_temp_file (1024 * 1024 , rand = False )
517
604
hash = etag (localfile )
518
605
assert hash == 'FnlAdmDasGTQOIgrU1QIZaGDv_1D'
519
606
remove_temp_file (localfile )
520
607
521
608
def test_large_size (self ):
522
- localfile = create_temp_file (4 * 1024 * 1024 + 1 )
609
+ localfile = create_temp_file (4 * 1024 * 1024 + 1 , rand = False )
523
610
hash = etag (localfile )
524
611
assert hash == 'ljF323utglY3GI6AvLgawSJ4_dgk'
525
612
remove_temp_file (localfile )
0 commit comments