root / snf-tools / synnefo_tools / burnin / pithos_tests.py @ e7f5ebd0
History | View | Annotate | Download (44 kB)
1 |
# Copyright 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 |
"""
|
35 |
This is the burnin class that tests the Pithos functionality
|
36 |
|
37 |
"""
|
38 |
|
39 |
import random |
40 |
from datetime import datetime |
41 |
from tempfile import NamedTemporaryFile |
42 |
|
43 |
from synnefo_tools.burnin.common import BurninTests, Proper |
44 |
from kamaki.clients import ClientError |
45 |
|
46 |
|
47 |
def sample_block(f, block): |
48 |
block_size = 4 * 1024 * 1024 |
49 |
f.seek(block * block_size) |
50 |
ch = [f.read(1)]
|
51 |
f.seek(block_size / 2, 1) |
52 |
ch.append(f.read(1))
|
53 |
f.seek((block + 1) * block_size - 1) |
54 |
ch.append(f.read(1))
|
55 |
return ch
|
56 |
|
57 |
|
58 |
# Too many public methods. pylint: disable-msg=R0904
|
59 |
class PithosTestSuite(BurninTests): |
60 |
"""Test Pithos functionality"""
|
61 |
containers = Proper(value=None)
|
62 |
created_container = Proper(value=None)
|
63 |
now_unformated = Proper(value=datetime.utcnow()) |
64 |
obj_metakey = Proper(value=None)
|
65 |
large_file = Proper(value=None)
|
66 |
|
67 |
def test_005_account_head(self): |
68 |
"""Test account HEAD"""
|
69 |
self._set_pithos_account(self._get_uuid()) |
70 |
pithos = self.clients.pithos
|
71 |
r = pithos.account_head() |
72 |
self.assertEqual(r.status_code, 204) |
73 |
self.info('Returns 204') |
74 |
|
75 |
r = pithos.account_head(until='1000000000')
|
76 |
self.assertEqual(r.status_code, 204) |
77 |
datestring = unicode(r.headers['x-account-until-timestamp']) |
78 |
self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring) |
79 |
self.assertTrue('x-account-policy-quota' in r.headers) |
80 |
self.info('Until and policy quota exist') |
81 |
|
82 |
for format in pithos.DATE_FORMATS: |
83 |
now_formated = self.now_unformated.strftime(format)
|
84 |
r1 = pithos.account_head( |
85 |
if_modified_since=now_formated, success=(204, 304, 412)) |
86 |
r2 = pithos.account_head( |
87 |
if_unmodified_since=now_formated, success=(204, 304, 412)) |
88 |
self.assertNotEqual(r1.status_code, r2.status_code)
|
89 |
self.info('If_(un)modified_since is OK') |
90 |
|
91 |
def test_010_account_get(self): |
92 |
"""Test account GET"""
|
93 |
self.info('Preparation') |
94 |
pithos = self.clients.pithos
|
95 |
for i in range(1, 3): |
96 |
cont_name = "cont%s_%s%s" % (
|
97 |
i, self.run_id or 0, random.randint(1000, 9999)) |
98 |
self._create_pithos_container(cont_name)
|
99 |
pithos.container, obj = cont_name, 'shared_file'
|
100 |
pithos.create_object(obj) |
101 |
pithos.set_object_sharing(obj, read_permission='*')
|
102 |
self.info('Created object /%s/%s' % (cont_name, obj)) |
103 |
|
104 |
# Try to re-create the same container
|
105 |
pithos.create_container(cont_name) |
106 |
|
107 |
r = pithos.list_containers() |
108 |
fullLen = len(r)
|
109 |
self.assertTrue(fullLen > 2) |
110 |
self.info('Normal use is OK') |
111 |
|
112 |
cnames = [c['name'] for c in r] |
113 |
self.assertEqual(sorted(list(set(cnames))), sorted(cnames)) |
114 |
self.info('Containers have unique names') |
115 |
|
116 |
r = pithos.account_get(limit=1)
|
117 |
self.assertEqual(len(r.json), 1) |
118 |
self.info('Limit works') |
119 |
|
120 |
r = pithos.account_get(marker='cont')
|
121 |
cont1, cont3 = r.json[0], r.json[2] |
122 |
self.info('Marker works') |
123 |
|
124 |
r = pithos.account_get(limit=2, marker='cont') |
125 |
conames = [container['name'] for container in r.json if ( |
126 |
container['name'].lower().startswith('cont'))] |
127 |
self.assertTrue(cont1['name'] in conames) |
128 |
self.assertFalse(cont3['name'] in conames) |
129 |
self.info('Marker-limit combination works') |
130 |
|
131 |
r = pithos.account_get(show_only_shared=True)
|
132 |
self.assertTrue(cont_name in [c['name'] for c in r.json]) |
133 |
self.info('Show-only-shared works') |
134 |
|
135 |
r = pithos.account_get(until=1342609206.0)
|
136 |
self.assertTrue(len(r.json) <= fullLen) |
137 |
self.info('Until works') |
138 |
|
139 |
for format in pithos.DATE_FORMATS: |
140 |
now_formated = self.now_unformated.strftime(format)
|
141 |
r1 = pithos.account_get( |
142 |
if_modified_since=now_formated, success=(200, 304, 412)) |
143 |
r2 = pithos.account_get( |
144 |
if_unmodified_since=now_formated, success=(200, 304, 412)) |
145 |
self.assertNotEqual(r1.status_code, r2.status_code)
|
146 |
self.info('If_(un)modified_since is OK') |
147 |
|
148 |
def test_015_account_post(self): |
149 |
"""Test account POST"""
|
150 |
pithos = self.clients.pithos
|
151 |
r = pithos.account_post() |
152 |
self.assertEqual(r.status_code, 202) |
153 |
self.info('Status code is OK') |
154 |
|
155 |
rand_num = '%s%s' % (self.run_id or 0, random.randint(1000, 9999)) |
156 |
grpName = 'grp%s' % rand_num
|
157 |
|
158 |
u1, u2 = pithos.account, 'invalid-user-uuid-%s' % rand_num
|
159 |
self.assertRaises(
|
160 |
ClientError, pithos.set_account_group, grpName, [u1, u2]) |
161 |
self.info('Invalid uuid is handled correctly') |
162 |
|
163 |
pithos.set_account_group(grpName, [u1]) |
164 |
r = pithos.get_account_group() |
165 |
self.assertEqual(r['x-account-group-' + grpName], '%s' % u1) |
166 |
self.info('Account group is OK') |
167 |
pithos.del_account_group(grpName) |
168 |
r = pithos.get_account_group() |
169 |
self.assertTrue('x-account-group-' + grpName not in r) |
170 |
self.info('Removed account group') |
171 |
|
172 |
mprefix = 'meta%s' % rand_num
|
173 |
pithos.set_account_meta({ |
174 |
mprefix + '1': 'v1', mprefix + '2': 'v2'}) |
175 |
r = pithos.get_account_meta() |
176 |
self.assertEqual(r['x-account-meta-' + mprefix + '1'], 'v1') |
177 |
self.assertEqual(r['x-account-meta-' + mprefix + '2'], 'v2') |
178 |
self.info('Account meta is OK') |
179 |
|
180 |
pithos.del_account_meta(mprefix + '1')
|
181 |
r = pithos.get_account_meta() |
182 |
self.assertTrue('x-account-meta-' + mprefix + '1' not in r) |
183 |
self.assertTrue('x-account-meta-' + mprefix + '2' in r) |
184 |
self.info('Selective removal of account meta is OK') |
185 |
|
186 |
pithos.del_account_meta(mprefix + '2')
|
187 |
r = pithos.get_account_meta() |
188 |
self.assertTrue('x-account-meta-' + mprefix + '2' not in r) |
189 |
self.info('Temporary account meta are removed') |
190 |
|
191 |
def test_020_container_head(self): |
192 |
"""Test container HEAD"""
|
193 |
pithos = self.clients.pithos
|
194 |
r = pithos.container_head() |
195 |
self.assertEqual(r.status_code, 204) |
196 |
self.info('Status code is OK') |
197 |
|
198 |
r = pithos.container_head(until=1000000, success=(204, 404)) |
199 |
self.assertEqual(r.status_code, 404) |
200 |
self.info('Until works') |
201 |
|
202 |
for format in pithos.DATE_FORMATS: |
203 |
now_formated = self.now_unformated.strftime(format)
|
204 |
r1 = pithos.container_head( |
205 |
if_modified_since=now_formated, success=(204, 304, 412)) |
206 |
r2 = pithos.container_head( |
207 |
if_unmodified_since=now_formated, success=(204, 304, 412)) |
208 |
self.assertNotEqual(r1.status_code, r2.status_code)
|
209 |
|
210 |
k = 'metakey%s' % random.randint(1000, 9999) |
211 |
pithos.set_container_meta({k: 'our value'})
|
212 |
r = pithos.get_container_meta() |
213 |
k = 'x-container-meta-%s' % k
|
214 |
self.assertIn(k, r)
|
215 |
self.assertEqual('our value', r[k]) |
216 |
self.info('Container meta exists') |
217 |
|
218 |
self.obj_metakey = 'metakey%s' % random.randint(1000, 9999) |
219 |
obj = 'object_with_meta'
|
220 |
pithos.create_object(obj) |
221 |
pithos.set_object_meta(obj, {self.obj_metakey: 'our value'}) |
222 |
r = pithos.get_container_object_meta() |
223 |
self.assertIn('x-container-object-meta', r) |
224 |
self.assertIn(
|
225 |
self.obj_metakey, r['x-container-object-meta'].lower()) |
226 |
self.info('Container object meta exists') |
227 |
|
228 |
def test_025_container_get(self): |
229 |
"""Test container GET"""
|
230 |
pithos = self.clients.pithos
|
231 |
|
232 |
r = pithos.container_get() |
233 |
self.assertEqual(r.status_code, 200) |
234 |
self.info('Status code is OK') |
235 |
|
236 |
fullLen = len(r.json)
|
237 |
self.assertGreater(fullLen, 0) |
238 |
self.info('There are enough (%s) containers' % fullLen) |
239 |
|
240 |
obj1 = 'test%s' % random.randint(1000, 9999) |
241 |
pithos.create_object(obj1) |
242 |
obj2 = 'test%s' % random.randint(1000, 9999) |
243 |
pithos.create_object(obj2) |
244 |
obj3 = 'another%s.test' % random.randint(1000, 9999) |
245 |
pithos.create_object(obj3) |
246 |
|
247 |
r = pithos.container_get(prefix='test')
|
248 |
self.assertTrue(len(r.json) > 1) |
249 |
test_objects = [o for o in r.json if o['name'].startswith('test')] |
250 |
self.assertEqual(len(r.json), len(test_objects)) |
251 |
self.info('Prefix is OK') |
252 |
|
253 |
r = pithos.container_get(limit=1)
|
254 |
self.assertEqual(len(r.json), 1) |
255 |
self.info('Limit is OK') |
256 |
|
257 |
r = pithos.container_get(marker=obj3[:-5])
|
258 |
self.assertTrue(len(r.json) > 1) |
259 |
aoobjects = [obj for obj in r.json if obj['name'] > obj3[:-5]] |
260 |
self.assertEqual(len(r.json), len(aoobjects)) |
261 |
self.info('Marker is OK') |
262 |
|
263 |
r = pithos.container_get(prefix=obj3, delimiter='.')
|
264 |
self.assertTrue(fullLen > len(r.json)) |
265 |
self.info('Delimiter is OK') |
266 |
|
267 |
r = pithos.container_get(path='/')
|
268 |
fullLen += 3
|
269 |
self.assertEqual(fullLen, len(r.json)) |
270 |
self.info('Path is OK') |
271 |
|
272 |
r = pithos.container_get(format='xml')
|
273 |
self.assertEqual(r.text.split()[4], 'name="' + pithos.container + '">') |
274 |
self.info('Format is OK') |
275 |
|
276 |
r = pithos.container_get(meta=[self.obj_metakey, ])
|
277 |
self.assertTrue(len(r.json) > 0) |
278 |
self.info('Meta is OK') |
279 |
|
280 |
r = pithos.container_get(show_only_shared=True)
|
281 |
self.assertTrue(len(r.json) < fullLen) |
282 |
self.info('Show-only-shared is OK') |
283 |
|
284 |
try:
|
285 |
r = pithos.container_get(until=1000000000)
|
286 |
datestring = unicode(r.headers['x-account-until-timestamp']) |
287 |
self.assertEqual(u'Sun, 09 Sep 2001 01:46:40 GMT', datestring) |
288 |
self.info('Until is OK') |
289 |
except ClientError:
|
290 |
pass
|
291 |
|
292 |
def test_030_container_put(self): |
293 |
"""Test container PUT"""
|
294 |
pithos = self.clients.pithos
|
295 |
pithos.container = 'cont%s%s' % (
|
296 |
self.run_id or 0, random.randint(1000, 9999)) |
297 |
self.temp_containers.append(pithos.container)
|
298 |
|
299 |
r = pithos.create_container() |
300 |
self.assertTrue(isinstance(r, dict)) |
301 |
|
302 |
r = pithos.get_container_limit(pithos.container) |
303 |
cquota = r.values()[0]
|
304 |
newquota = 2 * int(cquota) |
305 |
self.info('Limit is OK') |
306 |
pithos.del_container() |
307 |
|
308 |
r = pithos.create_container(sizelimit=newquota) |
309 |
self.assertTrue(isinstance(r, dict)) |
310 |
|
311 |
r = pithos.get_container_limit(pithos.container) |
312 |
xquota = int(r.values()[0]) |
313 |
self.assertEqual(newquota, xquota)
|
314 |
self.info('Can set container limit') |
315 |
pithos.del_container() |
316 |
|
317 |
r = pithos.create_container(versioning='auto')
|
318 |
self.assertTrue(isinstance(r, dict)) |
319 |
|
320 |
r = pithos.get_container_versioning(pithos.container) |
321 |
nvers = r.values()[0]
|
322 |
self.assertEqual('auto', nvers) |
323 |
self.info('Versioning=auto is OK') |
324 |
pithos.del_container() |
325 |
|
326 |
r = pithos.container_put(versioning='none')
|
327 |
self.assertEqual(r.status_code, 201) |
328 |
|
329 |
r = pithos.get_container_versioning(pithos.container) |
330 |
nvers = r.values()[0]
|
331 |
self.assertEqual('none', nvers) |
332 |
self.info('Versioning=none is OK') |
333 |
pithos.del_container() |
334 |
|
335 |
r = pithos.create_container(metadata={'m1': 'v1', 'm2': 'v2'}) |
336 |
self.assertTrue(isinstance(r, dict)) |
337 |
|
338 |
r = pithos.get_container_meta(pithos.container) |
339 |
self.assertTrue('x-container-meta-m1' in r) |
340 |
self.assertEqual(r['x-container-meta-m1'], 'v1') |
341 |
self.assertTrue('x-container-meta-m2' in r) |
342 |
self.assertEqual(r['x-container-meta-m2'], 'v2') |
343 |
|
344 |
r = pithos.container_put(metadata={'m1': '', 'm2': 'v2a'}) |
345 |
self.assertEqual(r.status_code, 202) |
346 |
|
347 |
r = pithos.get_container_meta(pithos.container) |
348 |
self.assertTrue('x-container-meta-m1' not in r) |
349 |
self.assertTrue('x-container-meta-m2' in r) |
350 |
self.assertEqual(r['x-container-meta-m2'], 'v2a') |
351 |
self.info('Container meta is OK') |
352 |
|
353 |
pithos.del_container_meta(pithos.container) |
354 |
|
355 |
def test_035_container_post(self): |
356 |
"""Test container POST"""
|
357 |
pithos = self.clients.pithos
|
358 |
|
359 |
r = pithos.container_post() |
360 |
self.assertEqual(r.status_code, 202) |
361 |
self.info('Status is OK') |
362 |
|
363 |
pithos.set_container_meta({'m1': 'v1', 'm2': 'v2'}) |
364 |
r = pithos.get_container_meta(pithos.container) |
365 |
self.assertTrue('x-container-meta-m1' in r) |
366 |
self.assertEqual(r['x-container-meta-m1'], 'v1') |
367 |
self.assertTrue('x-container-meta-m2' in r) |
368 |
self.assertEqual(r['x-container-meta-m2'], 'v2') |
369 |
self.info('Set metadata works') |
370 |
|
371 |
r = pithos.del_container_meta('m1')
|
372 |
r = pithos.set_container_meta({'m2': 'v2a'}) |
373 |
r = pithos.get_container_meta(pithos.container) |
374 |
self.assertTrue('x-container-meta-m1' not in r) |
375 |
self.assertTrue('x-container-meta-m2' in r) |
376 |
self.assertEqual(r['x-container-meta-m2'], 'v2a') |
377 |
self.info('Delete metadata works') |
378 |
|
379 |
r = pithos.get_container_limit(pithos.container) |
380 |
cquota = r.values()[0]
|
381 |
newquota = 2 * int(cquota) |
382 |
r = pithos.set_container_limit(newquota) |
383 |
r = pithos.get_container_limit(pithos.container) |
384 |
xquota = int(r.values()[0]) |
385 |
self.assertEqual(newquota, xquota)
|
386 |
self.info('Set quota works') |
387 |
|
388 |
pithos.set_container_versioning('auto')
|
389 |
r = pithos.get_container_versioning(pithos.container) |
390 |
nvers = r.values()[0]
|
391 |
self.assertEqual('auto', nvers) |
392 |
pithos.set_container_versioning('none')
|
393 |
r = pithos.get_container_versioning(pithos.container) |
394 |
nvers = r.values()[0]
|
395 |
self.assertEqual('none', nvers) |
396 |
self.info('Set versioning works') |
397 |
|
398 |
f = self._create_large_file(1024 * 1024 * 100) |
399 |
self.large_file = f
|
400 |
self.info('Created file %s of 100 MB' % f.name) |
401 |
|
402 |
pithos.create_directory('dir')
|
403 |
self.info('Upload the file ...') |
404 |
r = pithos.upload_object('/dir/sample.file', f)
|
405 |
for term in ('content-length', 'content-type', 'x-object-version'): |
406 |
self.assertTrue(term in r) |
407 |
r = pithos.get_object_info('/dir/sample.file')
|
408 |
self.assertTrue(int(r['content-length']) > 100000000) |
409 |
self.info('Made remote directory /dir and object /dir/sample.file') |
410 |
|
411 |
"""What is tranfer_encoding? What should I check about it? """
|
412 |
#TODO
|
413 |
|
414 |
obj = 'object_with_meta'
|
415 |
pithos.container = self.temp_containers[-2] |
416 |
r = pithos.object_post( |
417 |
obj, update='False', metadata={'newmeta': 'newval'}) |
418 |
|
419 |
r = pithos.get_object_info(obj) |
420 |
self.assertTrue('x-object-meta-newmeta' in r) |
421 |
self.assertFalse('x-object-meta-%s' % self.obj_metakey not in r) |
422 |
self.info('Metadata with update=False works') |
423 |
|
424 |
def test_040_container_delete(self): |
425 |
"""Test container DELETE"""
|
426 |
pithos = self.clients.pithos
|
427 |
|
428 |
r = pithos.container_delete(success=409)
|
429 |
self.assertEqual(r.status_code, 409) |
430 |
self.assertRaises(ClientError, pithos.container_delete)
|
431 |
self.info('Successfully failed to delete non-empty container') |
432 |
|
433 |
r = pithos.container_delete(until='1000000000')
|
434 |
self.assertEqual(r.status_code, 204) |
435 |
self.info('Successfully failed to delete old-timestamped container') |
436 |
|
437 |
obj_names = [o['name'] for o in pithos.container_get().json] |
438 |
pithos.del_container(delimiter='/')
|
439 |
r = pithos.container_get() |
440 |
self.assertEqual(len(r.json), 0) |
441 |
self.info('Successfully emptied container') |
442 |
|
443 |
for obj in obj_names: |
444 |
r = pithos.get_object_versionlist(obj) |
445 |
self.assertTrue(len(r) > 0) |
446 |
self.info('Versions are still there') |
447 |
|
448 |
pithos.purge_container() |
449 |
for obj in obj_names: |
450 |
self.assertRaises(ClientError, pithos.get_object_versionlist, obj)
|
451 |
self.info('Successfully purged container') |
452 |
|
453 |
self.temp_containers.remove(pithos.container)
|
454 |
pithos.container = self.temp_containers[-1] |
455 |
|
456 |
def test_045_object_head(self): |
457 |
"""Test object HEAD"""
|
458 |
pithos = self.clients.pithos
|
459 |
|
460 |
obj = 'dir/sample.file'
|
461 |
r = pithos.object_head(obj) |
462 |
self.assertEqual(r.status_code, 200) |
463 |
self.info('Status code is OK') |
464 |
etag = r.headers['etag']
|
465 |
real_version = r.headers['x-object-version']
|
466 |
|
467 |
self.assertRaises(ClientError, pithos.object_head, obj, version=-10) |
468 |
r = pithos.object_head(obj, version=real_version) |
469 |
self.assertEqual(r.headers['x-object-version'], real_version) |
470 |
self.info('Version works') |
471 |
|
472 |
r = pithos.object_head(obj, if_etag_match=etag) |
473 |
self.assertEqual(r.status_code, 200) |
474 |
self.info('if-etag-match is OK') |
475 |
|
476 |
r = pithos.object_head( |
477 |
obj, if_etag_not_match=etag, success=(200, 412, 304)) |
478 |
self.assertNotEqual(r.status_code, 200) |
479 |
self.info('if-etag-not-match works') |
480 |
|
481 |
r = pithos.object_head( |
482 |
obj, version=real_version, if_etag_match=etag, success=200)
|
483 |
self.assertEqual(r.status_code, 200) |
484 |
self.info('Version with if-etag-match works') |
485 |
|
486 |
for format in pithos.DATE_FORMATS: |
487 |
now_formated = self.now_unformated.strftime(format)
|
488 |
r1 = pithos.object_head( |
489 |
obj, if_modified_since=now_formated, success=(200, 304, 412)) |
490 |
r2 = pithos.object_head( |
491 |
obj, if_unmodified_since=now_formated, success=(200, 304, 412)) |
492 |
self.assertNotEqual(r1.status_code, r2.status_code)
|
493 |
self.info('if-(un)modified-since works') |
494 |
|
495 |
def test_050_object_get(self): |
496 |
"""Test object GET"""
|
497 |
pithos = self.clients.pithos
|
498 |
obj = 'dir/sample.file'
|
499 |
|
500 |
r = pithos.object_get(obj) |
501 |
self.assertEqual(r.status_code, 200) |
502 |
self.info('Status code is OK') |
503 |
|
504 |
osize = int(r.headers['content-length']) |
505 |
etag = r.headers['etag']
|
506 |
|
507 |
r = pithos.object_get(obj, hashmap=True)
|
508 |
self.assertEqual(
|
509 |
set(('hashes', 'block_size', 'block_hash', 'bytes')), set(r.json)) |
510 |
self.info('Hashmap works') |
511 |
hash0 = r.json['hashes'][0] |
512 |
|
513 |
r = pithos.object_get(obj, format='xml', hashmap=True) |
514 |
self.assertTrue(r.text.split('hash>')[1].startswith(hash0)) |
515 |
self.info('Hashmap with XML format works') |
516 |
|
517 |
rangestr = 'bytes=%s-%s' % (osize / 3, osize / 2) |
518 |
r = pithos.object_get(obj, data_range=rangestr, success=(200, 206)) |
519 |
partsize = int(r.headers['content-length']) |
520 |
self.assertTrue(0 < partsize and partsize <= 1 + osize / 3) |
521 |
self.info('Range x-y works') |
522 |
orig = r.text |
523 |
|
524 |
rangestr = 'bytes=%s' % (osize / 3) |
525 |
r = pithos.object_get( |
526 |
obj, data_range=rangestr, if_range=True, success=(200, 206)) |
527 |
partsize = int(r.headers['content-length']) |
528 |
self.assertTrue(partsize, 1 + (osize / 3)) |
529 |
diff = set(r.text).symmetric_difference(set(orig[:partsize])) |
530 |
self.assertEqual(len(diff), 0) |
531 |
self.info('Range x works') |
532 |
|
533 |
rangestr = 'bytes=-%s' % (osize / 3) |
534 |
r = pithos.object_get( |
535 |
obj, data_range=rangestr, if_range=True, success=(200, 206)) |
536 |
partsize = int(r.headers['content-length']) |
537 |
self.assertTrue(partsize, osize / 3) |
538 |
diff = set(r.text).symmetric_difference(set(orig[-partsize:])) |
539 |
self.assertEqual(len(diff), 0) |
540 |
self.info('Range -x works') |
541 |
|
542 |
r = pithos.object_get(obj, if_etag_match=etag) |
543 |
self.assertEqual(r.status_code, 200) |
544 |
self.info('if-etag-match works') |
545 |
|
546 |
r = pithos.object_get(obj, if_etag_not_match=etag + 'LALALA')
|
547 |
self.assertEqual(r.status_code, 200) |
548 |
self.info('if-etag-not-match works') |
549 |
|
550 |
for format in pithos.DATE_FORMATS: |
551 |
now_formated = self.now_unformated.strftime(format)
|
552 |
r1 = pithos.object_get( |
553 |
obj, if_modified_since=now_formated, success=(200, 304, 412)) |
554 |
r2 = pithos.object_get( |
555 |
obj, if_unmodified_since=now_formated, success=(200, 304, 412)) |
556 |
self.assertNotEqual(r1.status_code, r2.status_code)
|
557 |
self.info('if(un)modified-since works') |
558 |
|
559 |
obj, dnl_f = 'dir/sample.file', NamedTemporaryFile()
|
560 |
self.info('Download %s as %s ...' % (obj, dnl_f.name)) |
561 |
pithos.download_object(obj, dnl_f) |
562 |
self.info('Download is completed') |
563 |
|
564 |
f_size = len(orig)
|
565 |
for pos in (0, f_size / 2, f_size - 128): |
566 |
dnl_f.seek(pos) |
567 |
self.large_file.seek(pos)
|
568 |
self.assertEqual(self.large_file.read(64), dnl_f.read(64)) |
569 |
self.info('Sampling shows that files match') |
570 |
|
571 |
self.info('Create a boring file of 42 blocks...') |
572 |
bor_f = self._create_boring_file(42) |
573 |
trg_fname = 'dir/uploaded.file'
|
574 |
self.info('Now, upload the boring file as %s...' % trg_fname) |
575 |
pithos.upload_object(trg_fname, bor_f) |
576 |
self.info('Boring file %s is uploaded as %s' % (bor_f.name, trg_fname)) |
577 |
dnl_f = NamedTemporaryFile() |
578 |
self.info('Download boring file as %s' % dnl_f.name) |
579 |
pithos.download_object(trg_fname, dnl_f) |
580 |
self.info('File is downloaded') |
581 |
|
582 |
for i in range(42): |
583 |
self.assertEqual(sample_block(bor_f, i), sample_block(dnl_f, i))
|
584 |
|
585 |
def test_055_object_put(self): |
586 |
"""Test object PUT"""
|
587 |
pithos = self.clients.pithos
|
588 |
obj = 'sample.file'
|
589 |
|
590 |
pithos.create_object(obj + '.FAKE')
|
591 |
r = pithos.get_object_info(obj + '.FAKE')
|
592 |
self.assertEqual(
|
593 |
set(r['content-type']), set('application/octer-stream')) |
594 |
self.info('Simple call creates a new object correctly') |
595 |
|
596 |
r = pithos.object_put( |
597 |
obj, |
598 |
data='a',
|
599 |
content_type='application/octer-stream',
|
600 |
permissions=dict(
|
601 |
read=['accX:groupA', 'u1', 'u2'], |
602 |
write=['u2', 'u3']), |
603 |
metadata=dict(key1='val1', key2='val2'), |
604 |
content_encoding='UTF-8',
|
605 |
content_disposition='attachment; filename="fname.ext"')
|
606 |
self.assertEqual(r.status_code, 201) |
607 |
self.info('Status code is OK') |
608 |
etag = r.headers['etag']
|
609 |
|
610 |
r = pithos.get_object_info(obj) |
611 |
self.assertTrue('content-disposition' in r) |
612 |
self.assertEqual(
|
613 |
r['content-disposition'], 'attachment; filename="fname.ext"') |
614 |
self.info('Content-disposition is OK') |
615 |
|
616 |
sharing = r['x-object-sharing'].split('; ') |
617 |
self.assertTrue(sharing[0].startswith('read=')) |
618 |
read = set(sharing[0][5:].split(',')) |
619 |
self.assertEqual(set(('u1', 'accx:groupa')), read) |
620 |
self.assertTrue(sharing[1].startswith('write=')) |
621 |
write = set(sharing[1][6:].split(',')) |
622 |
self.assertEqual(set(('u2', 'u3')), write) |
623 |
self.info('Permissions are OK') |
624 |
|
625 |
r = pithos.get_object_meta(obj) |
626 |
self.assertEqual(r['x-object-meta-key1'], 'val1') |
627 |
self.assertEqual(r['x-object-meta-key2'], 'val2') |
628 |
self.info('Meta are OK') |
629 |
|
630 |
pithos.object_put( |
631 |
obj, |
632 |
if_etag_match=etag, |
633 |
data='b',
|
634 |
content_type='application/octet-stream',
|
635 |
public=True)
|
636 |
self.info('If-etag-match is OK') |
637 |
|
638 |
r = pithos.object_get(obj) |
639 |
self.assertTrue('x-object-public' in r.headers) |
640 |
self.info('Publishing works') |
641 |
|
642 |
etag = r.headers['etag']
|
643 |
self.assertEqual(r.text, 'b') |
644 |
self.info('Remote object content is correct') |
645 |
|
646 |
r = pithos.object_put( |
647 |
obj, |
648 |
if_etag_not_match=etag, |
649 |
data='c',
|
650 |
content_type='application/octet-stream',
|
651 |
success=(201, 412)) |
652 |
self.assertEqual(r.status_code, 412) |
653 |
self.info('If-etag-not-match is OK') |
654 |
|
655 |
r = pithos.get_object_info('dir')
|
656 |
self.assertEqual(r['content-type'], 'application/directory') |
657 |
self.info('Directory has been created correctly') |
658 |
|
659 |
r = pithos.object_put( |
660 |
'%s_v2' % obj,
|
661 |
format=None,
|
662 |
copy_from='/%s/%s' % (pithos.container, obj),
|
663 |
content_encoding='application/octet-stream',
|
664 |
source_account=pithos.account, |
665 |
content_length=0,
|
666 |
success=201)
|
667 |
self.assertEqual(r.status_code, 201) |
668 |
r1 = pithos.get_object_info(obj) |
669 |
r2 = pithos.get_object_info('%s_v2' % obj)
|
670 |
self.assertEqual(r1['x-object-hash'], r2['x-object-hash']) |
671 |
self.info('Object has being copied in same container, OK') |
672 |
|
673 |
pithos.copy_object( |
674 |
src_container=pithos.container, |
675 |
src_object=obj, |
676 |
dst_container=self.temp_containers[-2], |
677 |
dst_object='%s_new' % obj)
|
678 |
pithos.container = self.temp_containers[-2] |
679 |
r1 = pithos.get_object_info('%s_new' % obj)
|
680 |
pithos.container = self.temp_containers[-1] |
681 |
r2 = pithos.get_object_info(obj) |
682 |
self.assertEqual(r1['x-object-hash'], r2['x-object-hash']) |
683 |
self.info('Object has being copied in another container, OK') |
684 |
|
685 |
fromstr = '/%s/%s_new' % (self.temp_containers[-2], obj) |
686 |
r = pithos.object_put( |
687 |
obj, |
688 |
format=None,
|
689 |
copy_from=fromstr, |
690 |
content_encoding='application/octet-stream',
|
691 |
source_account=pithos.account, |
692 |
content_length=0,
|
693 |
success=201)
|
694 |
self.assertEqual(r.status_code, 201) |
695 |
self.info('Cross container put accepts content_encoding') |
696 |
|
697 |
r = pithos.get_object_info(obj) |
698 |
self.assertEqual(r['etag'], etag) |
699 |
self.info('Etag is OK') |
700 |
|
701 |
r = pithos.object_put( |
702 |
'%s_v3' % obj,
|
703 |
format=None,
|
704 |
move_from=fromstr, |
705 |
content_encoding='application/octet-stream',
|
706 |
source_account='nonExistendAddress@NeverLand.com',
|
707 |
content_length=0,
|
708 |
success=(403, ))
|
709 |
self.info('Fake source account is handled correctly') |
710 |
|
711 |
r1 = pithos.get_object_info(obj) |
712 |
pithos.container = self.temp_containers[-2] |
713 |
pithos.move_object( |
714 |
src_container=self.temp_containers[-1], |
715 |
src_object=obj, |
716 |
dst_container=pithos.container, |
717 |
dst_object=obj + '_new')
|
718 |
r0 = pithos.get_object_info(obj + '_new')
|
719 |
self.assertEqual(r1['x-object-hash'], r0['x-object-hash']) |
720 |
self.info('Cross container move is OK') |
721 |
|
722 |
pithos.container = self.temp_containers[-1] |
723 |
pithos.create_container(versioning='auto')
|
724 |
pithos.upload_from_string(obj, 'first version')
|
725 |
source_hashmap = pithos.get_object_hashmap(obj)['hashes']
|
726 |
pithos.upload_from_string(obj, 'second version')
|
727 |
pithos.upload_from_string(obj, 'third version')
|
728 |
versions = pithos.get_object_versionlist(obj) |
729 |
self.assertEqual(len(versions), 3) |
730 |
vers0 = versions[0][0] |
731 |
|
732 |
pithos.container = self.temp_containers[-2] |
733 |
pithos.object_put( |
734 |
obj, |
735 |
format=None,
|
736 |
move_from='/%s/%s' % (self.temp_containers[-1], obj), |
737 |
source_version=vers0, |
738 |
content_encoding='application/octet-stream',
|
739 |
content_length=0, success=201) |
740 |
target_hashmap = pithos.get_object_hashmap(obj)['hashes']
|
741 |
self.info('Source-version is probably not OK (Check bug #4963)') |
742 |
source_hashmap, target_hashmap = source_hashmap, target_hashmap |
743 |
# Comment out until it's fixed
|
744 |
# self.assertEqual(source_hashmap, target_hashmap)
|
745 |
# self.info('Source-version is OK')
|
746 |
|
747 |
mobj = 'manifest.test'
|
748 |
txt = ''
|
749 |
for i in range(10): |
750 |
txt += '%s' % i
|
751 |
pithos.object_put( |
752 |
'%s/%s' % (mobj, i),
|
753 |
data='%s' % i,
|
754 |
content_length=1,
|
755 |
success=201,
|
756 |
content_type='application/octet-stream',
|
757 |
content_encoding='application/octet-stream')
|
758 |
pithos.object_put( |
759 |
mobj, |
760 |
content_length=0,
|
761 |
content_type='application/octet-stream',
|
762 |
manifest='%s/%s' % (pithos.container, mobj))
|
763 |
r = pithos.object_get(mobj) |
764 |
self.assertEqual(r.text, txt)
|
765 |
self.info('Manifest file creation works') |
766 |
|
767 |
f = self._create_large_file(1024 * 10) |
768 |
pithos.upload_object('sample.file', f)
|
769 |
r = pithos.get_object_info('sample.file')
|
770 |
self.assertEqual(int(r['content-length']), 10240) |
771 |
self.info('Overwrite is OK') |
772 |
|
773 |
"""MISSING: test transfer-encoding?"""
|
774 |
|
775 |
def test_060_object_copy(self): |
776 |
"""Test object COPY"""
|
777 |
pithos = self.clients.pithos
|
778 |
obj, trg = 'source.file2copy', 'copied.file' |
779 |
data = '{"key1":"val1", "key2":"val2"}'
|
780 |
|
781 |
r = pithos.object_put( |
782 |
obj, |
783 |
content_type='application/octet-stream',
|
784 |
data=data, |
785 |
metadata=dict(mkey1='mval1', mkey2='mval2'), |
786 |
permissions=dict(
|
787 |
read=['accX:groupA', 'u1', 'u2'], |
788 |
write=['u2', 'u3']), |
789 |
content_disposition='attachment; filename="fname.ext"')
|
790 |
self.info('Prepared a file /%s/%s' % (pithos.container, obj)) |
791 |
|
792 |
r = pithos.object_copy( |
793 |
obj, |
794 |
destination='/%s/%s' % (pithos.container, trg),
|
795 |
ignore_content_type=False, content_type='application/json', |
796 |
metadata={'mkey2': 'mval2a', 'mkey3': 'mval3'}, |
797 |
permissions={'write': ['u5', 'accX:groupB']}) |
798 |
self.assertEqual(r.status_code, 201) |
799 |
self.info('Status code is OK') |
800 |
|
801 |
r = pithos.get_object_info(trg) |
802 |
self.assertTrue('content-disposition' in r) |
803 |
self.info('Content-disposition is OK') |
804 |
|
805 |
self.assertEqual(r['x-object-meta-mkey1'], 'mval1') |
806 |
self.assertEqual(r['x-object-meta-mkey2'], 'mval2a') |
807 |
self.assertEqual(r['x-object-meta-mkey3'], 'mval3') |
808 |
self.info('Metadata are OK') |
809 |
|
810 |
r = pithos.get_object_sharing(trg) |
811 |
self.assertFalse('read' in r or 'u2' in r['write']) |
812 |
self.assertTrue('accx:groupb' in r['write']) |
813 |
self.info('Sharing is OK') |
814 |
|
815 |
r = pithos.object_copy( |
816 |
obj, |
817 |
destination='/%s/%s' % (pithos.container, obj),
|
818 |
content_encoding='utf8',
|
819 |
content_type='application/json',
|
820 |
destination_account='nonExistendAddress@NeverLand.com',
|
821 |
success=(201, 404)) |
822 |
self.assertEqual(r.status_code, 404) |
823 |
self.info('Non existing UUID correctly causes a 404') |
824 |
|
825 |
r = pithos.object_copy( |
826 |
obj, |
827 |
destination='/%s/%s' % (self.temp_containers[-1], obj), |
828 |
content_encoding='utf8',
|
829 |
content_type='application/json')
|
830 |
self.assertEqual(r.status_code, 201) |
831 |
self.assertEqual(
|
832 |
r.headers['content-type'],
|
833 |
'application/json; charset=UTF-8')
|
834 |
|
835 |
pithos.container = self.temp_containers[-1] |
836 |
r = pithos.object_get(obj) |
837 |
etag = r.headers['etag']
|
838 |
ctype = r.headers['content-type']
|
839 |
self.assertEqual(ctype, 'application/json') |
840 |
self.info('Cross container copy w. content-type/encoding is OK') |
841 |
|
842 |
r = pithos.object_copy( |
843 |
obj, |
844 |
destination='/%s/%s0' % (pithos.container, obj),
|
845 |
ignore_content_type=True,
|
846 |
content_type='text/x-python')
|
847 |
self.assertEqual(r.status_code, 201) |
848 |
self.assertNotEqual(r.headers['content-type'], 'application/json') |
849 |
r = pithos.object_get(obj + '0')
|
850 |
self.assertNotEqual(r.headers['content-type'], 'text/x-python') |
851 |
|
852 |
r = pithos.object_copy( |
853 |
obj, |
854 |
destination='/%s/%s1' % (pithos.container, obj),
|
855 |
if_etag_match=etag) |
856 |
self.assertEqual(r.status_code, 201) |
857 |
self.info('if-etag-match is OK') |
858 |
|
859 |
r = pithos.object_copy( |
860 |
obj, |
861 |
destination='/%s/%s2' % (pithos.container, obj),
|
862 |
if_etag_not_match='lalala')
|
863 |
self.assertEqual(r.status_code, 201) |
864 |
self.info('if-etag-not-match is OK') |
865 |
|
866 |
r = pithos.object_copy( |
867 |
'%s2' % obj,
|
868 |
destination='/%s/%s3' % (pithos.container, obj),
|
869 |
format='xml',
|
870 |
public=True)
|
871 |
self.assertEqual(r.status_code, 201) |
872 |
self.assertTrue('xml' in r.headers['content-type']) |
873 |
|
874 |
r = pithos.get_object_info(obj + '3')
|
875 |
self.assertTrue('x-object-public' in r) |
876 |
self.info('Publish, format and source-version are OK') |
877 |
|
878 |
def test_065_object_move(self): |
879 |
"""Test object MOVE"""
|
880 |
pithos = self.clients.pithos
|
881 |
obj = 'source.file2move'
|
882 |
data = '{"key1": "val1", "key2": "val2"}'
|
883 |
|
884 |
r = pithos.object_put( |
885 |
obj, |
886 |
content_type='application/octet-stream',
|
887 |
data=data, |
888 |
metadata=dict(mkey1='mval1', mkey2='mval2'), |
889 |
permissions=dict(
|
890 |
read=['accX:groupA', 'u1', 'u2'], |
891 |
write=['u2', 'u3'])) |
892 |
self.info('Prepared a file /%s/%s' % (pithos.container, obj)) |
893 |
|
894 |
r = pithos.object_move( |
895 |
obj, |
896 |
destination='/%s/%s0' % (pithos.container, obj),
|
897 |
ignore_content_type=False, content_type='application/json', |
898 |
metadata={'mkey2': 'mval2a', 'mkey3': 'mval3'}, |
899 |
permissions={'write': ['u5', 'accX:groupB']}) |
900 |
self.assertEqual(r.status_code, 201) |
901 |
self.info('Status code is OK') |
902 |
|
903 |
r = pithos.get_object_meta(obj + '0')
|
904 |
self.assertEqual(r['x-object-meta-mkey1'], 'mval1') |
905 |
self.assertEqual(r['x-object-meta-mkey2'], 'mval2a') |
906 |
self.assertEqual(r['x-object-meta-mkey3'], 'mval3') |
907 |
self.info('Metadata are OK') |
908 |
|
909 |
r = pithos.get_object_sharing(obj + '0')
|
910 |
self.assertFalse('read' in r) |
911 |
self.assertTrue('u5' in r['write']) |
912 |
self.assertTrue('accx:groupb' in r['write']) |
913 |
self.info('Sharing is OK') |
914 |
|
915 |
self.assertRaises(ClientError, pithos.get_object_info, obj)
|
916 |
self.info('Old object is not there, which is OK') |
917 |
|
918 |
r = pithos.object_move( |
919 |
obj + '0',
|
920 |
destination='/%s/%s' % (pithos.container, obj),
|
921 |
content_encoding='utf8',
|
922 |
content_type='application/json',
|
923 |
destination_account='nonExistendAddress@NeverLand.com',
|
924 |
success=(201, 404)) |
925 |
self.assertEqual(r.status_code, 404) |
926 |
self.info('Non existing UUID correctly causes a 404') |
927 |
|
928 |
r = pithos.object_move( |
929 |
obj + '0',
|
930 |
destination='/%s/%s' % (self.temp_containers[-2], obj), |
931 |
content_encoding='utf8',
|
932 |
content_type='application/json',
|
933 |
content_disposition='attachment; filename="fname.ext"')
|
934 |
self.assertEqual(r.status_code, 201) |
935 |
self.assertEqual(
|
936 |
r.headers['content-type'],
|
937 |
'application/json; charset=UTF-8')
|
938 |
|
939 |
pithos.container = self.temp_containers[-2] |
940 |
r = pithos.object_get(obj) |
941 |
etag = r.headers['etag']
|
942 |
ctype = r.headers['content-type']
|
943 |
self.assertEqual(ctype, 'application/json') |
944 |
self.assertTrue('fname.ext' in r.headers['content-disposition']) |
945 |
self.info('Cross container copy w. content-type/encoding is OK') |
946 |
|
947 |
r = pithos.object_move( |
948 |
obj, |
949 |
destination='/%s/%s0' % (pithos.container, obj),
|
950 |
ignore_content_type=True,
|
951 |
content_type='text/x-python')
|
952 |
self.assertEqual(r.status_code, 201) |
953 |
self.assertNotEqual(r.headers['content-type'], 'application/json') |
954 |
r = pithos.object_get(obj + '0')
|
955 |
self.assertNotEqual(r.headers['content-type'], 'text/x-python') |
956 |
|
957 |
r = pithos.object_move( |
958 |
obj + '0',
|
959 |
destination='/%s/%s' % (pithos.container, obj),
|
960 |
if_etag_match=etag) |
961 |
self.assertEqual(r.status_code, 201) |
962 |
self.info('if-etag-match is OK') |
963 |
|
964 |
r = pithos.object_move( |
965 |
obj, |
966 |
destination='/%s/%s0' % (pithos.container, obj),
|
967 |
if_etag_not_match='lalala')
|
968 |
self.assertEqual(r.status_code, 201) |
969 |
self.info('if-etag-not-match is OK') |
970 |
|
971 |
r = pithos.object_move( |
972 |
obj + '0',
|
973 |
destination='/%s/%s' % (pithos.container, obj),
|
974 |
format='xml',
|
975 |
public=True)
|
976 |
self.assertEqual(r.status_code, 201) |
977 |
self.assertTrue('xml' in r.headers['content-type']) |
978 |
|
979 |
r = pithos.get_object_info(obj) |
980 |
self.assertTrue('x-object-public' in r) |
981 |
self.info('Publish, format and source-version are OK') |
982 |
|
983 |
def test_070_object_post(self): |
984 |
"""Test object POST"""
|
985 |
pithos = self.clients.pithos
|
986 |
obj = 'sample2post.file'
|
987 |
newf = NamedTemporaryFile() |
988 |
newf.writelines([ |
989 |
'ello!\n',
|
990 |
'This is a test line\n',
|
991 |
'inside a test file\n'])
|
992 |
newf.flush() |
993 |
|
994 |
r = pithos.object_put( |
995 |
obj, |
996 |
content_type='text/x-python',
|
997 |
data='H',
|
998 |
metadata=dict(mkey1='mval1', mkey2='mval2'), |
999 |
permissions=dict(
|
1000 |
read=['accX:groupA', 'u1', 'u2'], |
1001 |
write=['u2', 'u3'])) |
1002 |
self.info(
|
1003 |
'Prepared a local file %s & a remote object %s', newf.name, obj)
|
1004 |
|
1005 |
newf.seek(0)
|
1006 |
pithos.append_object(obj, newf) |
1007 |
r = pithos.object_get(obj) |
1008 |
self.assertEqual(r.text[:5], 'Hello') |
1009 |
self.info('Append is OK') |
1010 |
|
1011 |
newf.seek(0)
|
1012 |
r = pithos.overwrite_object(obj, 0, 10, newf) |
1013 |
r = pithos.object_get(obj) |
1014 |
self.assertTrue(r.text.startswith('ello!')) |
1015 |
self.assertEqual(r.headers['content-type'], 'text/x-python') |
1016 |
self.info('Overwrite (involves content-legth/range/type) is OK') |
1017 |
|
1018 |
r = pithos.truncate_object(obj, 5)
|
1019 |
r = pithos.object_get(obj) |
1020 |
self.assertEqual(r.text, 'ello!') |
1021 |
self.assertEqual(r.headers['content-type'], 'text/x-python') |
1022 |
self.info(
|
1023 |
'Truncate (involves content-range, object-bytes and source-object)'
|
1024 |
' is OK')
|
1025 |
|
1026 |
pithos.set_object_meta(obj, {'mkey2': 'mval2a', 'mkey3': 'mval3'}) |
1027 |
r = pithos.get_object_meta(obj) |
1028 |
self.assertEqual(r['x-object-meta-mkey1'], 'mval1') |
1029 |
self.assertEqual(r['x-object-meta-mkey2'], 'mval2a') |
1030 |
self.assertEqual(r['x-object-meta-mkey3'], 'mval3') |
1031 |
pithos.del_object_meta(obj, 'mkey1')
|
1032 |
r = pithos.get_object_meta(obj) |
1033 |
self.assertFalse('x-object-meta-mkey1' in r) |
1034 |
self.info('Metadata are OK') |
1035 |
|
1036 |
pithos.set_object_sharing( |
1037 |
obj, read_permission=['u4', 'u5'], write_permission=['u4']) |
1038 |
r = pithos.get_object_sharing(obj) |
1039 |
self.assertTrue('read' in r) |
1040 |
self.assertTrue('u5' in r['read']) |
1041 |
self.assertTrue('write' in r) |
1042 |
self.assertTrue('u4' in r['write']) |
1043 |
pithos.del_object_sharing(obj) |
1044 |
r = pithos.get_object_sharing(obj) |
1045 |
self.assertTrue(len(r) == 0) |
1046 |
self.info('Sharing is OK') |
1047 |
|
1048 |
pithos.publish_object(obj) |
1049 |
r = pithos.get_object_info(obj) |
1050 |
self.assertTrue('x-object-public' in r) |
1051 |
pithos.unpublish_object(obj) |
1052 |
r = pithos.get_object_info(obj) |
1053 |
self.assertFalse('x-object-public' in r) |
1054 |
self.info('Publishing is OK') |
1055 |
|
1056 |
etag = r['etag']
|
1057 |
r = pithos.object_post( |
1058 |
obj, |
1059 |
update=True,
|
1060 |
public=True,
|
1061 |
if_etag_not_match=etag, |
1062 |
success=(412, 202, 204)) |
1063 |
self.assertEqual(r.status_code, 412) |
1064 |
self.info('if-etag-not-match is OK') |
1065 |
|
1066 |
r = pithos.object_post( |
1067 |
obj, |
1068 |
update=True,
|
1069 |
public=True,
|
1070 |
if_etag_match=etag, |
1071 |
content_type='application/octet-srteam',
|
1072 |
content_encoding='application/json')
|
1073 |
|
1074 |
r = pithos.get_object_info(obj) |
1075 |
helloVersion = r['x-object-version']
|
1076 |
self.assertTrue('x-object-public' in r) |
1077 |
self.assertEqual(r['content-type'], 'text/x-python') |
1078 |
self.info('If-etag-match is OK') |
1079 |
|
1080 |
pithos.container = self.temp_containers[-1] |
1081 |
pithos.create_object(obj) |
1082 |
r = pithos.object_post( |
1083 |
obj, |
1084 |
update=True,
|
1085 |
content_type='application/octet-srteam',
|
1086 |
content_length=5,
|
1087 |
content_range='bytes 1-5/*',
|
1088 |
source_object='/%s/%s' % (self.temp_containers[-2], obj), |
1089 |
source_account='thisAccountWillNeverExist@adminland.com',
|
1090 |
source_version=helloVersion, |
1091 |
data='12345',
|
1092 |
success=(416, 202, 204)) |
1093 |
self.assertEqual(r.status_code, 416) |
1094 |
self.info('Successfully failed with invalid user UUID') |
1095 |
|
1096 |
pithos.upload_from_string(obj, '12345')
|
1097 |
r = pithos.object_post( |
1098 |
obj, |
1099 |
update=True,
|
1100 |
content_type='application/octet-srteam',
|
1101 |
content_length=3,
|
1102 |
content_range='bytes 1-3/*',
|
1103 |
source_object='/%s/%s' % (self.temp_containers[-2], obj), |
1104 |
source_account=pithos.account, |
1105 |
source_version=helloVersion, |
1106 |
data='123',
|
1107 |
content_disposition='attachment; filename="fname.ext"')
|
1108 |
|
1109 |
r = pithos.object_get(obj) |
1110 |
self.assertEqual(r.text, '1ell5') |
1111 |
self.info('Cross container POST with source-version/account are OK') |
1112 |
|
1113 |
self.assertTrue('content-disposition' in r.headers) |
1114 |
self.assertTrue('fname.ext' in r.headers['content-disposition']) |
1115 |
self.info('Content-disposition POST is OK') |
1116 |
|
1117 |
mobj = 'manifest.test'
|
1118 |
txt = ''
|
1119 |
for i in range(10): |
1120 |
txt += '%s' % i
|
1121 |
r = pithos.object_put( |
1122 |
'%s/%s' % (mobj, i),
|
1123 |
data='%s' % i,
|
1124 |
content_length=1,
|
1125 |
success=201,
|
1126 |
content_encoding='application/octet-stream',
|
1127 |
content_type='application/octet-stream')
|
1128 |
|
1129 |
pithos.create_object_by_manifestation( |
1130 |
mobj, content_type='application/octet-stream')
|
1131 |
|
1132 |
r = pithos.object_post( |
1133 |
mobj, manifest='%s/%s' % (pithos.container, mobj))
|
1134 |
|
1135 |
r = pithos.object_get(mobj) |
1136 |
self.assertEqual(r.text, txt)
|
1137 |
self.info('Manifestation is OK') |
1138 |
|
1139 |
"""We need to check transfer_encoding """
|
1140 |
|
1141 |
def test_075_object_delete(self): |
1142 |
"""Test object DELETE"""
|
1143 |
pithos = self.clients.pithos
|
1144 |
obj = 'sample2post.file'
|
1145 |
|
1146 |
r = pithos.object_delete(obj, until=1000000)
|
1147 |
r = pithos.object_get(obj, success=(200, 404)) |
1148 |
self.assertEqual(r.status_code, 200) |
1149 |
self.info('Successfully failed to delete with false "until"') |
1150 |
|
1151 |
r = pithos.object_delete(obj) |
1152 |
self.assertEqual(r.status_code, 204) |
1153 |
self.info('Status code is OK') |
1154 |
|
1155 |
r = pithos.object_get(obj, success=(200, 404)) |
1156 |
self.assertEqual(r.status_code, 404) |
1157 |
self.info('Successfully failed to delete a deleted file') |
1158 |
|
1159 |
@classmethod
|
1160 |
def tearDownClass(cls): # noqa |
1161 |
"""Clean up"""
|
1162 |
from kamaki.cli.logger import deactivate |
1163 |
deactivate('kamaki.clients.send')
|
1164 |
deactivate('kamaki.clients.recv')
|
1165 |
pithos = cls.clients.pithos |
1166 |
for c in getattr(cls, 'temp_containers', []): |
1167 |
pithos.container = c |
1168 |
try:
|
1169 |
pithos.del_container(delimiter='/')
|
1170 |
pithos.purge_container(c) |
1171 |
except ClientError as ce: |
1172 |
print ('Failed to destroy container (%s)' % ce) |