1 # Copyright 2011 GRNET S.A. All rights reserved.
3 # Redistribution and use in source and binary forms, with or
4 # without modification, are permitted provided that the following
7 # 1. Redistributions of source code must retain the above
8 # copyright notice, this list of conditions and the following
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.
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.
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.
35 #Monkey-patch everything for gevent early on
36 gevent.monkey.patch_all()
38 from argparse import ArgumentParser
40 import time, datetime, os, sys
41 from shutil import copyfile
43 from kamaki.clients import ClientError
44 from kamaki.clients.pithos import PithosClient as pithos
45 from kamaki.clients.cyclades import CycladesClient as cyclades
49 class testCyclades(unittest.TestCase):
50 """Set up a Cyclades thorough test"""
53 url='https://cyclades.okeanos.grnet.gr/api/v1.1'
54 token='MI6PT0yrXJ9Ji/x8l9Wmig=='
55 account='saxtouri@gmail.com'
56 self.img = '1395fdfb-51b4-419f-bb02-f7d632860611'
59 #url = 'https://cyclades.okeanos.io/api/v1.1'
60 #token='0TpoyAXqJSPxLdDuZHiLOA=='
61 #account='saxtouri@admin.grnet.gr'
62 #self.img = '43cc8497-61c3-4c46-ae8d-3e33861f8527'
64 # u'status': u'ACTIVE',
65 # u'updated': u'2012-08-21T12:57:39+00:00',
66 # u'name': u'Debian Base',
67 # u'created': u'2012-08-21T12:56:53+00:00',
69 # u'id': u'43cc8497-61c3-4c46-ae8d-3e33861f8527',
72 # u'kernel': u'2.6.32',
73 # u'osfamily': u'linux',
79 # u'1', u'description':
80 # u'Debian Squeeze Base System'}
86 self.now = time.mktime(time.gmtime())
87 self.servname1 = 'serv'+unicode(self.now)
88 self.servname2 = self.servname1+'_v2'
90 #servers have to be created at the begining...
92 self.client = cyclades(url, token)
96 """Destoy servers used in testing"""
97 if 0 >= len(self.servers):
99 there_are_servers_running = True
103 print('-> Found %s servers to delete'%len(self.servers))
104 while there_are_servers_running:
105 there_are_servers_running = False
107 c = ['|','/','-','\\']
109 sys.stdout.write('\t. . . wait %s seconds: '%waitime)
110 for i in range(4*waitime):
112 suffix = '%ss %s'%(i/4, c[i%4])
113 sys.stdout.write(oldlen*'\b'+suffix)
116 oldlen = len(': '+suffix)
117 print(oldlen*'\b'+oldlen*' ')
120 dservers = self.client.list_servers(detail=True)
121 for server in dservers:
122 if server['name'] in self.servers.keys():
123 there_are_servers_running = True
124 sys.stdout.write('\t%s status:%s '%(server['name'], server['status']))
125 if server['status'] == 'BUILD':
128 print('\tDELETE %s'%server['name'])
129 self._delete_server(server['id'])
130 self.servers.pop(server['name'])
131 deleted_servers[server['name']] = 0
133 elif server['name'] in deleted_servers.keys():
134 there_are_servers_running = True
135 sys.stdout.write('\t%s status:%s '%(server['name'], server['status']))
136 retries = deleted_servers[server['name']]
138 print('\tretry DELETE %s'%server['name'])
139 self._delete_server(server['id'])
143 print('\tnot deleted yet ...')
144 deleted_servers[server['name']] = retries + 1
146 def _create_server(self, servername, flavorid, imageid, personality=None):
147 server = self.client.create_server(servername, flavorid, imageid, personality)
148 self.servers[servername] = server
151 def _delete_server(self, servid):
152 self.client.delete_server(servid)
160 def assert_dicts_are_deeply_equal(self, d1, d2):
161 for k,v in d1.items():
162 self.assertTrue(d2.has_key(k))
163 if isinstance(v, dict):
164 self.assert_dicts_are_deeply_equal(v, d2[k])
166 self.assertEqual(unicode(v), unicode(d2[k]))
170 "Prepare a full Cyclades test scenario"
174 self.server1 = self._create_server(self.servname1, self.flavorid, self.img)
175 self.server2 = self._create_server(self.servname2, self.flavorid, self.img)
178 sys.stdout.write(' test create server')
179 self._test_create_server()
182 sys.stdout.write(' test list servers')
183 self._test_list_servers()
186 sys.stdout.write(' test get server details')
187 self._test_get_server_details()
190 sys.stdout.write(' test get image details')
191 self._test_get_image_details()
195 def test_list_servers(self):
196 """Test list servers"""
199 self.server1 = self._create_server(self.servname1, self.flavorid, self.img)
200 self.server2 = self._create_server(self.servname2, self.flavorid, self.img)
201 self._test_list_servers()
203 def _test_list_servers(self):
204 servers = self.client.list_servers()
205 dservers = self.client.list_servers(detail=True)
207 """detailed and simple are same size"""
208 self.assertEqual(len(dservers), len(servers))
209 for i in range(len(servers)):
210 for field in ['created', 'flavorRef', 'hostId', 'imageRef', 'progress',
211 'status', 'updated']:
212 self.assertFalse(servers[i].has_key(field))
213 self.assertTrue(dservers[i].has_key(field))
215 """detailed and simple contain same names"""
216 names = sorted(map(lambda x: x["name"], servers))
217 dnames = sorted(map(lambda x: x["name"], dservers))
218 self.assertEqual(names, dnames)
220 def test_create_server(self):
221 """Test create_server"""
224 self.server1 = self._create_server(self.servname1, self.flavorid, self.img)
225 self._test_create_server()
227 def _test_create_server(self):
228 self.assertEqual(self.server1["name"], self.servname1)
229 self.assertEqual(self.server1["flavorRef"], self.flavorid)
230 self.assertEqual(self.server1["imageRef"], self.img)
231 self.assertEqual(self.server1["status"], "BUILD")
233 def test_get_server_details(self):
234 """Test get_server_details"""
237 self.server1 = self._create_server(self.servname1, self.flavorid, self.img)
238 self._test_get_server_details()
240 def _test_get_server_details(self):
241 r = self.client.get_server_details(self.server1['id'])
242 self.assertEqual(r["name"], self.servname1)
243 self.assertEqual(r["flavorRef"], self.flavorid)
244 self.assertEqual(r["imageRef"], self.img)
245 self.assertEqual(r["status"], "BUILD")
247 def test_get_image_details(self):
248 """Test get_image_details"""
251 self._test_get_image_details()
253 def _test_get_image_details(self):
254 r = self.client.get_image_details(self.img)
256 self.assert_dicts_are_deeply_equal(r, d)
258 class testPithos(unittest.TestCase):
259 """Set up a Pithos+ thorough test"""
262 url = 'http://127.0.0.1:8000/v1'
263 token = 'C/yBXmz3XjTFBnujc2biAg=='
264 token = 'ac0yH8cQMEZu3M3Mp1MWGA=='
265 account = 'admin@adminland.com'
268 url='https://pithos.okeanos.grnet.gr/v1'
270 token='Kn+G9dfmlPLR2WFnhfBOow=='
271 account='saxtouri@grnet.gr'
274 url='https://pithos.okeanos.io/v1'
275 token='0TpoyAXqJSPxLdDuZHiLOA=='
276 account='saxtouri@admin.grnet.gr'
280 def add_handler(name, level, prefix=''):
281 h = logging.StreamHandler()
282 fmt = logging.Formatter(prefix + '%(message)s')
284 logger = logging.getLogger(name)
286 logger.setLevel(level)
288 sendlog = logging.getLogger('clients.send')
289 recvlog = logging.getLogger('clients.recv')
290 add_handler('requests', logging.INFO, prefix='* ')
291 add_handler('clients.send', logging.INFO, prefix='> ')
292 add_handler('clients.recv', logging.INFO, prefix='< ')
297 self.client = pithos(url, token, account, container)
298 self.now = time.mktime(time.gmtime())
299 self.c1 = 'c1_'+unicode(self.now)
300 self.c2 = 'c2_'+unicode(self.now)
301 self.c3 = 'c3_'+unicode(self.now)
304 self.client.create_container(self.c1)
305 self.client.create_container(self.c2)
306 self.client.create_container(self.c3)
307 self.makeNewObject(self.c1, 'test')
308 self.makeNewObject(self.c2, 'test')
309 self.now_unformated = datetime.datetime.utcnow()
310 self.makeNewObject(self.c1, 'test1')
311 self.makeNewObject(self.c2, 'test1')
312 """Prepare an object to be shared - also its container"""
313 self.client.container = self.c1
314 r = self.client.object_post('test', update=True, permitions={'read':'someUser'})
316 self.makeNewObject(self.c1, 'another.test')
318 def makeNewObject(self, container, obj):
319 self.client.container = container
320 r = self.client.object_put(obj, content_type='application/octet-stream',
321 data= 'file '+obj+' that lives in '+container,
322 metadata={'incontainer':container})
324 def forceDeleteContainer(self, container):
325 self.client.container = container
327 r = self.client.list_objects()
332 self.client.del_object(name)
333 r = self.client.container_delete()
337 """Destroy test cases"""
338 if self.fname is not None:
340 os.remove(self.fname)
344 self.forceDeleteContainer(self.c1)
345 self.forceDeleteContainer(self.c2)
347 self.forceDeleteContainer(self.c3)
350 self.client.container=''
353 """Perform a full Pithos+ kamaki support test"""
355 def test_account_head(self):
356 """Test account_HEAD"""
357 r = self.client.account_head()
358 self.assertEqual(r.status_code, 204)
360 r = self.client.account_head(until='1000000000')
361 self.assertEqual(r.status_code, 204)
363 r = self.client.get_account_info(until='1000000000')
364 datestring = unicode(r['x-account-until-timestamp'])
365 self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring)
367 r = self.client.get_account_quota()
368 self.assertTrue(r.has_key('x-account-policy-quota'))
370 r = self.client.get_account_versioning()
371 self.assertTrue(r.has_key('x-account-policy-versioning'))
373 """Check if(un)modified_since"""
374 for format in self.client.DATE_FORMATS:
375 now_formated = self.now_unformated.strftime(format)
376 r1 = self.client.account_head(if_modified_since=now_formated, success=(204, 304, 412))
379 r2 = self.client.account_head(if_unmodified_since=now_formated, success=(204, 304, 412))
382 self.assertNotEqual(sc1, sc2)
384 def test_account_get(self):
385 """Test account_GET"""
386 #r = self.client.account_get()
387 #self.assertEqual(r.status_code, 200)
388 r = self.client.list_containers()
390 self.assertTrue(fullLen > 2)
392 r = self.client.account_get(limit=1)
393 self.assertEqual(len(r.json), 1)
396 r = self.client.account_get(marker='c2_')
397 temp_c0 = r.json[0]['name']
398 temp_c2 = r.json[2]['name']
400 r = self.client.account_get(limit=2, marker='c2_')
401 conames = [container['name'] for container in r.json \
402 if container['name'].lower().startswith('c2_')]
403 self.assertTrue(temp_c0 in conames)
404 self.assertFalse(temp_c2 in conames)
407 r = self.client.account_get(show_only_shared=True)
408 self.assertTrue(self.c1 in [c['name'] for c in r.json])
410 r = self.client.account_get(until=1342609206)
411 self.assertTrue(len(r.json) <= fullLen)
413 """Check if(un)modified_since"""
414 for format in self.client.DATE_FORMATS:
415 now_formated = self.now_unformated.strftime(format)
416 r1 = self.client.account_get(if_modified_since=now_formated, success=(200, 304, 412))
419 r2 = self.client.account_get(if_unmodified_since=now_formated, success=(200, 304, 412))
422 self.assertNotEqual(sc1, sc2)
424 """Check sharing_accounts"""
425 r = self.client.get_sharing_accounts()
426 self.assertTrue(len(r)>0)
428 def test_account_post(self):
429 """Test account_POST"""
430 r = self.client.account_post()
431 self.assertEqual(r.status_code, 202)
432 grpName = 'grp'+unicode(self.now)
435 """Method set/del_account_meta and set_account_groupcall use account_post internally
437 self.client.set_account_group(grpName, ['u1', 'u2'])
438 r = self.client.get_account_group()
439 self.assertEqual(r['x-account-group-'+grpName], 'u1,u2')
440 self.client.del_account_group(grpName)
441 r = self.client.get_account_group()
442 self.assertTrue(not r.has_key('x-account-group-'+grpName))
444 mprefix = 'meta'+unicode(self.now)
445 self.client.set_account_meta({mprefix+'1':'v1', mprefix+'2':'v2'})
446 r = self.client.get_account_meta()
447 self.assertEqual(r['x-account-meta-'+mprefix+'1'], 'v1')
448 self.assertEqual(r['x-account-meta-'+mprefix+'2'], 'v2')
450 self.client.del_account_meta(mprefix+'1')
451 r = self.client.get_account_meta()
452 self.assertTrue(not r.has_key('x-account-meta-'+mprefix+'1'))
454 self.client.del_account_meta(mprefix+'2')
455 r = self.client.get_account_meta()
456 self.assertTrue(not r.has_key('x-account-meta-'+mprefix+'2'))
458 """Missing testing for quota, versioning, because normally
459 you don't have permitions to modify those at account level
463 self.client.set_account_quota(newquota)
464 #r = self.client.get_account_info()
466 #r = self.client.get_account_quota()
467 #self.assertEqual(r['x-account-policy-quota'], newquota)
468 self.client.set_account_versioning('auto')
470 def test_container_head(self):
471 """Test container_HEAD"""
472 self.client.container = self.c1
474 r = self.client.container_head()
475 self.assertEqual(r.status_code, 204)
478 r = self.client.container_head(until=1000000, success=(204, 404))
479 self.assertEqual(r.status_code, 404)
481 """Check and if(un)modified_since"""
482 for format in self.client.DATE_FORMATS:
483 now_formated = self.now_unformated.strftime(format)
484 r1 = self.client.container_head(if_modified_since=now_formated, success=(204, 304, 412))
487 r2 = self.client.container_head(if_unmodified_since=now_formated, success=(204, 304, 412))
490 self.assertNotEqual(sc1, sc2)
492 """Check container object meta"""
493 r = self.client.get_container_object_meta()
494 self.assertEqual(r['x-container-object-meta'], 'Incontainer')
496 def test_container_get(self):
497 """Test container_GET"""
498 self.client.container = self.c1
500 r = self.client.container_get()
501 self.assertEqual(r.status_code, 200)
502 fullLen = len(r.json)
505 r = self.client.container_get(prefix='test')
506 lalobjects = [obj for obj in r.json if obj['name'].startswith('test')]
507 self.assertTrue(len(r.json) > 1)
508 self.assertEqual(len(r.json), len(lalobjects))
511 r = self.client.container_get(limit=1)
512 self.assertEqual(len(r.json), 1)
515 r = self.client.container_get(marker='another')
516 self.assertTrue(len(r.json) > 1)
517 neobjects = [obj for obj in r.json if obj['name'] > 'another']
518 self.assertEqual(len(r.json), len(neobjects))
521 r = self.client.container_get(prefix='another.test', delimiter='.')
522 self.assertTrue(fullLen > len(r.json))
525 r = self.client.container_get(path='/')
526 self.assertEqual(fullLen, len(r.json))
529 r = self.client.container_get(format='xml')
530 self.assertEqual(r.text.split()[4], 'name="'+self.c1+'">')
533 r = self.client.container_get(meta=['incontainer'])
534 self.assertTrue(len(r.json) > 0)
537 r = self.client.container_get(show_only_shared=True)
538 self.assertTrue(len(r.json) < fullLen)
542 r = self.client.container_get(until=1000000000)
543 datestring = unicode(r.headers['x-account-until-timestamp'])
544 self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring)
550 """Check and if un/modified_since"""
551 for format in self.client.DATE_FORMATS:
552 now_formated = self.now_unformated.strftime(format)
553 r1 = self.client.container_get(if_modified_since=now_formated, success=(200, 304, 412))
556 r2 = self.client.container_get(if_unmodified_since=now_formated, success=(200, 304, 412))
559 self.assertNotEqual(sc1, sc2)
561 def test_container_put(self):
562 """Test container_PUT"""
563 self.client.container = self.c2
565 r = self.client.container_put()
566 self.assertEqual(r.status_code, 202)
569 r = self.client.get_container_quota(self.client.container)
570 cquota = r.values()[0]
571 newquota = 2*int(cquota)
573 r = self.client.container_put(quota=newquota)
574 self.assertEqual(r.status_code, 202)
576 r = self.client.get_container_quota(self.client.container)
577 xquota = int(r.values()[0])
578 self.assertEqual(newquota, xquota)
580 r = self.client.container_put(versioning='auto')
581 self.assertEqual(r.status_code, 202)
583 r = self.client.get_container_versioning(self.client.container)
584 nvers = r.values()[0]
585 self.assertEqual('auto', nvers)
587 r = self.client.container_put(versioning='none')
588 self.assertEqual(r.status_code, 202)
590 r = self.client.get_container_versioning(self.client.container)
591 nvers = r.values()[0]
592 self.assertEqual('none', nvers)
594 r = self.client.container_put(metadata={'m1':'v1', 'm2':'v2'})
595 self.assertEqual(r.status_code, 202)
597 r = self.client.get_container_meta(self.client.container)
598 self.assertTrue(r.has_key('x-container-meta-m1'))
599 self.assertEqual(r['x-container-meta-m1'], 'v1')
600 self.assertTrue(r.has_key('x-container-meta-m2'))
601 self.assertEqual(r['x-container-meta-m2'], 'v2')
603 r = self.client.container_put(metadata={'m1':'', 'm2':'v2a'})
604 self.assertEqual(r.status_code, 202)
606 r = self.client.get_container_meta(self.client.container)
607 self.assertTrue(not r.has_key('x-container-meta-m1'))
608 self.assertTrue(r.has_key('x-container-meta-m2'))
609 self.assertEqual(r['x-container-meta-m2'], 'v2a')
611 self.client.del_container_meta(self.client.container)
613 def test_container_post(self):
614 """Test container_POST"""
615 self.client.container = self.c2
618 r = self.client.container_post()
619 self.assertEqual(r.status_code, 202)
623 self.client.set_container_meta({'m1':'v1', 'm2':'v2'})
624 r = self.client.get_container_meta(self.client.container)
625 self.assertTrue(r.has_key('x-container-meta-m1'))
626 self.assertEqual(r['x-container-meta-m1'], 'v1')
627 self.assertTrue(r.has_key('x-container-meta-m2'))
628 self.assertEqual(r['x-container-meta-m2'], 'v2')
631 r = self.client.del_container_meta('m1')
632 r = self.client.set_container_meta({'m2':'v2a'})
633 r = self.client.get_container_meta(self.client.container)
634 self.assertTrue(not r.has_key('x-container-meta-m1'))
635 self.assertTrue(r.has_key('x-container-meta-m2'))
636 self.assertEqual(r['x-container-meta-m2'], 'v2a')
639 r = self.client.get_container_quota(self.client.container)
640 cquota = r.values()[0]
641 newquota = 2*int(cquota)
642 r = self.client.set_container_quota(newquota)
643 r = self.client.get_container_quota(self.client.container)
644 xquota = int(r.values()[0])
645 self.assertEqual(newquota, xquota)
646 r = self.client.set_container_quota(cquota)
647 r = self.client.get_container_quota(self.client.container)
648 xquota = r.values()[0]
649 self.assertEqual(cquota, xquota)
651 """Check versioning"""
652 self.client.set_container_versioning('auto')
653 r = self.client.get_container_versioning(self.client.container)
654 nvers = r.values()[0]
655 self.assertEqual('auto', nvers)
656 self.client.set_container_versioning('none')
657 r = self.client.get_container_versioning(self.client.container)
658 nvers = r.values()[0]
659 self.assertEqual('none', nvers)
661 """put_block uses content_type and content_length to
662 post blocks of data 2 container. All that in upload_object"""
663 """Change a file at fs"""
664 self.create_large_file(1024*1024*100, 'l100M.'+unicode(self.now))
665 """Upload it at a directory in container"""
666 self.client.create_directory('dir')
667 newf = open(self.fname, 'r')
668 self.client.upload_object('/dir/sample.file', newf)
670 """Check if file has been uploaded"""
671 r = self.client.get_object_info('/dir/sample.file')
672 self.assertTrue(int(r['content-length']) > 100000000)
674 """WTF is tranfer_encoding? What should I check about th** s**t? """
677 """Check update=False"""
678 r = self.client.object_post('test', update=False, metadata={'newmeta':'newval'})
680 r = self.client.get_object_info('test')
681 self.assertTrue(r.has_key('x-object-meta-newmeta'))
682 self.assertFalse(r.has_key('x-object-meta-incontainer'))
684 r = self.client.del_container_meta('m2')
686 def test_container_delete(self):
687 """Test container_DELETE"""
689 """Fail to delete a non-empty container"""
690 self.client.container = self.c2
691 r = self.client.container_delete(success=409)
692 self.assertEqual(r.status_code, 409)
695 """Fail to delete c3 (empty) container"""
696 self.client.container = self.c3
697 r = self.client.container_delete(until='1000000000')
698 self.assertEqual(r.status_code, 204)
701 """Delete c3 (empty) container"""
702 r = self.client.container_delete()
703 self.assertEqual(r.status_code, 204)
705 """Purge container(empty a container), check versionlist"""
706 self.client.container = self.c1
707 r = self.client.object_head('test', success=(200, 404))
708 self.assertEqual(r.status_code, 200)
709 self.client.del_container(delimiter='/')
710 r = self.client.object_head('test', success=(200, 404))
711 self.assertEqual(r.status_code, 404)
712 r = self.client.get_object_versionlist('test')
713 self.assertTrue(len(r) > 0)
714 self.assertTrue(len(r[0])>1)
715 self.client.purge_container()
716 self.assertRaises(ClientError, self.client.get_object_versionlist, 'test')
718 def test_object_head(self):
719 """Test object_HEAD"""
720 self.client.container = self.c2
723 r = self.client.object_head(obj)
724 self.assertEqual(r.status_code, 200)
725 etag = r.headers['etag']
728 r = self.client.object_head(obj, version=40)
729 self.assertEqual(r.headers['x-object-version'], '40')
732 r = self.client.object_head(obj, if_etag_match=etag)
733 self.assertEqual(r.status_code, 200)
735 r = self.client.object_head(obj, if_etag_not_match=etag, success=(200, 412, 304))
736 self.assertNotEqual(r.status_code, 200)
739 r = self.client.object_head(obj, version=40, if_etag_match=etag, success=412)
740 self.assertEqual(r.status_code, 412)
743 """Check and if(un)modified_since"""
744 for format in self.client.DATE_FORMATS:
745 now_formated = self.now_unformated.strftime(format)
746 r1 = self.client.object_head(obj, if_modified_since=now_formated,
747 success=(200, 304, 412))
750 r2 = self.client.object_head(obj, if_unmodified_since=now_formated,
751 success=(200, 304, 412))
754 self.assertNotEqual(sc1, sc2)
756 def test_object_get(self):
757 """Test object_GET"""
758 self.client.container = self.c1
761 r = self.client.object_get(obj)
762 self.assertEqual(r.status_code, 200)
764 osize = int(r.headers['content-length'])
765 etag = r.headers['etag']
768 r = self.client.object_get(obj, hashmap=True)
769 self.assertTrue(r.json.has_key('hashes') \
770 and r.json.has_key('block_hash') \
771 and r.json.has_key('block_size') \
772 and r.json.has_key('bytes'))
775 r = self.client.object_get(obj, format='xml', hashmap=True)
776 self.assertEqual(len(r.text.split('hash>')), 3)
779 rangestr = 'bytes=%s-%s'%(osize/3, osize/2)
780 r = self.client.object_get(obj, data_range=rangestr, success=(200, 206))
781 partsize = int(r.headers['content-length'])
782 self.assertTrue(0 < partsize and partsize <= 1+osize/3)
785 rangestr = 'bytes=%s-%s'%(osize/3, osize/2)
786 r = self.client.object_get(obj, data_range=rangestr, if_range=True, success=(200, 206))
787 partsize = int(r.headers['content-length'])
788 self.assertTrue(0 < partsize and partsize <= 1+osize/3)
791 r = self.client.object_get(obj, if_etag_match=etag)
792 self.assertEqual(r.status_code, 200)
795 r = self.client.object_get(obj, if_etag_not_match=etag+'LALALA')
796 self.assertEqual(r.status_code, 200)
799 """Check and if(un)modified_since"""
800 for format in self.client.DATE_FORMATS:
801 now_formated = self.now_unformated.strftime(format)
802 r1 = self.client.object_get(obj, if_modified_since=now_formated,
803 success=(200, 304, 412))
806 r2 = self.client.object_get(obj, if_unmodified_since=now_formated, success=(200, 304, 412))
809 self.assertNotEqual(sc1, sc2)
811 def test_object_put(self):
812 """Test object_PUT"""
814 self.client.container = self.c2
817 """create the object"""
818 r = self.client.object_put(obj, data='a', content_type='application/octer-stream',
819 permitions={'read':['accX:groupA', 'u1', 'u2'], 'write':['u2', 'u3']},
820 metadata={'key1':'val1', 'key2':'val2'}, content_encoding='UTF-8',
821 content_disposition='attachment; filename="fname.ext"')
822 self.assertEqual(r.status_code, 201)
823 etag = r.headers['etag']
825 """Check content-disposition"""
826 r = self.client.get_object_info(obj)
827 self.assertTrue(r.has_key('content-disposition'))
829 """Check permitions"""
830 r = self.client.get_object_sharing(obj)
831 self.assertTrue('accx:groupa' in r['read'])
832 self.assertTrue('u1' in r['read'])
833 self.assertTrue('u2' in r['write'])
834 self.assertTrue('u3' in r['write'])
837 r = self.client.get_object_meta(obj)
838 self.assertEqual(r['x-object-meta-key1'], 'val1')
839 self.assertEqual(r['x-object-meta-key2'], 'val2')
841 """Check public and if_etag_match"""
842 r = self.client.object_put(obj, if_etag_match=etag, data='b',
843 content_type='application/octet-stream', public=True)
845 r = self.client.object_get(obj)
846 self.assertTrue(r.headers.has_key('x-object-public'))
847 vers2 = int(r.headers['x-object-version'])
848 etag = r.headers['etag']
849 self.assertEqual(r.text, 'b')
851 """Check if_etag_not_match"""
852 r = self.client.object_put(obj, if_etag_not_match=etag, data='c',
853 content_type='application/octet-stream', success=(201, 412))
854 self.assertEqual(r.status_code, 412)
857 """Check content_type and content_length"""
858 tmpdir = 'dir'+unicode(self.now)
859 r = self.client.object_put(tmpdir, content_type='application/directory',
862 r = self.client.get_object_info(tmpdir)
863 self.assertEqual(r['content-type'], 'application/directory')
865 """Check copy_from, content_encoding"""
866 r = self.client.object_put('%s/%s'%(tmpdir, obj), format=None,
867 copy_from='/%s/%s'%(self.client.container, obj),
868 content_encoding='application/octet-stream',
869 source_account=self.client.account,
870 content_length=0, success=201)
871 self.assertEqual(r.status_code, 201)
873 """Test copy_object for cross-conctainer copy"""
874 self.client.copy_object(src_container=self.c2, src_object='%s/%s'%(tmpdir, obj),
875 dst_container=self.c1, dst_object=obj)
876 self.client.container = self.c1
877 r1 = self.client.get_object_info(obj)
878 self.client.container = self.c2
879 r2 = self.client.get_object_info('%s/%s'%(tmpdir, obj))
880 self.assertEqual(r1['x-object-hash'],r2['x-object-hash'])
882 """Check cross-container copy_from, content_encoding"""
883 self.client.container = self.c1
884 fromstr = '/'+self.c2+'/'+tmpdir+'/'+obj
885 r = self.client.object_put(obj, format=None, copy_from=fromstr,
886 content_encoding='application/octet-stream',
887 source_account=self.client.account,
888 content_length=0, success=201)
890 self.assertEqual(r.status_code, 201)
891 r = self.client.get_object_info(obj)
892 self.assertEqual(r['etag'], etag)
894 """Check source_account"""
895 self.client.container = self.c2
896 fromstr = '/'+self.c1+'/'+obj
897 r = self.client.object_put(obj+'v2', format=None, move_from=fromstr,
898 content_encoding='application/octet-stream',
899 source_account='nonExistendAddress@NeverLand.com',
900 content_length=0, success=(201, 403))
901 self.assertEqual(r.status_code, 403)
903 """Check cross-container move_from"""
904 self.client.container = self.c1
905 r1 = self.client.get_object_info(obj)
906 self.client.container = self.c2
907 self.client.move_object(src_container=self.c1, src_object=obj, dst_container=self.c2,
909 r0 = self.client.get_object_info(obj+'v0')
910 self.assertEqual(r1['x-object-hash'], r0['x-object-hash'])
912 """Check move_from"""
913 r = self.client.object_put(obj+'v1', format=None,
914 move_from='/'+self.c2+'/'+obj,
915 source_version = vers2,
916 content_encoding='application/octet-stream',
917 content_length=0, success=201)
920 mobj = 'manifest.test'
924 r = self.client.object_put('%s/%s'%(mobj, i), data='%s'%i, content_length=1, success=201,
925 content_type='application/octet-stream', content_encoding='application/octet-stream')
927 r = self.client.object_put(mobj, content_length=0, content_type='application/octet-stream',
928 manifest='%s/%s'%(self.client.container, mobj))
930 r = self.client.object_get(mobj)
931 self.assertEqual(r.text, txt)
933 """Upload a local file with one request"""
934 self.create_large_file(1024*10, 'l10K.'+unicode(self.now))
935 newf = open(self.fname, 'r')
936 self.client.upload_object('sample.file', newf)
938 """Check if file has been uploaded"""
939 r = self.client.get_object_info('sample.file')
940 self.assertEqual(int(r['content-length']), 10260)
942 """Some problems with transfer-encoding?"""
944 def test_object_copy(self):
945 """Test object_COPY"""
946 self.client.container=self.c2
949 data= '{"key1":"val1", "key2":"val2"}'
950 r = self.client.object_put(obj+'orig', content_type='application/octet-stream',
951 data= data, metadata={'mkey1':'mval1', 'mkey2':'mval2'},
953 'read':['accX:groupA', 'u1', 'u2'],
954 'write':['u2', 'u3']},
955 content_disposition='attachment; filename="fname.ext"')
957 r = self.client.object_copy(obj+'orig',
958 destination = '/'+self.client.container+'/'+obj,
959 ignore_content_type=False, content_type='application/json',
960 metadata={'mkey2':'mval2a', 'mkey3':'mval3'},
961 permitions={'write':['u5', 'accX:groupB']})
962 self.assertEqual(r.status_code, 201)
964 """Check content-disposition"""
965 r = self.client.get_object_info(obj)
966 self.assertTrue(r.has_key('content-disposition'))
969 r = self.client.get_object_meta(obj)
970 self.assertEqual(r['x-object-meta-mkey1'], 'mval1')
971 self.assertEqual(r['x-object-meta-mkey2'], 'mval2a')
972 self.assertEqual(r['x-object-meta-mkey3'], 'mval3')
974 """Check permitions"""
975 r = self.client.get_object_sharing(obj)
976 self.assertFalse(r.has_key('read') or 'u2' in r['write'])
977 self.assertTrue('accx:groupb' in r['write'])
979 """Check destination account"""
980 r = self.client.object_copy(obj, destination='/%s/%s'%(self.c1,obj), content_encoding='utf8',
981 content_type='application/json', destination_account='nonExistendAddress@NeverLand.com',
983 self.assertEqual(r.status_code, 403)
986 """Check destination being another container
987 and also content_type and content encoding"""
988 r = self.client.object_copy(obj, destination='/%s/%s'%(self.c1,obj),
989 content_encoding='utf8', content_type='application/json')
990 self.assertEqual(r.status_code, 201)
991 self.assertEqual(r.headers['content-type'], 'application/json; charset=UTF-8')
994 """Check ignore_content_type and content_type"""
995 r = self.client.object_get(obj)
996 etag = r.headers['etag']
997 ctype = r.headers['content-type']
998 self.assertEqual(ctype, 'application/json')
1000 r = self.client.object_copy(obj+'orig',
1001 destination = '/'+self.client.container+'/'+obj+'0',
1002 ignore_content_type=True, content_type='application/json')
1003 self.assertEqual(r.status_code, 201)
1004 self.assertNotEqual(r.headers['content-type'], 'application/json')
1007 """Check if_etag_(not_)match"""
1008 r = self.client.object_copy(obj,
1009 destination='/'+self.client.container+'/'+obj+'1', if_etag_match=etag)
1010 self.assertEqual(r.status_code, 201)
1012 r = self.client.object_copy(obj,
1013 destination='/'+self.client.container+'/'+obj+'2', if_etag_not_match='lalala')
1014 self.assertEqual(r.status_code, 201)
1015 vers2 = r.headers['x-object-version']
1018 """Check source_version, public and format """
1019 r = self.client.object_copy(obj+'2', destination='/'+self.client.container+'/'+obj+'3', source_version=vers2, format='xml', public=True)
1020 self.assertEqual(r.status_code, 201)
1021 self.assertTrue(r.headers['content-type'].index('xml') > 0)
1023 r = self.client.get_object_info(obj+'3')
1024 self.assertTrue(r.has_key('x-object-public'))
1026 def test_object_move(self):
1027 """Test object_MOVE"""
1028 self.client.container= self.c2
1031 data= '{"key1":"val1", "key2":"val2"}'
1032 r = self.client.object_put(obj+'orig', content_type='application/octet-stream',
1033 data= data, metadata={'mkey1':'mval1', 'mkey2':'mval2'},
1034 permitions={'read':['accX:groupA', 'u1', 'u2'], 'write':['u2', 'u3']})
1036 r = self.client.object_move(obj+'orig', destination = '/'+self.client.container+'/'+obj,
1037 ignore_content_type=False, content_type='application/json',
1038 metadata={'mkey2':'mval2a', 'mkey3':'mval3'},
1039 permitions={'write':['u5', 'accX:groupB']})
1040 self.assertEqual(r.status_code, 201)
1043 """Check Metadata"""
1044 r = self.client.get_object_meta(obj)
1045 self.assertEqual(r['x-object-meta-mkey1'], 'mval1')
1046 self.assertEqual(r['x-object-meta-mkey2'], 'mval2a')
1047 self.assertEqual(r['x-object-meta-mkey3'], 'mval3')
1049 """Check permitions"""
1050 r = self.client.get_object_sharing(obj)
1051 self.assertFalse(r.has_key('read'))
1052 self.assertTrue('u5' in r['write'])
1053 self.assertTrue('accx:groupb' in r['write'])
1055 """Check destination account"""
1056 r = self.client.object_move(obj, destination='/%s/%s'%(self.c1,obj), content_encoding='utf8',
1057 content_type='application/json', destination_account='nonExistendAddress@NeverLand.com',
1059 self.assertEqual(r.status_code, 403)
1062 """Check destination being another container and also
1063 content_type, content_disposition and content encoding"""
1064 r = self.client.object_move(obj, destination='/%s/%s'%(self.c1,obj),
1065 content_encoding='utf8', content_type='application/json',
1066 content_disposition='attachment; filename="fname.ext"')
1067 self.assertEqual(r.status_code, 201)
1068 self.assertEqual(r.headers['content-type'], 'application/json; charset=UTF-8')
1069 self.client.container=self.c1
1070 r = self.client.get_object_info(obj)
1071 self.assertTrue(r.has_key('content-disposition') and 'fname.ext' in r['content-disposition'])
1073 ctype = r['content-type']
1074 self.assertEqual(ctype, 'application/json')
1076 """Check ignore_content_type and content_type"""
1077 r = self.client.object_move(obj, destination = '/%s/%s'%(self.c2,obj),
1078 ignore_content_type=True, content_type='application/json')
1079 self.assertEqual(r.status_code, 201)
1080 self.assertNotEqual(r.headers['content-type'], 'application/json')
1083 """Check if_etag_(not_)match"""
1084 self.client.container=self.c2
1085 r = self.client.object_move(obj, destination='/'+self.client.container+'/'+obj+'0',
1087 self.assertEqual(r.status_code, 201)
1089 r = self.client.object_move(obj+'0', destination='/'+self.client.container+'/'+obj+'1',
1090 if_etag_not_match='lalala')
1091 self.assertEqual(r.status_code, 201)
1094 """Check public and format """
1095 r = self.client.object_move(obj+'1', destination='/'+self.client.container+'/'+obj+'2',
1096 format='xml', public=True)
1097 self.assertEqual(r.status_code, 201)
1098 self.assertTrue(r.headers['content-type'].index('xml') > 0)
1100 r = self.client.get_object_info(obj+'2')
1101 self.assertTrue(r.has_key('x-object-public'))
1103 def test_object_post(self):
1104 """Test object_POST"""
1105 self.client.container=self.c2
1107 """create a filesystem file"""
1109 newf = open(self.fname, 'w')
1110 newf.writelines(['ello!\n','This is a test line\n','inside a test file\n'])
1112 """create a file on container"""
1113 r = self.client.object_put(obj, content_type='application/octet-stream',
1114 data= 'H', metadata={'mkey1':'mval1', 'mkey2':'mval2'},
1115 permitions={'read':['accX:groupA', 'u1', 'u2'], 'write':['u2', 'u3']})
1118 """Append tests update, content_range, content_type, content_length"""
1119 newf = open(obj, 'r')
1120 self.client.append_object(obj, newf)
1121 r = self.client.object_get(obj)
1122 self.assertTrue(r.text.startswith('Hello!'))
1125 """Overwrite tests update, content_type, content_length, content_range"""
1127 r = self.client.overwrite_object(obj, 0, 10, newf)
1128 r = self.client.object_get(obj)
1129 self.assertTrue(r.text.startswith('ello!'))
1133 """Truncate tests update, content_range, content_type,
1134 object_bytes and source_object"""
1135 r = self.client.truncate_object(obj, 5)
1136 r = self.client.object_get(obj)
1137 self.assertEqual(r.text, 'ello!')
1140 """Check metadata"""
1141 self.client.set_object_meta(obj, {'mkey2':'mval2a', 'mkey3':'mval3'})
1142 r = self.client.get_object_meta(obj)
1143 self.assertEqual(r['x-object-meta-mkey1'], 'mval1')
1144 self.assertEqual(r['x-object-meta-mkey2'], 'mval2a')
1145 self.assertEqual(r['x-object-meta-mkey3'], 'mval3')
1146 self.client.del_object_meta('mkey1', obj)
1147 r = self.client.get_object_meta(obj)
1148 self.assertFalse(r.has_key('x-object-meta-mkey1'))
1150 """Check permitions"""
1151 self.client.set_object_sharing(obj,
1152 read_permition=['u4', 'u5'], write_permition=['u4'])
1153 r = self.client.get_object_sharing(obj)
1154 self.assertTrue(r.has_key('read'))
1155 self.assertTrue('u5' in r['read'])
1156 self.assertTrue(r.has_key('write'))
1157 self.assertTrue('u4' in r['write'])
1158 self.client.del_object_sharing(obj)
1159 r = self.client.get_object_sharing(obj)
1160 self.assertTrue(len(r) == 0)
1163 self.client.publish_object(obj)
1164 r = self.client.get_object_info(obj)
1165 self.assertTrue(r.has_key('x-object-public'))
1166 self.client.unpublish_object(obj)
1167 r = self.client.get_object_info(obj)
1168 self.assertFalse(r.has_key('x-object-public'))
1170 """Check if_etag_(not)match"""
1172 #r = self.client.object_post(obj, update=True, public=True,
1173 # if_etag_not_match=etag, success=(412,202,204))
1174 #self.assertEqual(r.status_code, 412)
1176 r = self.client.object_post(obj, update=True, public=True,
1177 if_etag_match=etag, content_encoding='application/json')
1179 r = self.client.get_object_info(obj)
1180 helloVersion = r['x-object-version']
1181 self.assertTrue(r.has_key('x-object-public'))
1182 self.assertEqual(r['content-encoding'], 'application/json')
1184 """Check source_version and source_account and content_disposition"""
1185 r = self.client.object_post(obj, update=True, content_type='application/octet-srteam',
1186 content_length=5, content_range='bytes 1-5/*', source_object='/%s/%s'%(self.c2,obj),
1187 source_account='thisAccountWillNeverExist@adminland.com',
1188 source_version=helloVersion, data='12345', success=(403, 202, 204))
1189 self.assertEqual(r.status_code, 403)
1191 r = self.client.object_post(obj, update=True, content_type='application/octet-srteam',
1192 content_length=5, content_range='bytes 1-5/*', source_object='/%s/%s'%(self.c2,obj),
1193 source_account=self.client.account, source_version=helloVersion, data='12345',
1194 content_disposition='attachment; filename="fname.ext"')
1196 r = self.client.object_get(obj)
1197 self.assertEqual(r.text, 'eello!')
1198 self.assertTrue(r.headers.has_key('content-disposition')
1199 and 'fname.ext' in r.headers['content-disposition'])
1202 """Check manifest"""
1203 mobj = 'manifest.test'
1207 r = self.client.object_put('%s/%s'%(mobj, i), data='%s'%i, content_length=1, success=201,
1208 content_encoding='application/octet-stream', content_type='application/octet-stream')
1210 #r = self.client.object_put(mobj, content_length=0, content_type='application/octet-stream')
1211 self.client.create_object_by_manifestation(mobj, content_type='application/octet-stream')
1213 r = self.client.object_post(mobj, manifest='%s/%s'%(self.client.container, mobj))
1215 r = self.client.object_get(mobj)
1216 self.assertEqual(r.text, txt)
1219 """We need to check transfer_encoding """
1221 def test_object_delete(self):
1222 """Test object_DELETE"""
1223 self.client.container=self.c2
1225 """create a file on container"""
1226 r = self.client.object_put(obj, content_type='application/octet-stream',
1227 data= 'H', metadata={'mkey1':'mval1', 'mkey2':'mval2'},
1228 permitions={'read':['accX:groupA', 'u1', 'u2'], 'write':['u2', 'u3']})
1231 """Check with false until"""
1232 r = self.client.object_delete(obj, until=1000000)
1234 r = self.client.object_get(obj, success=(200, 404))
1235 self.assertEqual(r.status_code, 200)
1238 """Check normal case"""
1239 r = self.client.object_delete(obj)
1240 self.assertEqual(r.status_code, 204)
1242 r = self.client.object_get(obj, success=(200, 404))
1243 self.assertEqual(r.status_code, 404)
1246 def create_large_file(self, size, name):
1247 """Create a large file at fs"""
1250 random.seed(self.now)
1251 f = open(self.fname, 'w')
1252 sys.stdout.write(' create random file %s of size %s'%(name, size)+' 0%')
1253 for hobyte_id in range(size/8):
1254 sss = 'hobt%s'%random.randint(1000, 9999)
1256 if 0 == (hobyte_id*800)%size:
1258 sys.stdout.write('\b\b')
1259 prs = (hobyte_id*800)//size
1261 sys.stdout.write('\b')
1262 sys.stdout.write('%s'%prs+'%')
1269 parser = ArgumentParser(add_help=False)
1270 parser.add_argument('-h', '--help', dest='help', action='store_true', default=False,
1271 help="Show this help message and exit")
1274 if __name__ == '__main__':
1275 parser = init_parser()
1276 args, argv = parser.parse_known_args()
1278 if len(argv) > 2 or getattr(args,'help') or len(argv) < 1:
1279 raise Exception('\tusage: tests.py <group> [command]')
1280 suiteFew = unittest.TestSuite()
1282 if len(argv) == 0 or argv[0] == 'pithos':
1284 suiteFew.addTest(unittest.makeSuite(testPithos))
1286 suiteFew.addTest(testPithos('test_'+argv[1]))
1287 if len(argv) == 0 or argv[0] == 'cyclades':
1289 #suiteFew.addTest(unittest.makeSuite(testCyclades))
1290 suiteFew.addTest(testCyclades('test_000'))
1292 suiteFew.addTest(testCyclades('test_'+argv[1]))
1294 unittest.TextTestRunner(verbosity = 2).run(suiteFew)