Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (18.4 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 os
40
import random
41
import tempfile
42
from datetime import datetime
43

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

    
47

    
48
# Too many public methods. pylint: disable-msg=R0904
49
class PithosTestSuite(BurninTests):
50
    """Test Pithos functionality"""
51
    containers = Proper(value=None)
52
    created_container = Proper(value=None)
53
    now_unformated = Proper(value=datetime.utcnow())
54
    obj_metakey = Proper(value=None)
55

    
56
    def test_005_account_head(self):
57
        """HEAD on pithos account"""
58
        self._set_pithos_account(self._get_uuid())
59
        pithos = self.clients.pithos
60
        r = pithos.account_head()
61
        self.assertEqual(r.status_code, 204)
62
        self.info('Returns 204')
63

    
64
        r = pithos.account_head(until='1000000000')
65
        self.assertEqual(r.status_code, 204)
66
        datestring = unicode(r.headers['x-account-until-timestamp'])
67
        self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring)
68
        self.assertTrue('x-account-policy-quota' in r.headers)
69
        self.info('Until and policy quota exist')
70

    
71
        for format in pithos.DATE_FORMATS:
72
            now_formated = self.now_unformated.strftime(format)
73
            r1 = pithos.account_head(
74
                if_modified_since=now_formated, success=(204, 304, 412))
75
            r2 = pithos.account_head(
76
                if_unmodified_since=now_formated, success=(204, 304, 412))
77
            self.assertNotEqual(r1.status_code, r2.status_code)
78
        self.info('If_(un)modified_since is OK')
79

    
80
    def test_010_account_get(self):
81
        """Test account_get"""
82
        self.info('Preparation')
83
        pithos = self.clients.pithos
84
        for i in range(1, 3):
85
            cont_name = "cont%s_%s%s" % (
86
                i, self.run_id or 0, random.randint(1000, 9999))
87
            self._create_pithos_container(cont_name)
88
        pithos.container, obj = cont_name, 'shared_file'
89
        pithos.create_object(obj)
90
        pithos.set_object_sharing(obj, read_permission='*')
91
        self.info('Created object /%s/%s' % (cont_name, obj))
92

    
93
        r = pithos.list_containers()
94
        fullLen = len(r)
95
        self.assertTrue(fullLen > 2)
96
        self.info('Normal use is OK')
97

    
98
        r = pithos.account_get(limit=1)
99
        self.assertEqual(len(r.json), 1)
100
        self.info('Limit works')
101

    
102
        r = pithos.account_get(marker='cont')
103
        cont1, cont3 = r.json[0], r.json[2]
104
        self.info('Marker works')
105

    
106
        r = pithos.account_get(limit=2, marker='cont')
107
        conames = [container['name'] for container in r.json if (
108
            container['name'].lower().startswith('cont'))]
109
        self.assertTrue(cont1['name'] in conames)
110
        self.assertFalse(cont3['name'] in conames)
111
        self.info('Marker-limit combination works')
112

    
113
        r = pithos.account_get(show_only_shared=True)
114
        self.assertTrue(cont_name in [c['name'] for c in r.json])
115
        self.info('Show-only-shared works')
116

    
117
        r = pithos.account_get(until=1342609206.0)
118
        self.assertTrue(len(r.json) <= fullLen)
119
        self.info('Until works')
120

    
121
        for format in pithos.DATE_FORMATS:
122
            now_formated = self.now_unformated.strftime(format)
123
            r1 = pithos.account_get(
124
                if_modified_since=now_formated, success=(200, 304, 412))
125
            r2 = pithos.account_get(
126
                if_unmodified_since=now_formated, success=(200, 304, 412))
127
            self.assertNotEqual(r1.status_code, r2.status_code)
128
        self.info('If_(un)modified_since is OK')
129

    
130
    def test_015_account_post(self):
131
        """Test account_post"""
132
        pithos = self.clients.pithos
133
        r = pithos.account_post()
134
        self.assertEqual(r.status_code, 202)
135
        self.info('Status code is OK')
136

    
137
        rand_num = '%s%s' % (self.run_id or 0, random.randint(1000, 9999))
138
        grpName = 'grp%s' % rand_num
139

    
140
        u1, u2 = pithos.account, 'invalid-user-uuid-%s' % rand_num
141
        self.assertRaises(
142
            ClientError, pithos.set_account_group, grpName, [u1, u2])
143
        self.info('Invalid uuid is handled correctly')
144

    
145
        pithos.set_account_group(grpName, [u1])
146
        r = pithos.get_account_group()
147
        self.assertEqual(r['x-account-group-' + grpName], '%s' % u1)
148
        self.info('Account group is OK')
149
        pithos.del_account_group(grpName)
150
        r = pithos.get_account_group()
151
        self.assertTrue('x-account-group-' + grpName not in r)
152
        self.info('Removed account group')
153

    
154
        mprefix = 'meta%s' % rand_num
155
        pithos.set_account_meta({
156
            mprefix + '1': 'v1', mprefix + '2': 'v2'})
157
        r = pithos.get_account_meta()
158
        self.assertEqual(r['x-account-meta-' + mprefix + '1'], 'v1')
159
        self.assertEqual(r['x-account-meta-' + mprefix + '2'], 'v2')
160
        self.info('Account meta is OK')
161

    
162
        pithos.del_account_meta(mprefix + '1')
163
        r = pithos.get_account_meta()
164
        self.assertTrue('x-account-meta-' + mprefix + '1' not in r)
165
        self.assertTrue('x-account-meta-' + mprefix + '2' in r)
166
        self.info('Selective removal of account meta is OK')
167

    
168
        pithos.del_account_meta(mprefix + '2')
169
        r = pithos.get_account_meta()
170
        self.assertTrue('x-account-meta-' + mprefix + '2' not in r)
171
        self.info('Temporary account meta are removed')
172

    
173
    def test_020_container_head(self):
174
        """Test container HEAD"""
175
        pithos = self.clients.pithos
176
        r = pithos.container_head()
177
        self.assertEqual(r.status_code, 204)
178
        self.info('Status code is OK')
179

    
180
        r = pithos.container_head(until=1000000, success=(204, 404))
181
        self.assertEqual(r.status_code, 404)
182
        self.info('Until works')
183

    
184
        for format in pithos.DATE_FORMATS:
185
            now_formated = self.now_unformated.strftime(format)
186
            r1 = pithos.container_head(
187
                if_modified_since=now_formated, success=(204, 304, 412))
188
            r2 = pithos.container_head(
189
                if_unmodified_since=now_formated, success=(204, 304, 412))
190
            self.assertNotEqual(r1.status_code, r2.status_code)
191

    
192
        k = 'metakey%s' % random.randint(1000, 9999)
193
        pithos.set_container_meta({k: 'our value'})
194
        r = pithos.get_container_meta()
195
        k = 'x-container-meta-%s' % k
196
        self.assertIn(k, r)
197
        self.assertEqual('our value', r[k])
198
        self.info('Container meta exists')
199

    
200
        self.obj_metakey = 'metakey%s' % random.randint(1000, 9999)
201
        obj = 'object_with_meta'
202
        pithos.create_object(obj)
203
        pithos.set_object_meta(obj, {self.obj_metakey: 'our value'})
204
        r = pithos.get_container_object_meta()
205
        self.assertIn('x-container-object-meta', r)
206
        self.assertIn(
207
            self.obj_metakey, r['x-container-object-meta'].lower())
208
        self.info('Container object meta exists')
209

    
210
    def test_025_container_get(self):
211
        """Test container GET"""
212
        pithos = self.clients.pithos
213

    
214
        r = pithos.container_get()
215
        self.assertEqual(r.status_code, 200)
216
        self.info('Status code is OK')
217

    
218
        fullLen = len(r.json)
219
        obj1 = 'test%s' % random.randint(1000, 9999)
220
        pithos.create_object(obj1)
221
        obj2 = 'test%s' % random.randint(1000, 9999)
222
        pithos.create_object(obj2)
223
        obj3 = 'another%s.test' % random.randint(1000, 9999)
224
        pithos.create_object(obj3)
225

    
226
        r = pithos.container_get(prefix='test')
227
        self.assertTrue(len(r.json) > 1)
228
        test_objects = [o for o in r.json if o['name'].startswith('test')]
229
        self.assertEqual(len(r.json), len(test_objects))
230
        self.info('Prefix is OK')
231

    
232
        r = pithos.container_get(limit=1)
233
        self.assertEqual(len(r.json), 1)
234
        self.info('Limit is OK')
235

    
236
        r = pithos.container_get(marker=obj3[:-5])
237
        self.assertTrue(len(r.json) > 1)
238
        aoobjects = [obj for obj in r.json if obj['name'] > obj3[:-5]]
239
        self.assertEqual(len(r.json), len(aoobjects))
240
        self.info('Marker is OK')
241

    
242
        r = pithos.container_get(prefix=obj3, delimiter='.')
243
        self.assertTrue(fullLen > len(r.json))
244
        self.info('Delimiter is OK')
245

    
246
        r = pithos.container_get(path='/')
247
        fullLen += 3
248
        self.assertEqual(fullLen, len(r.json))
249
        self.info('Path is OK')
250

    
251
        r = pithos.container_get(format='xml')
252
        self.assertEqual(r.text.split()[4], 'name="' + pithos.container + '">')
253
        self.info('Format is OK')
254

    
255
        r = pithos.container_get(meta=[self.obj_metakey, ])
256
        self.assertTrue(len(r.json) > 0)
257
        self.info('Meta is OK')
258

    
259
        r = pithos.container_get(show_only_shared=True)
260
        self.assertTrue(len(r.json) < fullLen)
261
        self.info('Show-only-shared is OK')
262

    
263
        try:
264
            r = pithos.container_get(until=1000000000)
265
            datestring = unicode(r.headers['x-account-until-timestamp'])
266
            self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring)
267
            self.info('Until is OK')
268
        except ClientError:
269
            pass
270

    
271
    def test_030_container_put(self):
272
        """Test container PUT"""
273
        pithos = self.clients.pithos
274
        pithos.container = 'cont%s%s' % (
275
            self.run_id or 0, random.randint(1000, 9999))
276
        self.temp_containers.append(pithos.container)
277

    
278
        r = pithos.create_container()
279
        self.assertTrue(isinstance(r, dict))
280

    
281
        r = pithos.get_container_limit(pithos.container)
282
        cquota = r.values()[0]
283
        newquota = 2 * int(cquota)
284
        self.info('Limit is OK')
285
        pithos.del_container()
286

    
287
        r = pithos.create_container(sizelimit=newquota)
288
        self.assertTrue(isinstance(r, dict))
289

    
290
        r = pithos.get_container_limit(pithos.container)
291
        xquota = int(r.values()[0])
292
        self.assertEqual(newquota, xquota)
293
        self.info('Can set container limit')
294
        pithos.del_container()
295

    
296
        r = pithos.create_container(versioning='auto')
297
        self.assertTrue(isinstance(r, dict))
298

    
299
        r = pithos.get_container_versioning(pithos.container)
300
        nvers = r.values()[0]
301
        self.assertEqual('auto', nvers)
302
        self.info('Versioning=auto is OK')
303
        pithos.del_container()
304

    
305
        r = pithos.container_put(versioning='none')
306
        self.assertEqual(r.status_code, 201)
307

    
308
        r = pithos.get_container_versioning(pithos.container)
309
        nvers = r.values()[0]
310
        self.assertEqual('none', nvers)
311
        self.info('Versioning=none is OK')
312
        pithos.del_container()
313

    
314
        r = pithos.create_container(metadata={'m1': 'v1', 'm2': 'v2'})
315
        self.assertTrue(isinstance(r, dict))
316

    
317
        r = pithos.get_container_meta(pithos.container)
318
        self.assertTrue('x-container-meta-m1' in r)
319
        self.assertEqual(r['x-container-meta-m1'], 'v1')
320
        self.assertTrue('x-container-meta-m2' in r)
321
        self.assertEqual(r['x-container-meta-m2'], 'v2')
322

    
323
        r = pithos.container_put(metadata={'m1': '', 'm2': 'v2a'})
324
        self.assertEqual(r.status_code, 202)
325

    
326
        r = pithos.get_container_meta(pithos.container)
327
        self.assertTrue('x-container-meta-m1' not in r)
328
        self.assertTrue('x-container-meta-m2' in r)
329
        self.assertEqual(r['x-container-meta-m2'], 'v2a')
330
        self.info('Container meta is OK')
331

    
332
        pithos.del_container_meta(pithos.container)
333

    
334
    def test_035_container_post(self):
335
        """Test container POST"""
336
        pithos = self.clients.pithos
337

    
338
        r = pithos.container_post()
339
        self.assertEqual(r.status_code, 202)
340
        self.info('Status is OK')
341

    
342
        pithos.set_container_meta({'m1': 'v1', 'm2': 'v2'})
343
        r = pithos.get_container_meta(pithos.container)
344
        self.assertTrue('x-container-meta-m1' in r)
345
        self.assertEqual(r['x-container-meta-m1'], 'v1')
346
        self.assertTrue('x-container-meta-m2' in r)
347
        self.assertEqual(r['x-container-meta-m2'], 'v2')
348
        self.info('Set metadata works')
349

    
350
        r = pithos.del_container_meta('m1')
351
        r = pithos.set_container_meta({'m2': 'v2a'})
352
        r = pithos.get_container_meta(pithos.container)
353
        self.assertTrue('x-container-meta-m1' not in r)
354
        self.assertTrue('x-container-meta-m2' in r)
355
        self.assertEqual(r['x-container-meta-m2'], 'v2a')
356
        self.info('Delete metadata works')
357

    
358
        r = pithos.get_container_limit(pithos.container)
359
        cquota = r.values()[0]
360
        newquota = 2 * int(cquota)
361
        r = pithos.set_container_limit(newquota)
362
        r = pithos.get_container_limit(pithos.container)
363
        xquota = int(r.values()[0])
364
        self.assertEqual(newquota, xquota)
365
        self.info('Set quota works')
366

    
367
        pithos.set_container_versioning('auto')
368
        r = pithos.get_container_versioning(pithos.container)
369
        nvers = r.values()[0]
370
        self.assertEqual('auto', nvers)
371
        pithos.set_container_versioning('none')
372
        r = pithos.get_container_versioning(pithos.container)
373
        nvers = r.values()[0]
374
        self.assertEqual('none', nvers)
375
        self.info('Set versioning works')
376

    
377
        f = self._create_large_file(1024 * 1024 * 100)
378
        self.info('Created file %s of 100 MB' % f.name)
379

    
380
        pithos.create_directory('dir')
381
        r = pithos.upload_object('/dir/sample.file', f)
382
        for term in ('content-length', 'content-type', 'x-object-version'):
383
            self.assertTrue(term in r)
384
        r = pithos.get_object_info('/dir/sample.file')
385
        self.assertTrue(int(r['content-length']) > 100000000)
386
        self.info('Made remote directory /dir and object /dir/sample.file')
387

    
388
        """What is tranfer_encoding? What should I check about it? """
389
        #TODO
390

    
391
        obj = 'object_with_meta'
392
        pithos.container = self.temp_containers[-2]
393
        r = pithos.object_post(
394
            obj, update='False', metadata={'newmeta': 'newval'})
395

    
396
        r = pithos.get_object_info(obj)
397
        self.assertTrue('x-object-meta-newmeta' in r)
398
        self.assertFalse('x-object-meta-%s' % self.obj_metakey not in r)
399
        self.info('Metadata with update=False works')
400

    
401
    def test_050_stop_test(self):
402
        """STOP TESTING ALREADY"""
403
        self.assertTrue(False)
404

    
405
    def test_051_list_containers(self):
406
        """Test container list actually returns containers"""
407
        self.containers = self._get_list_of_containers()
408
        self.assertGreater(len(self.containers), 0)
409
        self.lala = 1
410

    
411
    def test_052_unique_containers(self):
412
        """Test if containers have unique names"""
413
        names = [n['name'] for n in self.containers]
414
        names = sorted(names)
415
        self.assertEqual(sorted(list(set(names))), names)
416

    
417
    def test_054_upload_file(self):
418
        """Test uploading a txt file to Pithos"""
419
        # Create a tmp file
420
        with tempfile.TemporaryFile(dir=self.temp_directory) as fout:
421
            fout.write("This is a temp file")
422
            fout.seek(0, 0)
423
            # Upload the file,
424
            # The container is the one choosen during the `create_container'
425
            self.clients.pithos.upload_object("test.txt", fout)
426
            # Verify quotas
427
            self._check_quotas(diskspace=+os.fstat(fout.fileno()).st_size)
428

    
429
    def test_055_download_file(self):
430
        """Test downloading the file from Pithos"""
431
        # Create a tmp directory to save the file
432
        with tempfile.TemporaryFile(dir=self.temp_directory) as fout:
433
            self.clients.pithos.download_object("test.txt", fout)
434
            # Now read the file
435
            fout.seek(0, 0)
436
            contents = fout.read()
437
            # Compare results
438
            self.info("Comparing contents with the uploaded file")
439
            self.assertEqual(contents, "This is a temp file")
440

    
441
    def test_056_remove(self):
442
        """Test removing files and containers from Pithos"""
443
        self.info("Removing the file %s from container %s",
444
                  "test.txt", self.created_container)
445
        # The container is the one choosen during the `create_container'
446
        content_length = \
447
            self.clients.pithos.get_object_info("test.txt")['content-length']
448
        self.clients.pithos.del_object("test.txt")
449

    
450
        # Verify quotas
451
        self._check_quotas(diskspace=-int(content_length))
452

    
453
        self.info("Removing the container %s", self.created_container)
454
        self.clients.pithos.purge_container()
455

    
456
        # List containers
457
        containers = self._get_list_of_containers()
458
        self.info("Check that the container %s has been deleted",
459
                  self.created_container)
460
        names = [n['name'] for n in containers]
461
        self.assertNotIn(self.created_container, names)
462
        # We successfully deleted our container, no need to do it
463
        # in our clean up phase
464
        self.created_container = None
465

    
466
    @classmethod
467
    def tearDownClass(cls):  # noqa
468
        """Clean up"""
469
        from kamaki.cli.logger import deactivate
470
        deactivate('kamaki.clients.send')
471
        deactivate('kamaki.clients.recv')
472
        pithos = cls.clients.pithos
473
        for c in getattr(cls, 'temp_containers', []):
474
            pithos.container = c
475
            try:
476
                pithos.del_container(delimiter='/')
477
                pithos.purge_container(c)
478
            except ClientError as ce:
479
                print ('Failed to destroy container (%s)' % ce)