Statistics
| Branch: | Tag: | Revision:

root / snf-tools / synnefo_tools / burnin / pithos_tests.py @ eea28492

History | View | Annotate | Download (23 kB)

1
# Copyright 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
"""
35
This is the burnin class that tests the Pithos functionality
36

37
"""
38

    
39
import random
40
from datetime import datetime
41
from tempfile import NamedTemporaryFile
42

    
43
from synnefo_tools.burnin.common import BurninTests, Proper
44
from kamaki.clients import ClientError
45

    
46

    
47
def sample_block(f, block):
48
    block_size = 4 * 1024 * 1024
49
    f.seek(block * block_size)
50
    ch = [f.read(1)]
51
    f.seek(block_size / 2, 1)
52
    ch.append(f.read(1))
53
    f.seek((block + 1) * block_size - 1)
54
    ch.append(f.read(1))
55
    return ch
56

    
57

    
58
# Too many public methods. pylint: disable-msg=R0904
59
class PithosTestSuite(BurninTests):
60
    """Test Pithos functionality"""
61
    containers = Proper(value=None)
62
    created_container = Proper(value=None)
63
    now_unformated = Proper(value=datetime.utcnow())
64
    obj_metakey = Proper(value=None)
65
    large_file = Proper(value=None)
66

    
67
    def test_005_account_head(self):
68
        """HEAD on pithos account"""
69
        self._set_pithos_account(self._get_uuid())
70
        pithos = self.clients.pithos
71
        r = pithos.account_head()
72
        self.assertEqual(r.status_code, 204)
73
        self.info('Returns 204')
74

    
75
        r = pithos.account_head(until='1000000000')
76
        self.assertEqual(r.status_code, 204)
77
        datestring = unicode(r.headers['x-account-until-timestamp'])
78
        self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring)
79
        self.assertTrue('x-account-policy-quota' in r.headers)
80
        self.info('Until and policy quota exist')
81

    
82
        for format in pithos.DATE_FORMATS:
83
            now_formated = self.now_unformated.strftime(format)
84
            r1 = pithos.account_head(
85
                if_modified_since=now_formated, success=(204, 304, 412))
86
            r2 = pithos.account_head(
87
                if_unmodified_since=now_formated, success=(204, 304, 412))
88
            self.assertNotEqual(r1.status_code, r2.status_code)
89
        self.info('If_(un)modified_since is OK')
90

    
91
    def test_010_account_get(self):
92
        """Test account_get"""
93
        self.info('Preparation')
94
        pithos = self.clients.pithos
95
        for i in range(1, 3):
96
            cont_name = "cont%s_%s%s" % (
97
                i, self.run_id or 0, random.randint(1000, 9999))
98
            self._create_pithos_container(cont_name)
99
        pithos.container, obj = cont_name, 'shared_file'
100
        pithos.create_object(obj)
101
        pithos.set_object_sharing(obj, read_permission='*')
102
        self.info('Created object /%s/%s' % (cont_name, obj))
103

    
104
        r = pithos.list_containers()
105
        fullLen = len(r)
106
        self.assertTrue(fullLen > 2)
107
        self.info('Normal use is OK')
108

    
109
        r = pithos.account_get(limit=1)
110
        self.assertEqual(len(r.json), 1)
111
        self.info('Limit works')
112

    
113
        r = pithos.account_get(marker='cont')
114
        cont1, cont3 = r.json[0], r.json[2]
115
        self.info('Marker works')
116

    
117
        r = pithos.account_get(limit=2, marker='cont')
118
        conames = [container['name'] for container in r.json if (
119
            container['name'].lower().startswith('cont'))]
120
        self.assertTrue(cont1['name'] in conames)
121
        self.assertFalse(cont3['name'] in conames)
122
        self.info('Marker-limit combination works')
123

    
124
        r = pithos.account_get(show_only_shared=True)
125
        self.assertTrue(cont_name in [c['name'] for c in r.json])
126
        self.info('Show-only-shared works')
127

    
128
        r = pithos.account_get(until=1342609206.0)
129
        self.assertTrue(len(r.json) <= fullLen)
130
        self.info('Until works')
131

    
132
        for format in pithos.DATE_FORMATS:
133
            now_formated = self.now_unformated.strftime(format)
134
            r1 = pithos.account_get(
135
                if_modified_since=now_formated, success=(200, 304, 412))
136
            r2 = pithos.account_get(
137
                if_unmodified_since=now_formated, success=(200, 304, 412))
138
            self.assertNotEqual(r1.status_code, r2.status_code)
139
        self.info('If_(un)modified_since is OK')
140

    
141
    def test_015_account_post(self):
142
        """Test account_post"""
143
        pithos = self.clients.pithos
144
        r = pithos.account_post()
145
        self.assertEqual(r.status_code, 202)
146
        self.info('Status code is OK')
147

    
148
        rand_num = '%s%s' % (self.run_id or 0, random.randint(1000, 9999))
149
        grpName = 'grp%s' % rand_num
150

    
151
        u1, u2 = pithos.account, 'invalid-user-uuid-%s' % rand_num
152
        self.assertRaises(
153
            ClientError, pithos.set_account_group, grpName, [u1, u2])
154
        self.info('Invalid uuid is handled correctly')
155

    
156
        pithos.set_account_group(grpName, [u1])
157
        r = pithos.get_account_group()
158
        self.assertEqual(r['x-account-group-' + grpName], '%s' % u1)
159
        self.info('Account group is OK')
160
        pithos.del_account_group(grpName)
161
        r = pithos.get_account_group()
162
        self.assertTrue('x-account-group-' + grpName not in r)
163
        self.info('Removed account group')
164

    
165
        mprefix = 'meta%s' % rand_num
166
        pithos.set_account_meta({
167
            mprefix + '1': 'v1', mprefix + '2': 'v2'})
168
        r = pithos.get_account_meta()
169
        self.assertEqual(r['x-account-meta-' + mprefix + '1'], 'v1')
170
        self.assertEqual(r['x-account-meta-' + mprefix + '2'], 'v2')
171
        self.info('Account meta is OK')
172

    
173
        pithos.del_account_meta(mprefix + '1')
174
        r = pithos.get_account_meta()
175
        self.assertTrue('x-account-meta-' + mprefix + '1' not in r)
176
        self.assertTrue('x-account-meta-' + mprefix + '2' in r)
177
        self.info('Selective removal of account meta is OK')
178

    
179
        pithos.del_account_meta(mprefix + '2')
180
        r = pithos.get_account_meta()
181
        self.assertTrue('x-account-meta-' + mprefix + '2' not in r)
182
        self.info('Temporary account meta are removed')
183

    
184
    def test_020_container_head(self):
185
        """Test container HEAD"""
186
        pithos = self.clients.pithos
187
        r = pithos.container_head()
188
        self.assertEqual(r.status_code, 204)
189
        self.info('Status code is OK')
190

    
191
        r = pithos.container_head(until=1000000, success=(204, 404))
192
        self.assertEqual(r.status_code, 404)
193
        self.info('Until works')
194

    
195
        for format in pithos.DATE_FORMATS:
196
            now_formated = self.now_unformated.strftime(format)
197
            r1 = pithos.container_head(
198
                if_modified_since=now_formated, success=(204, 304, 412))
199
            r2 = pithos.container_head(
200
                if_unmodified_since=now_formated, success=(204, 304, 412))
201
            self.assertNotEqual(r1.status_code, r2.status_code)
202

    
203
        k = 'metakey%s' % random.randint(1000, 9999)
204
        pithos.set_container_meta({k: 'our value'})
205
        r = pithos.get_container_meta()
206
        k = 'x-container-meta-%s' % k
207
        self.assertIn(k, r)
208
        self.assertEqual('our value', r[k])
209
        self.info('Container meta exists')
210

    
211
        self.obj_metakey = 'metakey%s' % random.randint(1000, 9999)
212
        obj = 'object_with_meta'
213
        pithos.create_object(obj)
214
        pithos.set_object_meta(obj, {self.obj_metakey: 'our value'})
215
        r = pithos.get_container_object_meta()
216
        self.assertIn('x-container-object-meta', r)
217
        self.assertIn(
218
            self.obj_metakey, r['x-container-object-meta'].lower())
219
        self.info('Container object meta exists')
220

    
221
    def test_025_container_get(self):
222
        """Test container GET"""
223
        pithos = self.clients.pithos
224

    
225
        r = pithos.container_get()
226
        self.assertEqual(r.status_code, 200)
227
        self.info('Status code is OK')
228

    
229
        fullLen = len(r.json)
230
        self.assertGreater(fullLen, 0)
231
        self.info('There are enough (%s) containers' % fullLen)
232

    
233
        obj1 = 'test%s' % random.randint(1000, 9999)
234
        pithos.create_object(obj1)
235
        obj2 = 'test%s' % random.randint(1000, 9999)
236
        pithos.create_object(obj2)
237
        obj3 = 'another%s.test' % random.randint(1000, 9999)
238
        pithos.create_object(obj3)
239

    
240
        r = pithos.container_get(prefix='test')
241
        self.assertTrue(len(r.json) > 1)
242
        test_objects = [o for o in r.json if o['name'].startswith('test')]
243
        self.assertEqual(len(r.json), len(test_objects))
244
        self.info('Prefix is OK')
245

    
246
        r = pithos.container_get(limit=1)
247
        self.assertEqual(len(r.json), 1)
248
        self.info('Limit is OK')
249

    
250
        r = pithos.container_get(marker=obj3[:-5])
251
        self.assertTrue(len(r.json) > 1)
252
        aoobjects = [obj for obj in r.json if obj['name'] > obj3[:-5]]
253
        self.assertEqual(len(r.json), len(aoobjects))
254
        self.info('Marker is OK')
255

    
256
        r = pithos.container_get(prefix=obj3, delimiter='.')
257
        self.assertTrue(fullLen > len(r.json))
258
        self.info('Delimiter is OK')
259

    
260
        r = pithos.container_get(path='/')
261
        fullLen += 3
262
        self.assertEqual(fullLen, len(r.json))
263
        self.info('Path is OK')
264

    
265
        r = pithos.container_get(format='xml')
266
        self.assertEqual(r.text.split()[4], 'name="' + pithos.container + '">')
267
        self.info('Format is OK')
268

    
269
        r = pithos.container_get(meta=[self.obj_metakey, ])
270
        self.assertTrue(len(r.json) > 0)
271
        self.info('Meta is OK')
272

    
273
        r = pithos.container_get(show_only_shared=True)
274
        self.assertTrue(len(r.json) < fullLen)
275
        self.info('Show-only-shared is OK')
276

    
277
        try:
278
            r = pithos.container_get(until=1000000000)
279
            datestring = unicode(r.headers['x-account-until-timestamp'])
280
            self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring)
281
            self.info('Until is OK')
282
        except ClientError:
283
            pass
284

    
285
    def test_030_container_put(self):
286
        """Test container PUT"""
287
        pithos = self.clients.pithos
288
        pithos.container = 'cont%s%s' % (
289
            self.run_id or 0, random.randint(1000, 9999))
290
        self.temp_containers.append(pithos.container)
291

    
292
        r = pithos.create_container()
293
        self.assertTrue(isinstance(r, dict))
294

    
295
        r = pithos.get_container_limit(pithos.container)
296
        cquota = r.values()[0]
297
        newquota = 2 * int(cquota)
298
        self.info('Limit is OK')
299
        pithos.del_container()
300

    
301
        r = pithos.create_container(sizelimit=newquota)
302
        self.assertTrue(isinstance(r, dict))
303

    
304
        r = pithos.get_container_limit(pithos.container)
305
        xquota = int(r.values()[0])
306
        self.assertEqual(newquota, xquota)
307
        self.info('Can set container limit')
308
        pithos.del_container()
309

    
310
        r = pithos.create_container(versioning='auto')
311
        self.assertTrue(isinstance(r, dict))
312

    
313
        r = pithos.get_container_versioning(pithos.container)
314
        nvers = r.values()[0]
315
        self.assertEqual('auto', nvers)
316
        self.info('Versioning=auto is OK')
317
        pithos.del_container()
318

    
319
        r = pithos.container_put(versioning='none')
320
        self.assertEqual(r.status_code, 201)
321

    
322
        r = pithos.get_container_versioning(pithos.container)
323
        nvers = r.values()[0]
324
        self.assertEqual('none', nvers)
325
        self.info('Versioning=none is OK')
326
        pithos.del_container()
327

    
328
        r = pithos.create_container(metadata={'m1': 'v1', 'm2': 'v2'})
329
        self.assertTrue(isinstance(r, dict))
330

    
331
        r = pithos.get_container_meta(pithos.container)
332
        self.assertTrue('x-container-meta-m1' in r)
333
        self.assertEqual(r['x-container-meta-m1'], 'v1')
334
        self.assertTrue('x-container-meta-m2' in r)
335
        self.assertEqual(r['x-container-meta-m2'], 'v2')
336

    
337
        r = pithos.container_put(metadata={'m1': '', 'm2': 'v2a'})
338
        self.assertEqual(r.status_code, 202)
339

    
340
        r = pithos.get_container_meta(pithos.container)
341
        self.assertTrue('x-container-meta-m1' not in r)
342
        self.assertTrue('x-container-meta-m2' in r)
343
        self.assertEqual(r['x-container-meta-m2'], 'v2a')
344
        self.info('Container meta is OK')
345

    
346
        pithos.del_container_meta(pithos.container)
347

    
348
    def test_035_container_post(self):
349
        """Test container POST"""
350
        pithos = self.clients.pithos
351

    
352
        r = pithos.container_post()
353
        self.assertEqual(r.status_code, 202)
354
        self.info('Status is OK')
355

    
356
        pithos.set_container_meta({'m1': 'v1', 'm2': 'v2'})
357
        r = pithos.get_container_meta(pithos.container)
358
        self.assertTrue('x-container-meta-m1' in r)
359
        self.assertEqual(r['x-container-meta-m1'], 'v1')
360
        self.assertTrue('x-container-meta-m2' in r)
361
        self.assertEqual(r['x-container-meta-m2'], 'v2')
362
        self.info('Set metadata works')
363

    
364
        r = pithos.del_container_meta('m1')
365
        r = pithos.set_container_meta({'m2': 'v2a'})
366
        r = pithos.get_container_meta(pithos.container)
367
        self.assertTrue('x-container-meta-m1' not in r)
368
        self.assertTrue('x-container-meta-m2' in r)
369
        self.assertEqual(r['x-container-meta-m2'], 'v2a')
370
        self.info('Delete metadata works')
371

    
372
        r = pithos.get_container_limit(pithos.container)
373
        cquota = r.values()[0]
374
        newquota = 2 * int(cquota)
375
        r = pithos.set_container_limit(newquota)
376
        r = pithos.get_container_limit(pithos.container)
377
        xquota = int(r.values()[0])
378
        self.assertEqual(newquota, xquota)
379
        self.info('Set quota works')
380

    
381
        pithos.set_container_versioning('auto')
382
        r = pithos.get_container_versioning(pithos.container)
383
        nvers = r.values()[0]
384
        self.assertEqual('auto', nvers)
385
        pithos.set_container_versioning('none')
386
        r = pithos.get_container_versioning(pithos.container)
387
        nvers = r.values()[0]
388
        self.assertEqual('none', nvers)
389
        self.info('Set versioning works')
390

    
391
        f = self._create_large_file(1024 * 1024 * 100)
392
        self.large_file = f
393
        self.info('Created file %s of 100 MB' % f.name)
394

    
395
        pithos.create_directory('dir')
396
        self.info('Upload the file ...')
397
        r = pithos.upload_object('/dir/sample.file', f)
398
        for term in ('content-length', 'content-type', 'x-object-version'):
399
            self.assertTrue(term in r)
400
        r = pithos.get_object_info('/dir/sample.file')
401
        self.assertTrue(int(r['content-length']) > 100000000)
402
        self.info('Made remote directory /dir and object /dir/sample.file')
403

    
404
        """What is tranfer_encoding? What should I check about it? """
405
        #TODO
406

    
407
        obj = 'object_with_meta'
408
        pithos.container = self.temp_containers[-2]
409
        r = pithos.object_post(
410
            obj, update='False', metadata={'newmeta': 'newval'})
411

    
412
        r = pithos.get_object_info(obj)
413
        self.assertTrue('x-object-meta-newmeta' in r)
414
        self.assertFalse('x-object-meta-%s' % self.obj_metakey not in r)
415
        self.info('Metadata with update=False works')
416

    
417
    def test_040_container_delete(self):
418
        """Test container DELETE"""
419
        pithos = self.clients.pithos
420

    
421
        r = pithos.container_delete(success=409)
422
        self.assertEqual(r.status_code, 409)
423
        self.assertRaises(ClientError, pithos.container_delete)
424
        self.info('Successfully failed to delete non-empty container')
425

    
426
        r = pithos.container_delete(until='1000000000')
427
        self.assertEqual(r.status_code, 204)
428
        self.info('Successfully failed to delete old-timestamped container')
429

    
430
        obj_names = [o['name'] for o in pithos.container_get().json]
431
        pithos.del_container(delimiter='/')
432
        r = pithos.container_get()
433
        self.assertEqual(len(r.json), 0)
434
        self.info('Successfully emptied container')
435

    
436
        for obj in obj_names:
437
            r = pithos.get_object_versionlist(obj)
438
            self.assertTrue(len(r) > 0)
439
        self.info('Versions are still there')
440

    
441
        pithos.purge_container()
442
        for obj in obj_names:
443
            self.assertRaises(ClientError, pithos.get_object_versionlist, obj)
444
        self.info('Successfully purged container')
445

    
446
        self.temp_containers.remove(pithos.container)
447
        pithos.container = self.temp_containers[-1]
448

    
449
    def test_045_object_head(self):
450
        """Test object HEAD"""
451
        pithos = self.clients.pithos
452

    
453
        obj = 'dir/sample.file'
454
        r = pithos.object_head(obj)
455
        self.assertEqual(r.status_code, 200)
456
        self.info('Status code is OK')
457
        etag = r.headers['etag']
458
        real_version = r.headers['x-object-version']
459

    
460
        self.assertRaises(ClientError, pithos.object_head, obj, version=-10)
461
        r = pithos.object_head(obj, version=real_version)
462
        self.assertEqual(r.headers['x-object-version'], real_version)
463
        self.info('Version works')
464

    
465
        r = pithos.object_head(obj, if_etag_match=etag)
466
        self.assertEqual(r.status_code, 200)
467
        self.info('if-etag-match is OK')
468

    
469
        r = pithos.object_head(
470
            obj, if_etag_not_match=etag, success=(200, 412, 304))
471
        self.assertNotEqual(r.status_code, 200)
472
        self.info('if-etag-not-match works')
473

    
474
        r = pithos.object_head(
475
            obj, version=real_version, if_etag_match=etag, success=200)
476
        self.assertEqual(r.status_code, 200)
477
        self.info('Version with if-etag-match works')
478

    
479
        for format in pithos.DATE_FORMATS:
480
            now_formated = self.now_unformated.strftime(format)
481
            r1 = pithos.object_head(
482
                obj, if_modified_since=now_formated, success=(200, 304, 412))
483
            r2 = pithos.object_head(
484
                obj, if_unmodified_since=now_formated, success=(200, 304, 412))
485
            self.assertNotEqual(r1.status_code, r2.status_code)
486
        self.info('if-(un)modified-since works')
487

    
488
    def test_050_object_get(self):
489
        """Test object GET"""
490
        pithos = self.clients.pithos
491
        obj = 'dir/sample.file'
492

    
493
        r = pithos.object_get(obj)
494
        self.assertEqual(r.status_code, 200)
495
        self.info('Status code is OK')
496

    
497
        osize = int(r.headers['content-length'])
498
        etag = r.headers['etag']
499

    
500
        r = pithos.object_get(obj, hashmap=True)
501
        self.assertEqual(
502
            set(('hashes', 'block_size', 'block_hash', 'bytes')), set(r.json))
503
        self.info('Hashmap works')
504
        hash0 = r.json['hashes'][0]
505

    
506
        r = pithos.object_get(obj, format='xml', hashmap=True)
507
        self.assertTrue(r.text.split('hash>')[1].startswith(hash0))
508
        self.info('Hashmap with XML format works')
509

    
510
        rangestr = 'bytes=%s-%s' % (osize / 3, osize / 2)
511
        r = pithos.object_get(obj, data_range=rangestr, success=(200, 206))
512
        partsize = int(r.headers['content-length'])
513
        self.assertTrue(0 < partsize and partsize <= 1 + osize / 3)
514
        self.info('Range x-y works')
515
        orig = r.text
516

    
517
        rangestr = 'bytes=%s' % (osize / 3)
518
        r = pithos.object_get(
519
            obj, data_range=rangestr, if_range=True, success=(200, 206))
520
        partsize = int(r.headers['content-length'])
521
        self.assertTrue(partsize, 1 + (osize / 3))
522
        diff = set(r.text).symmetric_difference(set(orig[:partsize]))
523
        self.assertEqual(len(diff), 0)
524
        self.info('Range x works')
525

    
526
        rangestr = 'bytes=-%s' % (osize / 3)
527
        r = pithos.object_get(
528
            obj, data_range=rangestr, if_range=True, success=(200, 206))
529
        partsize = int(r.headers['content-length'])
530
        self.assertTrue(partsize, osize / 3)
531
        diff = set(r.text).symmetric_difference(set(orig[-partsize:]))
532
        self.assertEqual(len(diff), 0)
533
        self.info('Range -x works')
534

    
535
        r = pithos.object_get(obj, if_etag_match=etag)
536
        self.assertEqual(r.status_code, 200)
537
        self.info('if-etag-match works')
538

    
539
        r = pithos.object_get(obj, if_etag_not_match=etag + 'LALALA')
540
        self.assertEqual(r.status_code, 200)
541
        self.info('if-etag-not-match works')
542

    
543
        for format in pithos.DATE_FORMATS:
544
            now_formated = self.now_unformated.strftime(format)
545
            r1 = pithos.object_get(
546
                obj, if_modified_since=now_formated, success=(200, 304, 412))
547
            r2 = pithos.object_get(
548
                obj, if_unmodified_since=now_formated, success=(200, 304, 412))
549
            self.assertNotEqual(r1.status_code, r2.status_code)
550
        self.info('if(un)modified-since works')
551

    
552
        obj, dnl_f = 'dir/sample.file', NamedTemporaryFile()
553
        self.info('Download %s as %s ...' % (obj, dnl_f.name))
554
        pithos.download_object(obj, dnl_f)
555
        self.info('Download is completed')
556

    
557
        f_size = len(orig)
558
        for pos in (0, f_size / 2, f_size - 128):
559
            dnl_f.seek(pos)
560
            self.large_file.seek(pos)
561
            self.assertEqual(self.large_file.read(64), dnl_f.read(64))
562
        self.info('Sampling shows that files match')
563

    
564
        """Upload a boring file"""
565
        self.info('Create a boring file of 42 blocks...')
566
        bor_f = self._create_boring_file(42)
567
        trg_fname = 'dir/uploaded.file'
568
        self.info('Now, upload the boring file as %s...' % trg_fname)
569
        pithos.upload_object(trg_fname, bor_f)
570
        self.info('Boring file %s is uploaded as %s' % (bor_f.name, trg_fname))
571
        dnl_f = NamedTemporaryFile()
572
        self.info('Download boring file as %s' % dnl_f.name)
573
        pithos.download_object(trg_fname, dnl_f)
574
        self.info('File is downloaded')
575

    
576
        for i in range(42):
577
            self.assertEqual(sample_block(bor_f, i), sample_block(dnl_f, i))
578

    
579
    def test_150_stop_test(self):
580
        """STOP TESTING ALREADY"""
581
        self.assertTrue(False)
582

    
583
    def test_152_unique_containers(self):
584
        """Test if containers have unique names"""
585
        names = [n['name'] for n in self.containers]
586
        names = sorted(names)
587
        self.assertEqual(sorted(list(set(names))), names)
588

    
589
    @classmethod
590
    def tearDownClass(cls):  # noqa
591
        """Clean up"""
592
        from kamaki.cli.logger import deactivate
593
        deactivate('kamaki.clients.send')
594
        deactivate('kamaki.clients.recv')
595
        pithos = cls.clients.pithos
596
        for c in getattr(cls, 'temp_containers', []):
597
            pithos.container = c
598
            try:
599
                pithos.del_container(delimiter='/')
600
                pithos.purge_container(c)
601
            except ClientError as ce:
602
                print ('Failed to destroy container (%s)' % ce)