Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (14.5 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%s' % random.randint(1000, 9999)
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_050_stop_test(self):
272
        """STOP TESTING ALREADY"""
273
        self.assertTrue(False)
274

    
275
    def test_051_list_containers(self):
276
        """Test container list actually returns containers"""
277
        self.containers = self._get_list_of_containers()
278
        self.assertGreater(len(self.containers), 0)
279
        self.lala = 1
280

    
281
    def test_052_unique_containers(self):
282
        """Test if containers have unique names"""
283
        names = [n['name'] for n in self.containers]
284
        names = sorted(names)
285
        self.assertEqual(sorted(list(set(names))), names)
286

    
287
    def test_053_create_container(self):
288
        """Test creating a new container"""
289
        names = [n['name'] for n in self.containers]
290
        while True:
291
            rand_num = random.randint(1000, 9999)
292
            rand_name = "%s%s" % (self.run_id or 0, rand_num)
293
            self.info("Trying container name %s", rand_name)
294
            if rand_name not in names:
295
                break
296
            self.info("Container name %s already exists", rand_name)
297
        # Create container
298
        self._create_pithos_container(rand_name)
299
        # Verify that container is created
300
        containers = self._get_list_of_containers()
301
        self.info("Verify that container %s is created", rand_name)
302
        names = [n['name'] for n in containers]
303
        self.assertIn(rand_name, names)
304
        # Keep the name of the container so we can remove it
305
        # at cleanup phase, if something goes wrong.
306
        self.created_container = rand_name
307

    
308
    def test_054_upload_file(self):
309
        """Test uploading a txt file to Pithos"""
310
        # Create a tmp file
311
        with tempfile.TemporaryFile(dir=self.temp_directory) as fout:
312
            fout.write("This is a temp file")
313
            fout.seek(0, 0)
314
            # Upload the file,
315
            # The container is the one choosen during the `create_container'
316
            self.clients.pithos.upload_object("test.txt", fout)
317
            # Verify quotas
318
            self._check_quotas(diskspace=+os.fstat(fout.fileno()).st_size)
319

    
320
    def test_055_download_file(self):
321
        """Test downloading the file from Pithos"""
322
        # Create a tmp directory to save the file
323
        with tempfile.TemporaryFile(dir=self.temp_directory) as fout:
324
            self.clients.pithos.download_object("test.txt", fout)
325
            # Now read the file
326
            fout.seek(0, 0)
327
            contents = fout.read()
328
            # Compare results
329
            self.info("Comparing contents with the uploaded file")
330
            self.assertEqual(contents, "This is a temp file")
331

    
332
    def test_056_remove(self):
333
        """Test removing files and containers from Pithos"""
334
        self.info("Removing the file %s from container %s",
335
                  "test.txt", self.created_container)
336
        # The container is the one choosen during the `create_container'
337
        content_length = \
338
            self.clients.pithos.get_object_info("test.txt")['content-length']
339
        self.clients.pithos.del_object("test.txt")
340

    
341
        # Verify quotas
342
        self._check_quotas(diskspace=-int(content_length))
343

    
344
        self.info("Removing the container %s", self.created_container)
345
        self.clients.pithos.purge_container()
346

    
347
        # List containers
348
        containers = self._get_list_of_containers()
349
        self.info("Check that the container %s has been deleted",
350
                  self.created_container)
351
        names = [n['name'] for n in containers]
352
        self.assertNotIn(self.created_container, names)
353
        # We successfully deleted our container, no need to do it
354
        # in our clean up phase
355
        self.created_container = None
356

    
357
    @classmethod
358
    def tearDownClass(cls):  # noqa
359
        """Clean up"""
360
        from kamaki.cli.logger import deactivate
361
        deactivate('kamaki.clients.send')
362
        deactivate('kamaki.clients.recv')
363
        pithos = cls.clients.pithos
364
        for c in getattr(cls, 'temp_containers', []):
365
            pithos.container = c
366
            try:
367
                pithos.del_container(delimiter='/')
368
                pithos.purge_container(c)
369
            except ClientError as ce:
370
                print ('Failed to destroy container (%s)' % ce)