Completed
Push — master ( fdf85a...dfca6d )
by
unknown
14s
created

AuthTestCase.test_noKey()   A

Complexity

Conditions 3

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
2
# flake8: noqa
3
import os
4
import string
5
import random
6
import tempfile
7
import requests
8
9
import unittest
10
import pytest
11
12
from qiniu import Auth, set_default, etag, PersistentFop, build_op, op_save, Zone
13
from qiniu import put_data, put_file, put_stream
14
from qiniu import BucketManager, build_batch_copy, build_batch_rename, build_batch_move, build_batch_stat, build_batch_delete
15
from qiniu import urlsafe_base64_encode, urlsafe_base64_decode
16
17
from qiniu.compat import is_py2, is_py3, b
18
19
from qiniu.services.storage.uploader import _form_put
20
21
import qiniu.config
22
23
if is_py2:
24
    import sys
25
    import StringIO
26
    import urllib
27
    reload(sys)
28
    sys.setdefaultencoding('utf-8')
29
    StringIO = StringIO.StringIO
30
    urlopen = urllib.urlopen
31
elif is_py3:
32
    import io
33
    import urllib
34
    StringIO = io.StringIO
35
    urlopen = urllib.request.urlopen
36
37
access_key = os.getenv('QINIU_ACCESS_KEY')
38
secret_key = os.getenv('QINIU_SECRET_KEY')
39
bucket_name = os.getenv('QINIU_TEST_BUCKET')
40
41
dummy_access_key = 'abcdefghklmnopq'
42
dummy_secret_key = '1234567890'
43
dummy_auth = Auth(dummy_access_key, dummy_secret_key)
44
45
46
def rand_string(length):
47
    lib = string.ascii_uppercase
48
    return ''.join([random.choice(lib) for i in range(0, length)])
49
50
51
def create_temp_file(size):
52
    t = tempfile.mktemp()
53
    f = open(t, 'wb')
54
    f.seek(size-1)
55
    f.write(b('0'))
56
    f.close()
57
    return t
58
59
60
def remove_temp_file(file):
61
    try:
62
        os.remove(file)
63
    except OSError:
64
        pass
65
66
67
def is_travis():
68
    return os.environ['QINIU_TEST_ENV'] == 'travis'
69
70
71
class UtilsTest(unittest.TestCase):
72
73
    def test_urlsafe(self):
74
        a = 'hello\x96'
75
        u = urlsafe_base64_encode(a)
76
        assert b(a) == urlsafe_base64_decode(u)
77
78
79
class AuthTestCase(unittest.TestCase):
80
81
    def test_token(self):
82
        token = dummy_auth.token('test')
83
        assert token == 'abcdefghklmnopq:mSNBTR7uS2crJsyFr2Amwv1LaYg='
84
85
    def test_token_with_data(self):
86
        token = dummy_auth.token_with_data('test')
87
        assert token == 'abcdefghklmnopq:-jP8eEV9v48MkYiBGs81aDxl60E=:dGVzdA=='
88
89
    def test_noKey(self):
90
        with pytest.raises(ValueError):
91
            Auth(None, None).token('nokey')
92
        with pytest.raises(ValueError):
93
            Auth('', '').token('nokey')
94
95
    def test_token_of_request(self):
96
        token = dummy_auth.token_of_request('http://www.qiniu.com?go=1', 'test', '')
97
        assert token == 'abcdefghklmnopq:cFyRVoWrE3IugPIMP5YJFTO-O-Y='
98
        token = dummy_auth.token_of_request('http://www.qiniu.com?go=1', 'test', 'application/x-www-form-urlencoded')
99
        assert token == 'abcdefghklmnopq:svWRNcacOE-YMsc70nuIYdaa1e4='
100
101
    def test_verify_callback(self):
102
        body = 'name=sunflower.jpg&hash=Fn6qeQi4VDLQ347NiRm-RlQx_4O2&location=Shanghai&price=1500.00&uid=123'
103
        url = 'test.qiniu.com/callback'
104
        ok = dummy_auth.verify_callback('QBox abcdefghklmnopq:ZWyeM5ljWMRFwuPTPOwQ4RwSto4=', url, body)
105
        assert ok
106
107
108
class BucketTestCase(unittest.TestCase):
109
    q = Auth(access_key, secret_key)
110
    bucket = BucketManager(q)
111
112
    def test_list(self):
113
        ret, eof, info = self.bucket.list(bucket_name, limit=4)
114
        print(info)
115
        assert eof is False
116
        assert len(ret.get('items')) == 4
117
        ret, eof, info = self.bucket.list(bucket_name, limit=1000)
118
        print(info)
119
        assert eof is True
120
121
    def test_buckets(self):
122
        ret, info = self.bucket.buckets()
123
        print(info)
124
        assert bucket_name in ret
125
126
    def test_prefetch(self):
127
        ret, info = self.bucket.prefetch(bucket_name, 'python-sdk.html')
128
        print(info)
129
        assert ret['key'] == 'python-sdk.html'
130
131
    def test_fetch(self):
132
        ret, info = self.bucket.fetch('http://developer.qiniu.com/docs/v6/sdk/python-sdk.html', bucket_name, 'fetch.html')
133
        print(info)
134
        assert ret['key'] == 'fetch.html'
135
        assert 'hash' in ret
136
137
    def test_fetch_without_key(self):
138
        ret, info = self.bucket.fetch('http://developer.qiniu.com/docs/v6/sdk/python-sdk.html', bucket_name)
139
        print(info)
140
        assert ret['key'] == ret['hash']
141
        assert 'hash' in ret
142
143
    def test_stat(self):
144
        ret, info = self.bucket.stat(bucket_name, 'python-sdk.html')
145
        print(info)
146
        assert 'hash' in ret
147
148
    def test_delete(self):
149
        ret, info = self.bucket.delete(bucket_name, 'del')
150
        print(info)
151
        assert ret is None
152
        assert info.status_code == 612
153
154
    def test_rename(self):
155
        key = 'renameto'+rand_string(8)
156
        self.bucket.copy(bucket_name, 'copyfrom', bucket_name, key)
157
        key2 = key + 'move'
158
        ret, info = self.bucket.rename(bucket_name, key, key2)
159
        print(info)
160
        assert ret == {}
161
        ret, info = self.bucket.delete(bucket_name, key2)
162
        print(info)
163
        assert ret == {}
164
165
    def test_copy(self):
166
        key = 'copyto'+rand_string(8)
167
        ret, info = self.bucket.copy(bucket_name, 'copyfrom', bucket_name, key)
168
        print(info)
169
        assert ret == {}
170
        ret, info = self.bucket.delete(bucket_name, key)
171
        print(info)
172
        assert ret == {}
173
174
    def test_change_mime(self):
175
        ret, info = self.bucket.change_mime(bucket_name, 'python-sdk.html', 'text/html')
176
        print(info)
177
        assert ret == {}
178
179
    def test_copy(self):
180
        key = 'copyto'+rand_string(8)
181
        ret, info = self.bucket.copy(bucket_name, 'copyfrom', bucket_name, key)
182
        print(info)
183
        assert ret == {}
184
        ret, info = self.bucket.delete(bucket_name, key)
185
        print(info)
186
        assert ret == {}
187
188
    def test_copy_force(self):
189
        ret, info = self.bucket.copy(bucket_name, 'copyfrom', bucket_name, 'copyfrom', force='true')
190
        print(info)
191
        assert info.status_code == 200
192
193
    def test_change_mime(self):
194
        ret, info = self.bucket.change_mime(bucket_name, 'python-sdk.html', 'text/html')
195
        print(info)
196
        assert ret == {}
197
198
    def test_batch_copy(self):
199
        key = 'copyto'+rand_string(8)
200
        ops = build_batch_copy(bucket_name, {'copyfrom': key}, bucket_name)
201
        ret, info = self.bucket.batch(ops)
202
        print(info)
203
        assert ret[0]['code'] == 200
204
        ops = build_batch_delete(bucket_name, [key])
205
        ret, info = self.bucket.batch(ops)
206
        print(info)
207
        assert ret[0]['code'] == 200
208
209
    def test_batch_copy_force(self):
210
        ops = build_batch_copy(bucket_name, {'copyfrom': 'copyfrom'}, bucket_name, force='true')
211
        ret, info = self.bucket.batch(ops)
212
        print(info)
213
        assert ret[0]['code'] == 200
214
215
    def test_batch_move(self):
216
        key = 'moveto'+rand_string(8)
217
        self.bucket.copy(bucket_name, 'copyfrom', bucket_name, key)
218
        key2 = key + 'move'
219
        ops = build_batch_move(bucket_name, {key: key2}, bucket_name)
220
        ret, info = self.bucket.batch(ops)
221
        print(info)
222
        assert ret[0]['code'] == 200
223
        ret, info = self.bucket.delete(bucket_name, key2)
224
        print(info)
225
        assert ret == {}
226
227
    def test_batch_move_force(self):
228
        ret,info = self.bucket.copy(bucket_name, 'copyfrom', bucket_name, 'copyfrom', force='true')
229
        print(info)
230
        assert info.status_code == 200
231 View Code Duplication
        ops = build_batch_move(bucket_name, {'copyfrom':'copyfrom'}, bucket_name,force='true')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
232
        ret, info = self.bucket.batch(ops)
233
        print(info)
234
        assert ret[0]['code'] == 200
235
236
    def test_batch_rename(self):
237
        key = 'rename'+rand_string(8)
238
        self.bucket.copy(bucket_name, 'copyfrom', bucket_name, key)
239
        key2 = key + 'rename'
240
        ops = build_batch_move(bucket_name, {key: key2}, bucket_name)
241
        ret, info = self.bucket.batch(ops)
242
        print(info)
243
        assert ret[0]['code'] == 200
244
        ret, info = self.bucket.delete(bucket_name, key2)
245
        print(info)
246
        assert ret == {}
247
248
    def test_batch_rename_force(self):
249
        ret,info = self.bucket.rename(bucket_name, 'copyfrom', 'copyfrom', force='true')
250
        print(info)
251
        assert info.status_code == 200
252 View Code Duplication
        ops = build_batch_rename(bucket_name, {'copyfrom':'copyfrom'}, force='true')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
253
        ret, info = self.bucket.batch(ops)
254
        print(info)
255
        assert ret[0]['code'] == 200
256
257
    def test_batch_stat(self):
258
        ops = build_batch_stat(bucket_name, ['python-sdk.html'])
259
        ret, info = self.bucket.batch(ops)
260
        print(info)
261
        assert ret[0]['code'] == 200
262
263
    def test_delete_after_days(self):
264
        days = '5'
265
        ret, info = self.bucket.delete_after_days(bucket_name,'invaild.html', days)
266
        assert info.status_code == 612
267
        key = 'copyto'+rand_string(8)
268
        ret, info = self.bucket.copy(bucket_name, 'copyfrom', bucket_name, key)
269
        ret, info = self.bucket.delete_after_days(bucket_name, key, days)
270
        assert info.status_code == 200
271
272
273
class UploaderTestCase(unittest.TestCase):
274
275
    mime_type = "text/plain"
276
    params = {'x:a': 'a'}
277
    q = Auth(access_key, secret_key)
278
279
    def test_put(self):
280
        key = 'a\\b\\c"hello'
281
        data = 'hello bubby!'
282
        token = self.q.upload_token(bucket_name)
283
        ret, info = put_data(token, key, data)
284
        print(info)
285
        assert ret['key'] == key
286
287
    def test_put_crc(self):
288
        key = ''
289
        data = 'hello bubby!'
290
        token = self.q.upload_token(bucket_name, key)
291
        ret, info = put_data(token, key, data, check_crc=True)
292
        print(info)
293
        assert ret['key'] == key
294
295
    def test_putfile(self):
296
        localfile = __file__
297
        key = 'test_file'
298
299
        token = self.q.upload_token(bucket_name, key)
300
        ret, info = put_file(token, key, localfile, mime_type=self.mime_type, check_crc=True)
301
        print(info)
302
        assert ret['key'] == key
303
        assert ret['hash'] == etag(localfile)
304
305
    def test_putInvalidCrc(self):
306
        key = 'test_invalid'
307
        data = 'hello bubby!'
308
        crc32 = 'wrong crc32'
309
        token = self.q.upload_token(bucket_name)
310
        ret, info = _form_put(token, key, data, None, None, crc=crc32)
311
        print(info)
312
        assert ret is None
313
        assert info.status_code == 400
314
315
    def test_putWithoutKey(self):
316
        key = None
317
        data = 'hello bubby!'
318
        token = self.q.upload_token(bucket_name)
319
        ret, info = put_data(token, key, data)
320
        print(info)
321
        assert ret['hash'] == ret['key']
322
323
        data = 'hello bubby!'
324
        token = self.q.upload_token(bucket_name, 'nokey2')
325
        ret, info = put_data(token, None, data)
326
        print(info)
327
        assert ret is None
328
        assert info.status_code == 403  # key not match
329
330
    def test_withoutRead_withoutSeek_retry(self):
331
        key = 'retry'
332
        data = 'hello retry!'
333
        set_default(default_zone=Zone('http://a', 'http://upload.qiniu.com'))
334
        token = self.q.upload_token(bucket_name)
335
        ret, info = put_data(token, key, data)
336
        print(info)
337
        assert ret['key'] == key
338
        assert ret['hash'] == 'FlYu0iBR1WpvYi4whKXiBuQpyLLk'
339
340
    def test_hasRead_hasSeek_retry(self):
341
        key = 'withReadAndSeek_retry'
342
        data = StringIO('hello retry again!')
343
        set_default(default_zone=Zone('http://a', 'http://upload.qiniu.com'))
344
        token = self.q.upload_token(bucket_name)
345
        ret, info = put_data(token, key, data)
346
        print(info)
347
        assert ret['key'] == key
348
        assert ret['hash'] == 'FuEbdt6JP2BqwQJi7PezYhmuVYOo'
349
350
    def test_hasRead_withoutSeek_retry(self):
351
        key = 'withReadAndWithoutSeek_retry'
352
        data = ReadWithoutSeek('I only have read attribute!')
353
        set_default(default_zone=Zone('http://a', 'http://upload.qiniu.com'))
354
        token = self.q.upload_token(bucket_name)
355
        ret, info = put_data(token, key, data)
356
        print(info)
357
        assert ret is None
358
359
    def test_hasRead_WithoutSeek_retry2(self):
360
        key = 'withReadAndWithoutSeek_retry2'
361
        data = urlopen("http://www.qiniu.com")
362
        set_default(default_zone=Zone('http://a', 'http://upload.qiniu.com'))
363
        token = self.q.upload_token(bucket_name, key)
364
        ret, info = put_data(token, key, data)
365
        print(info)
366
        assert ret is not None
367
368
    def test_putData_without_fname(self):
369
        if is_travis():
370
            return
371
        localfile = create_temp_file(30 * 1024 * 1024)
372
        key = 'test_putData_without_fname'
373
        with open(localfile, 'rb') as input_stream:
374
            token = self.q.upload_token(bucket_name)
375
            ret, info = put_data(token, key, input_stream)
376
            print(info)
377
            assert ret is not None
378
379
    def test_putData_without_fname1(self):
380
        if is_travis():
381
            return
382
        localfile = create_temp_file(30 * 1024 * 1024)
383
        key = 'test_putData_without_fname1'
384
        with open(localfile, 'rb') as input_stream:
385
            token = self.q.upload_token(bucket_name)
386
            ret, info = put_data(token, key, input_stream, self.params, self.mime_type, False, None, "")
387
            print(info)
388
            assert ret is not None
389
390
    def test_putData_without_fname2(self):
391
        if is_travis():
392
            return
393
        localfile = create_temp_file(30 * 1024 * 1024)
394
        key = 'test_putData_without_fname2'
395
        with open(localfile, 'rb') as input_stream:
396
            token = self.q.upload_token(bucket_name)
397
            ret, info = put_data(token, key, input_stream, self.params, self.mime_type, False, None, "  ")
398
            print(info)
399
            assert ret is not None
400
401
402
class ResumableUploaderTestCase(unittest.TestCase):
403
404
    mime_type = "text/plain"
405
    params = {'x:a': 'a'}
406
    q = Auth(access_key, secret_key)
407
408
    def test_put_stream(self):
409
        localfile = __file__
410
        key = 'test_file_r'
411
        size = os.stat(localfile).st_size
412
        with open(localfile, 'rb') as input_stream:
413
            token = self.q.upload_token(bucket_name, key)
414
            ret, info = put_stream(token, key, input_stream, os.path.basename(__file__), size, self.params, self.mime_type)
415
            print(info)
416
            assert ret['key'] == key
417
418
    def test_big_file(self):
419
        key = 'big'
420
        token = self.q.upload_token(bucket_name, key)
421
        localfile = create_temp_file(4 * 1024 * 1024 + 1)
422
        progress_handler = lambda progress, total: progress
423
        qiniu.set_default(default_zone=Zone('http://a', 'http://upload.qiniu.com'))
424
        ret, info = put_file(token, key, localfile, self.params, self.mime_type, progress_handler=progress_handler)
425
        print(info)
426
        assert ret['key'] == key
427
        remove_temp_file(localfile)
428
429
    def test_retry(self):
430
        localfile = __file__
431
        key = 'test_file_r_retry'
432
        qiniu.set_default(default_zone=Zone('http://a', 'http://upload.qiniu.com'))
433
        token = self.q.upload_token(bucket_name, key)
434
        ret, info = put_file(token, key, localfile, self.params, self.mime_type)
435
        print(info)
436
        assert ret['key'] == key
437
        assert ret['hash'] == etag(localfile)
438
439
440
class DownloadTestCase(unittest.TestCase):
441
442
    q = Auth(access_key, secret_key)
443
444
    def test_private_url(self):
445
        private_bucket = 'private-res'
446
        private_key = 'gogopher.jpg'
447
        base_url = 'http://%s/%s' % (private_bucket+'.qiniudn.com', private_key)
448
        private_url = self.q.private_download_url(base_url, expires=3600)
449
        print(private_url)
450
        r = requests.get(private_url)
451
        assert r.status_code == 200
452
453
454
class MediaTestCase(unittest.TestCase):
455
    def test_pfop(self):
456
        q = Auth(access_key, secret_key)
457
        pfop = PersistentFop(q, 'testres', 'sdktest')
458
        op = op_save('avthumb/m3u8/segtime/10/vcodec/libx264/s/320x240', 'pythonsdk', 'pfoptest')
459
        ops = []
460
        ops.append(op)
461
        ret, info = pfop.execute('sintel_trailer.mp4', ops, 1)
462
        print(info)
463
        assert ret['persistentId'] is not None
464
465
466
class EtagTestCase(unittest.TestCase):
467
    def test_zero_size(self):
468
        open("x", 'a').close()
469
        hash = etag("x")
470
        assert hash == 'Fto5o-5ea0sNMlW_75VgGJCv2AcJ'
471
        remove_temp_file("x")
472
    def test_small_size(self):
473
        localfile = create_temp_file(1024 * 1024)
474
        hash = etag(localfile)
475
        assert hash == 'FnlAdmDasGTQOIgrU1QIZaGDv_1D'
476
        remove_temp_file(localfile)
477
    def test_large_size(self):
478
        localfile = create_temp_file(4 * 1024 * 1024 + 1)
479
        hash = etag(localfile)
480
        assert hash == 'ljF323utglY3GI6AvLgawSJ4_dgk'
481
        remove_temp_file(localfile)
482
483
484
class ReadWithoutSeek(object):
485
    def __init__(self, str):
486
        self.str = str
487
        pass
488
489
    def read(self):
490
        print(self.str)
491
492
if __name__ == '__main__':
493
    unittest.main()
494