Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / livetest / pithos.py @ 79b4f177

History | View | Annotate | Download (43.6 kB)

1
# Copyright 2012-2013 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
import time
35
import datetime
36
from os import urandom
37
from tempfile import NamedTemporaryFile
38

    
39
from kamaki.clients import livetest, ClientError
40
from kamaki.clients.pithos import PithosClient
41
from kamaki.clients.astakos import AstakosClient
42

    
43

    
44
class Pithos(livetest.Generic):
45

    
46
    files = []
47

    
48
    def setUp(self):
49
        self.client = PithosClient(
50
            self['store', 'url'],
51
            self['store', 'token'],
52
            AstakosClient(
53
                self['astakos', 'url'],
54
                self['store', 'token']
55
            ).term('uuid'))
56

    
57
        self.now = time.mktime(time.gmtime())
58
        self.now_unformated = datetime.datetime.utcnow()
59
        self._init_data()
60

    
61
        """Prepare an object to be shared - also its container"""
62
        self.client.container = self.c1
63
        self.client.object_post(
64
            'test',
65
            update=True,
66
            permissions={'read': [self.client.account]})
67

    
68
        self.create_remote_object(self.c1, 'another.test')
69

    
70
    def _init_data(self):
71
        self.c1 = 'c1_' + unicode(self.now)
72
        self.c2 = 'c2_' + unicode(self.now)
73
        self.c3 = 'c3_' + unicode(self.now)
74
        try:
75
            self.client.create_container(self.c2)
76
        except ClientError:
77
            pass
78
        try:
79
            self.client.create_container(self.c1)
80
        except ClientError:
81
            pass
82
        try:
83
            self.client.create_container(self.c3)
84
        except ClientError:
85
            pass
86

    
87
        self.create_remote_object(self.c1, 'test')
88
        self.create_remote_object(self.c2, 'test')
89
        self.create_remote_object(self.c1, 'test1')
90
        self.create_remote_object(self.c2, 'test1')
91

    
92
    def create_remote_object(self, container, obj):
93
        self.client.container = container
94
        self.client.object_put(
95
            obj,
96
            content_type='application/octet-stream',
97
            data='file %s that lives in %s' % (obj, container),
98
            metadata={'incontainer': container})
99

    
100
    def forceDeleteContainer(self, container):
101
        self.client.container = container
102
        try:
103
            r = self.client.list_objects()
104
        except ClientError:
105
            return
106
        for obj in r:
107
            name = obj['name']
108
            self.client.del_object(name)
109
        r = self.client.container_delete()
110
        self.container = ''
111

    
112
    def tearDown(self):
113
        """Destroy test cases"""
114
        for f in self.files:
115
            f.close()
116
        self.forceDeleteContainer(self.c1)
117
        self.forceDeleteContainer(self.c2)
118
        try:
119
            self.forceDeleteContainer(self.c3)
120
        except ClientError:
121
            pass
122
        self.client.container = ''
123

    
124
    def test_000(self):
125
        """Prepare a full Pithos+ test"""
126
        print('')
127
        super(self.__class__, self).test_000()
128

    
129
    def test_account_head(self):
130
        """Test account_HEAD"""
131
        self._test_0010_account_head()
132

    
133
    def _test_0010_account_head(self):
134
        r = self.client.account_head()
135
        self.assertEqual(r.status_code, 204)
136

    
137
        r = self.client.account_head(until='1000000000')
138
        self.assertEqual(r.status_code, 204)
139

    
140
        r = self.client.get_account_info(until='1000000000')
141
        datestring = unicode(r['x-account-until-timestamp'])
142
        self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring)
143

    
144
        r = self.client.get_account_quota()
145
        self.assertTrue('x-account-policy-quota' in r)
146

    
147
        r = self.client.get_account_versioning()
148
        self.assertTrue('x-account-policy-versioning' in r)
149

    
150
        """Check if(un)modified_since"""
151
        for format in self.client.DATE_FORMATS:
152
            now_formated = self.now_unformated.strftime(format)
153
            r1 = self.client.account_head(
154
                if_modified_since=now_formated,
155
                success=(204, 304, 412))
156
            sc1 = r1.status_code
157
            r1.release()
158
            r2 = self.client.account_head(
159
                if_unmodified_since=now_formated,
160
                success=(204, 304, 412))
161
            sc2 = r2.status_code
162
            r2.release()
163
            self.assertNotEqual(sc1, sc2)
164

    
165
    def test_account_get(self):
166
        """Test account_GET"""
167
        self._test_0020_account_get()
168

    
169
    def _test_0020_account_get(self):
170
        #r = self.client.account_get()
171
        #self.assertEqual(r.status_code, 200)
172
        r = self.client.list_containers()
173
        fullLen = len(r)
174
        self.assertTrue(fullLen > 2)
175

    
176
        r = self.client.account_get(limit=1)
177
        self.assertEqual(len(r.json), 1)
178

    
179
        r = self.client.account_get(marker='c2_')
180
        temp_c0 = r.json[0]['name']
181
        temp_c2 = r.json[2]['name']
182

    
183
        r = self.client.account_get(limit=2, marker='c2_')
184
        conames = [container['name'] for container in r.json if (
185
            container['name'].lower().startswith('c2_'))]
186
        self.assertTrue(temp_c0 in conames)
187
        self.assertFalse(temp_c2 in conames)
188

    
189
        r = self.client.account_get(show_only_shared=True)
190
        self.assertTrue(self.c1 in [c['name'] for c in r.json])
191

    
192
        r = self.client.account_get(until=1342609206)
193
        self.assertTrue(len(r.json) <= fullLen)
194

    
195
        """Check if(un)modified_since"""
196
        for format in self.client.DATE_FORMATS:
197
            now_formated = self.now_unformated.strftime(format)
198
            r1 = self.client.account_get(
199
                if_modified_since=now_formated,
200
                success=(200, 304, 412))
201
            sc1 = r1.status_code
202
            r1.release()
203
            r2 = self.client.account_get(
204
                if_unmodified_since=now_formated,
205
                success=(200, 304, 412))
206
            sc2 = r2.status_code
207
            r2.release()
208
            self.assertNotEqual(sc1, sc2)
209

    
210
        """Check sharing_accounts"""
211
        r = self.client.get_sharing_accounts()
212
        self.assertTrue(len(r) > 0)
213

    
214
    def test_account_post(self):
215
        """Test account_POST"""
216
        self._test_0030_account_post()
217

    
218
    def _test_0030_account_post(self):
219
        r = self.client.account_post()
220
        self.assertEqual(r.status_code, 202)
221
        grpName = 'grp' + unicode(self.now)
222

    
223
        """Method set/del_account_meta and set_account_groupcall use
224
            account_post internally
225
        """
226
        u1 = self.client.account
227
        u2 = self.client.account
228
        self.client.set_account_group(grpName, [u1, u2])
229
        r = self.client.get_account_group()
230
        self.assertEqual(r['x-account-group-' + grpName], '%s,%s' % (u1, u2))
231
        self.client.del_account_group(grpName)
232
        r = self.client.get_account_group()
233
        self.assertTrue('x-account-group-' + grpName not in r)
234

    
235
        mprefix = 'meta' + unicode(self.now)
236
        self.client.set_account_meta({
237
            mprefix + '1': 'v1',
238
            mprefix + '2': 'v2'})
239
        r = self.client.get_account_meta()
240
        self.assertEqual(r['x-account-meta-' + mprefix + '1'], 'v1')
241
        self.assertEqual(r['x-account-meta-' + mprefix + '2'], 'v2')
242

    
243
        self.client.del_account_meta(mprefix + '1')
244
        r = self.client.get_account_meta()
245
        self.assertTrue('x-account-meta-' + mprefix + '1' not in r)
246

    
247
        self.client.del_account_meta(mprefix + '2')
248
        r = self.client.get_account_meta()
249
        self.assertTrue('x-account-meta-' + mprefix + '2' not in r)
250

    
251
        """Missing testing for quota, versioning, because normally
252
        you don't have permissions to modify those at account level
253
        """
254

    
255
        newquota = 1000000
256
        self.client.set_account_quota(newquota)
257
        #r = self.client.get_account_info()
258
        #print(unicode(r))
259
        #r = self.client.get_account_quota()
260
        #self.assertEqual(r['x-account-policy-quota'], newquota)
261
        self.client.set_account_versioning('auto')
262

    
263
    def test_container_head(self):
264
        """Test container_HEAD"""
265
        self._test_0040_container_head()
266

    
267
    def _test_0040_container_head(self):
268
        self.client.container = self.c1
269

    
270
        r = self.client.container_head()
271
        self.assertEqual(r.status_code, 204)
272

    
273
        """Check until"""
274
        r = self.client.container_head(until=1000000, success=(204, 404))
275
        self.assertEqual(r.status_code, 404)
276

    
277
        """Check and if(un)modified_since"""
278
        for format in self.client.DATE_FORMATS:
279
            now_formated = self.now_unformated.strftime(format)
280
            r1 = self.client.container_head(
281
                if_modified_since=now_formated,
282
                success=(204, 304, 412))
283
            sc1 = r1.status_code
284
            r1.release()
285
            r2 = self.client.container_head(
286
                if_unmodified_since=now_formated,
287
                success=(204, 304, 412))
288
            sc2 = r2.status_code
289
            r2.release()
290
            self.assertNotEqual(sc1, sc2)
291

    
292
        """Check container object meta"""
293
        r = self.client.get_container_object_meta()
294
        self.assertEqual(r['x-container-object-meta'], 'Incontainer')
295

    
296
    def test_container_get(self):
297
        """Test container_GET"""
298
        self._test_0050_container_get()
299

    
300
    def _test_0050_container_get(self):
301
        self.client.container = self.c1
302

    
303
        r = self.client.container_get()
304
        self.assertEqual(r.status_code, 200)
305
        fullLen = len(r.json)
306

    
307
        r = self.client.container_get(prefix='test')
308
        lalobjects = [obj for obj in r.json if obj['name'].startswith('test')]
309
        self.assertTrue(len(r.json) > 1)
310
        self.assertEqual(len(r.json), len(lalobjects))
311

    
312
        r = self.client.container_get(limit=1)
313
        self.assertEqual(len(r.json), 1)
314

    
315
        r = self.client.container_get(marker='another')
316
        self.assertTrue(len(r.json) > 1)
317
        neobjects = [obj for obj in r.json if obj['name'] > 'another']
318
        self.assertEqual(len(r.json), len(neobjects))
319

    
320
        r = self.client.container_get(prefix='another.test', delimiter='.')
321
        self.assertTrue(fullLen > len(r.json))
322

    
323
        r = self.client.container_get(path='/')
324
        self.assertEqual(fullLen, len(r.json))
325

    
326
        r = self.client.container_get(format='xml')
327
        self.assertEqual(r.text.split()[4], 'name="' + self.c1 + '">')
328

    
329
        r = self.client.container_get(meta=['incontainer'])
330
        self.assertTrue(len(r.json) > 0)
331

    
332
        r = self.client.container_get(show_only_shared=True)
333
        self.assertTrue(len(r.json) < fullLen)
334

    
335
        try:
336
            r = self.client.container_get(until=1000000000)
337
            datestring = unicode(r.headers['x-account-until-timestamp'])
338
            self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring)
339

    
340
        except ClientError:
341

    
342
            pass
343

    
344
        """Check and if un/modified_since"""
345
        for format in self.client.DATE_FORMATS:
346
            now_formated = self.now_unformated.strftime(format)
347
            r1 = self.client.container_get(
348
                if_modified_since=now_formated,
349
                success=(200, 304, 412))
350
            sc1 = r1.status_code
351
            r1.release()
352
            r2 = self.client.container_get(
353
                if_unmodified_since=now_formated,
354
                success=(200, 304, 412))
355
            sc2 = r2.status_code
356
            r2.release()
357
            self.assertNotEqual(sc1, sc2)
358

    
359
    def test_container_put(self):
360
        """Test container_PUT"""
361
        self._test_0050_container_put()
362

    
363
    def _test_0050_container_put(self):
364
        self.client.container = self.c2
365

    
366
        r = self.client.container_put()
367
        self.assertEqual(r.status_code, 202)
368

    
369
        r = self.client.get_container_quota(self.client.container)
370
        cquota = r.values()[0]
371
        newquota = 2 * int(cquota)
372

    
373
        r = self.client.container_put(quota=newquota)
374
        self.assertEqual(r.status_code, 202)
375

    
376
        r = self.client.get_container_quota(self.client.container)
377
        xquota = int(r.values()[0])
378
        self.assertEqual(newquota, xquota)
379

    
380
        r = self.client.container_put(versioning='auto')
381
        self.assertEqual(r.status_code, 202)
382

    
383
        r = self.client.get_container_versioning(self.client.container)
384
        nvers = r.values()[0]
385
        self.assertEqual('auto', nvers)
386

    
387
        r = self.client.container_put(versioning='none')
388
        self.assertEqual(r.status_code, 202)
389

    
390
        r = self.client.get_container_versioning(self.client.container)
391
        nvers = r.values()[0]
392
        self.assertEqual('none', nvers)
393

    
394
        r = self.client.container_put(metadata={'m1': 'v1', 'm2': 'v2'})
395
        self.assertEqual(r.status_code, 202)
396

    
397
        r = self.client.get_container_meta(self.client.container)
398
        self.assertTrue('x-container-meta-m1' in r)
399
        self.assertEqual(r['x-container-meta-m1'], 'v1')
400
        self.assertTrue('x-container-meta-m2' in r)
401
        self.assertEqual(r['x-container-meta-m2'], 'v2')
402

    
403
        r = self.client.container_put(metadata={'m1': '', 'm2': 'v2a'})
404
        self.assertEqual(r.status_code, 202)
405

    
406
        r = self.client.get_container_meta(self.client.container)
407
        self.assertTrue('x-container-meta-m1' not in r)
408
        self.assertTrue('x-container-meta-m2' in r)
409
        self.assertEqual(r['x-container-meta-m2'], 'v2a')
410

    
411
        self.client.del_container_meta(self.client.container)
412

    
413
    def test_container_post(self):
414
        """Test container_POST"""
415
        self._test_0060_container_post()
416

    
417
    def _test_0060_container_post(self):
418
        self.client.container = self.c2
419

    
420
        """Simple post"""
421
        r = self.client.container_post()
422
        self.assertEqual(r.status_code, 202)
423

    
424
        """post meta"""
425
        self.client.set_container_meta({'m1': 'v1', 'm2': 'v2'})
426
        r = self.client.get_container_meta(self.client.container)
427
        self.assertTrue('x-container-meta-m1' in r)
428
        self.assertEqual(r['x-container-meta-m1'], 'v1')
429
        self.assertTrue('x-container-meta-m2' in r)
430
        self.assertEqual(r['x-container-meta-m2'], 'v2')
431

    
432
        """post/2del meta"""
433
        r = self.client.del_container_meta('m1')
434
        r = self.client.set_container_meta({'m2': 'v2a'})
435
        r = self.client.get_container_meta(self.client.container)
436
        self.assertTrue('x-container-meta-m1' not in r)
437
        self.assertTrue('x-container-meta-m2' in r)
438
        self.assertEqual(r['x-container-meta-m2'], 'v2a')
439

    
440
        """check quota"""
441
        r = self.client.get_container_quota(self.client.container)
442
        cquota = r.values()[0]
443
        newquota = 2 * int(cquota)
444
        r = self.client.set_container_quota(newquota)
445
        r = self.client.get_container_quota(self.client.container)
446
        xquota = int(r.values()[0])
447
        self.assertEqual(newquota, xquota)
448
        r = self.client.set_container_quota(cquota)
449
        r = self.client.get_container_quota(self.client.container)
450
        xquota = r.values()[0]
451
        self.assertEqual(cquota, xquota)
452

    
453
        """Check versioning"""
454
        self.client.set_container_versioning('auto')
455
        r = self.client.get_container_versioning(self.client.container)
456
        nvers = r.values()[0]
457
        self.assertEqual('auto', nvers)
458
        self.client.set_container_versioning('none')
459
        r = self.client.get_container_versioning(self.client.container)
460
        nvers = r.values()[0]
461
        self.assertEqual('none', nvers)
462

    
463
        """put_block uses content_type and content_length to
464
        post blocks of data 2 container. All that in upload_object"""
465
        """Change a file at fs"""
466
        f = self.create_large_file(1024 * 1024 * 100)
467
        """Upload it at a directory in container"""
468
        self.client.create_directory('dir')
469
        self.client.upload_object('/dir/sample.file', f)
470
        """Check if file has been uploaded"""
471
        r = self.client.get_object_info('/dir/sample.file')
472
        self.assertTrue(int(r['content-length']) > 100000000)
473

    
474
        """What is tranfer_encoding? What should I check about it? """
475
        #TODO
476

    
477
        """Check update=False"""
478
        r = self.client.object_post(
479
            'test',
480
            update=False,
481
            metadata={'newmeta': 'newval'})
482

    
483
        r = self.client.get_object_info('test')
484
        self.assertTrue('x-object-meta-newmeta' in r)
485
        self.assertFalse('x-object-meta-incontainer' in r)
486

    
487
        r = self.client.del_container_meta('m2')
488

    
489
    def test_container_delete(self):
490
        """Test container_DELETE"""
491
        self._test_0070_container_delete()
492

    
493
    def _test_0070_container_delete(self):
494

    
495
        """Fail to delete a non-empty container"""
496
        self.client.container = self.c2
497
        r = self.client.container_delete(success=409)
498
        self.assertEqual(r.status_code, 409)
499

    
500
        """Fail to delete c3 (empty) container"""
501
        self.client.container = self.c3
502
        r = self.client.container_delete(until='1000000000')
503
        self.assertEqual(r.status_code, 204)
504

    
505
        """Delete c3 (empty) container"""
506
        r = self.client.container_delete()
507
        self.assertEqual(r.status_code, 204)
508

    
509
        """Purge container(empty a container), check versionlist"""
510
        self.client.container = self.c1
511
        r = self.client.object_head('test', success=(200, 404))
512
        self.assertEqual(r.status_code, 200)
513
        self.client.del_container(delimiter='/')
514
        r = self.client.object_head('test', success=(200, 404))
515
        self.assertEqual(r.status_code, 404)
516
        r = self.client.get_object_versionlist('test')
517
        self.assertTrue(len(r) > 0)
518
        self.assertTrue(len(r[0]) > 1)
519
        self.client.purge_container()
520
        self.assertRaises(
521
            ClientError,
522
            self.client.get_object_versionlist,
523
            'test')
524

    
525
    def _test_0080_recreate_deleted_data(self):
526
        self._init_data()
527

    
528
    def test_object_head(self):
529
        """Test object_HEAD"""
530
        self._test_0090_object_head()
531

    
532
    def _test_0090_object_head(self):
533
        self.client.container = self.c2
534
        obj = 'test'
535

    
536
        r = self.client.object_head(obj)
537
        self.assertEqual(r.status_code, 200)
538
        etag = r.headers['etag']
539

    
540
        r = self.client.object_head(obj, version=40)
541
        self.assertEqual(r.headers['x-object-version'], '40')
542

    
543
        r = self.client.object_head(obj, if_etag_match=etag)
544
        self.assertEqual(r.status_code, 200)
545

    
546
        r = self.client.object_head(
547
            obj,
548
            if_etag_not_match=etag,
549
            success=(200, 412, 304))
550
        self.assertNotEqual(r.status_code, 200)
551

    
552
        r = self.client.object_head(
553
            obj,
554
            version=40,
555
            if_etag_match=etag,
556
            success=412)
557
        self.assertEqual(r.status_code, 412)
558

    
559
        """Check and if(un)modified_since"""
560
        for format in self.client.DATE_FORMATS:
561
            now_formated = self.now_unformated.strftime(format)
562
            r1 = self.client.object_head(
563
                obj,
564
                if_modified_since=now_formated,
565
                success=(200, 304, 412))
566
            sc1 = r1.status_code
567
            r1.release()
568
            r2 = self.client.object_head(
569
                obj,
570
                if_unmodified_since=now_formated,
571
                success=(200, 304, 412))
572
            sc2 = r2.status_code
573
            r2.release()
574
            self.assertNotEqual(sc1, sc2)
575

    
576
    def test_object_get(self):
577
        """Test object_GET"""
578
        self._test_0100_object_get()
579

    
580
    def _test_0100_object_get(self):
581
        self.client.container = self.c1
582
        obj = 'test'
583

    
584
        r = self.client.object_get(obj)
585
        self.assertEqual(r.status_code, 200)
586

    
587
        osize = int(r.headers['content-length'])
588
        etag = r.headers['etag']
589

    
590
        r = self.client.object_get(obj, hashmap=True)
591
        for term in ('hashes', 'block_hash', 'block_hash', 'bytes'):
592
            self.assertTrue(term in r.json)
593

    
594
        r = self.client.object_get(obj, format='xml', hashmap=True)
595
        self.assertEqual(len(r.text.split('hash>')), 3)
596

    
597
        rangestr = 'bytes=%s-%s' % (osize / 3, osize / 2)
598
        r = self.client.object_get(
599
            obj,
600
            data_range=rangestr,
601
            success=(200, 206))
602
        partsize = int(r.headers['content-length'])
603
        self.assertTrue(0 < partsize and partsize <= 1 + osize / 3)
604

    
605
        rangestr = 'bytes=%s-%s' % (osize / 3, osize / 2)
606
        r = self.client.object_get(
607
            obj,
608
            data_range=rangestr,
609
            if_range=True,
610
            success=(200, 206))
611
        partsize = int(r.headers['content-length'])
612
        self.assertTrue(0 < partsize and partsize <= 1 + osize / 3)
613

    
614
        r = self.client.object_get(obj, if_etag_match=etag)
615
        self.assertEqual(r.status_code, 200)
616

    
617
        r = self.client.object_get(obj, if_etag_not_match=etag + 'LALALA')
618
        self.assertEqual(r.status_code, 200)
619

    
620
        """Check and if(un)modified_since"""
621
        for format in self.client.DATE_FORMATS:
622
            now_formated = self.now_unformated.strftime(format)
623
            r1 = self.client.object_get(
624
                obj,
625
                if_modified_since=now_formated,
626
                success=(200, 304, 412))
627
            sc1 = r1.status_code
628
            r1.release()
629
            r2 = self.client.object_get(
630
                obj,
631
                if_unmodified_since=now_formated,
632
                success=(200, 304, 412))
633
            sc2 = r2.status_code
634
            r2.release()
635
            self.assertNotEqual(sc1, sc2)
636

    
637
        """Upload an object to download"""
638
        trg_fname = 'remotefile_%s' % self.now
639
        f_size = 59247824
640
        src_f = self.create_large_file(f_size)
641
        print('\tUploading...')
642
        self.client.upload_object(trg_fname, src_f)
643
        print('\tDownloading...')
644
        self.files.append(NamedTemporaryFile())
645
        dnl_f = self.files[-1]
646
        self.client.download_object(trg_fname, dnl_f)
647

    
648
        print('\tCheck if files match...')
649
        for pos in (0, f_size / 2, f_size - 20):
650
            src_f.seek(pos)
651
            dnl_f.seek(pos)
652
            self.assertEqual(src_f.read(10), dnl_f.read(10))
653

    
654
    def test_object_put(self):
655
        """Test object_PUT"""
656
        self._test_object_put()
657

    
658
    def _test_object_put(self):
659
        self.client.container = self.c2
660
        obj = 'another.test'
661

    
662
        self.client.create_object(obj + '.FAKE')
663
        r = self.client.get_object_info(obj + '.FAKE')
664
        self.assertEqual(r['content-type'], 'application/octet-stream')
665

    
666
        """create the object"""
667
        r = self.client.object_put(
668
            obj,
669
            data='a',
670
            content_type='application/octer-stream',
671
            permissions=dict(
672
                read=['accX:groupA', 'u1', 'u2'],
673
                write=['u2', 'u3']),
674
            metadata=dict(key1='val1', key2='val2'),
675
            content_encoding='UTF-8',
676
            content_disposition='attachment; filename="fname.ext"')
677
        self.assertEqual(r.status_code, 201)
678
        etag = r.headers['etag']
679

    
680
        """Check content-disposition"""
681
        r = self.client.get_object_info(obj)
682
        self.assertTrue('content-disposition' in r)
683

    
684
        """Check permissions"""
685
        r = self.client.get_object_sharing(obj)
686
        self.assertTrue('accx:groupa' in r['read'])
687
        self.assertTrue('u1' in r['read'])
688
        self.assertTrue('u2' in r['write'])
689
        self.assertTrue('u3' in r['write'])
690

    
691
        """Check metadata"""
692
        r = self.client.get_object_meta(obj)
693
        self.assertEqual(r['x-object-meta-key1'], 'val1')
694
        self.assertEqual(r['x-object-meta-key2'], 'val2')
695

    
696
        """Check public and if_etag_match"""
697
        r = self.client.object_put(
698
            obj,
699
            if_etag_match=etag,
700
            data='b',
701
            content_type='application/octet-stream',
702
            public=True)
703

    
704
        r = self.client.object_get(obj)
705
        self.assertTrue('x-object-public' in r.headers)
706
        vers2 = int(r.headers['x-object-version'])
707
        etag = r.headers['etag']
708
        self.assertEqual(r.text, 'b')
709

    
710
        """Check if_etag_not_match"""
711
        r = self.client.object_put(
712
            obj,
713
            if_etag_not_match=etag,
714
            data='c',
715
            content_type='application/octet-stream',
716
            success=(201, 412))
717
        self.assertEqual(r.status_code, 412)
718

    
719
        """Check content_type and content_length"""
720
        tmpdir = 'dir' + unicode(self.now)
721
        r = self.client.object_put(
722
            tmpdir,
723
            content_type='application/directory',
724
            content_length=0)
725

    
726
        r = self.client.get_object_info(tmpdir)
727
        self.assertEqual(r['content-type'], 'application/directory')
728

    
729
        """Check copy_from, content_encoding"""
730
        r = self.client.object_put(
731
            '%s/%s' % (tmpdir, obj),
732
            format=None,
733
            copy_from='/%s/%s' % (self.client.container, obj),
734
            content_encoding='application/octet-stream',
735
            source_account=self.client.account,
736
            content_length=0,
737
            success=201)
738
        self.assertEqual(r.status_code, 201)
739

    
740
        """Test copy_object for cross-conctainer copy"""
741
        self.client.copy_object(
742
            src_container=self.c2,
743
            src_object='%s/%s' % (tmpdir, obj),
744
            dst_container=self.c1,
745
            dst_object=obj)
746
        self.client.container = self.c1
747
        r1 = self.client.get_object_info(obj)
748
        self.client.container = self.c2
749
        r2 = self.client.get_object_info('%s/%s' % (tmpdir, obj))
750
        self.assertEqual(r1['x-object-hash'], r2['x-object-hash'])
751

    
752
        """Check cross-container copy_from, content_encoding"""
753
        self.client.container = self.c1
754
        fromstr = '/%s/%s/%s' % (self.c2, tmpdir, obj)
755
        r = self.client.object_put(
756
            obj,
757
            format=None,
758
            copy_from=fromstr,
759
            content_encoding='application/octet-stream',
760
            source_account=self.client.account,
761
            content_length=0,
762
            success=201)
763

    
764
        self.assertEqual(r.status_code, 201)
765
        r = self.client.get_object_info(obj)
766
        self.assertEqual(r['etag'], etag)
767

    
768
        """Check source_account"""
769
        self.client.container = self.c2
770
        fromstr = '/%s/%s' % (self.c1, obj)
771
        r = self.client.object_put(
772
            '%sv2' % obj,
773
            format=None,
774
            move_from=fromstr,
775
            content_encoding='application/octet-stream',
776
            source_account='nonExistendAddress@NeverLand.com',
777
            content_length=0,
778
            success=(201, 403))
779
        self.assertEqual(r.status_code, 403)
780

    
781
        """Check cross-container move_from"""
782
        self.client.container = self.c1
783
        r1 = self.client.get_object_info(obj)
784
        self.client.container = self.c2
785
        self.client.move_object(
786
            src_container=self.c1,
787
            src_object=obj,
788
            dst_container=self.c2,
789
            dst_object=obj + 'v0')
790
        r0 = self.client.get_object_info(obj + 'v0')
791
        self.assertEqual(r1['x-object-hash'], r0['x-object-hash'])
792

    
793
        """Check move_from"""
794
        r = self.client.object_put(
795
            '%sv1' % obj,
796
            format=None,
797
            move_from='/%s/%s' % (self.c2, obj),
798
            source_version=vers2,
799
            content_encoding='application/octet-stream',
800
            content_length=0, success=201)
801

    
802
        """Check manifest"""
803
        mobj = 'manifest.test'
804
        txt = ''
805
        for i in range(10):
806
            txt += '%s' % i
807
            r = self.client.object_put(
808
                '%s/%s' % (mobj, i),
809
                data='%s' % i,
810
                content_length=1,
811
                success=201,
812
                content_type='application/octet-stream',
813
                content_encoding='application/octet-stream')
814

    
815
        r = self.client.object_put(
816
            mobj,
817
            content_length=0,
818
            content_type='application/octet-stream',
819
            manifest='%s/%s' % (self.client.container, mobj))
820

    
821
        r = self.client.object_get(mobj)
822
        self.assertEqual(r.text, txt)
823

    
824
        """Upload a local file with one request"""
825
        newf = self.create_large_file(1024 * 10)
826
        self.client.upload_object('sample.file', newf)
827
        """Check if file has been uploaded"""
828
        r = self.client.get_object_info('sample.file')
829
        self.assertEqual(int(r['content-length']), 10240)
830

    
831
        """Some problems with transfer-encoding?"""
832

    
833
    def test_object_copy(self):
834
        """Test object_COPY"""
835
        self._test_0110_object_copy()
836

    
837
    def _test_0110_object_copy(self):
838
        self.client.container = self.c2
839
        obj = 'test2'
840

    
841
        data = '{"key1":"val1", "key2":"val2"}'
842
        r = self.client.object_put(
843
            '%sorig' % obj,
844
            content_type='application/octet-stream',
845
            data=data,
846
            metadata=dict(mkey1='mval1', mkey2='mval2'),
847
            permissions=dict(
848
                read=['accX:groupA', 'u1', 'u2'],
849
                write=['u2', 'u3']),
850
            content_disposition='attachment; filename="fname.ext"')
851

    
852
        r = self.client.object_copy(
853
            '%sorig' % obj,
854
            destination='/%s/%s' % (self.client.container, obj),
855
            ignore_content_type=False, content_type='application/json',
856
            metadata={'mkey2': 'mval2a', 'mkey3': 'mval3'},
857
            permissions={'write': ['u5', 'accX:groupB']})
858
        self.assertEqual(r.status_code, 201)
859

    
860
        """Check content-disposition"""
861
        r = self.client.get_object_info(obj)
862
        self.assertTrue('content-disposition' in r)
863

    
864
        """Check Metadata"""
865
        r = self.client.get_object_meta(obj)
866
        self.assertEqual(r['x-object-meta-mkey1'], 'mval1')
867
        self.assertEqual(r['x-object-meta-mkey2'], 'mval2a')
868
        self.assertEqual(r['x-object-meta-mkey3'], 'mval3')
869

    
870
        """Check permissions"""
871
        r = self.client.get_object_sharing(obj)
872
        self.assertFalse('read' in r or 'u2' in r['write'])
873
        self.assertTrue('accx:groupb' in r['write'])
874

    
875
        """Check destination account"""
876
        r = self.client.object_copy(
877
            obj,
878
            destination='/%s/%s' % (self.c1, obj),
879
            content_encoding='utf8',
880
            content_type='application/json',
881
            destination_account='nonExistendAddress@NeverLand.com',
882
            success=(201, 403))
883
        self.assertEqual(r.status_code, 403)
884

    
885
        """Check destination being another container
886
        and also content_type and content encoding"""
887
        r = self.client.object_copy(
888
            obj,
889
            destination='/%s/%s' % (self.c1, obj),
890
            content_encoding='utf8',
891
            content_type='application/json')
892
        self.assertEqual(r.status_code, 201)
893
        self.assertEqual(
894
            r.headers['content-type'],
895
            'application/json; charset=UTF-8')
896

    
897
        """Check ignore_content_type and content_type"""
898
        r = self.client.object_get(obj)
899
        etag = r.headers['etag']
900
        ctype = r.headers['content-type']
901
        self.assertEqual(ctype, 'application/json')
902

    
903
        r = self.client.object_copy(
904
            '%sorig' % obj,
905
            destination='/%s/%s0' % (self.client.container, obj),
906
            ignore_content_type=True,
907
            content_type='application/json')
908
        self.assertEqual(r.status_code, 201)
909
        self.assertNotEqual(r.headers['content-type'], 'application/json')
910

    
911
        """Check if_etag_(not_)match"""
912
        r = self.client.object_copy(
913
            obj,
914
            destination='/%s/%s1' % (self.client.container, obj),
915
            if_etag_match=etag)
916
        self.assertEqual(r.status_code, 201)
917

    
918
        r = self.client.object_copy(
919
            obj,
920
            destination='/%s/%s2' % (self.client.container, obj),
921
            if_etag_not_match='lalala')
922
        self.assertEqual(r.status_code, 201)
923
        vers2 = r.headers['x-object-version']
924

    
925
        """Check source_version, public and format """
926
        r = self.client.object_copy(
927
            '%s2' % obj,
928
            destination='/%s/%s3' % (self.client.container, obj),
929
            source_version=vers2,
930
            format='xml',
931
            public=True)
932
        self.assertEqual(r.status_code, 201)
933
        self.assertTrue(r.headers['content-type'].index('xml') > 0)
934

    
935
        r = self.client.get_object_info(obj + '3')
936
        self.assertTrue('x-object-public' in r)
937

    
938
    def test_object_move(self):
939
        """Test object_MOVE"""
940
        self._test_0120_object_move()
941

    
942
    def _test_0120_object_move(self):
943
        self.client.container = self.c2
944
        obj = 'test2'
945

    
946
        data = '{"key1": "val1", "key2": "val2"}'
947
        r = self.client.object_put(
948
            '%sorig' % obj,
949
            content_type='application/octet-stream',
950
            data=data,
951
            metadata=dict(mkey1='mval1', mkey2='mval2'),
952
            permissions=dict(
953
                read=['accX:groupA', 'u1', 'u2'],
954
                write=['u2', 'u3']))
955

    
956
        r = self.client.object_move(
957
            '%sorig' % obj,
958
            destination='/%s/%s' % (self.client.container, obj),
959
            ignore_content_type=False,
960
            content_type='application/json',
961
            metadata=dict(mkey2='mval2a', mkey3='mval3'),
962
            permissions=dict(write=['u5', 'accX:groupB']))
963
        self.assertEqual(r.status_code, 201)
964

    
965
        """Check Metadata"""
966
        r = self.client.get_object_meta(obj)
967
        self.assertEqual(r['x-object-meta-mkey1'], 'mval1')
968
        self.assertEqual(r['x-object-meta-mkey2'], 'mval2a')
969
        self.assertEqual(r['x-object-meta-mkey3'], 'mval3')
970

    
971
        """Check permissions"""
972
        r = self.client.get_object_sharing(obj)
973
        self.assertFalse('read' in r)
974
        self.assertTrue('u5' in r['write'])
975
        self.assertTrue('accx:groupb' in r['write'])
976

    
977
        """Check destination account"""
978
        r = self.client.object_move(
979
            obj,
980
            destination='/%s/%s' % (self.c1, obj),
981
            content_encoding='utf8',
982
            content_type='application/json',
983
            destination_account='nonExistendAddress@NeverLand.com',
984
            success=(201, 403))
985
        self.assertEqual(r.status_code, 403)
986

    
987
        """Check destination being another container and also
988
        content_type, content_disposition and content encoding"""
989
        r = self.client.object_move(
990
            obj,
991
            destination='/%s/%s' % (self.c1, obj),
992
            content_encoding='utf8',
993
            content_type='application/json',
994
            content_disposition='attachment; filename="fname.ext"')
995
        self.assertEqual(r.status_code, 201)
996
        self.assertEqual(
997
            r.headers['content-type'],
998
            'application/json; charset=UTF-8')
999
        self.client.container = self.c1
1000
        r = self.client.get_object_info(obj)
1001
        self.assertTrue('content-disposition' in r)
1002
        self.assertTrue('fname.ext' in r['content-disposition'])
1003
        etag = r['etag']
1004
        ctype = r['content-type']
1005
        self.assertEqual(ctype, 'application/json')
1006

    
1007
        """Check ignore_content_type and content_type"""
1008
        r = self.client.object_move(
1009
            obj,
1010
            destination='/%s/%s' % (self.c2, obj),
1011
            ignore_content_type=True,
1012
            content_type='application/json')
1013
        self.assertEqual(r.status_code, 201)
1014
        self.assertNotEqual(r.headers['content-type'], 'application/json')
1015

    
1016
        """Check if_etag_(not_)match"""
1017
        self.client.container = self.c2
1018
        r = self.client.object_move(
1019
            obj,
1020
            destination='/%s/%s0' % (self.client.container, obj),
1021
            if_etag_match=etag)
1022
        self.assertEqual(r.status_code, 201)
1023

    
1024
        r = self.client.object_move(
1025
            '%s0' % obj,
1026
            destination='/%s/%s1' % (self.client.container, obj),
1027
            if_etag_not_match='lalala')
1028
        self.assertEqual(r.status_code, 201)
1029

    
1030
        """Check public and format """
1031
        r = self.client.object_move(
1032
            '%s1' % obj,
1033
            destination='/%s/%s2' % (self.client.container, obj),
1034
            format='xml',
1035
            public=True)
1036
        self.assertEqual(r.status_code, 201)
1037
        self.assertTrue(r.headers['content-type'].index('xml') > 0)
1038

    
1039
        r = self.client.get_object_info(obj + '2')
1040
        self.assertTrue('x-object-public' in r)
1041

    
1042
    def test_object_post(self):
1043
        """Test object_POST"""
1044
        self._test_0130_object_post()
1045

    
1046
    def _test_0130_object_post(self):
1047
        self.client.container = self.c2
1048
        obj = 'test2'
1049
        """create a filesystem file"""
1050
        self.files.append(NamedTemporaryFile())
1051
        newf = self.files[-1]
1052
        newf.writelines([
1053
            'ello!\n',
1054
            'This is a test line\n',
1055
            'inside a test file\n'])
1056
        """create a file on container"""
1057
        r = self.client.object_put(
1058
            obj,
1059
            content_type='application/octet-stream',
1060
            data='H',
1061
            metadata=dict(mkey1='mval1', mkey2='mval2'),
1062
            permissions=dict(
1063
                read=['accX:groupA', 'u1', 'u2'],
1064
                write=['u2', 'u3']))
1065

    
1066
        """Append livetest update, content_[range|type|length]"""
1067
        newf.seek(0)
1068
        self.client.append_object(obj, newf)
1069
        r = self.client.object_get(obj)
1070
        self.assertTrue(r.text.startswith('Hello!'))
1071

    
1072
        """Overwrite livetest update,
1073
            content_type, content_length, content_range
1074
        """
1075
        newf.seek(0)
1076
        r = self.client.overwrite_object(obj, 0, 10, newf)
1077
        r = self.client.object_get(obj)
1078
        self.assertTrue(r.text.startswith('ello!'))
1079

    
1080
        """Truncate livetest update,
1081
            content_range, content_type, object_bytes and source_object"""
1082
        r = self.client.truncate_object(obj, 5)
1083
        r = self.client.object_get(obj)
1084
        self.assertEqual(r.text, 'ello!')
1085

    
1086
        """Check metadata"""
1087
        self.client.set_object_meta(obj, {'mkey2': 'mval2a', 'mkey3': 'mval3'})
1088
        r = self.client.get_object_meta(obj)
1089
        self.assertEqual(r['x-object-meta-mkey1'], 'mval1')
1090
        self.assertEqual(r['x-object-meta-mkey2'], 'mval2a')
1091
        self.assertEqual(r['x-object-meta-mkey3'], 'mval3')
1092
        self.client.del_object_meta(obj, 'mkey1')
1093
        r = self.client.get_object_meta(obj)
1094
        self.assertFalse('x-object-meta-mkey1' in r)
1095

    
1096
        """Check permissions"""
1097
        self.client.set_object_sharing(
1098
            obj,
1099
            read_permition=['u4', 'u5'],
1100
            write_permition=['u4'])
1101
        r = self.client.get_object_sharing(obj)
1102
        self.assertTrue('read' in r)
1103
        self.assertTrue('u5' in r['read'])
1104
        self.assertTrue('write' in r)
1105
        self.assertTrue('u4' in r['write'])
1106
        self.client.del_object_sharing(obj)
1107
        r = self.client.get_object_sharing(obj)
1108
        self.assertTrue(len(r) == 0)
1109

    
1110
        """Check publish"""
1111
        self.client.publish_object(obj)
1112
        r = self.client.get_object_info(obj)
1113
        self.assertTrue('x-object-public' in r)
1114
        self.client.unpublish_object(obj)
1115
        r = self.client.get_object_info(obj)
1116
        self.assertFalse('x-object-public' in r)
1117

    
1118
        """Check if_etag_(not)match"""
1119
        etag = r['etag']
1120
        """
1121
        r = self.client.object_post(
1122
            obj,
1123
            update=True,
1124
            public=True,
1125
            if_etag_not_match=etag,
1126
            success=(412, 202, 204))
1127
        self.assertEqual(r.status_code, 412)
1128
        """
1129

    
1130
        r = self.client.object_post(
1131
            obj,
1132
            update=True,
1133
            public=True,
1134
            if_etag_match=etag,
1135
            content_encoding='application/json')
1136

    
1137
        r = self.client.get_object_info(obj)
1138
        helloVersion = r['x-object-version']
1139
        self.assertTrue('x-object-public' in r)
1140
        self.assertEqual(r['content-encoding'], 'application/json')
1141

    
1142
        """Check source_version and source_account and content_disposition"""
1143
        r = self.client.object_post(
1144
            obj,
1145
            update=True,
1146
            content_type='application/octet-srteam',
1147
            content_length=5,
1148
            content_range='bytes 1-5/*',
1149
            source_object='/%s/%s' % (self.c2, obj),
1150
            source_account='thisAccountWillNeverExist@adminland.com',
1151
            source_version=helloVersion,
1152
            data='12345',
1153
            success=(403, 202, 204))
1154
        self.assertEqual(r.status_code, 403)
1155

    
1156
        r = self.client.object_post(
1157
            obj,
1158
            update=True,
1159
            content_type='application/octet-srteam',
1160
            content_length=5,
1161
            content_range='bytes 1-5/*',
1162
            source_object='/%s/%s' % (self.c2, obj),
1163
            source_account=self.client.account,
1164
            source_version=helloVersion,
1165
            data='12345',
1166
            content_disposition='attachment; filename="fname.ext"')
1167

    
1168
        r = self.client.object_get(obj)
1169
        self.assertEqual(r.text, 'eello!')
1170
        self.assertTrue('content-disposition' in r.headers)
1171
        self.assertTrue('fname.ext' in r.headers['content-disposition'])
1172

    
1173
        """Check manifest"""
1174
        mobj = 'manifest.test'
1175
        txt = ''
1176
        for i in range(10):
1177
            txt += '%s' % i
1178
            r = self.client.object_put(
1179
                '%s/%s' % (mobj, i),
1180
                data='%s' % i,
1181
                content_length=1,
1182
                success=201,
1183
                content_encoding='application/octet-stream',
1184
                content_type='application/octet-stream')
1185

    
1186
        self.client.create_object_by_manifestation(
1187
            mobj,
1188
            content_type='application/octet-stream')
1189

    
1190
        r = self.client.object_post(
1191
            mobj,
1192
            manifest='%s/%s' % (self.client.container, mobj))
1193

    
1194
        r = self.client.object_get(mobj)
1195
        self.assertEqual(r.text, txt)
1196

    
1197
        """We need to check transfer_encoding """
1198

    
1199
    def test_object_delete(self):
1200
        """Test object_DELETE"""
1201
        self._test_0140_object_delete()
1202

    
1203
    def _test_0140_object_delete(self):
1204
        self.client.container = self.c2
1205
        obj = 'test2'
1206
        """create a file on container"""
1207
        r = self.client.object_put(
1208
            obj,
1209
            content_type='application/octet-stream',
1210
            data='H',
1211
            metadata=dict(mkey1='mval1', mkey2='mval2'),
1212
            permissions=dict(
1213
                read=['accX:groupA', 'u1', 'u2'],
1214
                write=['u2', 'u3']))
1215

    
1216
        """Check with false until"""
1217
        r = self.client.object_delete(obj, until=1000000)
1218

    
1219
        r = self.client.object_get(obj, success=(200, 404))
1220
        self.assertEqual(r.status_code, 200)
1221

    
1222
        """Check normal case"""
1223
        r = self.client.object_delete(obj)
1224
        self.assertEqual(r.status_code, 204)
1225

    
1226
        r = self.client.object_get(obj, success=(200, 404))
1227
        self.assertEqual(r.status_code, 404)
1228

    
1229
    def create_large_file(self, size):
1230
        """Create a large file at fs"""
1231
        self.files.append(NamedTemporaryFile())
1232
        f = self.files[-1]
1233
        Ki = size / 8
1234
        bytelist = [b * Ki for b in range(size / Ki)]
1235

    
1236
        def append2file(step):
1237
            f.seek(step)
1238
            f.write(urandom(Ki))
1239
            f.flush()
1240
        self.do_with_progress_bar(
1241
            append2file,
1242
            ' create rand file %s (%sB): ' % (f.name, size),
1243
            bytelist)
1244
        f.seek(0)
1245
        return f