Completed
Pull Request — master (#251)
by
unknown
02:18
created

BucketTestCase.test_batch_rename()   A

Complexity

Conditions 3

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
c 0
b 0
f 0
dl 0
loc 11
rs 9.4285
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_deprecatedPolicy(self):
102
        with pytest.raises(ValueError):
103
            dummy_auth.upload_token('1', None, policy={'asyncOps': 1})
104
105
    def test_verify_callback(self):
106
        body = 'name=sunflower.jpg&hash=Fn6qeQi4VDLQ347NiRm-RlQx_4O2&location=Shanghai&price=1500.00&uid=123'
107
        url = 'test.qiniu.com/callback'
108
        ok = dummy_auth.verify_callback('QBox abcdefghklmnopq:ZWyeM5ljWMRFwuPTPOwQ4RwSto4=', url, body)
109
        assert ok
110
111
112
class BucketTestCase(unittest.TestCase):
113
    q = Auth(access_key, secret_key)
114
    bucket = BucketManager(q)
115
116
    def test_list(self):
117
        ret, eof, info = self.bucket.list(bucket_name, limit=4)
118
        print(info)
119
        assert eof is False
120
        assert len(ret.get('items')) == 4
121
        ret, eof, info = self.bucket.list(bucket_name, limit=100)
122
        print(info)
123
        assert eof is True
124
125
    def test_buckets(self):
126
        ret, info = self.bucket.buckets()
127
        print(info)
128
        assert bucket_name in ret
129
130
    def test_prefetch(self):
131
        ret, info = self.bucket.prefetch(bucket_name, 'python-sdk.html')
132
        print(info)
133
        assert ret['key'] == 'python-sdk.html'
134
135
    def test_fetch(self):
136
        ret, info = self.bucket.fetch('http://developer.qiniu.com/docs/v6/sdk/python-sdk.html', bucket_name, 'fetch.html')
137
        print(info)
138
        assert ret['key'] == 'fetch.html'
139
        assert 'hash' in ret
140
141
    def test_fetch_without_key(self):
142
        ret, info = self.bucket.fetch('http://developer.qiniu.com/docs/v6/sdk/python-sdk.html', bucket_name)
143
        print(info)
144
        assert ret['key'] == ret['hash']
145
        assert 'hash' in ret
146
147
    def test_stat(self):
148
        ret, info = self.bucket.stat(bucket_name, 'python-sdk.html')
149
        print(info)
150
        assert 'hash' in ret
151
152
    def test_delete(self):
153
        ret, info = self.bucket.delete(bucket_name, 'del')
154
        print(info)
155
        assert ret is None
156
        assert info.status_code == 612
157
158
    def test_rename(self):
159
        key = 'renameto'+rand_string(8)
160
        self.bucket.copy(bucket_name, 'copyfrom', bucket_name, key)
161
        key2 = key + 'move'
162
        ret, info = self.bucket.rename(bucket_name, key, key2)
163
        print(info)
164
        assert ret == {}
165
        ret, info = self.bucket.delete(bucket_name, key2)
166
        print(info)
167
        assert ret == {}
168
169
    def test_copy(self):
170
        key = 'copyto'+rand_string(8)
171
        ret, info = self.bucket.copy(bucket_name, 'copyfrom', bucket_name, key)
172
        print(info)
173
        assert ret == {}
174
        ret, info = self.bucket.delete(bucket_name, key)
175
        print(info)
176
        assert ret == {}
177
178
    def test_change_mime(self):
179
        ret, info = self.bucket.change_mime(bucket_name, 'python-sdk.html', 'text/html')
180
        print(info)
181
        assert ret == {}
182
183
    def test_copy(self):
184
        key = 'copyto'+rand_string(8)
185
        ret, info = self.bucket.copy(bucket_name, 'copyfrom', bucket_name, key)
186
        print(info)
187
        assert ret == {}
188
        ret, info = self.bucket.delete(bucket_name, key)
189
        print(info)
190
        assert ret == {}
191
192
    def test_copy_force(self):
193
        ret, info = self.bucket.copy(bucket_name, 'copyfrom', bucket_name, 'copyfrom', force='true')
194
        print(info)
195
        assert info.status_code == 200
196
197
    def test_change_mime(self):
198
        ret, info = self.bucket.change_mime(bucket_name, 'python-sdk.html', 'text/html')
199
        print(info)
200
        assert ret == {}
201
202
    def test_batch_copy(self):
203
        key = 'copyto'+rand_string(8)
204
        ops = build_batch_copy(bucket_name, {'copyfrom': key}, bucket_name)
205
        ret, info = self.bucket.batch(ops)
206
        print(info)
207
        assert ret[0]['code'] == 200
208
        ops = build_batch_delete(bucket_name, [key])
209
        ret, info = self.bucket.batch(ops)
210
        print(info)
211
        assert ret[0]['code'] == 200
212
213
    def test_batch_copy_force(self):
214
        ops = build_batch_copy(bucket_name, {'copyfrom': 'copyfrom'}, bucket_name, force='true')
215
        ret, info = self.bucket.batch(ops)
216
        print(info)
217
        assert ret[0]['code'] == 200
218
219
    def test_batch_move(self):
220
        key = 'moveto'+rand_string(8)
221
        self.bucket.copy(bucket_name, 'copyfrom', bucket_name, key)
222
        key2 = key + 'move'
223
        ops = build_batch_move(bucket_name, {key: key2}, bucket_name)
224
        ret, info = self.bucket.batch(ops)
225
        print(info)
226
        assert ret[0]['code'] == 200
227
        ret, info = self.bucket.delete(bucket_name, key2)
228
        print(info)
229
        assert ret == {}
230
231 View Code Duplication
    def test_batch_move_force(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
232
        ret,info = self.bucket.copy(bucket_name, 'copyfrom', bucket_name, 'copyfrom', force='true')
233
        print(info)
234
        assert info.status_code == 200
235
        ops = build_batch_move(bucket_name, {'copyfrom':'copyfrom'}, bucket_name,force='true')
236
        ret, info = self.bucket.batch(ops)
237
        print(info)
238
        assert ret[0]['code'] == 200
239
240
    def test_batch_rename(self):
241
        key = 'rename'+rand_string(8)
242
        self.bucket.copy(bucket_name, 'copyfrom', bucket_name, key)
243
        key2 = key + 'rename'
244
        ops = build_batch_move(bucket_name, {key: key2}, bucket_name)
245
        ret, info = self.bucket.batch(ops)
246
        print(info)
247
        assert ret[0]['code'] == 200
248
        ret, info = self.bucket.delete(bucket_name, key2)
249
        print(info)
250
        assert ret == {}
251
252 View Code Duplication
    def test_batch_rename_force(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
253
        ret,info = self.bucket.rename(bucket_name, 'copyfrom', 'copyfrom', force='true')
254
        print(info)
255
        assert info.status_code == 200
256
        ops = build_batch_rename(bucket_name, {'copyfrom':'copyfrom'}, force='true')
257
        ret, info = self.bucket.batch(ops)
258
        print(info)
259
        assert ret[0]['code'] == 200
260
261
    def test_batch_stat(self):
262
        ops = build_batch_stat(bucket_name, ['python-sdk.html'])
263
        ret, info = self.bucket.batch(ops)
264
        print(info)
265
        assert ret[0]['code'] == 200
266
267
    def test_delete_after_days(self):
268
        days = '5'
269
        ret, info = self.bucket.delete_after_days(bucket_name,'invaild.html', days)
270
        assert info.status_code == 612
271
        ret, info = self.bucket.delete_after_days(bucket_name,'fetch.html', days )
272
        assert info.status_code == 200
273
274
275
class UploaderTestCase(unittest.TestCase):
276
277
    mime_type = "text/plain"
278
    params = {'x:a': 'a'}
279
    q = Auth(access_key, secret_key)
280
281
    def test_put(self):
282
        key = 'a\\b\\c"hello'
283
        data = 'hello bubby!'
284
        token = self.q.upload_token(bucket_name)
285
        ret, info = put_data(token, key, data)
286
        print(info)
287
        assert ret['key'] == key
288
289
    def test_put_crc(self):
290
        key = ''
291
        data = 'hello bubby!'
292
        token = self.q.upload_token(bucket_name, key)
293
        ret, info = put_data(token, key, data, check_crc=True)
294
        print(info)
295
        assert ret['key'] == key
296
297
    def test_putfile(self):
298
        localfile = __file__
299
        key = 'test_file'
300
301
        token = self.q.upload_token(bucket_name, key)
302
        ret, info = put_file(token, key, localfile, mime_type=self.mime_type, check_crc=True)
303
        print(info)
304
        assert ret['key'] == key
305
        assert ret['hash'] == etag(localfile)
306
307
    def test_putInvalidCrc(self):
308
        key = 'test_invalid'
309
        data = 'hello bubby!'
310
        crc32 = 'wrong crc32'
311
        token = self.q.upload_token(bucket_name)
312
        ret, info = _form_put(token, key, data, None, None, crc=crc32)
313
        print(info)
314
        assert ret is None
315
        assert info.status_code == 400
316
317
    def test_putWithoutKey(self):
318
        key = None
319
        data = 'hello bubby!'
320
        token = self.q.upload_token(bucket_name)
321
        ret, info = put_data(token, key, data)
322
        print(info)
323
        assert ret['hash'] == ret['key']
324
325
        data = 'hello bubby!'
326
        token = self.q.upload_token(bucket_name, 'nokey2')
327
        ret, info = put_data(token, None, data)
328
        print(info)
329
        assert ret is None
330
        assert info.status_code == 403  # key not match
331
332
    def test_withoutRead_withoutSeek_retry(self):
333
        key = 'retry'
334
        data = 'hello retry!'
335
        set_default(default_zone=Zone('http://a', 'http://upload.qiniu.com'))
336
        token = self.q.upload_token(bucket_name)
337
        ret, info = put_data(token, key, data)
338
        print(info)
339
        assert ret['key'] == key
340
        assert ret['hash'] == 'FlYu0iBR1WpvYi4whKXiBuQpyLLk'
341
342
    def test_hasRead_hasSeek_retry(self):
343
        key = 'withReadAndSeek_retry'
344
        data = StringIO('hello retry again!')
345
        set_default(default_zone=Zone('http://a', 'http://upload.qiniu.com'))
346
        token = self.q.upload_token(bucket_name)
347
        ret, info = put_data(token, key, data)
348
        print(info)
349
        assert ret['key'] == key
350
        assert ret['hash'] == 'FuEbdt6JP2BqwQJi7PezYhmuVYOo'
351
352
    def test_hasRead_withoutSeek_retry(self):
353
        key = 'withReadAndWithoutSeek_retry'
354
        data = ReadWithoutSeek('I only have read attribute!')
355
        set_default(default_zone=Zone('http://a', 'http://upload.qiniu.com'))
356
        token = self.q.upload_token(bucket_name)
357
        ret, info = put_data(token, key, data)
358
        print(info)
359
        assert ret is None
360
361
    def test_hasRead_WithoutSeek_retry2(self):
362
        key = 'withReadAndWithoutSeek_retry2'
363
        data = urlopen("http://www.qiniu.com")
364
        set_default(default_zone=Zone('http://a', 'http://upload.qiniu.com'))
365
        token = self.q.upload_token(bucket_name, key)
366
        ret, info = put_data(token, key, data)
367
        print(info)
368
        assert ret is not None
369
370
    def test_putData_without_fname(self):
371
        if is_travis():
372
            return
373
        localfile = create_temp_file(30 * 1024 * 1024)
374
        key = 'test_putData_without_fname'
375
        with open(localfile, 'rb') as input_stream:
376
            token = self.q.upload_token(bucket_name)
377
            ret, info = put_data(token, key, input_stream)
378
            print(info)
379
            assert ret is not None
380
381
    def test_putData_without_fname1(self):
382
        if is_travis():
383
            return
384
        localfile = create_temp_file(30 * 1024 * 1024)
385
        key = 'test_putData_without_fname1'
386
        with open(localfile, 'rb') as input_stream:
387
            token = self.q.upload_token(bucket_name)
388
            ret, info = put_data(token, key, input_stream, self.params, self.mime_type, False, None, "")
389
            print(info)
390
            assert ret is not None
391
392
    def test_putData_without_fname2(self):
393
        if is_travis():
394
            return
395
        localfile = create_temp_file(30 * 1024 * 1024)
396
        key = 'test_putData_without_fname2'
397
        with open(localfile, 'rb') as input_stream:
398
            token = self.q.upload_token(bucket_name)
399
            ret, info = put_data(token, key, input_stream, self.params, self.mime_type, False, None, "  ")
400
            print(info)
401
            assert ret is not None
402
403
404
class ResumableUploaderTestCase(unittest.TestCase):
405
406
    mime_type = "text/plain"
407
    params = {'x:a': 'a'}
408
    q = Auth(access_key, secret_key)
409
410
    def test_put_stream(self):
411
        localfile = __file__
412
        key = 'test_file_r'
413
        size = os.stat(localfile).st_size
414
        with open(localfile, 'rb') as input_stream:
415
            token = self.q.upload_token(bucket_name, key)
416
            ret, info = put_stream(token, key, input_stream, os.path.basename(__file__), size, self.params, self.mime_type)
417
            print(info)
418
            assert ret['key'] == key
419
420
    def test_big_file(self):
421
        key = 'big'
422
        token = self.q.upload_token(bucket_name, key)
423
        localfile = create_temp_file(4 * 1024 * 1024 + 1)
424
        progress_handler = lambda progress, total: progress
425
        qiniu.set_default(default_zone=Zone('http://a', 'http://upload.qiniu.com'))
426
        ret, info = put_file(token, key, localfile, self.params, self.mime_type, progress_handler=progress_handler)
427
        print(info)
428
        assert ret['key'] == key
429
        remove_temp_file(localfile)
430
431
    def test_retry(self):
432
        localfile = __file__
433
        key = 'test_file_r_retry'
434
        qiniu.set_default(default_zone=Zone('http://a', 'http://upload.qiniu.com'))
435
        token = self.q.upload_token(bucket_name, key)
436
        ret, info = put_file(token, key, localfile, self.params, self.mime_type)
437
        print(info)
438
        assert ret['key'] == key
439
        assert ret['hash'] == etag(localfile)
440
441
442
class DownloadTestCase(unittest.TestCase):
443
444
    q = Auth(access_key, secret_key)
445
446
    def test_private_url(self):
447
        private_bucket = 'private-res'
448
        private_key = 'gogopher.jpg'
449
        base_url = 'http://%s/%s' % (private_bucket+'.qiniudn.com', private_key)
450
        private_url = self.q.private_download_url(base_url, expires=3600)
451
        print(private_url)
452
        r = requests.get(private_url)
453
        assert r.status_code == 200
454
455
456
class MediaTestCase(unittest.TestCase):
457
    def test_pfop(self):
458
        q = Auth(access_key, secret_key)
459
        pfop = PersistentFop(q, 'testres', 'sdktest')
460
        op = op_save('avthumb/m3u8/segtime/10/vcodec/libx264/s/320x240', 'pythonsdk', 'pfoptest')
461
        ops = []
462
        ops.append(op)
463
        ret, info = pfop.execute('sintel_trailer.mp4', ops, 1)
464
        print(info)
465
        assert ret['persistentId'] is not None
466
467
468
class EtagTestCase(unittest.TestCase):
469
    def test_zero_size(self):
470
        open("x", 'a').close()
471
        hash = etag("x")
472
        assert hash == 'Fto5o-5ea0sNMlW_75VgGJCv2AcJ'
473
        remove_temp_file("x")
474
    def test_small_size(self):
475
        localfile = create_temp_file(1024 * 1024)
476
        hash = etag(localfile)
477
        assert hash == 'FnlAdmDasGTQOIgrU1QIZaGDv_1D'
478
        remove_temp_file(localfile)
479
    def test_large_size(self):
480
        localfile = create_temp_file(4 * 1024 * 1024 + 1)
481
        hash = etag(localfile)
482
        assert hash == 'ljF323utglY3GI6AvLgawSJ4_dgk'
483
        remove_temp_file(localfile)
484
485
486
class ReadWithoutSeek(object):
487
    def __init__(self, str):
488
        self.str = str
489
        pass
490
491
    def read(self):
492
        print(self.str)
493
494
if __name__ == '__main__':
495
    unittest.main()
496