Rename tests to livetest in kamaki.clients
[kamaki] / kamaki / clients / livetest / pithos.py
1 # Copyright 2012-2013 GRNET S.A. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or
4 # without modification, are permitted provided that the following
5 # conditions are met:
6 #
7 #   1. Redistributions of source code must retain the above
8 #      copyright notice, this list of conditions and the following
9 #      disclaimer.
10 #
11 #   2. Redistributions in binary form must reproduce the above
12 #      copyright notice, this list of conditions and the following
13 #      disclaimer in the documentation and/or other materials
14 #      provided with the distribution.
15 #
16 # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 # POSSIBILITY OF SUCH DAMAGE.
28 #
29 # The views and conclusions contained in the software and
30 # documentation are those of the authors and should not be
31 # interpreted as representing official policies, either expressed
32 # or implied, of GRNET S.A.
33
34 import time
35 import datetime
36 from os import urandom
37 from tempfile import NamedTemporaryFile
38
39 from kamaki.clients import livetest, ClientError
40 from kamaki.clients.pithos import PithosClient
41 from kamaki.clients.astakos import AstakosClient
42
43
44 class Pithos(livetest.Generic):
45
46     files = []
47
48     def setUp(self):
49         self.client = PithosClient(
50             self['store', 'url'],
51             self['store', 'token'],
52             AstakosClient(
53                 self['astakos', 'url'],
54                 self['store', 'token']
55             ).term('uuid'))
56
57         self.now = time.mktime(time.gmtime())
58         self.now_unformated = datetime.datetime.utcnow()
59         self._init_data()
60
61         """Prepare an object to be shared - also its container"""
62         self.client.container = self.c1
63         self.client.object_post(
64             'test',
65             update=True,
66             permissions={'read': [self.client.account]})
67
68         self.create_remote_object(self.c1, 'another.test')
69
70     def _init_data(self):
71         self.c1 = 'c1_' + unicode(self.now)
72         self.c2 = 'c2_' + unicode(self.now)
73         self.c3 = 'c3_' + unicode(self.now)
74         try:
75             self.client.create_container(self.c2)
76         except ClientError:
77             pass
78         try:
79             self.client.create_container(self.c1)
80         except ClientError:
81             pass
82         try:
83             self.client.create_container(self.c3)
84         except ClientError:
85             pass
86
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')
91
92     def create_remote_object(self, container, obj):
93         self.client.container = container
94         self.client.object_put(
95             obj,
96             content_type='application/octet-stream',
97             data='file %s that lives in %s' % (obj, container),
98             metadata={'incontainer': container})
99
100     def forceDeleteContainer(self, container):
101         self.client.container = container
102         try:
103             r = self.client.list_objects()
104         except ClientError:
105             return
106         for obj in r:
107             name = obj['name']
108             self.client.del_object(name)
109         r = self.client.container_delete()
110         self.container = ''
111
112     def tearDown(self):
113         """Destroy test cases"""
114         for f in self.files:
115             f.close()
116         self.forceDeleteContainer(self.c1)
117         self.forceDeleteContainer(self.c2)
118         try:
119             self.forceDeleteContainer(self.c3)
120         except ClientError:
121             pass
122         self.client.container = ''
123
124     def test_000(self):
125         """Prepare a full Pithos+ test"""
126         print('')
127         super(self.__class__, self).test_000()
128
129     def test_account_head(self):
130         """Test account_HEAD"""
131         self._test_0010_account_head()
132
133     def _test_0010_account_head(self):
134         r = self.client.account_head()
135         self.assertEqual(r.status_code, 204)
136
137         r = self.client.account_head(until='1000000000')
138         self.assertEqual(r.status_code, 204)
139
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)
143
144         r = self.client.get_account_quota()
145         self.assertTrue('x-account-policy-quota' in r)
146
147         r = self.client.get_account_versioning()
148         self.assertTrue('x-account-policy-versioning' in r)
149
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))
156             sc1 = r1.status_code
157             r1.release()
158             r2 = self.client.account_head(
159                 if_unmodified_since=now_formated,
160                 success=(204, 304, 412))
161             sc2 = r2.status_code
162             r2.release()
163             self.assertNotEqual(sc1, sc2)
164
165     def test_account_get(self):
166         """Test account_GET"""
167         self._test_0020_account_get()
168
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()
173         fullLen = len(r)
174         self.assertTrue(fullLen > 2)
175
176         r = self.client.account_get(limit=1)
177         self.assertEqual(len(r.json), 1)
178
179         r = self.client.account_get(marker='c2_')
180         temp_c0 = r.json[0]['name']
181         temp_c2 = r.json[2]['name']
182
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)
188
189         r = self.client.account_get(show_only_shared=True)
190         self.assertTrue(self.c1 in [c['name'] for c in r.json])
191
192         r = self.client.account_get(until=1342609206)
193         self.assertTrue(len(r.json) <= fullLen)
194
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))
201             sc1 = r1.status_code
202             r1.release()
203             r2 = self.client.account_get(
204                 if_unmodified_since=now_formated,
205                 success=(200, 304, 412))
206             sc2 = r2.status_code
207             r2.release()
208             self.assertNotEqual(sc1, sc2)
209
210         """Check sharing_accounts"""
211         r = self.client.get_sharing_accounts()
212         self.assertTrue(len(r) > 0)
213
214     def test_account_post(self):
215         """Test account_POST"""
216         self._test_0030_account_post()
217
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)
222
223         """Method set/del_account_meta and set_account_groupcall use
224             account_post internally
225         """
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)
234
235         mprefix = 'meta' + unicode(self.now)
236         self.client.set_account_meta({
237             mprefix + '1': 'v1',
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')
242
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)
246
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)
250
251         """Missing testing for quota, versioning, because normally
252         you don't have permissions to modify those at account level
253         """
254
255         newquota = 1000000
256         self.client.set_account_quota(newquota)
257         #r = self.client.get_account_info()
258         #print(unicode(r))
259         #r = self.client.get_account_quota()
260         #self.assertEqual(r['x-account-policy-quota'], newquota)
261         self.client.set_account_versioning('auto')
262
263     def test_container_head(self):
264         """Test container_HEAD"""
265         self._test_0040_container_head()
266
267     def _test_0040_container_head(self):
268         self.client.container = self.c1
269
270         r = self.client.container_head()
271         self.assertEqual(r.status_code, 204)
272
273         """Check until"""
274         r = self.client.container_head(until=1000000, success=(204, 404))
275         self.assertEqual(r.status_code, 404)
276
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))
283             sc1 = r1.status_code
284             r1.release()
285             r2 = self.client.container_head(
286                 if_unmodified_since=now_formated,
287                 success=(204, 304, 412))
288             sc2 = r2.status_code
289             r2.release()
290             self.assertNotEqual(sc1, sc2)
291
292         """Check container object meta"""
293         r = self.client.get_container_object_meta()
294         self.assertEqual(r['x-container-object-meta'], 'Incontainer')
295
296     def test_container_get(self):
297         """Test container_GET"""
298         self._test_0050_container_get()
299
300     def _test_0050_container_get(self):
301         self.client.container = self.c1
302
303         r = self.client.container_get()
304         self.assertEqual(r.status_code, 200)
305         fullLen = len(r.json)
306
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))
311
312         r = self.client.container_get(limit=1)
313         self.assertEqual(len(r.json), 1)
314
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))
319
320         r = self.client.container_get(prefix='another.test', delimiter='.')
321         self.assertTrue(fullLen > len(r.json))
322
323         r = self.client.container_get(path='/')
324         self.assertEqual(fullLen, len(r.json))
325
326         r = self.client.container_get(format='xml')
327         self.assertEqual(r.text.split()[4], 'name="' + self.c1 + '">')
328
329         r = self.client.container_get(meta=['incontainer'])
330         self.assertTrue(len(r.json) > 0)
331
332         r = self.client.container_get(show_only_shared=True)
333         self.assertTrue(len(r.json) < fullLen)
334
335         try:
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)
339
340         except ClientError:
341
342             pass
343
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))
350             sc1 = r1.status_code
351             r1.release()
352             r2 = self.client.container_get(
353                 if_unmodified_since=now_formated,
354                 success=(200, 304, 412))
355             sc2 = r2.status_code
356             r2.release()
357             self.assertNotEqual(sc1, sc2)
358
359     def test_container_put(self):
360         """Test container_PUT"""
361         self._test_0050_container_put()
362
363     def _test_0050_container_put(self):
364         self.client.container = self.c2
365
366         r = self.client.container_put()
367         self.assertEqual(r.status_code, 202)
368
369         r = self.client.get_container_quota(self.client.container)
370         cquota = r.values()[0]
371         newquota = 2 * int(cquota)
372
373         r = self.client.container_put(quota=newquota)
374         self.assertEqual(r.status_code, 202)
375
376         r = self.client.get_container_quota(self.client.container)
377         xquota = int(r.values()[0])
378         self.assertEqual(newquota, xquota)
379
380         r = self.client.container_put(versioning='auto')
381         self.assertEqual(r.status_code, 202)
382
383         r = self.client.get_container_versioning(self.client.container)
384         nvers = r.values()[0]
385         self.assertEqual('auto', nvers)
386
387         r = self.client.container_put(versioning='none')
388         self.assertEqual(r.status_code, 202)
389
390         r = self.client.get_container_versioning(self.client.container)
391         nvers = r.values()[0]
392         self.assertEqual('none', nvers)
393
394         r = self.client.container_put(metadata={'m1': 'v1', 'm2': 'v2'})
395         self.assertEqual(r.status_code, 202)
396
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')
402
403         r = self.client.container_put(metadata={'m1': '', 'm2': 'v2a'})
404         self.assertEqual(r.status_code, 202)
405
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')
410
411         self.client.del_container_meta(self.client.container)
412
413     def test_container_post(self):
414         """Test container_POST"""
415         self._test_0060_container_post()
416
417     def _test_0060_container_post(self):
418         self.client.container = self.c2
419
420         """Simple post"""
421         r = self.client.container_post()
422         self.assertEqual(r.status_code, 202)
423
424         """post meta"""
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')
431
432         """post/2del meta"""
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')
439
440         """check quota"""
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)
452
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)
462
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)
473
474         """What is tranfer_encoding? What should I check about it? """
475         #TODO
476
477         """Check update=False"""
478         r = self.client.object_post(
479             'test',
480             update=False,
481             metadata={'newmeta': 'newval'})
482
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)
486
487         r = self.client.del_container_meta('m2')
488
489     def test_container_delete(self):
490         """Test container_DELETE"""
491         self._test_0070_container_delete()
492
493     def _test_0070_container_delete(self):
494
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)
499
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)
504
505         """Delete c3 (empty) container"""
506         r = self.client.container_delete()
507         self.assertEqual(r.status_code, 204)
508
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()
520         self.assertRaises(
521             ClientError,
522             self.client.get_object_versionlist,
523             'test')
524
525     def _test_0080_recreate_deleted_data(self):
526         self._init_data()
527
528     def test_object_head(self):
529         """Test object_HEAD"""
530         self._test_0090_object_head()
531
532     def _test_0090_object_head(self):
533         self.client.container = self.c2
534         obj = 'test'
535
536         r = self.client.object_head(obj)
537         self.assertEqual(r.status_code, 200)
538         etag = r.headers['etag']
539
540         r = self.client.object_head(obj, version=40)
541         self.assertEqual(r.headers['x-object-version'], '40')
542
543         r = self.client.object_head(obj, if_etag_match=etag)
544         self.assertEqual(r.status_code, 200)
545
546         r = self.client.object_head(
547             obj,
548             if_etag_not_match=etag,
549             success=(200, 412, 304))
550         self.assertNotEqual(r.status_code, 200)
551
552         r = self.client.object_head(
553             obj,
554             version=40,
555             if_etag_match=etag,
556             success=412)
557         self.assertEqual(r.status_code, 412)
558
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(
563                 obj,
564                 if_modified_since=now_formated,
565                 success=(200, 304, 412))
566             sc1 = r1.status_code
567             r1.release()
568             r2 = self.client.object_head(
569                 obj,
570                 if_unmodified_since=now_formated,
571                 success=(200, 304, 412))
572             sc2 = r2.status_code
573             r2.release()
574             self.assertNotEqual(sc1, sc2)
575
576     def test_object_get(self):
577         """Test object_GET"""
578         self._test_0100_object_get()
579
580     def _test_0100_object_get(self):
581         self.client.container = self.c1
582         obj = 'test'
583
584         r = self.client.object_get(obj)
585         self.assertEqual(r.status_code, 200)
586
587         osize = int(r.headers['content-length'])
588         etag = r.headers['etag']
589
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)
593
594         r = self.client.object_get(obj, format='xml', hashmap=True)
595         self.assertEqual(len(r.text.split('hash>')), 3)
596
597         rangestr = 'bytes=%s-%s' % (osize / 3, osize / 2)
598         r = self.client.object_get(
599             obj,
600             data_range=rangestr,
601             success=(200, 206))
602         partsize = int(r.headers['content-length'])
603         self.assertTrue(0 < partsize and partsize <= 1 + osize / 3)
604
605         rangestr = 'bytes=%s-%s' % (osize / 3, osize / 2)
606         r = self.client.object_get(
607             obj,
608             data_range=rangestr,
609             if_range=True,
610             success=(200, 206))
611         partsize = int(r.headers['content-length'])
612         self.assertTrue(0 < partsize and partsize <= 1 + osize / 3)
613
614         r = self.client.object_get(obj, if_etag_match=etag)
615         self.assertEqual(r.status_code, 200)
616
617         r = self.client.object_get(obj, if_etag_not_match=etag + 'LALALA')
618         self.assertEqual(r.status_code, 200)
619
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(
624                 obj,
625                 if_modified_since=now_formated,
626                 success=(200, 304, 412))
627             sc1 = r1.status_code
628             r1.release()
629             r2 = self.client.object_get(
630                 obj,
631                 if_unmodified_since=now_formated,
632                 success=(200, 304, 412))
633             sc2 = r2.status_code
634             r2.release()
635             self.assertNotEqual(sc1, sc2)
636
637         """Upload an object to download"""
638         trg_fname = 'remotefile_%s' % self.now
639         f_size = 59247824
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)
647
648         print('\tCheck if files match...')
649         for pos in (0, f_size / 2, f_size - 20):
650             src_f.seek(pos)
651             dnl_f.seek(pos)
652             self.assertEqual(src_f.read(10), dnl_f.read(10))
653
654     def test_object_put(self):
655         """Test object_PUT"""
656         self._test_object_put()
657
658     def _test_object_put(self):
659         self.client.container = self.c2
660         obj = 'another.test'
661
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')
665
666         """create the object"""
667         r = self.client.object_put(
668             obj,
669             data='a',
670             content_type='application/octer-stream',
671             permissions=dict(
672                 read=['accX:groupA', 'u1', 'u2'],
673                 write=['u2', 'u3']),
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']
679
680         """Check content-disposition"""
681         r = self.client.get_object_info(obj)
682         self.assertTrue('content-disposition' in r)
683
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'])
690
691         """Check metadata"""
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')
695
696         """Check public and if_etag_match"""
697         r = self.client.object_put(
698             obj,
699             if_etag_match=etag,
700             data='b',
701             content_type='application/octet-stream',
702             public=True)
703
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')
709
710         """Check if_etag_not_match"""
711         r = self.client.object_put(
712             obj,
713             if_etag_not_match=etag,
714             data='c',
715             content_type='application/octet-stream',
716             success=(201, 412))
717         self.assertEqual(r.status_code, 412)
718
719         """Check content_type and content_length"""
720         tmpdir = 'dir' + unicode(self.now)
721         r = self.client.object_put(
722             tmpdir,
723             content_type='application/directory',
724             content_length=0)
725
726         r = self.client.get_object_info(tmpdir)
727         self.assertEqual(r['content-type'], 'application/directory')
728
729         """Check copy_from, content_encoding"""
730         r = self.client.object_put(
731             '%s/%s' % (tmpdir, obj),
732             format=None,
733             copy_from='/%s/%s' % (self.client.container, obj),
734             content_encoding='application/octet-stream',
735             source_account=self.client.account,
736             content_length=0,
737             success=201)
738         self.assertEqual(r.status_code, 201)
739
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,
745             dst_object=obj)
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'])
751
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(
756             obj,
757             format=None,
758             copy_from=fromstr,
759             content_encoding='application/octet-stream',
760             source_account=self.client.account,
761             content_length=0,
762             success=201)
763
764         self.assertEqual(r.status_code, 201)
765         r = self.client.get_object_info(obj)
766         self.assertEqual(r['etag'], etag)
767
768         """Check source_account"""
769         self.client.container = self.c2
770         fromstr = '/%s/%s' % (self.c1, obj)
771         r = self.client.object_put(
772             '%sv2' % obj,
773             format=None,
774             move_from=fromstr,
775             content_encoding='application/octet-stream',
776             source_account='nonExistendAddress@NeverLand.com',
777             content_length=0,
778             success=(201, 403))
779         self.assertEqual(r.status_code, 403)
780
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,
787             src_object=obj,
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'])
792
793         """Check move_from"""
794         r = self.client.object_put(
795             '%sv1' % obj,
796             format=None,
797             move_from='/%s/%s' % (self.c2, obj),
798             source_version=vers2,
799             content_encoding='application/octet-stream',
800             content_length=0, success=201)
801
802         """Check manifest"""
803         mobj = 'manifest.test'
804         txt = ''
805         for i in range(10):
806             txt += '%s' % i
807             r = self.client.object_put(
808                 '%s/%s' % (mobj, i),
809                 data='%s' % i,
810                 content_length=1,
811                 success=201,
812                 content_type='application/octet-stream',
813                 content_encoding='application/octet-stream')
814
815         r = self.client.object_put(
816             mobj,
817             content_length=0,
818             content_type='application/octet-stream',
819             manifest='%s/%s' % (self.client.container, mobj))
820
821         r = self.client.object_get(mobj)
822         self.assertEqual(r.text, txt)
823
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)
830
831         """Some problems with transfer-encoding?"""
832
833     def test_object_copy(self):
834         """Test object_COPY"""
835         self._test_0110_object_copy()
836
837     def _test_0110_object_copy(self):
838         self.client.container = self.c2
839         obj = 'test2'
840
841         data = '{"key1":"val1", "key2":"val2"}'
842         r = self.client.object_put(
843             '%sorig' % obj,
844             content_type='application/octet-stream',
845             data=data,
846             metadata=dict(mkey1='mval1', mkey2='mval2'),
847             permissions=dict(
848                 read=['accX:groupA', 'u1', 'u2'],
849                 write=['u2', 'u3']),
850             content_disposition='attachment; filename="fname.ext"')
851
852         r = self.client.object_copy(
853             '%sorig' % obj,
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)
859
860         """Check content-disposition"""
861         r = self.client.get_object_info(obj)
862         self.assertTrue('content-disposition' in r)
863
864         """Check Metadata"""
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')
869
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'])
874
875         """Check destination account"""
876         r = self.client.object_copy(
877             obj,
878             destination='/%s/%s' % (self.c1, obj),
879             content_encoding='utf8',
880             content_type='application/json',
881             destination_account='nonExistendAddress@NeverLand.com',
882             success=(201, 403))
883         self.assertEqual(r.status_code, 403)
884
885         """Check destination being another container
886         and also content_type and content encoding"""
887         r = self.client.object_copy(
888             obj,
889             destination='/%s/%s' % (self.c1, obj),
890             content_encoding='utf8',
891             content_type='application/json')
892         self.assertEqual(r.status_code, 201)
893         self.assertEqual(
894             r.headers['content-type'],
895             'application/json; charset=UTF-8')
896
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')
902
903         r = self.client.object_copy(
904             '%sorig' % obj,
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')
910
911         """Check if_etag_(not_)match"""
912         r = self.client.object_copy(
913             obj,
914             destination='/%s/%s1' % (self.client.container, obj),
915             if_etag_match=etag)
916         self.assertEqual(r.status_code, 201)
917
918         r = self.client.object_copy(
919             obj,
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']
924
925         """Check source_version, public and format """
926         r = self.client.object_copy(
927             '%s2' % obj,
928             destination='/%s/%s3' % (self.client.container, obj),
929             source_version=vers2,
930             format='xml',
931             public=True)
932         self.assertEqual(r.status_code, 201)
933         self.assertTrue(r.headers['content-type'].index('xml') > 0)
934
935         r = self.client.get_object_info(obj + '3')
936         self.assertTrue('x-object-public' in r)
937
938     def test_object_move(self):
939         """Test object_MOVE"""
940         self._test_0120_object_move()
941
942     def _test_0120_object_move(self):
943         self.client.container = self.c2
944         obj = 'test2'
945
946         data = '{"key1": "val1", "key2": "val2"}'
947         r = self.client.object_put(
948             '%sorig' % obj,
949             content_type='application/octet-stream',
950             data=data,
951             metadata=dict(mkey1='mval1', mkey2='mval2'),
952             permissions=dict(
953                 read=['accX:groupA', 'u1', 'u2'],
954                 write=['u2', 'u3']))
955
956         r = self.client.object_move(
957             '%sorig' % obj,
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)
964
965         """Check Metadata"""
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')
970
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'])
976
977         """Check destination account"""
978         r = self.client.object_move(
979             obj,
980             destination='/%s/%s' % (self.c1, obj),
981             content_encoding='utf8',
982             content_type='application/json',
983             destination_account='nonExistendAddress@NeverLand.com',
984             success=(201, 403))
985         self.assertEqual(r.status_code, 403)
986
987         """Check destination being another container and also
988         content_type, content_disposition and content encoding"""
989         r = self.client.object_move(
990             obj,
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)
996         self.assertEqual(
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'])
1003         etag = r['etag']
1004         ctype = r['content-type']
1005         self.assertEqual(ctype, 'application/json')
1006
1007         """Check ignore_content_type and content_type"""
1008         r = self.client.object_move(
1009             obj,
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')
1015
1016         """Check if_etag_(not_)match"""
1017         self.client.container = self.c2
1018         r = self.client.object_move(
1019             obj,
1020             destination='/%s/%s0' % (self.client.container, obj),
1021             if_etag_match=etag)
1022         self.assertEqual(r.status_code, 201)
1023
1024         r = self.client.object_move(
1025             '%s0' % obj,
1026             destination='/%s/%s1' % (self.client.container, obj),
1027             if_etag_not_match='lalala')
1028         self.assertEqual(r.status_code, 201)
1029
1030         """Check public and format """
1031         r = self.client.object_move(
1032             '%s1' % obj,
1033             destination='/%s/%s2' % (self.client.container, obj),
1034             format='xml',
1035             public=True)
1036         self.assertEqual(r.status_code, 201)
1037         self.assertTrue(r.headers['content-type'].index('xml') > 0)
1038
1039         r = self.client.get_object_info(obj + '2')
1040         self.assertTrue('x-object-public' in r)
1041
1042     def test_object_post(self):
1043         """Test object_POST"""
1044         self._test_0130_object_post()
1045
1046     def _test_0130_object_post(self):
1047         self.client.container = self.c2
1048         obj = 'test2'
1049         """create a filesystem file"""
1050         self.files.append(NamedTemporaryFile())
1051         newf = self.files[-1]
1052         newf.writelines([
1053             'ello!\n',
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(
1058             obj,
1059             content_type='application/octet-stream',
1060             data='H',
1061             metadata=dict(mkey1='mval1', mkey2='mval2'),
1062             permissions=dict(
1063                 read=['accX:groupA', 'u1', 'u2'],
1064                 write=['u2', 'u3']))
1065
1066         """Append livetest update, content_range, content_type, content_length"""
1067         newf.seek(0)
1068         self.client.append_object(obj, newf)
1069         r = self.client.object_get(obj)
1070         self.assertTrue(r.text.startswith('Hello!'))
1071
1072         """Overwrite livetest update,
1073             content_type, content_length, content_range
1074         """
1075         newf.seek(0)
1076         r = self.client.overwrite_object(obj, 0, 10, newf)
1077         r = self.client.object_get(obj)
1078         self.assertTrue(r.text.startswith('ello!'))
1079
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!')
1085
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)
1095
1096         """Check permissions"""
1097         self.client.set_object_sharing(
1098             obj,
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)
1109
1110         """Check publish"""
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)
1117
1118         """Check if_etag_(not)match"""
1119         etag = r['etag']
1120         """
1121         r = self.client.object_post(
1122             obj,
1123             update=True,
1124             public=True,
1125             if_etag_not_match=etag,
1126             success=(412, 202, 204))
1127         self.assertEqual(r.status_code, 412)
1128         """
1129
1130         r = self.client.object_post(
1131             obj,
1132             update=True,
1133             public=True,
1134             if_etag_match=etag,
1135             content_encoding='application/json')
1136
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')
1141
1142         """Check source_version and source_account and content_disposition"""
1143         r = self.client.object_post(
1144             obj,
1145             update=True,
1146             content_type='application/octet-srteam',
1147             content_length=5,
1148             content_range='bytes 1-5/*',
1149             source_object='/%s/%s' % (self.c2, obj),
1150             source_account='thisAccountWillNeverExist@adminland.com',
1151             source_version=helloVersion,
1152             data='12345',
1153             success=(403, 202, 204))
1154         self.assertEqual(r.status_code, 403)
1155
1156         r = self.client.object_post(
1157             obj,
1158             update=True,
1159             content_type='application/octet-srteam',
1160             content_length=5,
1161             content_range='bytes 1-5/*',
1162             source_object='/%s/%s' % (self.c2, obj),
1163             source_account=self.client.account,
1164             source_version=helloVersion,
1165             data='12345',
1166             content_disposition='attachment; filename="fname.ext"')
1167
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'])
1172
1173         """Check manifest"""
1174         mobj = 'manifest.test'
1175         txt = ''
1176         for i in range(10):
1177             txt += '%s' % i
1178             r = self.client.object_put(
1179                 '%s/%s' % (mobj, i),
1180                 data='%s' % i,
1181                 content_length=1,
1182                 success=201,
1183                 content_encoding='application/octet-stream',
1184                 content_type='application/octet-stream')
1185
1186         self.client.create_object_by_manifestation(
1187             mobj,
1188             content_type='application/octet-stream')
1189
1190         r = self.client.object_post(
1191             mobj,
1192             manifest='%s/%s' % (self.client.container, mobj))
1193
1194         r = self.client.object_get(mobj)
1195         self.assertEqual(r.text, txt)
1196
1197         """We need to check transfer_encoding """
1198
1199     def test_object_delete(self):
1200         """Test object_DELETE"""
1201         self._test_0140_object_delete()
1202
1203     def _test_0140_object_delete(self):
1204         self.client.container = self.c2
1205         obj = 'test2'
1206         """create a file on container"""
1207         r = self.client.object_put(
1208             obj,
1209             content_type='application/octet-stream',
1210             data='H',
1211             metadata=dict(mkey1='mval1', mkey2='mval2'),
1212             permissions=dict(
1213                 read=['accX:groupA', 'u1', 'u2'],
1214                 write=['u2', 'u3']))
1215
1216         """Check with false until"""
1217         r = self.client.object_delete(obj, until=1000000)
1218
1219         r = self.client.object_get(obj, success=(200, 404))
1220         self.assertEqual(r.status_code, 200)
1221
1222         """Check normal case"""
1223         r = self.client.object_delete(obj)
1224         self.assertEqual(r.status_code, 204)
1225
1226         r = self.client.object_get(obj, success=(200, 404))
1227         self.assertEqual(r.status_code, 404)
1228
1229     def create_large_file(self, size):
1230         """Create a large file at fs"""
1231         self.files.append(NamedTemporaryFile())
1232         f = self.files[-1]
1233         Ki = size / 8
1234         bytelist = [b * Ki for b in range(size / Ki)]
1235
1236         def append2file(step):
1237             f.seek(step)
1238             f.write(urandom(Ki))
1239             f.flush()
1240         self.do_with_progress_bar(
1241             append2file,
1242             ' create rand file %s (%sB): ' % (f.name, size),
1243             bytelist)
1244         f.seek(0)
1245         return f