Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / livetest / pithos.py @ 3e02e714

History | View | Annotate | Download (46.7 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
from string import ascii_letters
39

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

    
44

    
45
def chargen():
46
    """10 + 2 * 26 + 26 = 88"""
47
    while True:
48
        for CH in xrange(10):
49
            yield '%s' % CH
50
        for CH in ascii_letters:
51
            yield CH
52
        for CH in '~!@#$%^&*()_+`-=:";|<>?,./':
53
            yield CH
54

    
55

    
56
def sample_block(f, block):
57
    block_size = 4 * 1024 * 1024
58
    f.seek(block * block_size)
59
    ch = [f.read(1)]
60
    f.seek(block_size / 2, 1)
61
    ch.append(f.read(1))
62
    f.seek((block + 1) * block_size - 1)
63
    ch.append(f.read(1))
64
    return ch
65

    
66

    
67
class Pithos(livetest.Generic):
68

    
69
    files = []
70

    
71
    def setUp(self):
72
        self.cloud = 'cloud.%s' % self['testcloud']
73
        aurl, self.token = self[self.cloud, 'url'], self[self.cloud, 'token']
74
        self.auth_base = AstakosClient(aurl, self.token)
75
        purl = self.auth_base.get_service_endpoints(
76
            'object-store')['publicURL']
77
        self.uuid = self.auth_base.user_term('id')
78
        self.client = PithosClient(purl, self.token, self.uuid)
79

    
80
        self.now = time.mktime(time.gmtime())
81
        self.now_unformated = datetime.datetime.utcnow()
82
        self._init_data()
83

    
84
        """Prepare an object to be shared - also its container"""
85
        self.client.container = self.c1
86
        self.client.object_post(
87
            'test',
88
            update=True,
89
            permissions={'read': [self.client.account]})
90

    
91
        self.create_remote_object(self.c1, 'another.test')
92

    
93
    def _init_data(self):
94
        self.c1 = 'c1_' + unicode(self.now)
95
        self.c2 = 'c2_' + unicode(self.now)
96
        self.c3 = 'c3_' + unicode(self.now)
97
        try:
98
            self.client.create_container(self.c2)
99
        except ClientError:
100
            pass
101
        try:
102
            self.client.create_container(self.c1)
103
        except ClientError:
104
            pass
105
        try:
106
            self.client.create_container(self.c3)
107
        except ClientError:
108
            pass
109

    
110
        self.create_remote_object(self.c1, 'test')
111
        self.create_remote_object(self.c2, 'test')
112
        self.create_remote_object(self.c1, 'test1')
113
        self.create_remote_object(self.c2, 'test1')
114

    
115
    def create_remote_object(self, container, obj):
116
        self.client.container = container
117
        self.client.object_put(
118
            obj,
119
            content_type='application/octet-stream',
120
            data='file %s that lives in %s' % (obj, container),
121
            metadata={'incontainer': container})
122

    
123
    def forceDeleteContainer(self, container):
124
        self.client.container = container
125
        try:
126
            r = self.client.list_objects()
127
        except ClientError:
128
            return
129
        for obj in r:
130
            name = obj['name']
131
            self.client.del_object(name)
132
        r = self.client.container_delete()
133
        self.container = ''
134

    
135
    def tearDown(self):
136
        """Destroy test cases"""
137
        for f in self.files:
138
            f.close()
139
        self.forceDeleteContainer(self.c1)
140
        self.forceDeleteContainer(self.c2)
141
        try:
142
            self.forceDeleteContainer(self.c3)
143
        except ClientError:
144
            pass
145
        self.client.container = ''
146

    
147
    def test_000(self):
148
        """Prepare a full Pithos+ test"""
149
        print('')
150
        super(self.__class__, self).test_000()
151

    
152
    def test_account_head(self):
153
        """Test account_HEAD"""
154
        self._test_0010_account_head()
155

    
156
    def _test_0010_account_head(self):
157
        r = self.client.account_head()
158
        self.assertEqual(r.status_code, 204)
159

    
160
        r = self.client.account_head(until='1000000000')
161
        self.assertEqual(r.status_code, 204)
162

    
163
        r = self.client.get_account_info(until='1000000000')
164
        datestring = unicode(r['x-account-until-timestamp'])
165
        self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring)
166

    
167
        r = self.client.get_account_quota()
168
        self.assertTrue('x-account-policy-quota' in r)
169

    
170
        #r = self.client.get_account_versioning()
171
        #self.assertTrue('x-account-policy-versioning' in r)
172

    
173
        """Check if(un)modified_since"""
174
        for format in self.client.DATE_FORMATS:
175
            now_formated = self.now_unformated.strftime(format)
176
            r1 = self.client.account_head(
177
                if_modified_since=now_formated,
178
                success=(204, 304, 412))
179
            sc1 = r1.status_code
180
            r2 = self.client.account_head(
181
                if_unmodified_since=now_formated,
182
                success=(204, 304, 412))
183
            sc2 = r2.status_code
184
            self.assertNotEqual(sc1, sc2)
185

    
186
    def test_account_get(self):
187
        """Test account_GET"""
188
        self._test_0020_account_get()
189

    
190
    def _test_0020_account_get(self):
191
        #r = self.client.account_get()
192
        #self.assertEqual(r.status_code, 200)
193
        r = self.client.list_containers()
194
        fullLen = len(r)
195
        self.assertTrue(fullLen > 2)
196

    
197
        r = self.client.account_get(limit=1)
198
        self.assertEqual(len(r.json), 1)
199

    
200
        r = self.client.account_get(marker='c2_')
201
        temp_c0 = r.json[0]['name']
202
        temp_c2 = r.json[2]['name']
203

    
204
        r = self.client.account_get(limit=2, marker='c2_')
205
        conames = [container['name'] for container in r.json if (
206
            container['name'].lower().startswith('c2_'))]
207
        self.assertTrue(temp_c0 in conames)
208
        self.assertFalse(temp_c2 in conames)
209

    
210
        r = self.client.account_get(show_only_shared=True)
211
        self.assertTrue(self.c1 in [c['name'] for c in r.json])
212

    
213
        r = self.client.account_get(until=1342609206.0)
214
        self.assertTrue(len(r.json) <= fullLen)
215

    
216
        """Check if(un)modified_since"""
217
        for format in self.client.DATE_FORMATS:
218
            now_formated = self.now_unformated.strftime(format)
219
            r1 = self.client.account_get(
220
                if_modified_since=now_formated,
221
                success=(200, 304, 412))
222
            sc1 = r1.status_code
223
            r2 = self.client.account_get(
224
                if_unmodified_since=now_formated,
225
                success=(200, 304, 412))
226
            sc2 = r2.status_code
227
            self.assertNotEqual(sc1, sc2)
228

    
229
        """Check sharing_accounts"""
230
        r = self.client.get_sharing_accounts()
231
        self.assertTrue(len(r) > 0)
232

    
233
    def test_account_post(self):
234
        """Test account_POST"""
235
        self._test_0030_account_post()
236

    
237
    def _test_0030_account_post(self):
238
        r = self.client.account_post()
239
        self.assertEqual(r.status_code, 202)
240
        grpName = 'grp' + unicode(self.now)
241

    
242
        """Method set/del_account_meta and set_account_groupcall use
243
            account_post internally
244
        """
245
        u1 = self.client.account
246
        #  Invalid display name
247
        u2 = '1nc0r3c7-d15p14y-n4m3'
248
        #  valid display name
249
        u3 = '6488c1b2-cb06-40a8-a02a-d474b8d29c59'
250
        self.assertRaises(
251
            ClientError,
252
            self.client.set_account_group,
253
            grpName, [u1, u2])
254
        self.client.set_account_group(grpName, [u1])
255
        r = self.client.get_account_group()
256
        self.assertEqual(r['x-account-group-' + grpName], '%s' % u1)
257
        try:
258
            self.client.set_account_group(grpName, [u1, u3])
259
            r = self.client.get_account_group()
260
            self.assertEqual(
261
                r['x-account-group-' + grpName],
262
                '%s,%s' % (u1, u3))
263
        except:
264
            print('\tInvalid user id %s (it is ok, though)' % u3)
265
        self.client.del_account_group(grpName)
266
        r = self.client.get_account_group()
267
        self.assertTrue('x-account-group-' + grpName not in r)
268

    
269
        mprefix = 'meta' + unicode(self.now)
270
        self.client.set_account_meta({
271
            mprefix + '1': 'v1',
272
            mprefix + '2': 'v2'})
273
        r = self.client.get_account_meta()
274
        self.assertEqual(r['x-account-meta-' + mprefix + '1'], 'v1')
275
        self.assertEqual(r['x-account-meta-' + mprefix + '2'], 'v2')
276

    
277
        self.client.del_account_meta(mprefix + '1')
278
        r = self.client.get_account_meta()
279
        self.assertTrue('x-account-meta-' + mprefix + '1' not in r)
280

    
281
        self.client.del_account_meta(mprefix + '2')
282
        r = self.client.get_account_meta()
283
        self.assertTrue('x-account-meta-' + mprefix + '2' not in r)
284

    
285
        """Missing testing for quota, versioning, because normally
286
        you don't have permissions to modify those at account level
287
        """
288

    
289
        #newquota = 1000000
290
        #self.client.set_account_quota(newquota)
291
        #r = self.client.get_account_info()
292
        #print(unicode(r))
293
        #r = self.client.get_account_quota()
294
        #self.assertEqual(r['x-account-policy-quota'], newquota)
295
        #self.client.set_account_versioning('auto')
296

    
297
    def test_container_head(self):
298
        """Test container_HEAD"""
299
        self._test_0040_container_head()
300

    
301
    def _test_0040_container_head(self):
302
        self.client.container = self.c1
303

    
304
        r = self.client.container_head()
305
        self.assertEqual(r.status_code, 204)
306

    
307
        """Check until"""
308
        r = self.client.container_head(until=1000000, success=(204, 404))
309
        self.assertEqual(r.status_code, 404)
310

    
311
        """Check and if(un)modified_since"""
312
        for format in self.client.DATE_FORMATS:
313
            now_formated = self.now_unformated.strftime(format)
314
            r1 = self.client.container_head(
315
                if_modified_since=now_formated,
316
                success=(204, 304, 412))
317
            sc1 = r1.status_code
318
            r2 = self.client.container_head(
319
                if_unmodified_since=now_formated,
320
                success=(204, 304, 412))
321
            sc2 = r2.status_code
322
            self.assertNotEqual(sc1, sc2)
323

    
324
        """Check container object meta"""
325
        r = self.client.get_container_object_meta()
326
        self.assertEqual(r['x-container-object-meta'], 'Incontainer')
327

    
328
    def test_container_get(self):
329
        """Test container_GET"""
330
        self._test_0050_container_get()
331

    
332
    def _test_0050_container_get(self):
333
        self.client.container = self.c1
334

    
335
        r = self.client.container_get()
336
        self.assertEqual(r.status_code, 200)
337
        fullLen = len(r.json)
338

    
339
        r = self.client.container_get(prefix='test')
340
        lalobjects = [obj for obj in r.json if obj['name'].startswith('test')]
341
        self.assertTrue(len(r.json) > 1)
342
        self.assertEqual(len(r.json), len(lalobjects))
343

    
344
        r = self.client.container_get(limit=1)
345
        self.assertEqual(len(r.json), 1)
346

    
347
        r = self.client.container_get(marker='another')
348
        self.assertTrue(len(r.json) > 1)
349
        neobjects = [obj for obj in r.json if obj['name'] > 'another']
350
        self.assertEqual(len(r.json), len(neobjects))
351

    
352
        r = self.client.container_get(prefix='another.test', delimiter='.')
353
        self.assertTrue(fullLen > len(r.json))
354

    
355
        r = self.client.container_get(path='/')
356
        self.assertEqual(fullLen, len(r.json))
357

    
358
        r = self.client.container_get(format='xml')
359
        self.assertEqual(r.text.split()[4], 'name="' + self.c1 + '">')
360

    
361
        r = self.client.container_get(meta=['incontainer'])
362
        self.assertTrue(len(r.json) > 0)
363

    
364
        r = self.client.container_get(show_only_shared=True)
365
        self.assertTrue(len(r.json) < fullLen)
366

    
367
        try:
368
            r = self.client.container_get(until=1000000000)
369
            datestring = unicode(r.headers['x-account-until-timestamp'])
370
            self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring)
371

    
372
        except ClientError:
373

    
374
            pass
375

    
376
        """Check and if un/modified_since"""
377
        for format in self.client.DATE_FORMATS:
378
            now_formated = self.now_unformated.strftime(format)
379
            r1 = self.client.container_get(
380
                if_modified_since=now_formated,
381
                success=(200, 304, 412))
382
            sc1 = r1.status_code
383
            r2 = self.client.container_get(
384
                if_unmodified_since=now_formated,
385
                success=(200, 304, 412))
386
            sc2 = r2.status_code
387
            self.assertNotEqual(sc1, sc2)
388

    
389
    def test_container_put(self):
390
        """Test container_PUT"""
391
        self._test_0050_container_put()
392

    
393
    def _test_0050_container_put(self):
394
        self.client.container = self.c2
395

    
396
        r = self.client.create_container()
397
        self.assertTrue(isinstance(r, dict))
398

    
399
        r = self.client.get_container_limit(self.client.container)
400
        cquota = r.values()[0]
401
        newquota = 2 * int(cquota)
402

    
403
        r = self.client.create_container(sizelimit=newquota)
404
        self.assertTrue(isinstance(r, dict))
405

    
406
        r = self.client.get_container_limit(self.client.container)
407
        xquota = int(r.values()[0])
408
        self.assertEqual(newquota, xquota)
409

    
410
        r = self.client.create_container(versioning='auto')
411
        self.assertTrue(isinstance(r, dict))
412

    
413
        r = self.client.get_container_versioning(self.client.container)
414
        nvers = r.values()[0]
415
        self.assertEqual('auto', nvers)
416

    
417
        r = self.client.container_put(versioning='none')
418
        self.assertEqual(r.status_code, 202)
419

    
420
        r = self.client.get_container_versioning(self.client.container)
421
        nvers = r.values()[0]
422
        self.assertEqual('none', nvers)
423

    
424
        r = self.client.create_container(metadata={'m1': 'v1', 'm2': 'v2'})
425
        self.assertTrue(isinstance(r, dict))
426

    
427
        r = self.client.get_container_meta(self.client.container)
428
        self.assertTrue('x-container-meta-m1' in r)
429
        self.assertEqual(r['x-container-meta-m1'], 'v1')
430
        self.assertTrue('x-container-meta-m2' in r)
431
        self.assertEqual(r['x-container-meta-m2'], 'v2')
432

    
433
        r = self.client.container_put(metadata={'m1': '', 'm2': 'v2a'})
434
        self.assertEqual(r.status_code, 202)
435

    
436
        r = self.client.get_container_meta(self.client.container)
437
        self.assertTrue('x-container-meta-m1' not in r)
438
        self.assertTrue('x-container-meta-m2' in r)
439
        self.assertEqual(r['x-container-meta-m2'], 'v2a')
440

    
441
        self.client.del_container_meta(self.client.container)
442

    
443
    def test_container_post(self):
444
        """Test container_POST"""
445
        self._test_0060_container_post()
446

    
447
    def _test_0060_container_post(self):
448
        self.client.container = self.c2
449

    
450
        """Simple post"""
451
        r = self.client.container_post()
452
        self.assertEqual(r.status_code, 202)
453

    
454
        """post meta"""
455
        self.client.set_container_meta({'m1': 'v1', 'm2': 'v2'})
456
        r = self.client.get_container_meta(self.client.container)
457
        self.assertTrue('x-container-meta-m1' in r)
458
        self.assertEqual(r['x-container-meta-m1'], 'v1')
459
        self.assertTrue('x-container-meta-m2' in r)
460
        self.assertEqual(r['x-container-meta-m2'], 'v2')
461

    
462
        """post/2del meta"""
463
        r = self.client.del_container_meta('m1')
464
        r = self.client.set_container_meta({'m2': 'v2a'})
465
        r = self.client.get_container_meta(self.client.container)
466
        self.assertTrue('x-container-meta-m1' not in r)
467
        self.assertTrue('x-container-meta-m2' in r)
468
        self.assertEqual(r['x-container-meta-m2'], 'v2a')
469

    
470
        """check quota"""
471
        r = self.client.get_container_limit(self.client.container)
472
        cquota = r.values()[0]
473
        newquota = 2 * int(cquota)
474
        r = self.client.set_container_limit(newquota)
475
        r = self.client.get_container_limit(self.client.container)
476
        xquota = int(r.values()[0])
477
        self.assertEqual(newquota, xquota)
478
        r = self.client.set_container_limit(cquota)
479
        r = self.client.get_container_limit(self.client.container)
480
        xquota = r.values()[0]
481
        self.assertEqual(cquota, xquota)
482

    
483
        """Check versioning"""
484
        self.client.set_container_versioning('auto')
485
        r = self.client.get_container_versioning(self.client.container)
486
        nvers = r.values()[0]
487
        self.assertEqual('auto', nvers)
488
        self.client.set_container_versioning('none')
489
        r = self.client.get_container_versioning(self.client.container)
490
        nvers = r.values()[0]
491
        self.assertEqual('none', nvers)
492

    
493
        """put_block uses content_type and content_length to
494
        post blocks of data 2 container. All that in upload_object"""
495
        """Change a file at fs"""
496
        f = self.create_large_file(1024 * 1024 * 100)
497
        """Upload it at a directory in container"""
498
        self.client.create_directory('dir')
499
        r = self.client.upload_object('/dir/sample.file', f)
500
        for term in ('content-length', 'content-type', 'x-object-version'):
501
            self.assertTrue(term in r)
502
        """Check if file has been uploaded"""
503
        r = self.client.get_object_info('/dir/sample.file')
504
        self.assertTrue(int(r['content-length']) > 100000000)
505

    
506
        """What is tranfer_encoding? What should I check about it? """
507
        #TODO
508

    
509
        """Check update=False"""
510
        r = self.client.object_post(
511
            'test',
512
            update=False,
513
            metadata={'newmeta': 'newval'})
514

    
515
        r = self.client.get_object_info('test')
516
        self.assertTrue('x-object-meta-newmeta' in r)
517
        self.assertFalse('x-object-meta-incontainer' in r)
518

    
519
        r = self.client.del_container_meta('m2')
520

    
521
    def test_container_delete(self):
522
        """Test container_DELETE"""
523
        self._test_0070_container_delete()
524

    
525
    def _test_0070_container_delete(self):
526

    
527
        """Fail to delete a non-empty container"""
528
        self.client.container = self.c2
529
        r = self.client.container_delete(success=409)
530
        self.assertEqual(r.status_code, 409)
531

    
532
        """Fail to delete c3 (empty) container"""
533
        self.client.container = self.c3
534
        r = self.client.container_delete(until='1000000000')
535
        self.assertEqual(r.status_code, 204)
536

    
537
        """Delete c3 (empty) container"""
538
        r = self.client.container_delete()
539
        self.assertEqual(r.status_code, 204)
540

    
541
        """Purge container(empty a container), check versionlist"""
542
        self.client.container = self.c1
543
        r = self.client.object_head('test', success=(200, 404))
544
        self.assertEqual(r.status_code, 200)
545
        self.client.del_container(delimiter='/')
546
        r = self.client.object_head('test', success=(200, 404))
547
        self.assertEqual(r.status_code, 404)
548
        r = self.client.get_object_versionlist('test')
549
        self.assertTrue(len(r) > 0)
550
        self.assertTrue(len(r[0]) > 1)
551
        self.client.purge_container()
552
        self.assertRaises(
553
            ClientError,
554
            self.client.get_object_versionlist,
555
            'test')
556

    
557
    def _test_0080_recreate_deleted_data(self):
558
        self._init_data()
559

    
560
    def test_object_head(self):
561
        """Test object_HEAD"""
562
        self._test_0090_object_head()
563

    
564
    def _test_0090_object_head(self):
565
        self.client.container = self.c2
566
        obj = 'test'
567

    
568
        r = self.client.object_head(obj)
569
        self.assertEqual(r.status_code, 200)
570
        etag = r.headers['etag']
571

    
572
        r = self.client.object_head(obj, version=40)
573
        self.assertEqual(r.headers['x-object-version'], '40')
574

    
575
        r = self.client.object_head(obj, if_etag_match=etag)
576
        self.assertEqual(r.status_code, 200)
577

    
578
        r = self.client.object_head(
579
            obj,
580
            if_etag_not_match=etag,
581
            success=(200, 412, 304))
582
        self.assertNotEqual(r.status_code, 200)
583

    
584
        r = self.client.object_head(
585
            obj,
586
            version=40,
587
            if_etag_match=etag,
588
            success=412)
589
        self.assertEqual(r.status_code, 412)
590

    
591
        """Check and if(un)modified_since"""
592
        for format in self.client.DATE_FORMATS:
593
            now_formated = self.now_unformated.strftime(format)
594
            r1 = self.client.object_head(
595
                obj,
596
                if_modified_since=now_formated,
597
                success=(200, 304, 412))
598
            sc1 = r1.status_code
599
            r2 = self.client.object_head(
600
                obj,
601
                if_unmodified_since=now_formated,
602
                success=(200, 304, 412))
603
            sc2 = r2.status_code
604
            self.assertNotEqual(sc1, sc2)
605

    
606
    def test_object_get(self):
607
        """Test object_GET"""
608
        self._test_0100_object_get()
609

    
610
    def _test_0100_object_get(self):
611
        self.client.container = self.c1
612
        obj = 'test'
613

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

    
617
        osize = int(r.headers['content-length'])
618
        etag = r.headers['etag']
619

    
620
        r = self.client.object_get(obj, hashmap=True)
621
        for term in ('hashes', 'block_hash', 'block_hash', 'bytes'):
622
            self.assertTrue(term in r.json)
623

    
624
        r = self.client.object_get(obj, format='xml', hashmap=True)
625
        self.assertEqual(len(r.text.split('hash>')), 3)
626

    
627
        rangestr = 'bytes=%s-%s' % (osize / 3, osize / 2)
628
        r = self.client.object_get(
629
            obj,
630
            data_range=rangestr,
631
            success=(200, 206))
632
        partsize = int(r.headers['content-length'])
633
        self.assertTrue(0 < partsize and partsize <= 1 + osize / 3)
634

    
635
        rangestr = 'bytes=%s-%s' % (osize / 3, osize / 2)
636
        r = self.client.object_get(
637
            obj,
638
            data_range=rangestr,
639
            if_range=True,
640
            success=(200, 206))
641
        partsize = int(r.headers['content-length'])
642
        self.assertTrue(0 < partsize and partsize <= 1 + osize / 3)
643

    
644
        r = self.client.object_get(obj, if_etag_match=etag)
645
        self.assertEqual(r.status_code, 200)
646

    
647
        r = self.client.object_get(obj, if_etag_not_match=etag + 'LALALA')
648
        self.assertEqual(r.status_code, 200)
649

    
650
        """Check and if(un)modified_since"""
651
        for format in self.client.DATE_FORMATS:
652
            now_formated = self.now_unformated.strftime(format)
653
            r1 = self.client.object_get(
654
                obj,
655
                if_modified_since=now_formated,
656
                success=(200, 304, 412))
657
            sc1 = r1.status_code
658
            r2 = self.client.object_get(
659
                obj,
660
                if_unmodified_since=now_formated,
661
                success=(200, 304, 412))
662
            sc2 = r2.status_code
663
            self.assertNotEqual(sc1, sc2)
664

    
665
        """Upload an object to download"""
666
        container_info_cache = dict()
667
        trg_fname = 'remotefile_%s' % self.now
668
        f_size = 59247824
669
        src_f = self.create_large_file(f_size)
670
        print('\tUploading...')
671
        r = self.client.upload_object(
672
            trg_fname, src_f,
673
            container_info_cache=container_info_cache)
674
        print('\tDownloading...')
675
        self.files.append(NamedTemporaryFile())
676
        dnl_f = self.files[-1]
677
        self.client.download_object(trg_fname, dnl_f)
678

    
679
        print('\tCheck if files match...')
680
        for pos in (0, f_size / 2, f_size - 128):
681
            src_f.seek(pos)
682
            dnl_f.seek(pos)
683
            self.assertEqual(src_f.read(64), dnl_f.read(64))
684

    
685
        print('\tDownload KiBs to string and check again...')
686
        for pos in (0, f_size / 2, f_size - 256):
687
            src_f.seek(pos)
688
            tmp_s = self.client.download_to_string(
689
                trg_fname,
690
                range_str='%s-%s' % (pos, (pos + 128)))
691
            self.assertEqual(tmp_s, src_f.read(len(tmp_s)))
692
        print('\tUploading KiBs as strings...')
693
        trg_fname = 'fromString_%s' % self.now
694
        src_size = 2 * 1024
695
        src_f.seek(0)
696
        src_str = src_f.read(src_size)
697
        self.client.upload_from_string(trg_fname, src_str)
698
        print('\tDownload as string and check...')
699
        tmp_s = self.client.download_to_string(trg_fname)
700
        self.assertEqual(tmp_s, src_str)
701

    
702
        """Upload a boring file"""
703
        trg_fname = 'boringfile_%s' % self.now
704
        src_f = self.create_boring_file(42)
705
        print('\tUploading boring file...')
706
        self.client.upload_object(
707
            trg_fname, src_f,
708
            container_info_cache=container_info_cache)
709
        print('\tDownloading boring file...')
710
        self.files.append(NamedTemporaryFile())
711
        dnl_f = self.files[-1]
712
        self.client.download_object(trg_fname, dnl_f)
713

    
714
        print('\tCheck if files match...')
715
        for i in range(42):
716
            self.assertEqual(sample_block(src_f, i), sample_block(dnl_f, i))
717

    
718
    def test_object_put(self):
719
        """Test object_PUT"""
720
        self._test_object_put()
721

    
722
    def _test_object_put(self):
723
        self.client.container = self.c2
724
        obj = 'another.test'
725

    
726
        self.client.create_object(obj + '.FAKE')
727
        r = self.client.get_object_info(obj + '.FAKE')
728
        self.assertEqual(r['content-type'], 'application/octet-stream')
729

    
730
        """create the object"""
731
        r = self.client.object_put(
732
            obj,
733
            data='a',
734
            content_type='application/octer-stream',
735
            permissions=dict(
736
                read=['accX:groupA', 'u1', 'u2'],
737
                write=['u2', 'u3']),
738
            metadata=dict(key1='val1', key2='val2'),
739
            content_encoding='UTF-8',
740
            content_disposition='attachment; filename="fname.ext"')
741
        self.assertEqual(r.status_code, 201)
742
        etag = r.headers['etag']
743

    
744
        """Check content-disposition"""
745
        r = self.client.get_object_info(obj)
746
        self.assertTrue('content-disposition' in r)
747

    
748
        """Check permissions"""
749
        r = self.client.get_object_sharing(obj)
750
        self.assertTrue('accx:groupa' in r['read'])
751
        self.assertTrue('u1' in r['read'])
752
        self.assertTrue('u2' in r['write'])
753
        self.assertTrue('u3' in r['write'])
754

    
755
        """Check metadata"""
756
        r = self.client.get_object_meta(obj)
757
        self.assertEqual(r['x-object-meta-key1'], 'val1')
758
        self.assertEqual(r['x-object-meta-key2'], 'val2')
759

    
760
        """Check public and if_etag_match"""
761
        r = self.client.object_put(
762
            obj,
763
            if_etag_match=etag,
764
            data='b',
765
            content_type='application/octet-stream',
766
            public=True)
767

    
768
        r = self.client.object_get(obj)
769
        self.assertTrue('x-object-public' in r.headers)
770
        vers2 = int(r.headers['x-object-version'])
771
        etag = r.headers['etag']
772
        self.assertEqual(r.text, 'b')
773

    
774
        """Check if_etag_not_match"""
775
        r = self.client.object_put(
776
            obj,
777
            if_etag_not_match=etag,
778
            data='c',
779
            content_type='application/octet-stream',
780
            success=(201, 412))
781
        self.assertEqual(r.status_code, 412)
782

    
783
        """Check content_type and content_length"""
784
        tmpdir = 'dir' + unicode(self.now)
785
        r = self.client.object_put(
786
            tmpdir,
787
            content_type='application/directory',
788
            content_length=0)
789

    
790
        r = self.client.get_object_info(tmpdir)
791
        self.assertEqual(r['content-type'], 'application/directory')
792

    
793
        """Check copy_from, content_encoding"""
794
        r = self.client.object_put(
795
            '%s/%s' % (tmpdir, obj),
796
            format=None,
797
            copy_from='/%s/%s' % (self.client.container, obj),
798
            content_encoding='application/octet-stream',
799
            source_account=self.client.account,
800
            content_length=0,
801
            success=201)
802
        self.assertEqual(r.status_code, 201)
803

    
804
        """Test copy_object for cross-conctainer copy"""
805
        self.client.copy_object(
806
            src_container=self.c2,
807
            src_object='%s/%s' % (tmpdir, obj),
808
            dst_container=self.c1,
809
            dst_object=obj)
810
        self.client.container = self.c1
811
        r1 = self.client.get_object_info(obj)
812
        self.client.container = self.c2
813
        r2 = self.client.get_object_info('%s/%s' % (tmpdir, obj))
814
        self.assertEqual(r1['x-object-hash'], r2['x-object-hash'])
815

    
816
        """Check cross-container copy_from, content_encoding"""
817
        self.client.container = self.c1
818
        fromstr = '/%s/%s/%s' % (self.c2, tmpdir, obj)
819
        r = self.client.object_put(
820
            obj,
821
            format=None,
822
            copy_from=fromstr,
823
            content_encoding='application/octet-stream',
824
            source_account=self.client.account,
825
            content_length=0,
826
            success=201)
827

    
828
        self.assertEqual(r.status_code, 201)
829
        r = self.client.get_object_info(obj)
830
        self.assertEqual(r['etag'], etag)
831

    
832
        """Check source_account"""
833
        self.client.container = self.c2
834
        fromstr = '/%s/%s' % (self.c1, obj)
835
        r = self.client.object_put(
836
            '%sv2' % obj,
837
            format=None,
838
            move_from=fromstr,
839
            content_encoding='application/octet-stream',
840
            source_account='nonExistendAddress@NeverLand.com',
841
            content_length=0,
842
            success=(201, 403))
843
        self.assertEqual(r.status_code, 403)
844

    
845
        """Check cross-container move_from"""
846
        self.client.container = self.c1
847
        r1 = self.client.get_object_info(obj)
848
        self.client.container = self.c2
849
        self.client.move_object(
850
            src_container=self.c1,
851
            src_object=obj,
852
            dst_container=self.c2,
853
            dst_object=obj + 'v0')
854
        r0 = self.client.get_object_info(obj + 'v0')
855
        self.assertEqual(r1['x-object-hash'], r0['x-object-hash'])
856

    
857
        """Check move_from"""
858
        r = self.client.object_put(
859
            '%sv1' % obj,
860
            format=None,
861
            move_from='/%s/%s' % (self.c2, obj),
862
            source_version=vers2,
863
            content_encoding='application/octet-stream',
864
            content_length=0, success=201)
865

    
866
        """Check manifest"""
867
        mobj = 'manifest.test'
868
        txt = ''
869
        for i in range(10):
870
            txt += '%s' % i
871
            r = self.client.object_put(
872
                '%s/%s' % (mobj, i),
873
                data='%s' % i,
874
                content_length=1,
875
                success=201,
876
                content_type='application/octet-stream',
877
                content_encoding='application/octet-stream')
878

    
879
        r = self.client.object_put(
880
            mobj,
881
            content_length=0,
882
            content_type='application/octet-stream',
883
            manifest='%s/%s' % (self.client.container, mobj))
884

    
885
        r = self.client.object_get(mobj)
886
        self.assertEqual(r.text, txt)
887

    
888
        """Upload a local file with one request"""
889
        newf = self.create_large_file(1024 * 10)
890
        self.client.upload_object('sample.file', newf)
891
        """Check if file has been uploaded"""
892
        r = self.client.get_object_info('sample.file')
893
        self.assertEqual(int(r['content-length']), 10240)
894

    
895
        """Some problems with transfer-encoding?"""
896

    
897
    def test_object_copy(self):
898
        """Test object_COPY"""
899
        self._test_0110_object_copy()
900

    
901
    def _test_0110_object_copy(self):
902
        #  TODO: check with source_account option
903
        self.client.container = self.c2
904
        obj = 'test2'
905

    
906
        data = '{"key1":"val1", "key2":"val2"}'
907
        r = self.client.object_put(
908
            '%sorig' % obj,
909
            content_type='application/octet-stream',
910
            data=data,
911
            metadata=dict(mkey1='mval1', mkey2='mval2'),
912
            permissions=dict(
913
                read=['accX:groupA', 'u1', 'u2'],
914
                write=['u2', 'u3']),
915
            content_disposition='attachment; filename="fname.ext"')
916

    
917
        r = self.client.object_copy(
918
            '%sorig' % obj,
919
            destination='/%s/%s' % (self.client.container, obj),
920
            ignore_content_type=False, content_type='application/json',
921
            metadata={'mkey2': 'mval2a', 'mkey3': 'mval3'},
922
            permissions={'write': ['u5', 'accX:groupB']})
923
        self.assertEqual(r.status_code, 201)
924

    
925
        """Check content-disposition"""
926
        r = self.client.get_object_info(obj)
927
        self.assertTrue('content-disposition' in r)
928

    
929
        """Check Metadata"""
930
        r = self.client.get_object_meta(obj)
931
        self.assertEqual(r['x-object-meta-mkey1'], 'mval1')
932
        self.assertEqual(r['x-object-meta-mkey2'], 'mval2a')
933
        self.assertEqual(r['x-object-meta-mkey3'], 'mval3')
934

    
935
        """Check permissions"""
936
        r = self.client.get_object_sharing(obj)
937
        self.assertFalse('read' in r or 'u2' in r['write'])
938
        self.assertTrue('accx:groupb' in r['write'])
939

    
940
        """Check destination account"""
941
        r = self.client.object_copy(
942
            obj,
943
            destination='/%s/%s' % (self.c1, obj),
944
            content_encoding='utf8',
945
            content_type='application/json',
946
            destination_account='nonExistendAddress@NeverLand.com',
947
            success=(201, 403))
948
        self.assertEqual(r.status_code, 403)
949

    
950
        """Check destination being another container
951
        and also content_type and content encoding"""
952
        r = self.client.object_copy(
953
            obj,
954
            destination='/%s/%s' % (self.c1, obj),
955
            content_encoding='utf8',
956
            content_type='application/json')
957
        self.assertEqual(r.status_code, 201)
958
        self.assertEqual(
959
            r.headers['content-type'],
960
            'application/json; charset=UTF-8')
961

    
962
        """Check ignore_content_type and content_type"""
963
        r = self.client.object_get(obj)
964
        etag = r.headers['etag']
965
        ctype = r.headers['content-type']
966
        self.assertEqual(ctype, 'application/json')
967

    
968
        r = self.client.object_copy(
969
            '%sorig' % obj,
970
            destination='/%s/%s0' % (self.client.container, obj),
971
            ignore_content_type=True,
972
            content_type='application/json')
973
        self.assertEqual(r.status_code, 201)
974
        self.assertNotEqual(r.headers['content-type'], 'application/json')
975

    
976
        """Check if_etag_(not_)match"""
977
        r = self.client.object_copy(
978
            obj,
979
            destination='/%s/%s1' % (self.client.container, obj),
980
            if_etag_match=etag)
981
        self.assertEqual(r.status_code, 201)
982

    
983
        r = self.client.object_copy(
984
            obj,
985
            destination='/%s/%s2' % (self.client.container, obj),
986
            if_etag_not_match='lalala')
987
        self.assertEqual(r.status_code, 201)
988
        vers2 = r.headers['x-object-version']
989

    
990
        """Check source_version, public and format """
991
        r = self.client.object_copy(
992
            '%s2' % obj,
993
            destination='/%s/%s3' % (self.client.container, obj),
994
            source_version=vers2,
995
            format='xml',
996
            public=True)
997
        self.assertEqual(r.status_code, 201)
998
        self.assertTrue(r.headers['content-type'].index('xml') > 0)
999

    
1000
        r = self.client.get_object_info(obj + '3')
1001
        self.assertTrue('x-object-public' in r)
1002

    
1003
    def test_object_move(self):
1004
        """Test object_MOVE"""
1005
        self._test_0120_object_move()
1006

    
1007
    def _test_0120_object_move(self):
1008
        self.client.container = self.c2
1009
        obj = 'test2'
1010

    
1011
        data = '{"key1": "val1", "key2": "val2"}'
1012
        r = self.client.object_put(
1013
            '%sorig' % obj,
1014
            content_type='application/octet-stream',
1015
            data=data,
1016
            metadata=dict(mkey1='mval1', mkey2='mval2'),
1017
            permissions=dict(
1018
                read=['accX:groupA', 'u1', 'u2'],
1019
                write=['u2', 'u3']))
1020

    
1021
        r = self.client.object_move(
1022
            '%sorig' % obj,
1023
            destination='/%s/%s' % (self.client.container, obj),
1024
            ignore_content_type=False,
1025
            content_type='application/json',
1026
            metadata=dict(mkey2='mval2a', mkey3='mval3'),
1027
            permissions=dict(write=['u5', 'accX:groupB']))
1028
        self.assertEqual(r.status_code, 201)
1029

    
1030
        """Check Metadata"""
1031
        r = self.client.get_object_meta(obj)
1032
        self.assertEqual(r['x-object-meta-mkey1'], 'mval1')
1033
        self.assertEqual(r['x-object-meta-mkey2'], 'mval2a')
1034
        self.assertEqual(r['x-object-meta-mkey3'], 'mval3')
1035

    
1036
        """Check permissions"""
1037
        r = self.client.get_object_sharing(obj)
1038
        self.assertFalse('read' in r)
1039
        self.assertTrue('u5' in r['write'])
1040
        self.assertTrue('accx:groupb' in r['write'])
1041

    
1042
        """Check destination account"""
1043
        r = self.client.object_move(
1044
            obj,
1045
            destination='/%s/%s' % (self.c1, obj),
1046
            content_encoding='utf8',
1047
            content_type='application/json',
1048
            destination_account='nonExistendAddress@NeverLand.com',
1049
            success=(201, 403))
1050
        self.assertEqual(r.status_code, 403)
1051

    
1052
        """Check destination being another container and also
1053
        content_type, content_disposition and content encoding"""
1054
        r = self.client.object_move(
1055
            obj,
1056
            destination='/%s/%s' % (self.c1, obj),
1057
            content_encoding='utf8',
1058
            content_type='application/json',
1059
            content_disposition='attachment; filename="fname.ext"')
1060
        self.assertEqual(r.status_code, 201)
1061
        self.assertEqual(
1062
            r.headers['content-type'],
1063
            'application/json; charset=UTF-8')
1064
        self.client.container = self.c1
1065
        r = self.client.get_object_info(obj)
1066
        self.assertTrue('content-disposition' in r)
1067
        self.assertTrue('fname.ext' in r['content-disposition'])
1068
        etag = r['etag']
1069
        ctype = r['content-type']
1070
        self.assertEqual(ctype, 'application/json')
1071

    
1072
        """Check ignore_content_type and content_type"""
1073
        r = self.client.object_move(
1074
            obj,
1075
            destination='/%s/%s' % (self.c2, obj),
1076
            ignore_content_type=True,
1077
            content_type='application/json')
1078
        self.assertEqual(r.status_code, 201)
1079
        self.assertNotEqual(r.headers['content-type'], 'application/json')
1080

    
1081
        """Check if_etag_(not_)match"""
1082
        self.client.container = self.c2
1083
        r = self.client.object_move(
1084
            obj,
1085
            destination='/%s/%s0' % (self.client.container, obj),
1086
            if_etag_match=etag)
1087
        self.assertEqual(r.status_code, 201)
1088

    
1089
        r = self.client.object_move(
1090
            '%s0' % obj,
1091
            destination='/%s/%s1' % (self.client.container, obj),
1092
            if_etag_not_match='lalala')
1093
        self.assertEqual(r.status_code, 201)
1094

    
1095
        """Check public and format """
1096
        r = self.client.object_move(
1097
            '%s1' % obj,
1098
            destination='/%s/%s2' % (self.client.container, obj),
1099
            format='xml',
1100
            public=True)
1101
        self.assertEqual(r.status_code, 201)
1102
        self.assertTrue(r.headers['content-type'].index('xml') > 0)
1103

    
1104
        r = self.client.get_object_info(obj + '2')
1105
        self.assertTrue('x-object-public' in r)
1106

    
1107
    def test_object_post(self):
1108
        """Test object_POST"""
1109
        self._test_0130_object_post()
1110

    
1111
    def _test_0130_object_post(self):
1112
        self.client.container = self.c2
1113
        obj = 'test2'
1114
        """create a filesystem file"""
1115
        self.files.append(NamedTemporaryFile())
1116
        newf = self.files[-1]
1117
        newf.writelines([
1118
            'ello!\n',
1119
            'This is a test line\n',
1120
            'inside a test file\n'])
1121
        """create a file on container"""
1122
        r = self.client.object_put(
1123
            obj,
1124
            content_type='application/octet-stream',
1125
            data='H',
1126
            metadata=dict(mkey1='mval1', mkey2='mval2'),
1127
            permissions=dict(
1128
                read=['accX:groupA', 'u1', 'u2'],
1129
                write=['u2', 'u3']))
1130

    
1131
        """Append livetest update, content_[range|type|length]"""
1132
        newf.seek(0)
1133
        self.client.append_object(obj, newf)
1134
        r = self.client.object_get(obj)
1135
        self.assertTrue(r.text.startswith('Hello!'))
1136

    
1137
        """Overwrite livetest update,
1138
            content_type, content_length, content_range
1139
        """
1140
        newf.seek(0)
1141
        r = self.client.overwrite_object(obj, 0, 10, newf)
1142
        r = self.client.object_get(obj)
1143
        self.assertTrue(r.text.startswith('ello!'))
1144

    
1145
        """Truncate livetest update,
1146
            content_range, content_type, object_bytes and source_object"""
1147
        r = self.client.truncate_object(obj, 5)
1148
        r = self.client.object_get(obj)
1149
        self.assertEqual(r.text, 'ello!')
1150

    
1151
        """Check metadata"""
1152
        self.client.set_object_meta(obj, {'mkey2': 'mval2a', 'mkey3': 'mval3'})
1153
        r = self.client.get_object_meta(obj)
1154
        self.assertEqual(r['x-object-meta-mkey1'], 'mval1')
1155
        self.assertEqual(r['x-object-meta-mkey2'], 'mval2a')
1156
        self.assertEqual(r['x-object-meta-mkey3'], 'mval3')
1157
        self.client.del_object_meta(obj, 'mkey1')
1158
        r = self.client.get_object_meta(obj)
1159
        self.assertFalse('x-object-meta-mkey1' in r)
1160

    
1161
        """Check permissions"""
1162
        self.client.set_object_sharing(
1163
            obj,
1164
            read_permission=['u4', 'u5'],
1165
            write_permission=['u4'])
1166
        r = self.client.get_object_sharing(obj)
1167
        self.assertTrue('read' in r)
1168
        self.assertTrue('u5' in r['read'])
1169
        self.assertTrue('write' in r)
1170
        self.assertTrue('u4' in r['write'])
1171
        self.client.del_object_sharing(obj)
1172
        r = self.client.get_object_sharing(obj)
1173
        self.assertTrue(len(r) == 0)
1174

    
1175
        """Check publish"""
1176
        self.client.publish_object(obj)
1177
        r = self.client.get_object_info(obj)
1178
        self.assertTrue('x-object-public' in r)
1179
        self.client.unpublish_object(obj)
1180
        r = self.client.get_object_info(obj)
1181
        self.assertFalse('x-object-public' in r)
1182

    
1183
        """Check if_etag_(not)match"""
1184
        etag = r['etag']
1185
        """
1186
        r = self.client.object_post(
1187
            obj,
1188
            update=True,
1189
            public=True,
1190
            if_etag_not_match=etag,
1191
            success=(412, 202, 204))
1192
        self.assertEqual(r.status_code, 412)
1193
        """
1194

    
1195
        r = self.client.object_post(
1196
            obj,
1197
            update=True,
1198
            public=True,
1199
            if_etag_match=etag,
1200
            content_encoding='application/json')
1201

    
1202
        r = self.client.get_object_info(obj)
1203
        helloVersion = r['x-object-version']
1204
        self.assertTrue('x-object-public' in r)
1205
        self.assertEqual(r['content-encoding'], 'application/json')
1206

    
1207
        """Check source_version and source_account and content_disposition"""
1208
        r = self.client.object_post(
1209
            obj,
1210
            update=True,
1211
            content_type='application/octet-srteam',
1212
            content_length=5,
1213
            content_range='bytes 1-5/*',
1214
            source_object='/%s/%s' % (self.c2, obj),
1215
            source_account='thisAccountWillNeverExist@adminland.com',
1216
            source_version=helloVersion,
1217
            data='12345',
1218
            success=(403, 202, 204))
1219
        self.assertEqual(r.status_code, 403)
1220

    
1221
        r = self.client.object_post(
1222
            obj,
1223
            update=True,
1224
            content_type='application/octet-srteam',
1225
            content_length=5,
1226
            content_range='bytes 1-5/*',
1227
            source_object='/%s/%s' % (self.c2, obj),
1228
            source_account=self.client.account,
1229
            source_version=helloVersion,
1230
            data='12345',
1231
            content_disposition='attachment; filename="fname.ext"')
1232

    
1233
        r = self.client.object_get(obj)
1234
        self.assertEqual(r.text, 'eello!')
1235
        self.assertTrue('content-disposition' in r.headers)
1236
        self.assertTrue('fname.ext' in r.headers['content-disposition'])
1237

    
1238
        """Check manifest"""
1239
        mobj = 'manifest.test'
1240
        txt = ''
1241
        for i in range(10):
1242
            txt += '%s' % i
1243
            r = self.client.object_put(
1244
                '%s/%s' % (mobj, i),
1245
                data='%s' % i,
1246
                content_length=1,
1247
                success=201,
1248
                content_encoding='application/octet-stream',
1249
                content_type='application/octet-stream')
1250

    
1251
        self.client.create_object_by_manifestation(
1252
            mobj,
1253
            content_type='application/octet-stream')
1254

    
1255
        r = self.client.object_post(
1256
            mobj,
1257
            manifest='%s/%s' % (self.client.container, mobj))
1258

    
1259
        r = self.client.object_get(mobj)
1260
        self.assertEqual(r.text, txt)
1261

    
1262
        """We need to check transfer_encoding """
1263

    
1264
    def test_object_delete(self):
1265
        """Test object_DELETE"""
1266
        self._test_0140_object_delete()
1267

    
1268
    def _test_0140_object_delete(self):
1269
        self.client.container = self.c2
1270
        obj = 'test2'
1271
        """create a file on container"""
1272
        r = self.client.object_put(
1273
            obj,
1274
            content_type='application/octet-stream',
1275
            data='H',
1276
            metadata=dict(mkey1='mval1', mkey2='mval2'),
1277
            permissions=dict(
1278
                read=['accX:groupA', 'u1', 'u2'],
1279
                write=['u2', 'u3']))
1280

    
1281
        """Check with false until"""
1282
        r = self.client.object_delete(obj, until=1000000)
1283

    
1284
        r = self.client.object_get(obj, success=(200, 404))
1285
        self.assertEqual(r.status_code, 200)
1286

    
1287
        """Check normal case"""
1288
        r = self.client.object_delete(obj)
1289
        self.assertEqual(r.status_code, 204)
1290

    
1291
        r = self.client.object_get(obj, success=(200, 404))
1292
        self.assertEqual(r.status_code, 404)
1293

    
1294
    def create_large_file(self, size):
1295
        """Create a large file at fs"""
1296
        self.files.append(NamedTemporaryFile())
1297
        f = self.files[-1]
1298
        Ki = size / 8
1299
        bytelist = [b * Ki for b in range(size / Ki)]
1300

    
1301
        def append2file(step):
1302
            f.seek(step)
1303
            f.write(urandom(Ki))
1304
            f.flush()
1305
        self.do_with_progress_bar(
1306
            append2file,
1307
            ' create rand file %s (%sB): ' % (f.name, size),
1308
            bytelist)
1309
        f.seek(0)
1310
        return f
1311

    
1312
    def create_boring_file(self, num_of_blocks):
1313
        """Create a file with some blocks being the same"""
1314
        self.files.append(NamedTemporaryFile())
1315
        tmpFile = self.files[-1]
1316
        block_size = 4 * 1024 * 1024
1317
        print('\n\tCreate boring file of %s blocks' % num_of_blocks)
1318
        chars = chargen()
1319
        while num_of_blocks:
1320
            fslice = 3 if num_of_blocks > 3 else num_of_blocks
1321
            tmpFile.write(fslice * block_size * chars.next())
1322
            num_of_blocks -= fslice
1323
        print('\t\tDone')
1324
        tmpFile.seek(0)
1325
        return tmpFile