1 # Copyright 2012-2013 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.
36 from os import urandom
37 from tempfile import NamedTemporaryFile
39 from kamaki.clients import livetest, ClientError
40 from kamaki.clients.pithos import PithosClient
41 from kamaki.clients.astakos import AstakosClient
44 class Pithos(livetest.Generic):
49 self.client = PithosClient(
51 self['store', 'token'],
53 self['astakos', 'url'],
54 self['store', 'token']
57 self.now = time.mktime(time.gmtime())
58 self.now_unformated = datetime.datetime.utcnow()
61 """Prepare an object to be shared - also its container"""
62 self.client.container = self.c1
63 self.client.object_post(
66 permissions={'read': [self.client.account]})
68 self.create_remote_object(self.c1, 'another.test')
71 self.c1 = 'c1_' + unicode(self.now)
72 self.c2 = 'c2_' + unicode(self.now)
73 self.c3 = 'c3_' + unicode(self.now)
75 self.client.create_container(self.c2)
79 self.client.create_container(self.c1)
83 self.client.create_container(self.c3)
87 self.create_remote_object(self.c1, 'test')
88 self.create_remote_object(self.c2, 'test')
89 self.create_remote_object(self.c1, 'test1')
90 self.create_remote_object(self.c2, 'test1')
92 def create_remote_object(self, container, obj):
93 self.client.container = container
94 self.client.object_put(
96 content_type='application/octet-stream',
97 data='file %s that lives in %s' % (obj, container),
98 metadata={'incontainer': container})
100 def forceDeleteContainer(self, container):
101 self.client.container = container
103 r = self.client.list_objects()
108 self.client.del_object(name)
109 r = self.client.container_delete()
113 """Destroy test cases"""
116 self.forceDeleteContainer(self.c1)
117 self.forceDeleteContainer(self.c2)
119 self.forceDeleteContainer(self.c3)
122 self.client.container = ''
125 """Prepare a full Pithos+ test"""
127 super(self.__class__, self).test_000()
129 def test_account_head(self):
130 """Test account_HEAD"""
131 self._test_0010_account_head()
133 def _test_0010_account_head(self):
134 r = self.client.account_head()
135 self.assertEqual(r.status_code, 204)
137 r = self.client.account_head(until='1000000000')
138 self.assertEqual(r.status_code, 204)
140 r = self.client.get_account_info(until='1000000000')
141 datestring = unicode(r['x-account-until-timestamp'])
142 self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring)
144 r = self.client.get_account_quota()
145 self.assertTrue('x-account-policy-quota' in r)
147 r = self.client.get_account_versioning()
148 self.assertTrue('x-account-policy-versioning' in r)
150 """Check if(un)modified_since"""
151 for format in self.client.DATE_FORMATS:
152 now_formated = self.now_unformated.strftime(format)
153 r1 = self.client.account_head(
154 if_modified_since=now_formated,
155 success=(204, 304, 412))
158 r2 = self.client.account_head(
159 if_unmodified_since=now_formated,
160 success=(204, 304, 412))
163 self.assertNotEqual(sc1, sc2)
165 def test_account_get(self):
166 """Test account_GET"""
167 self._test_0020_account_get()
169 def _test_0020_account_get(self):
170 #r = self.client.account_get()
171 #self.assertEqual(r.status_code, 200)
172 r = self.client.list_containers()
174 self.assertTrue(fullLen > 2)
176 r = self.client.account_get(limit=1)
177 self.assertEqual(len(r.json), 1)
179 r = self.client.account_get(marker='c2_')
180 temp_c0 = r.json[0]['name']
181 temp_c2 = r.json[2]['name']
183 r = self.client.account_get(limit=2, marker='c2_')
184 conames = [container['name'] for container in r.json if (
185 container['name'].lower().startswith('c2_'))]
186 self.assertTrue(temp_c0 in conames)
187 self.assertFalse(temp_c2 in conames)
189 r = self.client.account_get(show_only_shared=True)
190 self.assertTrue(self.c1 in [c['name'] for c in r.json])
192 r = self.client.account_get(until=1342609206)
193 self.assertTrue(len(r.json) <= fullLen)
195 """Check if(un)modified_since"""
196 for format in self.client.DATE_FORMATS:
197 now_formated = self.now_unformated.strftime(format)
198 r1 = self.client.account_get(
199 if_modified_since=now_formated,
200 success=(200, 304, 412))
203 r2 = self.client.account_get(
204 if_unmodified_since=now_formated,
205 success=(200, 304, 412))
208 self.assertNotEqual(sc1, sc2)
210 """Check sharing_accounts"""
211 r = self.client.get_sharing_accounts()
212 self.assertTrue(len(r) > 0)
214 def test_account_post(self):
215 """Test account_POST"""
216 self._test_0030_account_post()
218 def _test_0030_account_post(self):
219 r = self.client.account_post()
220 self.assertEqual(r.status_code, 202)
221 grpName = 'grp' + unicode(self.now)
223 """Method set/del_account_meta and set_account_groupcall use
224 account_post internally
226 u1 = self.client.account
227 u2 = self.client.account
228 self.client.set_account_group(grpName, [u1, u2])
229 r = self.client.get_account_group()
230 self.assertEqual(r['x-account-group-' + grpName], '%s,%s' % (u1, u2))
231 self.client.del_account_group(grpName)
232 r = self.client.get_account_group()
233 self.assertTrue('x-account-group-' + grpName not in r)
235 mprefix = 'meta' + unicode(self.now)
236 self.client.set_account_meta({
238 mprefix + '2': 'v2'})
239 r = self.client.get_account_meta()
240 self.assertEqual(r['x-account-meta-' + mprefix + '1'], 'v1')
241 self.assertEqual(r['x-account-meta-' + mprefix + '2'], 'v2')
243 self.client.del_account_meta(mprefix + '1')
244 r = self.client.get_account_meta()
245 self.assertTrue('x-account-meta-' + mprefix + '1' not in r)
247 self.client.del_account_meta(mprefix + '2')
248 r = self.client.get_account_meta()
249 self.assertTrue('x-account-meta-' + mprefix + '2' not in r)
251 """Missing testing for quota, versioning, because normally
252 you don't have permissions to modify those at account level
256 self.client.set_account_quota(newquota)
257 #r = self.client.get_account_info()
259 #r = self.client.get_account_quota()
260 #self.assertEqual(r['x-account-policy-quota'], newquota)
261 self.client.set_account_versioning('auto')
263 def test_container_head(self):
264 """Test container_HEAD"""
265 self._test_0040_container_head()
267 def _test_0040_container_head(self):
268 self.client.container = self.c1
270 r = self.client.container_head()
271 self.assertEqual(r.status_code, 204)
274 r = self.client.container_head(until=1000000, success=(204, 404))
275 self.assertEqual(r.status_code, 404)
277 """Check and if(un)modified_since"""
278 for format in self.client.DATE_FORMATS:
279 now_formated = self.now_unformated.strftime(format)
280 r1 = self.client.container_head(
281 if_modified_since=now_formated,
282 success=(204, 304, 412))
285 r2 = self.client.container_head(
286 if_unmodified_since=now_formated,
287 success=(204, 304, 412))
290 self.assertNotEqual(sc1, sc2)
292 """Check container object meta"""
293 r = self.client.get_container_object_meta()
294 self.assertEqual(r['x-container-object-meta'], 'Incontainer')
296 def test_container_get(self):
297 """Test container_GET"""
298 self._test_0050_container_get()
300 def _test_0050_container_get(self):
301 self.client.container = self.c1
303 r = self.client.container_get()
304 self.assertEqual(r.status_code, 200)
305 fullLen = len(r.json)
307 r = self.client.container_get(prefix='test')
308 lalobjects = [obj for obj in r.json if obj['name'].startswith('test')]
309 self.assertTrue(len(r.json) > 1)
310 self.assertEqual(len(r.json), len(lalobjects))
312 r = self.client.container_get(limit=1)
313 self.assertEqual(len(r.json), 1)
315 r = self.client.container_get(marker='another')
316 self.assertTrue(len(r.json) > 1)
317 neobjects = [obj for obj in r.json if obj['name'] > 'another']
318 self.assertEqual(len(r.json), len(neobjects))
320 r = self.client.container_get(prefix='another.test', delimiter='.')
321 self.assertTrue(fullLen > len(r.json))
323 r = self.client.container_get(path='/')
324 self.assertEqual(fullLen, len(r.json))
326 r = self.client.container_get(format='xml')
327 self.assertEqual(r.text.split()[4], 'name="' + self.c1 + '">')
329 r = self.client.container_get(meta=['incontainer'])
330 self.assertTrue(len(r.json) > 0)
332 r = self.client.container_get(show_only_shared=True)
333 self.assertTrue(len(r.json) < fullLen)
336 r = self.client.container_get(until=1000000000)
337 datestring = unicode(r.headers['x-account-until-timestamp'])
338 self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring)
344 """Check and if un/modified_since"""
345 for format in self.client.DATE_FORMATS:
346 now_formated = self.now_unformated.strftime(format)
347 r1 = self.client.container_get(
348 if_modified_since=now_formated,
349 success=(200, 304, 412))
352 r2 = self.client.container_get(
353 if_unmodified_since=now_formated,
354 success=(200, 304, 412))
357 self.assertNotEqual(sc1, sc2)
359 def test_container_put(self):
360 """Test container_PUT"""
361 self._test_0050_container_put()
363 def _test_0050_container_put(self):
364 self.client.container = self.c2
366 r = self.client.container_put()
367 self.assertEqual(r.status_code, 202)
369 r = self.client.get_container_quota(self.client.container)
370 cquota = r.values()[0]
371 newquota = 2 * int(cquota)
373 r = self.client.container_put(quota=newquota)
374 self.assertEqual(r.status_code, 202)
376 r = self.client.get_container_quota(self.client.container)
377 xquota = int(r.values()[0])
378 self.assertEqual(newquota, xquota)
380 r = self.client.container_put(versioning='auto')
381 self.assertEqual(r.status_code, 202)
383 r = self.client.get_container_versioning(self.client.container)
384 nvers = r.values()[0]
385 self.assertEqual('auto', nvers)
387 r = self.client.container_put(versioning='none')
388 self.assertEqual(r.status_code, 202)
390 r = self.client.get_container_versioning(self.client.container)
391 nvers = r.values()[0]
392 self.assertEqual('none', nvers)
394 r = self.client.container_put(metadata={'m1': 'v1', 'm2': 'v2'})
395 self.assertEqual(r.status_code, 202)
397 r = self.client.get_container_meta(self.client.container)
398 self.assertTrue('x-container-meta-m1' in r)
399 self.assertEqual(r['x-container-meta-m1'], 'v1')
400 self.assertTrue('x-container-meta-m2' in r)
401 self.assertEqual(r['x-container-meta-m2'], 'v2')
403 r = self.client.container_put(metadata={'m1': '', 'm2': 'v2a'})
404 self.assertEqual(r.status_code, 202)
406 r = self.client.get_container_meta(self.client.container)
407 self.assertTrue('x-container-meta-m1' not in r)
408 self.assertTrue('x-container-meta-m2' in r)
409 self.assertEqual(r['x-container-meta-m2'], 'v2a')
411 self.client.del_container_meta(self.client.container)
413 def test_container_post(self):
414 """Test container_POST"""
415 self._test_0060_container_post()
417 def _test_0060_container_post(self):
418 self.client.container = self.c2
421 r = self.client.container_post()
422 self.assertEqual(r.status_code, 202)
425 self.client.set_container_meta({'m1': 'v1', 'm2': 'v2'})
426 r = self.client.get_container_meta(self.client.container)
427 self.assertTrue('x-container-meta-m1' in r)
428 self.assertEqual(r['x-container-meta-m1'], 'v1')
429 self.assertTrue('x-container-meta-m2' in r)
430 self.assertEqual(r['x-container-meta-m2'], 'v2')
433 r = self.client.del_container_meta('m1')
434 r = self.client.set_container_meta({'m2': 'v2a'})
435 r = self.client.get_container_meta(self.client.container)
436 self.assertTrue('x-container-meta-m1' not in r)
437 self.assertTrue('x-container-meta-m2' in r)
438 self.assertEqual(r['x-container-meta-m2'], 'v2a')
441 r = self.client.get_container_quota(self.client.container)
442 cquota = r.values()[0]
443 newquota = 2 * int(cquota)
444 r = self.client.set_container_quota(newquota)
445 r = self.client.get_container_quota(self.client.container)
446 xquota = int(r.values()[0])
447 self.assertEqual(newquota, xquota)
448 r = self.client.set_container_quota(cquota)
449 r = self.client.get_container_quota(self.client.container)
450 xquota = r.values()[0]
451 self.assertEqual(cquota, xquota)
453 """Check versioning"""
454 self.client.set_container_versioning('auto')
455 r = self.client.get_container_versioning(self.client.container)
456 nvers = r.values()[0]
457 self.assertEqual('auto', nvers)
458 self.client.set_container_versioning('none')
459 r = self.client.get_container_versioning(self.client.container)
460 nvers = r.values()[0]
461 self.assertEqual('none', nvers)
463 """put_block uses content_type and content_length to
464 post blocks of data 2 container. All that in upload_object"""
465 """Change a file at fs"""
466 f = self.create_large_file(1024 * 1024 * 100)
467 """Upload it at a directory in container"""
468 self.client.create_directory('dir')
469 self.client.upload_object('/dir/sample.file', f)
470 """Check if file has been uploaded"""
471 r = self.client.get_object_info('/dir/sample.file')
472 self.assertTrue(int(r['content-length']) > 100000000)
474 """What is tranfer_encoding? What should I check about it? """
477 """Check update=False"""
478 r = self.client.object_post(
481 metadata={'newmeta': 'newval'})
483 r = self.client.get_object_info('test')
484 self.assertTrue('x-object-meta-newmeta' in r)
485 self.assertFalse('x-object-meta-incontainer' in r)
487 r = self.client.del_container_meta('m2')
489 def test_container_delete(self):
490 """Test container_DELETE"""
491 self._test_0070_container_delete()
493 def _test_0070_container_delete(self):
495 """Fail to delete a non-empty container"""
496 self.client.container = self.c2
497 r = self.client.container_delete(success=409)
498 self.assertEqual(r.status_code, 409)
500 """Fail to delete c3 (empty) container"""
501 self.client.container = self.c3
502 r = self.client.container_delete(until='1000000000')
503 self.assertEqual(r.status_code, 204)
505 """Delete c3 (empty) container"""
506 r = self.client.container_delete()
507 self.assertEqual(r.status_code, 204)
509 """Purge container(empty a container), check versionlist"""
510 self.client.container = self.c1
511 r = self.client.object_head('test', success=(200, 404))
512 self.assertEqual(r.status_code, 200)
513 self.client.del_container(delimiter='/')
514 r = self.client.object_head('test', success=(200, 404))
515 self.assertEqual(r.status_code, 404)
516 r = self.client.get_object_versionlist('test')
517 self.assertTrue(len(r) > 0)
518 self.assertTrue(len(r[0]) > 1)
519 self.client.purge_container()
522 self.client.get_object_versionlist,
525 def _test_0080_recreate_deleted_data(self):
528 def test_object_head(self):
529 """Test object_HEAD"""
530 self._test_0090_object_head()
532 def _test_0090_object_head(self):
533 self.client.container = self.c2
536 r = self.client.object_head(obj)
537 self.assertEqual(r.status_code, 200)
538 etag = r.headers['etag']
540 r = self.client.object_head(obj, version=40)
541 self.assertEqual(r.headers['x-object-version'], '40')
543 r = self.client.object_head(obj, if_etag_match=etag)
544 self.assertEqual(r.status_code, 200)
546 r = self.client.object_head(
548 if_etag_not_match=etag,
549 success=(200, 412, 304))
550 self.assertNotEqual(r.status_code, 200)
552 r = self.client.object_head(
557 self.assertEqual(r.status_code, 412)
559 """Check and if(un)modified_since"""
560 for format in self.client.DATE_FORMATS:
561 now_formated = self.now_unformated.strftime(format)
562 r1 = self.client.object_head(
564 if_modified_since=now_formated,
565 success=(200, 304, 412))
568 r2 = self.client.object_head(
570 if_unmodified_since=now_formated,
571 success=(200, 304, 412))
574 self.assertNotEqual(sc1, sc2)
576 def test_object_get(self):
577 """Test object_GET"""
578 self._test_0100_object_get()
580 def _test_0100_object_get(self):
581 self.client.container = self.c1
584 r = self.client.object_get(obj)
585 self.assertEqual(r.status_code, 200)
587 osize = int(r.headers['content-length'])
588 etag = r.headers['etag']
590 r = self.client.object_get(obj, hashmap=True)
591 for term in ('hashes', 'block_hash', 'block_hash', 'bytes'):
592 self.assertTrue(term in r.json)
594 r = self.client.object_get(obj, format='xml', hashmap=True)
595 self.assertEqual(len(r.text.split('hash>')), 3)
597 rangestr = 'bytes=%s-%s' % (osize / 3, osize / 2)
598 r = self.client.object_get(
602 partsize = int(r.headers['content-length'])
603 self.assertTrue(0 < partsize and partsize <= 1 + osize / 3)
605 rangestr = 'bytes=%s-%s' % (osize / 3, osize / 2)
606 r = self.client.object_get(
611 partsize = int(r.headers['content-length'])
612 self.assertTrue(0 < partsize and partsize <= 1 + osize / 3)
614 r = self.client.object_get(obj, if_etag_match=etag)
615 self.assertEqual(r.status_code, 200)
617 r = self.client.object_get(obj, if_etag_not_match=etag + 'LALALA')
618 self.assertEqual(r.status_code, 200)
620 """Check and if(un)modified_since"""
621 for format in self.client.DATE_FORMATS:
622 now_formated = self.now_unformated.strftime(format)
623 r1 = self.client.object_get(
625 if_modified_since=now_formated,
626 success=(200, 304, 412))
629 r2 = self.client.object_get(
631 if_unmodified_since=now_formated,
632 success=(200, 304, 412))
635 self.assertNotEqual(sc1, sc2)
637 """Upload an object to download"""
638 trg_fname = 'remotefile_%s' % self.now
640 src_f = self.create_large_file(f_size)
641 print('\tUploading...')
642 self.client.upload_object(trg_fname, src_f)
643 print('\tDownloading...')
644 self.files.append(NamedTemporaryFile())
645 dnl_f = self.files[-1]
646 self.client.download_object(trg_fname, dnl_f)
648 print('\tCheck if files match...')
649 for pos in (0, f_size / 2, f_size - 20):
652 self.assertEqual(src_f.read(10), dnl_f.read(10))
654 def test_object_put(self):
655 """Test object_PUT"""
656 self._test_object_put()
658 def _test_object_put(self):
659 self.client.container = self.c2
662 self.client.create_object(obj + '.FAKE')
663 r = self.client.get_object_info(obj + '.FAKE')
664 self.assertEqual(r['content-type'], 'application/octet-stream')
666 """create the object"""
667 r = self.client.object_put(
670 content_type='application/octer-stream',
672 read=['accX:groupA', 'u1', 'u2'],
674 metadata=dict(key1='val1', key2='val2'),
675 content_encoding='UTF-8',
676 content_disposition='attachment; filename="fname.ext"')
677 self.assertEqual(r.status_code, 201)
678 etag = r.headers['etag']
680 """Check content-disposition"""
681 r = self.client.get_object_info(obj)
682 self.assertTrue('content-disposition' in r)
684 """Check permissions"""
685 r = self.client.get_object_sharing(obj)
686 self.assertTrue('accx:groupa' in r['read'])
687 self.assertTrue('u1' in r['read'])
688 self.assertTrue('u2' in r['write'])
689 self.assertTrue('u3' in r['write'])
692 r = self.client.get_object_meta(obj)
693 self.assertEqual(r['x-object-meta-key1'], 'val1')
694 self.assertEqual(r['x-object-meta-key2'], 'val2')
696 """Check public and if_etag_match"""
697 r = self.client.object_put(
701 content_type='application/octet-stream',
704 r = self.client.object_get(obj)
705 self.assertTrue('x-object-public' in r.headers)
706 vers2 = int(r.headers['x-object-version'])
707 etag = r.headers['etag']
708 self.assertEqual(r.text, 'b')
710 """Check if_etag_not_match"""
711 r = self.client.object_put(
713 if_etag_not_match=etag,
715 content_type='application/octet-stream',
717 self.assertEqual(r.status_code, 412)
719 """Check content_type and content_length"""
720 tmpdir = 'dir' + unicode(self.now)
721 r = self.client.object_put(
723 content_type='application/directory',
726 r = self.client.get_object_info(tmpdir)
727 self.assertEqual(r['content-type'], 'application/directory')
729 """Check copy_from, content_encoding"""
730 r = self.client.object_put(
731 '%s/%s' % (tmpdir, obj),
733 copy_from='/%s/%s' % (self.client.container, obj),
734 content_encoding='application/octet-stream',
735 source_account=self.client.account,
738 self.assertEqual(r.status_code, 201)
740 """Test copy_object for cross-conctainer copy"""
741 self.client.copy_object(
742 src_container=self.c2,
743 src_object='%s/%s' % (tmpdir, obj),
744 dst_container=self.c1,
746 self.client.container = self.c1
747 r1 = self.client.get_object_info(obj)
748 self.client.container = self.c2
749 r2 = self.client.get_object_info('%s/%s' % (tmpdir, obj))
750 self.assertEqual(r1['x-object-hash'], r2['x-object-hash'])
752 """Check cross-container copy_from, content_encoding"""
753 self.client.container = self.c1
754 fromstr = '/%s/%s/%s' % (self.c2, tmpdir, obj)
755 r = self.client.object_put(
759 content_encoding='application/octet-stream',
760 source_account=self.client.account,
764 self.assertEqual(r.status_code, 201)
765 r = self.client.get_object_info(obj)
766 self.assertEqual(r['etag'], etag)
768 """Check source_account"""
769 self.client.container = self.c2
770 fromstr = '/%s/%s' % (self.c1, obj)
771 r = self.client.object_put(
775 content_encoding='application/octet-stream',
776 source_account='nonExistendAddress@NeverLand.com',
779 self.assertEqual(r.status_code, 403)
781 """Check cross-container move_from"""
782 self.client.container = self.c1
783 r1 = self.client.get_object_info(obj)
784 self.client.container = self.c2
785 self.client.move_object(
786 src_container=self.c1,
788 dst_container=self.c2,
789 dst_object=obj + 'v0')
790 r0 = self.client.get_object_info(obj + 'v0')
791 self.assertEqual(r1['x-object-hash'], r0['x-object-hash'])
793 """Check move_from"""
794 r = self.client.object_put(
797 move_from='/%s/%s' % (self.c2, obj),
798 source_version=vers2,
799 content_encoding='application/octet-stream',
800 content_length=0, success=201)
803 mobj = 'manifest.test'
807 r = self.client.object_put(
812 content_type='application/octet-stream',
813 content_encoding='application/octet-stream')
815 r = self.client.object_put(
818 content_type='application/octet-stream',
819 manifest='%s/%s' % (self.client.container, mobj))
821 r = self.client.object_get(mobj)
822 self.assertEqual(r.text, txt)
824 """Upload a local file with one request"""
825 newf = self.create_large_file(1024 * 10)
826 self.client.upload_object('sample.file', newf)
827 """Check if file has been uploaded"""
828 r = self.client.get_object_info('sample.file')
829 self.assertEqual(int(r['content-length']), 10240)
831 """Some problems with transfer-encoding?"""
833 def test_object_copy(self):
834 """Test object_COPY"""
835 self._test_0110_object_copy()
837 def _test_0110_object_copy(self):
838 self.client.container = self.c2
841 data = '{"key1":"val1", "key2":"val2"}'
842 r = self.client.object_put(
844 content_type='application/octet-stream',
846 metadata=dict(mkey1='mval1', mkey2='mval2'),
848 read=['accX:groupA', 'u1', 'u2'],
850 content_disposition='attachment; filename="fname.ext"')
852 r = self.client.object_copy(
854 destination='/%s/%s' % (self.client.container, obj),
855 ignore_content_type=False, content_type='application/json',
856 metadata={'mkey2': 'mval2a', 'mkey3': 'mval3'},
857 permissions={'write': ['u5', 'accX:groupB']})
858 self.assertEqual(r.status_code, 201)
860 """Check content-disposition"""
861 r = self.client.get_object_info(obj)
862 self.assertTrue('content-disposition' in r)
865 r = self.client.get_object_meta(obj)
866 self.assertEqual(r['x-object-meta-mkey1'], 'mval1')
867 self.assertEqual(r['x-object-meta-mkey2'], 'mval2a')
868 self.assertEqual(r['x-object-meta-mkey3'], 'mval3')
870 """Check permissions"""
871 r = self.client.get_object_sharing(obj)
872 self.assertFalse('read' in r or 'u2' in r['write'])
873 self.assertTrue('accx:groupb' in r['write'])
875 """Check destination account"""
876 r = self.client.object_copy(
878 destination='/%s/%s' % (self.c1, obj),
879 content_encoding='utf8',
880 content_type='application/json',
881 destination_account='nonExistendAddress@NeverLand.com',
883 self.assertEqual(r.status_code, 403)
885 """Check destination being another container
886 and also content_type and content encoding"""
887 r = self.client.object_copy(
889 destination='/%s/%s' % (self.c1, obj),
890 content_encoding='utf8',
891 content_type='application/json')
892 self.assertEqual(r.status_code, 201)
894 r.headers['content-type'],
895 'application/json; charset=UTF-8')
897 """Check ignore_content_type and content_type"""
898 r = self.client.object_get(obj)
899 etag = r.headers['etag']
900 ctype = r.headers['content-type']
901 self.assertEqual(ctype, 'application/json')
903 r = self.client.object_copy(
905 destination='/%s/%s0' % (self.client.container, obj),
906 ignore_content_type=True,
907 content_type='application/json')
908 self.assertEqual(r.status_code, 201)
909 self.assertNotEqual(r.headers['content-type'], 'application/json')
911 """Check if_etag_(not_)match"""
912 r = self.client.object_copy(
914 destination='/%s/%s1' % (self.client.container, obj),
916 self.assertEqual(r.status_code, 201)
918 r = self.client.object_copy(
920 destination='/%s/%s2' % (self.client.container, obj),
921 if_etag_not_match='lalala')
922 self.assertEqual(r.status_code, 201)
923 vers2 = r.headers['x-object-version']
925 """Check source_version, public and format """
926 r = self.client.object_copy(
928 destination='/%s/%s3' % (self.client.container, obj),
929 source_version=vers2,
932 self.assertEqual(r.status_code, 201)
933 self.assertTrue(r.headers['content-type'].index('xml') > 0)
935 r = self.client.get_object_info(obj + '3')
936 self.assertTrue('x-object-public' in r)
938 def test_object_move(self):
939 """Test object_MOVE"""
940 self._test_0120_object_move()
942 def _test_0120_object_move(self):
943 self.client.container = self.c2
946 data = '{"key1": "val1", "key2": "val2"}'
947 r = self.client.object_put(
949 content_type='application/octet-stream',
951 metadata=dict(mkey1='mval1', mkey2='mval2'),
953 read=['accX:groupA', 'u1', 'u2'],
956 r = self.client.object_move(
958 destination='/%s/%s' % (self.client.container, obj),
959 ignore_content_type=False,
960 content_type='application/json',
961 metadata=dict(mkey2='mval2a', mkey3='mval3'),
962 permissions=dict(write=['u5', 'accX:groupB']))
963 self.assertEqual(r.status_code, 201)
966 r = self.client.get_object_meta(obj)
967 self.assertEqual(r['x-object-meta-mkey1'], 'mval1')
968 self.assertEqual(r['x-object-meta-mkey2'], 'mval2a')
969 self.assertEqual(r['x-object-meta-mkey3'], 'mval3')
971 """Check permissions"""
972 r = self.client.get_object_sharing(obj)
973 self.assertFalse('read' in r)
974 self.assertTrue('u5' in r['write'])
975 self.assertTrue('accx:groupb' in r['write'])
977 """Check destination account"""
978 r = self.client.object_move(
980 destination='/%s/%s' % (self.c1, obj),
981 content_encoding='utf8',
982 content_type='application/json',
983 destination_account='nonExistendAddress@NeverLand.com',
985 self.assertEqual(r.status_code, 403)
987 """Check destination being another container and also
988 content_type, content_disposition and content encoding"""
989 r = self.client.object_move(
991 destination='/%s/%s' % (self.c1, obj),
992 content_encoding='utf8',
993 content_type='application/json',
994 content_disposition='attachment; filename="fname.ext"')
995 self.assertEqual(r.status_code, 201)
997 r.headers['content-type'],
998 'application/json; charset=UTF-8')
999 self.client.container = self.c1
1000 r = self.client.get_object_info(obj)
1001 self.assertTrue('content-disposition' in r)
1002 self.assertTrue('fname.ext' in r['content-disposition'])
1004 ctype = r['content-type']
1005 self.assertEqual(ctype, 'application/json')
1007 """Check ignore_content_type and content_type"""
1008 r = self.client.object_move(
1010 destination='/%s/%s' % (self.c2, obj),
1011 ignore_content_type=True,
1012 content_type='application/json')
1013 self.assertEqual(r.status_code, 201)
1014 self.assertNotEqual(r.headers['content-type'], 'application/json')
1016 """Check if_etag_(not_)match"""
1017 self.client.container = self.c2
1018 r = self.client.object_move(
1020 destination='/%s/%s0' % (self.client.container, obj),
1022 self.assertEqual(r.status_code, 201)
1024 r = self.client.object_move(
1026 destination='/%s/%s1' % (self.client.container, obj),
1027 if_etag_not_match='lalala')
1028 self.assertEqual(r.status_code, 201)
1030 """Check public and format """
1031 r = self.client.object_move(
1033 destination='/%s/%s2' % (self.client.container, obj),
1036 self.assertEqual(r.status_code, 201)
1037 self.assertTrue(r.headers['content-type'].index('xml') > 0)
1039 r = self.client.get_object_info(obj + '2')
1040 self.assertTrue('x-object-public' in r)
1042 def test_object_post(self):
1043 """Test object_POST"""
1044 self._test_0130_object_post()
1046 def _test_0130_object_post(self):
1047 self.client.container = self.c2
1049 """create a filesystem file"""
1050 self.files.append(NamedTemporaryFile())
1051 newf = self.files[-1]
1054 'This is a test line\n',
1055 'inside a test file\n'])
1056 """create a file on container"""
1057 r = self.client.object_put(
1059 content_type='application/octet-stream',
1061 metadata=dict(mkey1='mval1', mkey2='mval2'),
1063 read=['accX:groupA', 'u1', 'u2'],
1064 write=['u2', 'u3']))
1066 """Append livetest update, content_range, content_type, content_length"""
1068 self.client.append_object(obj, newf)
1069 r = self.client.object_get(obj)
1070 self.assertTrue(r.text.startswith('Hello!'))
1072 """Overwrite livetest update,
1073 content_type, content_length, content_range
1076 r = self.client.overwrite_object(obj, 0, 10, newf)
1077 r = self.client.object_get(obj)
1078 self.assertTrue(r.text.startswith('ello!'))
1080 """Truncate livetest update,
1081 content_range, content_type, object_bytes and source_object"""
1082 r = self.client.truncate_object(obj, 5)
1083 r = self.client.object_get(obj)
1084 self.assertEqual(r.text, 'ello!')
1086 """Check metadata"""
1087 self.client.set_object_meta(obj, {'mkey2': 'mval2a', 'mkey3': 'mval3'})
1088 r = self.client.get_object_meta(obj)
1089 self.assertEqual(r['x-object-meta-mkey1'], 'mval1')
1090 self.assertEqual(r['x-object-meta-mkey2'], 'mval2a')
1091 self.assertEqual(r['x-object-meta-mkey3'], 'mval3')
1092 self.client.del_object_meta(obj, 'mkey1')
1093 r = self.client.get_object_meta(obj)
1094 self.assertFalse('x-object-meta-mkey1' in r)
1096 """Check permissions"""
1097 self.client.set_object_sharing(
1099 read_permition=['u4', 'u5'],
1100 write_permition=['u4'])
1101 r = self.client.get_object_sharing(obj)
1102 self.assertTrue('read' in r)
1103 self.assertTrue('u5' in r['read'])
1104 self.assertTrue('write' in r)
1105 self.assertTrue('u4' in r['write'])
1106 self.client.del_object_sharing(obj)
1107 r = self.client.get_object_sharing(obj)
1108 self.assertTrue(len(r) == 0)
1111 self.client.publish_object(obj)
1112 r = self.client.get_object_info(obj)
1113 self.assertTrue('x-object-public' in r)
1114 self.client.unpublish_object(obj)
1115 r = self.client.get_object_info(obj)
1116 self.assertFalse('x-object-public' in r)
1118 """Check if_etag_(not)match"""
1121 r = self.client.object_post(
1125 if_etag_not_match=etag,
1126 success=(412, 202, 204))
1127 self.assertEqual(r.status_code, 412)
1130 r = self.client.object_post(
1135 content_encoding='application/json')
1137 r = self.client.get_object_info(obj)
1138 helloVersion = r['x-object-version']
1139 self.assertTrue('x-object-public' in r)
1140 self.assertEqual(r['content-encoding'], 'application/json')
1142 """Check source_version and source_account and content_disposition"""
1143 r = self.client.object_post(
1146 content_type='application/octet-srteam',
1148 content_range='bytes 1-5/*',
1149 source_object='/%s/%s' % (self.c2, obj),
1150 source_account='thisAccountWillNeverExist@adminland.com',
1151 source_version=helloVersion,
1153 success=(403, 202, 204))
1154 self.assertEqual(r.status_code, 403)
1156 r = self.client.object_post(
1159 content_type='application/octet-srteam',
1161 content_range='bytes 1-5/*',
1162 source_object='/%s/%s' % (self.c2, obj),
1163 source_account=self.client.account,
1164 source_version=helloVersion,
1166 content_disposition='attachment; filename="fname.ext"')
1168 r = self.client.object_get(obj)
1169 self.assertEqual(r.text, 'eello!')
1170 self.assertTrue('content-disposition' in r.headers)
1171 self.assertTrue('fname.ext' in r.headers['content-disposition'])
1173 """Check manifest"""
1174 mobj = 'manifest.test'
1178 r = self.client.object_put(
1179 '%s/%s' % (mobj, i),
1183 content_encoding='application/octet-stream',
1184 content_type='application/octet-stream')
1186 self.client.create_object_by_manifestation(
1188 content_type='application/octet-stream')
1190 r = self.client.object_post(
1192 manifest='%s/%s' % (self.client.container, mobj))
1194 r = self.client.object_get(mobj)
1195 self.assertEqual(r.text, txt)
1197 """We need to check transfer_encoding """
1199 def test_object_delete(self):
1200 """Test object_DELETE"""
1201 self._test_0140_object_delete()
1203 def _test_0140_object_delete(self):
1204 self.client.container = self.c2
1206 """create a file on container"""
1207 r = self.client.object_put(
1209 content_type='application/octet-stream',
1211 metadata=dict(mkey1='mval1', mkey2='mval2'),
1213 read=['accX:groupA', 'u1', 'u2'],
1214 write=['u2', 'u3']))
1216 """Check with false until"""
1217 r = self.client.object_delete(obj, until=1000000)
1219 r = self.client.object_get(obj, success=(200, 404))
1220 self.assertEqual(r.status_code, 200)
1222 """Check normal case"""
1223 r = self.client.object_delete(obj)
1224 self.assertEqual(r.status_code, 204)
1226 r = self.client.object_get(obj, success=(200, 404))
1227 self.assertEqual(r.status_code, 404)
1229 def create_large_file(self, size):
1230 """Create a large file at fs"""
1231 self.files.append(NamedTemporaryFile())
1234 bytelist = [b * Ki for b in range(size / Ki)]
1236 def append2file(step):
1238 f.write(urandom(Ki))
1240 self.do_with_progress_bar(
1242 ' create rand file %s (%sB): ' % (f.name, size),