Revision a3bca46c

b/kamaki/clients/tests/__init__.py
135 135
            if method[0].startswith('_test_')]
136 136
        failures = 0
137 137
        for method in methods:
138
            stdout.write('Test %s' % method[0][6:])
138
            stdout.write('Test %s ' % method[0][6:])
139
            stdout.flush()
139 140
            try:
140 141
                method[1]()
141 142
                print(' ...ok')
......
162 163

  
163 164
def _main(argv, config=None):
164 165
    suiteFew = TestSuite()
165
    """
166 166
    if len(argv) == 0 or argv[0] == 'pithos':
167
        if len(argv) == 1:
168
            suiteFew.addTest(unittest.makeSuite(testPithos))
169
        else:
170
            suiteFew.addTest(testPithos('test_' + argv[1]))
171
    """
167
        from kamaki.clients.tests.pithos import Pithos
168
        test_method = 'test_%s' % (argv[1] if len(argv) > 1 else '000')
169
        suiteFew.addTest(Pithos(test_method, config))
172 170
    if len(argv) == 0 or argv[0] == 'cyclades':
173 171
        from kamaki.clients.tests.cyclades import Cyclades
174 172
        test_method = 'test_%s' % (argv[1] if len(argv) > 1 else '000')
b/kamaki/clients/tests/cyclades.py
65 65
        """Destoy servers used in testing"""
66 66
        for net in self.networks.keys():
67 67
            self._delete_network(net)
68
        #self.do_with_progress_bar(
69
        #    self._delete_network,
70
        #    'Delete %s networks' % len(self.networks),
71
        #    self.networks.keys())
72 68
        for server in self.servers.values():
73 69
            self._delete_server(server['id'])
74 70
            print('DEL VM %s (%s)' % (server['id'], server['name']))
b/kamaki/clients/tests/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
import os
37
import tempfile
38

  
39
from kamaki.clients import tests, ClientError
40
from kamaki.clients.pithos import PithosClient
41

  
42

  
43
class Pithos(tests.Generic):
44

  
45
    fnames = []
46

  
47
    def setUp(self):
48
        self.client = PithosClient(
49
            self['store', 'url'],
50
            self['store', 'token'],
51
            self['store', 'account'])
52

  
53
        self.now = time.mktime(time.gmtime())
54
        self.now_unformated = datetime.datetime.utcnow()
55
        self._init_data()
56

  
57
        """Prepare an object to be shared - also its container"""
58
        self.client.container = self.c1
59
        self.client.object_post('test',
60
            update=True,
61
            permissions={'read': 'someUser'})
62

  
63
        self.create_remote_object(self.c1, 'another.test')
64

  
65
    def _init_data(self):
66
        self.c1 = 'c1_' + unicode(self.now)
67
        self.client.create_container(self.c1)
68
        self.c2 = 'c2_' + unicode(self.now)
69
        self.client.create_container(self.c2)
70
        self.c3 = 'c3_' + unicode(self.now)
71
        self.client.create_container(self.c3)
72

  
73
        self.create_remote_object(self.c1, 'test')
74
        self.create_remote_object(self.c2, 'test')
75
        self.create_remote_object(self.c1, 'test1')
76
        self.create_remote_object(self.c2, 'test1')
77

  
78
    def create_remote_object(self, container, obj):
79
        self.client.container = container
80
        self.client.object_put(obj,
81
            content_type='application/octet-stream',
82
            data='file %s that lives in %s' % (obj, container),
83
            metadata={'incontainer': container})
84

  
85
    def forceDeleteContainer(self, container):
86
        self.client.container = container
87
        try:
88
            r = self.client.list_objects()
89
        except ClientError:
90
            return
91
        for obj in r:
92
            name = obj['name']
93
            self.client.del_object(name)
94
        r = self.client.container_delete()
95
        self.container = ''
96

  
97
    def tearDown(self):
98
        """Destroy test cases"""
99
        for fname in self.fnames:
100
            try:
101
                os.remove(self.fname)
102
            except OSError:
103
                pass
104
        self.forceDeleteContainer(self.c1)
105
        self.forceDeleteContainer(self.c2)
106
        try:
107
            self.forceDeleteContainer(self.c3)
108
        except ClientError:
109
            pass
110
        self.client.container = ''
111

  
112
    def test_000(self):
113
        """Prepare a full Pithos+ test"""
114
        print('')
115
        super(self.__class__, self).test_000()
116

  
117
    def test_account_head(self):
118
        """Test account_HEAD"""
119
        self._test_0010_account_head()
120

  
121
    def _test_0010_account_head(self):
122
        r = self.client.account_head()
123
        self.assertEqual(r.status_code, 204)
124

  
125
        r = self.client.account_head(until='1000000000')
126
        self.assertEqual(r.status_code, 204)
127

  
128
        r = self.client.get_account_info(until='1000000000')
129
        datestring = unicode(r['x-account-until-timestamp'])
130
        self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring)
131

  
132
        r = self.client.get_account_quota()
133
        self.assertTrue('x-account-policy-quota' in r)
134

  
135
        r = self.client.get_account_versioning()
136
        self.assertTrue('x-account-policy-versioning' in r)
137

  
138
        """Check if(un)modified_since"""
139
        for format in self.client.DATE_FORMATS:
140
            now_formated = self.now_unformated.strftime(format)
141
            r1 = self.client.account_head(if_modified_since=now_formated,
142
                success=(204, 304, 412))
143
            sc1 = r1.status_code
144
            r1.release()
145
            r2 = self.client.account_head(if_unmodified_since=now_formated,
146
                success=(204, 304, 412))
147
            sc2 = r2.status_code
148
            r2.release()
149
            self.assertNotEqual(sc1, sc2)
150

  
151
    def test_account_get(self):
152
        """Test account_GET"""
153
        self._test_0020_account_get()
154

  
155
    def _test_0020_account_get(self):
156
        #r = self.client.account_get()
157
        #self.assertEqual(r.status_code, 200)
158
        r = self.client.list_containers()
159
        fullLen = len(r)
160
        self.assertTrue(fullLen > 2)
161

  
162
        r = self.client.account_get(limit=1)
163
        self.assertEqual(len(r.json), 1)
164

  
165
        r = self.client.account_get(marker='c2_')
166
        temp_c0 = r.json[0]['name']
167
        temp_c2 = r.json[2]['name']
168

  
169
        r = self.client.account_get(limit=2, marker='c2_')
170
        conames = [container['name'] for container in r.json \
171
            if container['name'].lower().startswith('c2_')]
172
        self.assertTrue(temp_c0 in conames)
173
        self.assertFalse(temp_c2 in conames)
174

  
175
        r = self.client.account_get(show_only_shared=True)
176
        self.assertTrue(self.c1 in [c['name'] for c in r.json])
177

  
178
        r = self.client.account_get(until=1342609206)
179
        self.assertTrue(len(r.json) <= fullLen)
180

  
181
        """Check if(un)modified_since"""
182
        for format in self.client.DATE_FORMATS:
183
            now_formated = self.now_unformated.strftime(format)
184
            r1 = self.client.account_get(if_modified_since=now_formated,
185
                success=(200, 304, 412))
186
            sc1 = r1.status_code
187
            r1.release()
188
            r2 = self.client.account_get(if_unmodified_since=now_formated,
189
                success=(200, 304, 412))
190
            sc2 = r2.status_code
191
            r2.release()
192
            self.assertNotEqual(sc1, sc2)
193

  
194
        """Check sharing_accounts"""
195
        r = self.client.get_sharing_accounts()
196
        self.assertTrue(len(r) > 0)
197

  
198
    def test_account_post(self):
199
        """Test account_POST"""
200
        self._test_0030_account_post()
201

  
202
    def _test_0030_account_post(self):
203
        r = self.client.account_post()
204
        self.assertEqual(r.status_code, 202)
205
        grpName = 'grp' + unicode(self.now)
206

  
207
        """Method set/del_account_meta and set_account_groupcall use
208
            account_post internally
209
        """
210
        self.client.set_account_group(grpName, ['u1', 'u2'])
211
        r = self.client.get_account_group()
212
        self.assertEqual(r['x-account-group-' + grpName], 'u1,u2')
213
        self.client.del_account_group(grpName)
214
        r = self.client.get_account_group()
215
        self.assertTrue('x-account-group-' + grpName not in r)
216

  
217
        mprefix = 'meta' + unicode(self.now)
218
        self.client.set_account_meta({mprefix + '1': 'v1',
219
            mprefix + '2': 'v2'})
220
        r = self.client.get_account_meta()
221
        self.assertEqual(r['x-account-meta-' + mprefix + '1'], 'v1')
222
        self.assertEqual(r['x-account-meta-' + mprefix + '2'], 'v2')
223

  
224
        self.client.del_account_meta(mprefix + '1')
225
        r = self.client.get_account_meta()
226
        self.assertTrue('x-account-meta-' + mprefix + '1' not in r)
227

  
228
        self.client.del_account_meta(mprefix + '2')
229
        r = self.client.get_account_meta()
230
        self.assertTrue('x-account-meta-' + mprefix + '2' not in r)
231

  
232
        """Missing testing for quota, versioning, because normally
233
        you don't have permissions to modify those at account level
234
        """
235

  
236
        newquota = 1000000
237
        self.client.set_account_quota(newquota)
238
        #r = self.client.get_account_info()
239
        #print(unicode(r))
240
        #r = self.client.get_account_quota()
241
        #self.assertEqual(r['x-account-policy-quota'], newquota)
242
        self.client.set_account_versioning('auto')
243

  
244
    def test_container_head(self):
245
        """Test container_HEAD"""
246
        self._test_0040_container_head()
247

  
248
    def _test_0040_container_head(self):
249
        self.client.container = self.c1
250

  
251
        r = self.client.container_head()
252
        self.assertEqual(r.status_code, 204)
253

  
254
        """Check until"""
255
        r = self.client.container_head(until=1000000, success=(204, 404))
256
        self.assertEqual(r.status_code, 404)
257

  
258
        """Check and if(un)modified_since"""
259
        for format in self.client.DATE_FORMATS:
260
            now_formated = self.now_unformated.strftime(format)
261
            r1 = self.client.container_head(if_modified_since=now_formated,
262
                success=(204, 304, 412))
263
            sc1 = r1.status_code
264
            r1.release()
265
            r2 = self.client.container_head(if_unmodified_since=now_formated,
266
                success=(204, 304, 412))
267
            sc2 = r2.status_code
268
            r2.release()
269
            self.assertNotEqual(sc1, sc2)
270

  
271
        """Check container object meta"""
272
        r = self.client.get_container_object_meta()
273
        self.assertEqual(r['x-container-object-meta'], 'Incontainer')
274

  
275
    def test_container_get(self):
276
        """Test container_GET"""
277
        self._test_0050_container_get()
278

  
279
    def _test_0050_container_get(self):
280
        self.client.container = self.c1
281

  
282
        r = self.client.container_get()
283
        self.assertEqual(r.status_code, 200)
284
        fullLen = len(r.json)
285

  
286
        r = self.client.container_get(prefix='test')
287
        lalobjects = [obj for obj in r.json if obj['name'].startswith('test')]
288
        self.assertTrue(len(r.json) > 1)
289
        self.assertEqual(len(r.json), len(lalobjects))
290

  
291
        r = self.client.container_get(limit=1)
292
        self.assertEqual(len(r.json), 1)
293

  
294
        r = self.client.container_get(marker='another')
295
        self.assertTrue(len(r.json) > 1)
296
        neobjects = [obj for obj in r.json if obj['name'] > 'another']
297
        self.assertEqual(len(r.json), len(neobjects))
298

  
299
        r = self.client.container_get(prefix='another.test', delimiter='.')
300
        self.assertTrue(fullLen > len(r.json))
301

  
302
        r = self.client.container_get(path='/')
303
        self.assertEqual(fullLen, len(r.json))
304

  
305
        r = self.client.container_get(format='xml')
306
        self.assertEqual(r.text.split()[4], 'name="' + self.c1 + '">')
307

  
308
        r = self.client.container_get(meta=['incontainer'])
309
        self.assertTrue(len(r.json) > 0)
310

  
311
        r = self.client.container_get(show_only_shared=True)
312
        self.assertTrue(len(r.json) < fullLen)
313

  
314
        try:
315
            r = self.client.container_get(until=1000000000)
316
            datestring = unicode(r.headers['x-account-until-timestamp'])
317
            self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring)
318

  
319
        except ClientError:
320

  
321
            pass
322

  
323
        """Check and if un/modified_since"""
324
        for format in self.client.DATE_FORMATS:
325
            now_formated = self.now_unformated.strftime(format)
326
            r1 = self.client.container_get(if_modified_since=now_formated,
327
                success=(200, 304, 412))
328
            sc1 = r1.status_code
329
            r1.release()
330
            r2 = self.client.container_get(if_unmodified_since=now_formated,
331
                success=(200, 304, 412))
332
            sc2 = r2.status_code
333
            r2.release()
334
            self.assertNotEqual(sc1, sc2)
335

  
336
    def test_container_put(self):
337
        """Test container_PUT"""
338
        self._test_0050_container_put()
339

  
340
    def _test_0050_container_put(self):
341
        self.client.container = self.c2
342

  
343
        r = self.client.container_put()
344
        self.assertEqual(r.status_code, 202)
345

  
346
        r = self.client.get_container_quota(self.client.container)
347
        cquota = r.values()[0]
348
        newquota = 2 * int(cquota)
349

  
350
        r = self.client.container_put(quota=newquota)
351
        self.assertEqual(r.status_code, 202)
352

  
353
        r = self.client.get_container_quota(self.client.container)
354
        xquota = int(r.values()[0])
355
        self.assertEqual(newquota, xquota)
356

  
357
        r = self.client.container_put(versioning='auto')
358
        self.assertEqual(r.status_code, 202)
359

  
360
        r = self.client.get_container_versioning(self.client.container)
361
        nvers = r.values()[0]
362
        self.assertEqual('auto', nvers)
363

  
364
        r = self.client.container_put(versioning='none')
365
        self.assertEqual(r.status_code, 202)
366

  
367
        r = self.client.get_container_versioning(self.client.container)
368
        nvers = r.values()[0]
369
        self.assertEqual('none', nvers)
370

  
371
        r = self.client.container_put(metadata={'m1': 'v1', 'm2': 'v2'})
372
        self.assertEqual(r.status_code, 202)
373

  
374
        r = self.client.get_container_meta(self.client.container)
375
        self.assertTrue('x-container-meta-m1' in r)
376
        self.assertEqual(r['x-container-meta-m1'], 'v1')
377
        self.assertTrue('x-container-meta-m2' in r)
378
        self.assertEqual(r['x-container-meta-m2'], 'v2')
379

  
380
        r = self.client.container_put(metadata={'m1': '', 'm2': 'v2a'})
381
        self.assertEqual(r.status_code, 202)
382

  
383
        r = self.client.get_container_meta(self.client.container)
384
        self.assertTrue('x-container-meta-m1' not in r)
385
        self.assertTrue('x-container-meta-m2' in r)
386
        self.assertEqual(r['x-container-meta-m2'], 'v2a')
387

  
388
        self.client.del_container_meta(self.client.container)
389

  
390
    def test_container_post(self):
391
        """Test container_POST"""
392
        self._test_0060_container_post()
393

  
394
    def _test_0060_container_post(self):
395
        self.client.container = self.c2
396

  
397
        """Simple post"""
398
        r = self.client.container_post()
399
        self.assertEqual(r.status_code, 202)
400

  
401
        """post meta"""
402
        self.client.set_container_meta({'m1': 'v1', 'm2': 'v2'})
403
        r = self.client.get_container_meta(self.client.container)
404
        self.assertTrue('x-container-meta-m1' in r)
405
        self.assertEqual(r['x-container-meta-m1'], 'v1')
406
        self.assertTrue('x-container-meta-m2' in r)
407
        self.assertEqual(r['x-container-meta-m2'], 'v2')
408

  
409
        """post/2del meta"""
410
        r = self.client.del_container_meta('m1')
411
        r = self.client.set_container_meta({'m2': 'v2a'})
412
        r = self.client.get_container_meta(self.client.container)
413
        self.assertTrue('x-container-meta-m1' not in r)
414
        self.assertTrue('x-container-meta-m2' in r)
415
        self.assertEqual(r['x-container-meta-m2'], 'v2a')
416

  
417
        """check quota"""
418
        r = self.client.get_container_quota(self.client.container)
419
        cquota = r.values()[0]
420
        newquota = 2 * int(cquota)
421
        r = self.client.set_container_quota(newquota)
422
        r = self.client.get_container_quota(self.client.container)
423
        xquota = int(r.values()[0])
424
        self.assertEqual(newquota, xquota)
425
        r = self.client.set_container_quota(cquota)
426
        r = self.client.get_container_quota(self.client.container)
427
        xquota = r.values()[0]
428
        self.assertEqual(cquota, xquota)
429

  
430
        """Check versioning"""
431
        self.client.set_container_versioning('auto')
432
        r = self.client.get_container_versioning(self.client.container)
433
        nvers = r.values()[0]
434
        self.assertEqual('auto', nvers)
435
        self.client.set_container_versioning('none')
436
        r = self.client.get_container_versioning(self.client.container)
437
        nvers = r.values()[0]
438
        self.assertEqual('none', nvers)
439

  
440
        """put_block uses content_type and content_length to
441
        post blocks of data 2 container. All that in upload_object"""
442
        """Change a file at fs"""
443
        fname = 'l100M.' + unicode(self.now)
444
        self.create_large_file(1024 * 1024 * 100, fname)
445
        self.fnames.append(fname)
446
        """Upload it at a directory in container"""
447
        self.client.create_directory('dir')
448
        newf = open(fname, 'rb')
449
        self.client.upload_object('/dir/sample.file', newf)
450
        newf.close()
451
        """Check if file has been uploaded"""
452
        r = self.client.get_object_info('/dir/sample.file')
453
        self.assertTrue(int(r['content-length']) > 100000000)
454

  
455
        """What is tranfer_encoding? What should I check about it? """
456
        #TODO
457

  
458
        """Check update=False"""
459
        r = self.client.object_post('test',
460
            update=False,
461
            metadata={'newmeta': 'newval'})
462

  
463
        r = self.client.get_object_info('test')
464
        self.assertTrue('x-object-meta-newmeta' in r)
465
        self.assertFalse('x-object-meta-incontainer' in r)
466

  
467
        r = self.client.del_container_meta('m2')
468

  
469
    def test_container_delete(self):
470
        """Test container_DELETE"""
471
        self._test_0070_container_delete()
472

  
473
    def _test_0070_container_delete(self):
474

  
475
        """Fail to delete a non-empty container"""
476
        self.client.container = self.c2
477
        r = self.client.container_delete(success=409)
478
        self.assertEqual(r.status_code, 409)
479

  
480
        """Fail to delete c3 (empty) container"""
481
        self.client.container = self.c3
482
        r = self.client.container_delete(until='1000000000')
483
        self.assertEqual(r.status_code, 204)
484

  
485
        """Delete c3 (empty) container"""
486
        r = self.client.container_delete()
487
        self.assertEqual(r.status_code, 204)
488

  
489
        """Purge container(empty a container), check versionlist"""
490
        self.client.container = self.c1
491
        r = self.client.object_head('test', success=(200, 404))
492
        self.assertEqual(r.status_code, 200)
493
        self.client.del_container(delimiter='/')
494
        r = self.client.object_head('test', success=(200, 404))
495
        self.assertEqual(r.status_code, 404)
496
        r = self.client.get_object_versionlist('test')
497
        self.assertTrue(len(r) > 0)
498
        self.assertTrue(len(r[0]) > 1)
499
        self.client.purge_container()
500
        self.assertRaises(ClientError,
501
            self.client.get_object_versionlist,
502
            'test')
503

  
504
    def _test_0080_recreate_deleted_data(self):
505
        self._init_data()
506

  
507
    def test_object_head(self):
508
        """Test object_HEAD"""
509
        self._test_0090_object_head()
510

  
511
    def _test_0090_object_head(self):
512
        self.client.container = self.c2
513
        obj = 'test'
514

  
515
        r = self.client.object_head(obj)
516
        self.assertEqual(r.status_code, 200)
517
        etag = r.headers['etag']
518

  
519
        r = self.client.object_head(obj, version=40)
520
        self.assertEqual(r.headers['x-object-version'], '40')
521

  
522
        r = self.client.object_head(obj, if_etag_match=etag)
523
        self.assertEqual(r.status_code, 200)
524

  
525
        r = self.client.object_head(obj,
526
            if_etag_not_match=etag,
527
            success=(200, 412, 304))
528
        self.assertNotEqual(r.status_code, 200)
529

  
530
        r = self.client.object_head(obj,
531
            version=40,
532
            if_etag_match=etag,
533
            success=412)
534
        self.assertEqual(r.status_code, 412)
535

  
536
        """Check and if(un)modified_since"""
537
        for format in self.client.DATE_FORMATS:
538
            now_formated = self.now_unformated.strftime(format)
539
            r1 = self.client.object_head(obj, if_modified_since=now_formated,
540
                success=(200, 304, 412))
541
            sc1 = r1.status_code
542
            r1.release()
543
            r2 = self.client.object_head(obj, if_unmodified_since=now_formated,
544
                success=(200, 304, 412))
545
            sc2 = r2.status_code
546
            r2.release()
547
            self.assertNotEqual(sc1, sc2)
548

  
549
    def test_object_get(self):
550
        """Test object_GET"""
551
        self._test_0100_object_get()
552

  
553
    def _test_0100_object_get(self):
554
        self.client.container = self.c1
555
        obj = 'test'
556

  
557
        r = self.client.object_get(obj)
558
        self.assertEqual(r.status_code, 200)
559

  
560
        osize = int(r.headers['content-length'])
561
        etag = r.headers['etag']
562

  
563
        r = self.client.object_get(obj, hashmap=True)
564
        self.assertTrue('hashes' in r.json\
565
            and 'block_hash' in r.json\
566
            and 'block_size' in r.json\
567
            and 'bytes' in r.json)
568

  
569
        r = self.client.object_get(obj, format='xml', hashmap=True)
570
        self.assertEqual(len(r.text.split('hash>')), 3)
571

  
572
        rangestr = 'bytes=%s-%s' % (osize / 3, osize / 2)
573
        r = self.client.object_get(obj,
574
            data_range=rangestr,
575
            success=(200, 206))
576
        partsize = int(r.headers['content-length'])
577
        self.assertTrue(0 < partsize and partsize <= 1 + osize / 3)
578

  
579
        rangestr = 'bytes=%s-%s' % (osize / 3, osize / 2)
580
        r = self.client.object_get(obj,
581
            data_range=rangestr,
582
            if_range=True,
583
            success=(200, 206))
584
        partsize = int(r.headers['content-length'])
585
        self.assertTrue(0 < partsize and partsize <= 1 + osize / 3)
586

  
587
        r = self.client.object_get(obj, if_etag_match=etag)
588
        self.assertEqual(r.status_code, 200)
589

  
590
        r = self.client.object_get(obj, if_etag_not_match=etag + 'LALALA')
591
        self.assertEqual(r.status_code, 200)
592

  
593
        """Check and if(un)modified_since"""
594
        for format in self.client.DATE_FORMATS:
595
            now_formated = self.now_unformated.strftime(format)
596
            r1 = self.client.object_get(obj, if_modified_since=now_formated,
597
                success=(200, 304, 412))
598
            sc1 = r1.status_code
599
            r1.release()
600
            r2 = self.client.object_get(obj,
601
                if_unmodified_since=now_formated,
602
                success=(200, 304, 412))
603
            sc2 = r2.status_code
604
            r2.release()
605
            self.assertNotEqual(sc1, sc2)
606

  
607
        """Upload an object to download"""
608
        src_file = tempfile.NamedTemporaryFile(delete=False)
609
        dnl_file = tempfile.NamedTemporaryFile(delete=False)
610

  
611
        src_fname = src_file.name
612
        dnl_fname = dnl_file.name
613

  
614
        src_file.close()
615
        dnl_file.close()
616

  
617
        trg_fname = 'remotefile_%s' % self.now
618
        f_size = 59247824
619
        self.create_large_file(f_size, src_fname)
620
        src_f = open(src_fname, 'rb+')
621
        print('\tUploading...')
622
        self.client.upload_object(trg_fname, src_f)
623
        src_f.close()
624
        print('\tDownloading...')
625
        dnl_f = open(dnl_fname, 'wb+')
626
        self.client.download_object(trg_fname, dnl_f)
627
        dnl_f.close()
628

  
629
        print('\tCheck if files match...')
630
        src_f = open(src_fname)
631
        dnl_f = open(dnl_fname)
632
        for pos in (0, f_size / 2, f_size - 20):
633
            src_f.seek(pos)
634
            dnl_f.seek(pos)
635
            self.assertEqual(src_f.read(10), dnl_f.read(10))
636
        src_f.close()
637
        dnl_f.close()
638

  
639
        os.remove(src_fname)
640
        os.remove(dnl_fname)
641

  
642
    def test_object_put(self):
643
        """Test object_PUT"""
644
        self._test_object_put()
645

  
646
    def _test_object_put(self):
647
        self.client.container = self.c2
648
        obj = 'another.test'
649

  
650
        self.client.create_object(obj + '.FAKE')
651
        r = self.client.get_object_info(obj + '.FAKE')
652
        self.assertEqual(r['content-type'], 'application/octet-stream')
653

  
654
        """create the object"""
655
        r = self.client.object_put(obj,
656
            data='a',
657
            content_type='application/octer-stream',
658
            permissions={
659
                'read': ['accX:groupA', 'u1', 'u2'],
660
                'write': ['u2', 'u3']},
661
            metadata={'key1': 'val1', 'key2': 'val2'},
662
            content_encoding='UTF-8',
663
            content_disposition='attachment; filename="fname.ext"')
664
        self.assertEqual(r.status_code, 201)
665
        etag = r.headers['etag']
666

  
667
        """Check content-disposition"""
668
        r = self.client.get_object_info(obj)
669
        self.assertTrue('content-disposition' in r)
670

  
671
        """Check permissions"""
672
        r = self.client.get_object_sharing(obj)
673
        self.assertTrue('accx:groupa' in r['read'])
674
        self.assertTrue('u1' in r['read'])
675
        self.assertTrue('u2' in r['write'])
676
        self.assertTrue('u3' in r['write'])
677

  
678
        """Check metadata"""
679
        r = self.client.get_object_meta(obj)
680
        self.assertEqual(r['x-object-meta-key1'], 'val1')
681
        self.assertEqual(r['x-object-meta-key2'], 'val2')
682

  
683
        """Check public and if_etag_match"""
684
        r = self.client.object_put(obj, if_etag_match=etag, data='b',
685
            content_type='application/octet-stream', public=True)
686

  
687
        r = self.client.object_get(obj)
688
        self.assertTrue('x-object-public' in r.headers)
689
        vers2 = int(r.headers['x-object-version'])
690
        etag = r.headers['etag']
691
        self.assertEqual(r.text, 'b')
692

  
693
        """Check if_etag_not_match"""
694
        r = self.client.object_put(obj, if_etag_not_match=etag, data='c',
695
            content_type='application/octet-stream', success=(201, 412))
696
        self.assertEqual(r.status_code, 412)
697

  
698
        """Check content_type and content_length"""
699
        tmpdir = 'dir' + unicode(self.now)
700
        r = self.client.object_put(tmpdir,
701
            content_type='application/directory',
702
            content_length=0)
703

  
704
        r = self.client.get_object_info(tmpdir)
705
        self.assertEqual(r['content-type'], 'application/directory')
706

  
707
        """Check copy_from, content_encoding"""
708
        r = self.client.object_put('%s/%s' % (tmpdir, obj),
709
            format=None,
710
            copy_from='/%s/%s' % (self.client.container, obj),
711
            content_encoding='application/octet-stream',
712
            source_account=self.client.account,
713
            content_length=0, success=201)
714
        self.assertEqual(r.status_code, 201)
715

  
716
        """Test copy_object for cross-conctainer copy"""
717
        self.client.copy_object(src_container=self.c2,
718
            src_object='%s/%s' % (tmpdir, obj),
719
            dst_container=self.c1,
720
            dst_object=obj)
721
        self.client.container = self.c1
722
        r1 = self.client.get_object_info(obj)
723
        self.client.container = self.c2
724
        r2 = self.client.get_object_info('%s/%s' % (tmpdir, obj))
725
        self.assertEqual(r1['x-object-hash'], r2['x-object-hash'])
726

  
727
        """Check cross-container copy_from, content_encoding"""
728
        self.client.container = self.c1
729
        fromstr = '/%s/%s/%s' % (self.c2, tmpdir, obj)
730
        r = self.client.object_put(obj,
731
            format=None,
732
            copy_from=fromstr,
733
            content_encoding='application/octet-stream',
734
            source_account=self.client.account,
735
            content_length=0, success=201)
736

  
737
        self.assertEqual(r.status_code, 201)
738
        r = self.client.get_object_info(obj)
739
        self.assertEqual(r['etag'], etag)
740

  
741
        """Check source_account"""
742
        self.client.container = self.c2
743
        fromstr = '/%s/%s' % (self.c1, obj)
744
        r = self.client.object_put(obj + 'v2',
745
            format=None,
746
            move_from=fromstr,
747
            content_encoding='application/octet-stream',
748
            source_account='nonExistendAddress@NeverLand.com',
749
            content_length=0,
750
            success=(201, 403))
751
        self.assertEqual(r.status_code, 403)
752

  
753
        """Check cross-container move_from"""
754
        self.client.container = self.c1
755
        r1 = self.client.get_object_info(obj)
756
        self.client.container = self.c2
757
        self.client.move_object(src_container=self.c1,
758
            src_object=obj,
759
            dst_container=self.c2,
760
            dst_object=obj + 'v0')
761
        r0 = self.client.get_object_info(obj + 'v0')
762
        self.assertEqual(r1['x-object-hash'], r0['x-object-hash'])
763

  
764
        """Check move_from"""
765
        r = self.client.object_put(obj + 'v1',
766
            format=None,
767
            move_from='/%s/%s' % (self.c2, obj),
768
            source_version=vers2,
769
            content_encoding='application/octet-stream',
770
            content_length=0, success=201)
771

  
772
        """Check manifest"""
773
        mobj = 'manifest.test'
774
        txt = ''
775
        for i in range(10):
776
            txt += '%s' % i
777
            r = self.client.object_put('%s/%s' % (mobj, i),
778
                data='%s' % i,
779
                content_length=1,
780
                success=201,
781
                content_type='application/octet-stream',
782
                content_encoding='application/octet-stream')
783

  
784
        r = self.client.object_put(mobj,
785
            content_length=0,
786
            content_type='application/octet-stream',
787
            manifest='%s/%s' % (self.client.container, mobj))
788

  
789
        r = self.client.object_get(mobj)
790
        self.assertEqual(r.text, txt)
791

  
792
        """Upload a local file with one request"""
793
        fname = 'l10K.' + unicode(self.now)
794
        self.create_large_file(1024 * 10, fname)
795
        self.fnames.append(fname)
796
        newf = open(fname, 'rb')
797
        self.client.upload_object('sample.file', newf)
798
        newf.close()
799
        """Check if file has been uploaded"""
800
        r = self.client.get_object_info('sample.file')
801
        self.assertEqual(int(r['content-length']), 10260)
802

  
803
        """Some problems with transfer-encoding?"""
804

  
805
    def test_object_copy(self):
806
        """Test object_COPY"""
807
        self._test_0110_object_copy()
808

  
809
    def _test_0110_object_copy(self):
810
        self.client.container = self.c2
811
        obj = 'test2'
812

  
813
        data = '{"key1":"val1", "key2":"val2"}'
814
        r = self.client.object_put(obj + 'orig',
815
            content_type='application/octet-stream',
816
            data=data,
817
            metadata={'mkey1': 'mval1', 'mkey2': 'mval2'},
818
            permissions={
819
                'read': ['accX:groupA', 'u1', 'u2'],
820
                'write': ['u2', 'u3']},
821
            content_disposition='attachment; filename="fname.ext"')
822

  
823
        r = self.client.object_copy(obj + 'orig',
824
            destination='/%s/%s' % (self.client.container, obj),
825
            ignore_content_type=False, content_type='application/json',
826
            metadata={'mkey2': 'mval2a', 'mkey3': 'mval3'},
827
            permissions={'write': ['u5', 'accX:groupB']})
828
        self.assertEqual(r.status_code, 201)
829

  
830
        """Check content-disposition"""
831
        r = self.client.get_object_info(obj)
832
        self.assertTrue('content-disposition' in r)
833

  
834
        """Check Metadata"""
835
        r = self.client.get_object_meta(obj)
836
        self.assertEqual(r['x-object-meta-mkey1'], 'mval1')
837
        self.assertEqual(r['x-object-meta-mkey2'], 'mval2a')
838
        self.assertEqual(r['x-object-meta-mkey3'], 'mval3')
839

  
840
        """Check permissions"""
841
        r = self.client.get_object_sharing(obj)
842
        self.assertFalse('read' in r or 'u2' in r['write'])
843
        self.assertTrue('accx:groupb' in r['write'])
844

  
845
        """Check destination account"""
846
        r = self.client.object_copy(obj,
847
            destination='/%s/%s' % (self.c1, obj),
848
            content_encoding='utf8',
849
            content_type='application/json',
850
            destination_account='nonExistendAddress@NeverLand.com',
851
            success=(201, 403))
852
        self.assertEqual(r.status_code, 403)
853

  
854
        """Check destination being another container
855
        and also content_type and content encoding"""
856
        r = self.client.object_copy(obj,
857
            destination='/%s/%s' % (self.c1, obj),
858
            content_encoding='utf8',
859
            content_type='application/json')
860
        self.assertEqual(r.status_code, 201)
861
        self.assertEqual(r.headers['content-type'],
862
            'application/json; charset=UTF-8')
863

  
864
        """Check ignore_content_type and content_type"""
865
        r = self.client.object_get(obj)
866
        etag = r.headers['etag']
867
        ctype = r.headers['content-type']
868
        self.assertEqual(ctype, 'application/json')
869

  
870
        r = self.client.object_copy(obj + 'orig',
871
            destination='/%s/%s0' % (self.client.container, obj),
872
            ignore_content_type=True,
873
            content_type='application/json')
874
        self.assertEqual(r.status_code, 201)
875
        self.assertNotEqual(r.headers['content-type'], 'application/json')
876

  
877
        """Check if_etag_(not_)match"""
878
        r = self.client.object_copy(obj,
879
            destination='/%s/%s1' % (self.client.container, obj),
880
            if_etag_match=etag)
881
        self.assertEqual(r.status_code, 201)
882

  
883
        r = self.client.object_copy(obj,
884
            destination='/%s/%s2' % (self.client.container, obj),
885
            if_etag_not_match='lalala')
886
        self.assertEqual(r.status_code, 201)
887
        vers2 = r.headers['x-object-version']
888

  
889
        """Check source_version, public and format """
890
        r = self.client.object_copy(obj + '2',
891
            destination='/%s/%s3' % (self.client.container, obj),
892
            source_version=vers2,
893
            format='xml',
894
            public=True)
895
        self.assertEqual(r.status_code, 201)
896
        self.assertTrue(r.headers['content-type'].index('xml') > 0)
897

  
898
        r = self.client.get_object_info(obj + '3')
899
        self.assertTrue('x-object-public' in r)
900

  
901
    def test_object_move(self):
902
        """Test object_MOVE"""
903
        self._test_0120_object_move()
904

  
905
    def _test_0120_object_move(self):
906
        self.client.container = self.c2
907
        obj = 'test2'
908

  
909
        data = '{"key1": "val1", "key2": "val2"}'
910
        r = self.client.object_put(obj + 'orig',
911
            content_type='application/octet-stream',
912
            data=data,
913
            metadata={'mkey1': 'mval1', 'mkey2': 'mval2'},
914
            permissions={'read': ['accX:groupA', 'u1', 'u2'],
915
                'write': ['u2', 'u3']})
916

  
917
        r = self.client.object_move(obj + 'orig',
918
            destination='/%s/%s' % (self.client.container, obj),
919
            ignore_content_type=False,
920
            content_type='application/json',
921
            metadata={'mkey2': 'mval2a', 'mkey3': 'mval3'},
922
            permissions={'write': ['u5', 'accX:groupB']})
923
        self.assertEqual(r.status_code, 201)
924

  
925
        """Check Metadata"""
926
        r = self.client.get_object_meta(obj)
927
        self.assertEqual(r['x-object-meta-mkey1'], 'mval1')
928
        self.assertEqual(r['x-object-meta-mkey2'], 'mval2a')
929
        self.assertEqual(r['x-object-meta-mkey3'], 'mval3')
930

  
931
        """Check permissions"""
932
        r = self.client.get_object_sharing(obj)
933
        self.assertFalse('read' in r)
934
        self.assertTrue('u5' in r['write'])
935
        self.assertTrue('accx:groupb' in r['write'])
936

  
937
        """Check destination account"""
938
        r = self.client.object_move(obj,
939
            destination='/%s/%s' % (self.c1, obj),
940
            content_encoding='utf8',
941
            content_type='application/json',
942
            destination_account='nonExistendAddress@NeverLand.com',
943
            success=(201, 403))
944
        self.assertEqual(r.status_code, 403)
945

  
946
        """Check destination being another container and also
947
        content_type, content_disposition and content encoding"""
948
        r = self.client.object_move(obj,
949
            destination='/%s/%s' % (self.c1, obj),
950
            content_encoding='utf8',
951
            content_type='application/json',
952
            content_disposition='attachment; filename="fname.ext"')
953
        self.assertEqual(r.status_code, 201)
954
        self.assertEqual(r.headers['content-type'],
955
            'application/json; charset=UTF-8')
956
        self.client.container = self.c1
957
        r = self.client.get_object_info(obj)
958
        self.assertTrue('content-disposition' in r\
959
            and 'fname.ext' in r['content-disposition'])
960
        etag = r['etag']
961
        ctype = r['content-type']
962
        self.assertEqual(ctype, 'application/json')
963

  
964
        """Check ignore_content_type and content_type"""
965
        r = self.client.object_move(obj,
966
            destination='/%s/%s' % (self.c2, obj),
967
            ignore_content_type=True,
968
            content_type='application/json')
969
        self.assertEqual(r.status_code, 201)
970
        self.assertNotEqual(r.headers['content-type'], 'application/json')
971

  
972
        """Check if_etag_(not_)match"""
973
        self.client.container = self.c2
974
        r = self.client.object_move(obj,
975
            destination='/%s/%s0' % (self.client.container, obj),
976
            if_etag_match=etag)
977
        self.assertEqual(r.status_code, 201)
978

  
979
        r = self.client.object_move(obj + '0',
980
            destination='/%s/%s1' % (self.client.container, obj),
981
            if_etag_not_match='lalala')
982
        self.assertEqual(r.status_code, 201)
983

  
984
        """Check public and format """
985
        r = self.client.object_move(obj + '1',
986
            destination='/%s/%s2' % (self.client.container, obj),
987
            format='xml', public=True)
988
        self.assertEqual(r.status_code, 201)
989
        self.assertTrue(r.headers['content-type'].index('xml') > 0)
990

  
991
        r = self.client.get_object_info(obj + '2')
992
        self.assertTrue('x-object-public' in r)
993

  
994
    def test_object_post(self):
995
        """Test object_POST"""
996
        self._test_0130_object_post()
997

  
998
    def _test_0130_object_post(self):
999
        self.client.container = self.c2
1000
        obj = 'test2'
1001
        """create a filesystem file"""
1002
        self.fnames.append(obj)
1003
        newf = open(self.fnames[-1], 'w')
1004
        newf.writelines(['ello!\n',
1005
            'This is a test line\n',
1006
            'inside a test file\n'])
1007
        newf.close()
1008
        """create a file on container"""
1009
        r = self.client.object_put(obj,
1010
            content_type='application/octet-stream',
1011
            data='H',
1012
            metadata={'mkey1': 'mval1', 'mkey2': 'mval2'},
1013
            permissions={'read': ['accX:groupA', 'u1', 'u2'],
1014
                'write': ['u2', 'u3']})
1015

  
1016
        """Append tests update, content_range, content_type, content_length"""
1017
        newf = open(obj, 'r')
1018
        self.client.append_object(obj, newf)
1019
        r = self.client.object_get(obj)
1020
        self.assertTrue(r.text.startswith('Hello!'))
1021

  
1022
        """Overwrite tests update,
1023
            content_type, content_length, content_range
1024
        """
1025
        newf.seek(0)
1026
        r = self.client.overwrite_object(obj, 0, 10, newf)
1027
        r = self.client.object_get(obj)
1028
        self.assertTrue(r.text.startswith('ello!'))
1029
        newf.close()
1030

  
1031
        """Truncate tests update,
1032
            content_range, content_type, object_bytes and source_object"""
1033
        r = self.client.truncate_object(obj, 5)
1034
        r = self.client.object_get(obj)
1035
        self.assertEqual(r.text, 'ello!')
1036

  
1037
        """Check metadata"""
1038
        self.client.set_object_meta(obj, {'mkey2': 'mval2a', 'mkey3': 'mval3'})
1039
        r = self.client.get_object_meta(obj)
1040
        self.assertEqual(r['x-object-meta-mkey1'], 'mval1')
1041
        self.assertEqual(r['x-object-meta-mkey2'], 'mval2a')
1042
        self.assertEqual(r['x-object-meta-mkey3'], 'mval3')
1043
        self.client.del_object_meta(obj, 'mkey1')
1044
        r = self.client.get_object_meta(obj)
1045
        self.assertFalse('x-object-meta-mkey1' in r)
1046

  
1047
        """Check permissions"""
1048
        self.client.set_object_sharing(obj,
1049
            read_permition=['u4', 'u5'], write_permition=['u4'])
1050
        r = self.client.get_object_sharing(obj)
1051
        self.assertTrue('read' in r)
1052
        self.assertTrue('u5' in r['read'])
1053
        self.assertTrue('write' in r)
1054
        self.assertTrue('u4' in r['write'])
1055
        self.client.del_object_sharing(obj)
1056
        r = self.client.get_object_sharing(obj)
1057
        self.assertTrue(len(r) == 0)
1058

  
1059
        """Check publish"""
1060
        self.client.publish_object(obj)
1061
        r = self.client.get_object_info(obj)
1062
        self.assertTrue('x-object-public' in r)
1063
        self.client.unpublish_object(obj)
1064
        r = self.client.get_object_info(obj)
1065
        self.assertFalse('x-object-public' in r)
1066

  
1067
        """Check if_etag_(not)match"""
1068
        etag = r['etag']
1069
        """
1070
        r = self.client.object_post(obj,
1071
            update=True,
1072
            public=True,
1073
            if_etag_not_match=etag,
1074
            success=(412, 202, 204))
1075
        self.assertEqual(r.status_code, 412)
1076
        """
1077

  
1078
        r = self.client.object_post(obj, update=True, public=True,
1079
            if_etag_match=etag, content_encoding='application/json')
1080

  
1081
        r = self.client.get_object_info(obj)
1082
        helloVersion = r['x-object-version']
1083
        self.assertTrue('x-object-public' in r)
1084
        self.assertEqual(r['content-encoding'], 'application/json')
1085

  
1086
        """Check source_version and source_account and content_disposition"""
1087
        r = self.client.object_post(obj,
1088
            update=True,
1089
            content_type='application/octet-srteam',
1090
            content_length=5,
1091
            content_range='bytes 1-5/*',
1092
            source_object='/%s/%s' % (self.c2, obj),
1093
            source_account='thisAccountWillNeverExist@adminland.com',
1094
            source_version=helloVersion,
1095
            data='12345',
1096
            success=(403, 202, 204))
1097
        self.assertEqual(r.status_code, 403)
1098

  
1099
        r = self.client.object_post(obj,
1100
            update=True,
1101
            content_type='application/octet-srteam',
1102
            content_length=5,
1103
            content_range='bytes 1-5/*',
1104
            source_object='/%s/%s' % (self.c2, obj),
1105
            source_account=self.client.account,
1106
            source_version=helloVersion,
1107
            data='12345',
1108
            content_disposition='attachment; filename="fname.ext"')
1109

  
1110
        r = self.client.object_get(obj)
1111
        self.assertEqual(r.text, 'eello!')
1112
        self.assertTrue('content-disposition' in r.headers\
1113
            and 'fname.ext' in r.headers['content-disposition'])
1114

  
1115
        """Check manifest"""
1116
        mobj = 'manifest.test'
1117
        txt = ''
1118
        for i in range(10):
1119
            txt += '%s' % i
1120
            r = self.client.object_put('%s/%s' % (mobj, i),
1121
            data='%s' % i,
1122
            content_length=1,
1123
            success=201,
1124
            content_encoding='application/octet-stream',
1125
            content_type='application/octet-stream')
1126

  
1127
        self.client.create_object_by_manifestation(mobj,
1128
            content_type='application/octet-stream')
1129

  
1130
        r = self.client.object_post(mobj,
1131
            manifest='%s/%s' % (self.client.container, mobj))
1132

  
1133
        r = self.client.object_get(mobj)
1134
        self.assertEqual(r.text, txt)
1135

  
1136
        """We need to check transfer_encoding """
1137

  
1138
    def test_object_delete(self):
1139
        """Test object_DELETE"""
1140
        self._test_0140_object_delete()
1141

  
1142
    def _test_0140_object_delete(self):
1143
        self.client.container = self.c2
1144
        obj = 'test2'
1145
        """create a file on container"""
1146
        r = self.client.object_put(obj,
1147
            content_type='application/octet-stream',
1148
            data='H',
1149
            metadata={'mkey1': 'mval1', 'mkey2': 'mval2'},
1150
            permissions={'read': ['accX:groupA', 'u1', 'u2'],
1151
                'write': ['u2', 'u3']})
1152

  
1153
        """Check with false until"""
1154
        r = self.client.object_delete(obj, until=1000000)
1155

  
1156
        r = self.client.object_get(obj, success=(200, 404))
1157
        self.assertEqual(r.status_code, 200)
1158

  
1159
        """Check normal case"""
1160
        r = self.client.object_delete(obj)
1161
        self.assertEqual(r.status_code, 204)
1162

  
1163
        r = self.client.object_get(obj, success=(200, 404))
1164
        self.assertEqual(r.status_code, 404)
1165

  
1166
    def create_large_file(self, size, name):
1167
        """Create a large file at fs"""
1168
        with open(self.fname, 'w') as f:
1169
            def append2file(step):
1170
                f.seek(step)
1171
                f.write(os.urandom(8))
1172
            self.do_with_progress_bar(
1173
                append2file,
1174
                ' create rand file %s (%sB): ' % (name, size),
1175
                [hobyte * 8 for hobyte in xrange(size / 8)])

Also available in: Unified diff