Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / tests.py @ 9f74ca46

History | View | Annotate | Download (21.9 kB)

1
# Copyright 2011 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 unittest
35
import time
36
import os
37

    
38
from kamaki.clients import pithos, cyclades
39

    
40
class testPithos(unittest.TestCase):
41
    def setUp(self):
42
        url = 'http://127.0.0.1:8000/v1'
43
        token = 'C/yBXmz3XjTFBnujc2biAg=='
44
        token = 'ac0yH8cQMEZu3M3Mp1MWGA=='
45
        account = 'admin@adminland.com'
46
        container=None
47
        self.client = pithos(url, token, account, container)
48
        self.now = time.mktime(time.gmtime())
49

    
50
    def test_account_head(self):
51
        r = self.client.account_head()
52
        self.assertEqual(r.status_code, 204)
53
        r = self.client.account_head(until='1000000000')
54
        self.assertEqual(r.status_code, 204)
55
        datestring = unicode(r.headers['x-account-until-timestamp'])
56
        self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring)
57
        self.client.reset_headers()
58
        r = self.client.account_head(if_modified_since=self.now)
59
        self.client.reset_headers()
60
        r = self.client.account_head(if_unmodified_since=10000)
61
        self.client.reset_headers()
62

    
63
    def test_account_get(self):
64
        r = self.client.account_get()
65
        self.assertEqual(r.status_code, 200)
66
        fullLen = len(r.json)
67
        self.assertEqual(fullLen, 3)
68

    
69
        r = self.client.account_get(limit=1)
70
        self.assertEqual(len(r.json), 1)
71

    
72
        r = self.client.account_get(limit=3, marker='test')
73
        self.assertNotEqual(len(r.json), 0)
74
        conames = [container['name'] for container in r.json if container['name'].lower().startswith('test')]
75
        self.assertEqual(len(conames), len(r.json))
76
        self.client.reset_headers()
77

    
78
        r = self.client.account_get(show_only_shared=True)
79
        self.assertEqual(len(r.json), 2)
80
        self.client.reset_headers()
81

    
82
        r = self.client.account_get(until=1342609206)
83
        self.assertTrue(len(r.json) < fullLen)
84
        self.client.reset_headers()
85

    
86
        """Missing Full testing for if_modified_since, if_unmodified_since
87
        """
88
        r = self.client.account_head(if_modified_since=self.now)
89
        self.client.reset_headers()
90
        r = self.client.account_head(if_unmodified_since=10000)
91
        self.client.reset_headers()
92

    
93
    def test_account_post(self):
94
        r = self.client.account_post()
95
        self.assertEqual(r.status_code, 202)
96
        grpName = 'tstgrp'
97

    
98
        """Method set/del_account_meta and set_account_groupcall account_post internally
99
        """
100
        self.client.set_account_group(grpName, ['u1', 'u2'])
101
        r = self.client.get_account_group()
102
        self.assertEqual(r['x-account-group-'+grpName], 'u1,u2')
103
        self.client.del_account_group(grpName)
104
        r = self.client.get_account_group()
105
        self.assertTrue(not r.has_key('x-account-group-grpName'))
106
        self.client.reset_headers()
107

    
108
        self.client.set_account_meta({'metatest1':'v1', 'metatest2':'v2'})
109
        r = self.client.get_account_meta()
110
        self.assertEqual(r['x-account-meta-metatest1'], 'v1')
111
        self.assertEqual(r['x-account-meta-metatest2'], 'v2')
112
        self.client.reset_headers()
113

    
114
        self.client.del_account_meta('metatest1')
115
        r = self.client.get_account_meta()
116
        self.assertTrue(not r.has_key('x-account-meta-metatest1'))
117
        self.client.reset_headers()
118

    
119
        self.client.del_account_meta('metatest2')
120
        r = self.client.get_account_meta()
121
        self.assertTrue(not r.has_key('x-account-meta-metatest2'))
122
        self.client.reset_headers()
123

    
124
        """Missing testing for quota, versioning, because normally
125
        you don't have permitions for modified those at account level
126
        """
127

    
128
    def test_container_head(self):
129
        self.client.container = 'testCo'
130

    
131
        r = self.client.account_head()
132
        self.assertEqual(r.status_code, 204)
133

    
134
        r = self.client.account_head(until=1000000000)
135
        datestring = unicode(r.headers['x-account-until-timestamp'])
136
        self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring)
137

    
138
        r = self.client.account_head(if_modified_since=1342609206)
139
        self.client.reset_headers()
140
        r = self.client.account_head(if_unmodified_since=1342609206)
141
        self.client.reset_headers()
142
        self.client.container = ''
143

    
144
    def test_container_get(self):
145
        self.client.container = 'testCo'
146

    
147
        r = self.client.container_get()
148
        self.assertEqual(r.status_code, 200)
149
        fullLen = len(r.json)
150

    
151
        r = self.client.container_get(prefix='lal')
152
        lalobjects = [obj for obj in r.json if obj['name'].startswith('lal')]
153
        self.assertTrue(len(r.json) > 1)
154
        self.assertEqual(len(r.json), len(lalobjects))
155
        self.client.reset_headers()
156

    
157
        r = self.client.container_get(limit=1)
158
        self.assertEqual(len(r.json), 1)
159
        self.client.reset_headers()
160

    
161
        r = self.client.container_get(marker='neo')
162
        self.assertTrue(len(r.json) > 1)
163
        neobjects = [obj for obj in r.json if obj['name'] > 'neo']
164
        self.assertEqual(len(r.json), len(neobjects))
165
        self.client.reset_headers()
166

    
167
        r = self.client.container_get(prefix='testDir/testDir', delimiter='2')
168
        self.assertTrue(fullLen > len(r.json))
169
        self.client.reset_headers()
170

    
171
        r = self.client.container_get(path='testDir/testDir2')
172
        self.assertTrue(fullLen > len(r.json))
173
        self.client.reset_headers()
174

    
175
        r = self.client.container_get(format='xml')
176
        self.assertEqual(r.text.split()[4], 'name="testCo">')
177
        self.client.reset_headers()
178

    
179
        r = self.client.container_get(meta=['Lalakis'])
180
        self.assertEqual(len(r.json), 1)
181
        self.client.reset_headers()
182

    
183
        r = self.client.container_get(show_only_shared=True)
184
        self.assertTrue(len(r.json) < fullLen)
185
        self.client.reset_headers()
186

    
187
        try:
188
            r = self.client.container_get(until=1000000000)
189
            datestring = unicode(r.headers['x-account-until-timestamp'])
190
            self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring)
191
        except:#Normally, container wasn't created in that date...
192
            pass
193
        self.client.reset_headers()
194

    
195
        """Missing Full testing for if_modified_since, if_unmodified_since
196
        """
197
        now = time.mktime(time.gmtime())
198
        r = self.client.container_get(if_modified_since=now)
199
        r = self.client.container_get(if_unmodified_since=now)
200

    
201
        self.container = ''
202
        self.client.reset_headers()
203
       
204
    def test_container_put(self):
205
        self.client.container = 'testCo'
206

    
207
        r = self.client.container_put()
208
        self.assertEqual(r.status_code, 202)
209

    
210
        r = self.client.get_container_quota(self.client.container)
211
        cquota = r.values()[0]
212
        newquota = 2*int(cquota)
213
        self.client.reset_headers()
214

    
215
        r = self.client.container_put(quota=newquota)
216
        self.assertEqual(r.status_code, 202)
217
        r = self.client.get_container_quota(self.client.container)
218
        xquota = int(r.values()[0])
219
        self.assertEqual(newquota, xquota)
220
        self.client.reset_headers()
221

    
222
        r = self.client.container_put(versioning='auto')
223
        self.assertEqual(r.status_code, 202)
224
        r = self.client.get_container_versioning(self.client.container)
225
        nvers = r.values()[0]
226
        self.assertEqual('auto', nvers)
227
        self.client.reset_headers()
228

    
229
        r = self.client.container_put(versioning='none')
230
        self.assertEqual(r.status_code, 202)
231
        r = self.client.get_container_versioning(self.client.container)
232
        nvers = r.values()[0]
233
        self.assertEqual('none', nvers)
234
        self.client.reset_headers()
235

    
236
        r = self.client.container_put(metadata={'m1':'v1', 'm2':'v2'})
237
        self.assertEqual(r.status_code, 202)
238
        r = self.client.get_container_meta(self.client.container)
239
        self.assertTrue(r.has_key('x-container-meta-m1'))
240
        self.assertEqual(r['x-container-meta-m1'], 'v1')
241
        self.assertTrue(r.has_key('x-container-meta-m2'))
242
        self.assertEqual(r['x-container-meta-m2'], 'v2')
243
        self.client.reset_headers()
244

    
245
        r = self.client.container_put(metadata={'m1':'', 'm2':'v2a'})
246
        self.assertEqual(r.status_code, 202)
247
        r = self.client.get_container_meta(self.client.container)
248
        self.assertTrue(not r.has_key('x-container-meta-m1'))
249
        self.assertTrue(r.has_key('x-container-meta-m2'))
250
        self.assertEqual(r['x-container-meta-m2'], 'v2a')
251
        self.client.reset_headers()
252
       
253
        self.client.del_container_meta(self.client.container) 
254
        self.client.container_put(quota=cquota)
255
        self.client.container = ''
256
        self.client.reset_headers()
257

    
258
    def test_container_post(self):
259
        self.client.container = 'testCo0'
260

    
261
        r = self.client.container_post()
262
        self.assertEqual(r.status_code, 202)
263

    
264
        self.client.set_container_meta({'m1':'v1', 'm2':'v2'})
265
        r = self.client.get_container_meta(self.client.container)
266
        self.assertTrue(r.has_key('x-container-meta-m1'))
267
        self.assertEqual(r['x-container-meta-m1'], 'v1')
268
        self.assertTrue(r.has_key('x-container-meta-m2'))
269
        self.assertEqual(r['x-container-meta-m2'], 'v2')
270
        self.client.reset_headers()
271

    
272
        r = self.client.del_container_meta('m1')
273
        r = self.client.set_container_meta({'m2':'v2a'})
274
        r = self.client.get_container_meta(self.client.container)
275
        self.assertTrue(not r.has_key('x-container-meta-m1'))
276
        self.assertTrue(r.has_key('x-container-meta-m2'))
277
        self.assertEqual(r['x-container-meta-m2'], 'v2a')
278
        self.client.reset_headers()
279

    
280
        r = self.client.get_container_quota(self.client.container)
281
        cquota = r.values()[0]
282
        newquota = 2*int(cquota)
283
        self.client.reset_headers()
284

    
285
        r = self.client.set_container_quota(newquota)
286
        r = self.client.get_container_quota(self.client.container)
287
        xquota = int(r.values()[0])
288
        self.assertEqual(newquota, xquota)
289
        self.client.reset_headers()
290

    
291
        r = self.client.set_container_quota(cquota)
292
        r = self.client.get_container_quota(self.client.container)
293
        xquota = r.values()[0]
294
        self.assertEqual(cquota, xquota)
295
        self.client.reset_headers()
296

    
297
        self.client.set_container_versioning('auto')
298
        r = self.client.get_container_versioning(self.client.container)
299
        nvers = r.values()[0]
300
        self.assertEqual('auto', nvers)
301
        self.client.reset_headers()
302

    
303
        self.client.set_container_versioning('none')
304
        r = self.client.get_container_versioning(self.client.container)
305
        nvers = r.values()[0]
306
        self.assertEqual('none', nvers)
307
        self.client.reset_headers()
308

    
309
        """Haven't figured out how to test put_block, which
310
        uses content_type and content_length to post blocks
311
        of data to container. But how do you check that
312
        the blocks are there?"""
313

    
314
        """WTF is tranfer_encoding? What should I check about th** s**t? """
315
        r = self.client.container_post(update=True, transfer_encoding='xlm')
316
        self.client.reset_headers()
317

    
318
        """This last part doesnt seem to work"""
319
        """self.client.container_post(update=False)"""
320
        """so we do it the wrong way"""
321
        r = self.client.del_container_meta('m2')
322
        self.client.container = ''
323
        self.client.reset_headers()
324

    
325
    def test_container_delete(self):
326
        container = 'testCo'+unicode(self.now)
327
        self.client.container = container
328

    
329
        """Create new container"""
330
        r = self.client.container_put()
331
        self.assertEqual(r.status_code, 201)
332
        self.client.reset_headers()
333

    
334
        """Fail to delete a non-empty container"""
335
        self.client.container = 'testCo'
336
        r = self.client.container_delete(success=409)
337
        self.assertEqual(r.status_code, 409)
338
        self.client.reset_headers()
339

    
340
        """Fail to delete this container"""
341
        self.client.container = container
342
        r = self.client.container_delete(until='1000000000')
343
        self.assertEqual(r.status_code, 204)
344
        self.client.reset_headers()
345

    
346
        """Delete this container"""
347
        r = self.client.container_delete()
348
        self.assertEqual(r.status_code, 204)
349

    
350
        self.client.container = ''
351
        self.client.reset_headers()
352

    
353
    def test_object_head(self):
354
        self.client.container = 'testCo0'
355
        obj = 'lolens'
356

    
357
        r = self.client.object_head(obj)
358
        self.assertEqual(r.status_code, 200)
359
        etag = r.headers['etag']
360

    
361
        r = self.client.object_head(obj, version=40)
362
        self.assertEqual(r.status_code, 200)
363
        self.client.reset_headers()
364

    
365
        r = self.client.object_head(obj, if_etag_match=etag)
366
        self.assertEqual(r.status_code, 200)
367
        """I believe if_etag_not_match does not work..."""
368
        self.client.reset_headers()
369

    
370
        r = self.client.object_head(obj, version=40, if_etag_match=etag, success=412)
371
        self.assertEqual(r.status_code, 412)
372
        self.client.reset_headers()
373

    
374
        """I believe if_un/modified_since does not work..."""
375
        r=self.client.object_head(obj, if_modified_since=self.now)
376
        self.assertEqual(r.status_code, 200)
377
        self.client.reset_headers()
378

    
379
        r=self.client.object_head(obj, if_unmodified_since=self.now)
380
        self.assertEqual(r.status_code, 200)
381

    
382
        self.client.container = ''
383
        self.client.reset_headers()
384

    
385
    def test_object_get(self):
386
        self.client.container = 'testCo'
387

    
388
        r = self.client.object_get('lolens')
389
        self.assertEqual(r.status_code, 200)
390
        osize = int(r.headers['content-length'])
391
        etag = r.headers['etag']
392

    
393
        r = self.client.object_get('lolens', hashmap=True)
394
        self.assertTrue(r.json.has_key('hashes') \
395
            and r.json.has_key('block_hash') \
396
            and r.json.has_key('block_size') \
397
            and r.json.has_key('bytes'))
398

    
399
        r = self.client.object_get('lolens', format='xml', hashmap=True)
400
        self.assertEqual(len(r.text.split('hash>')), 3)
401
        self.client.reset_headers()
402

    
403
        rangestr = 'bytes=%s-%s'%(osize/3, osize/2)
404
        r = self.client.object_get('lolens', data_range=rangestr, success=(200, 206))
405
        partsize = int(r.headers['content-length'])
406
        self.assertTrue(0 < partsize and partsize <= 1+osize/3)
407
        self.client.reset_headers()
408

    
409
        rangestr = 'bytes=%s-%s'%(osize/3, osize/2)
410
        r = self.client.object_get('lolens', data_range=rangestr, if_range=True, success=(200, 206))
411
        partsize = int(r.headers['content-length'])
412
        self.assertTrue(0 < partsize and partsize <= 1+osize/3)
413
        self.client.reset_headers()
414

    
415
        r = self.client.object_get('lolens', if_etag_match=etag)
416
        self.assertEqual(r.status_code, 200)
417
        self.client.reset_headers()
418

    
419
        r = self.client.object_get('lolens', if_etag_not_match=etag+'LALALA')
420
        self.assertEqual(r.status_code, 200)
421

    
422
        """I believe if_un/modified_since does not work..."""
423
        r=self.client.object_get('lolens', if_modified_since=self.now)
424
        self.assertEqual(r.status_code, 200)
425
        self.client.reset_headers()
426

    
427
        r=self.client.object_get('lolens', if_unmodified_since=self.now)
428
        self.assertEqual(r.status_code, 200)
429

    
430
        self.client.container = ''
431
        self.client.reset_headers()
432

    
433
    def test_object_put(self):
434
        self.client.container = 'testCo0'
435
        obj='obj'+unicode(self.now)
436

    
437
        r = self.client.object_put(obj, data='a', content_type='application/octer-stream',
438
            permitions={'read':['accX:groupA', 'u1', 'u2'], 'write':['u2', 'u3']},
439
            metadata={'key1':'val1', 'key2':'val2'})
440
        self.assertEqual(r.status_code, 201)
441
        self.client.reset_headers()
442

    
443
        r = self.client.object_get(obj)
444
        """Check permitions"""
445
        perms = r.headers['x-object-sharing']
446
        self.assertTrue(perms.index('u1') < perms.index('write') < perms.index('u2'))
447
        """Check metadata"""
448
        self.assertTrue(r.headers.has_key('x-object-meta-key1'))
449
        self.assertEqual(r.headers['x-object-meta-key1'], 'val1')
450
        self.assertTrue(r.headers.has_key('x-object-meta-key2'))
451
        self.assertEqual(r.headers['x-object-meta-key2'], 'val2')
452
        vers1 = int(r.headers['x-object-version'])
453
        self.assertEqual(r.headers['content-length'], '1')
454
        etag = r.headers['etag']
455
        self.client.reset_headers()
456

    
457
        r = self.client.object_put(obj, if_etag_match=etag, data='b',
458
            content_type='application/octet-stream', public=True)
459
        self.client.reset_headers()
460
        r = self.client.object_get(obj)
461
        """Check public"""
462
        self.assertTrue(r.headers.has_key('x-object-public'))
463
        vers2 = int(r.headers['x-object-version'])
464
        etag = r.headers['etag']
465
        self.assertEqual(r.text, 'b')
466
        self.client.reset_headers()
467

    
468
        r = self.client.object_put(obj, if_etag_not_match=etag, data='c', content_type='application/octet-stream', success=(201, 412))
469
        self.assertEqual(r.status_code, 412)
470
        self.client.reset_headers()
471

    
472
        tmpdir = 'dir'+unicode(self.now)
473
        r = self.client.object_put(tmpdir, content_type='application/directory', content_length=0)
474
        self.client.reset_headers()
475
        r = self.client.object_get(tmpdir)
476
        self.assertEqual(r.headers['content-type'], 'application/directory')
477
        self.client.reset_headers()
478

    
479
        r = self.client.object_put('%s/%s'%(tmpdir, obj), format=None, 
480
            copy_from='/%s/%s'%(self.client.container, obj),
481
            content_encoding='application/octet-stream', 
482
            source_account='admin@adminland.com', 
483
            content_length=0, success=201)
484
        self.assertEqual(r.status_code, 201)
485
        self.client.reset_headers()
486

    
487
        self.client.container = 'testCo'
488
        fromstr = '/testCo0/'+tmpdir+'/'+obj
489
        r = self.client.object_put(obj, format=None, copy_from=fromstr,
490
            content_encoding='application/octet-stream', 
491
            source_account='admin@adminland.com', 
492
            content_length=0, success=201)
493
        self.assertEqual(r.status_code, 201)
494
        self.client.reset_headers()
495
        r = self.client.object_get(obj)
496
        self.assertEqual(r.headers['etag'], etag)
497
        self.client.reset_headers()
498

    
499
        self.client.container = 'testCo0'
500
        fromstr = '/testCo/'+obj
501
        r = self.client.object_put(obj+'v2', format=None, move_from=fromstr,
502
            content_encoding='application/octet-stream', 
503
            source_account='nonExistendAddress@NeverLand.com', 
504
            content_length=0, success=(201, 403))
505
        self.assertEqual(r.status_code, 403)
506
        self.client.reset_headers()
507

    
508
        r = self.client.object_put(obj+'v0', format=None, 
509
            move_from='/testCo/'+obj, 
510
            content_encoding='application/octet-stream', 
511
            content_length=0, success=201)
512
        self.assertEqual(r.status_code, 201)
513
        self.client.reset_headers()
514
        r = self.client.object_get(obj+'v0')
515
        self.assertEqual(r.headers['etag'], etag)
516
        self.client.reset_headers()
517

    
518
        r = self.client.object_put(obj+'v1', format=None, 
519
            move_from='/testCo0/'+obj,
520
            source_version = vers2,
521
            content_encoding='application/octet-stream',
522
            content_length=0, success=201)
523
        self.client.reset_headers()
524

    
525
        """Some problems with transfer-encoding?
526
        Content_disposition? manifest?"""
527

    
528
        self.client.delete_object(tmpdir+'/'+obj)
529
        self.client.delete_object(tmpdir)
530
        self.client.delete_object(obj+'v1')
531
        self.client.delete_object(obj+'v0')
532
        self.client.container = ''
533
        self.client.reset_headers()
534

    
535
class testCyclades(unittest.TestCase):
536
    def setUp(self):
537
        pass
538

    
539
    def test_list_servers(self):
540
        pass
541

    
542
def suite():
543
    suite = unittest.TestSuite()
544
    suite.addTest(unittest.makeSuite(testPithos))
545
    #suite.addTest(unittest.makeSuite(testCyclades))
546
    return suite
547

    
548
if __name__ == '__main__':
549
    suiteFew = unittest.TestSuite()
550

    
551
    #kamaki/pithos.py
552
    suiteFew.addTest(testPithos('test_account_head'))
553
    suiteFew.addTest(testPithos('test_account_get'))
554
    suiteFew.addTest(testPithos('test_account_post'))
555
    suiteFew.addTest(testPithos('test_container_head'))
556
    suiteFew.addTest(testPithos('test_container_get'))
557
    suiteFew.addTest(testPithos('test_container_put'))
558
    suiteFew.addTest(testPithos('test_container_post'))
559
    suiteFew.addTest(testPithos('test_container_delete'))
560
    suiteFew.addTest(testPithos('test_object_head'))
561
    suiteFew.addTest(testPithos('test_object_get'))
562
    suiteFew.addTest(testPithos('test_object_put'))
563

    
564
    #kamaki/cyclades.py
565
    #suiteFew.addTest(testCyclades('test_list_servers'))
566

    
567
    unittest.TextTestRunner(verbosity = 2).run(suite())