Revision 7067193f
b/snf-pithos-tools/pithos/tools/test.py | ||
---|---|---|
2 | 2 |
#coding=utf8 |
3 | 3 |
|
4 | 4 |
# Copyright 2011-2012 GRNET S.A. All rights reserved. |
5 |
#
|
|
5 |
# |
|
6 | 6 |
# Redistribution and use in source and binary forms, with or |
7 | 7 |
# without modification, are permitted provided that the following |
8 | 8 |
# conditions are met: |
9 |
#
|
|
9 |
# |
|
10 | 10 |
# 1. Redistributions of source code must retain the above |
11 | 11 |
# copyright notice, this list of conditions and the following |
12 | 12 |
# disclaimer. |
13 |
#
|
|
13 |
# |
|
14 | 14 |
# 2. Redistributions in binary form must reproduce the above |
15 | 15 |
# copyright notice, this list of conditions and the following |
16 | 16 |
# disclaimer in the documentation and/or other materials |
17 | 17 |
# provided with the distribution. |
18 |
#
|
|
18 |
# |
|
19 | 19 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
20 | 20 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
21 | 21 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
... | ... | |
28 | 28 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
29 | 29 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
30 | 30 |
# POSSIBILITY OF SUCH DAMAGE. |
31 |
#
|
|
31 |
# |
|
32 | 32 |
# The views and conclusions contained in the software and |
33 | 33 |
# documentation are those of the authors and should not be |
34 | 34 |
# interpreted as representing official policies, either expressed |
... | ... | |
76 | 76 |
self.client = Pithos_Client(get_url(), get_auth(), get_user()) |
77 | 77 |
self._clean_account() |
78 | 78 |
self.invalid_client = Pithos_Client(get_url(), get_auth(), 'invalid') |
79 |
|
|
79 |
|
|
80 | 80 |
#keep track of initial account groups |
81 | 81 |
self.initial_groups = self.client.retrieve_account_groups() |
82 |
|
|
82 |
|
|
83 | 83 |
#keep track of initial account meta |
84 | 84 |
self.initial_meta = self.client.retrieve_account_metadata(restricted=True) |
85 |
|
|
85 |
|
|
86 | 86 |
self.extended = { |
87 | 87 |
'container':( |
88 | 88 |
'name', |
... | ... | |
98 | 98 |
'content_encoding', |
99 | 99 |
'last_modified',)} |
100 | 100 |
self.return_codes = (400, 401, 403, 404, 503,) |
101 |
|
|
101 |
|
|
102 | 102 |
def tearDown(self): |
103 | 103 |
#delete additionally created meta |
104 | 104 |
l = [] |
... | ... | |
106 | 106 |
if m not in self.initial_meta: |
107 | 107 |
l.append(m) |
108 | 108 |
self.client.delete_account_metadata(l) |
109 |
|
|
109 |
|
|
110 | 110 |
#delete additionally created groups |
111 | 111 |
l = [] |
112 | 112 |
for g in self.client.retrieve_account_groups(): |
... | ... | |
114 | 114 |
l.append(g) |
115 | 115 |
self.client.unset_account_groups(l) |
116 | 116 |
self._clean_account() |
117 |
|
|
117 |
|
|
118 | 118 |
def _clean_account(self): |
119 | 119 |
for c in self.client.list_containers(): |
120 | 120 |
while True: |
... | ... | |
126 | 126 |
for o in objects: |
127 | 127 |
self.client.delete_object(c, o) |
128 | 128 |
self.client.delete_container(c) |
129 |
|
|
129 |
|
|
130 | 130 |
def assert_status(self, status, codes): |
131 | 131 |
l = [elem for elem in self.return_codes] |
132 | 132 |
if type(codes) == types.ListType: |
... | ... | |
134 | 134 |
else: |
135 | 135 |
l.append(codes) |
136 | 136 |
self.assertTrue(status in l) |
137 |
|
|
137 |
|
|
138 | 138 |
def assert_extended(self, data, format, type, size=10000): |
139 | 139 |
if format == 'xml': |
140 | 140 |
self._assert_xml(data, type, size) |
141 | 141 |
elif format == 'json': |
142 | 142 |
self._assert_json(data, type, size) |
143 |
|
|
143 |
|
|
144 | 144 |
def _assert_json(self, data, type, size): |
145 | 145 |
convert = lambda s: s.lower() |
146 | 146 |
info = [convert(elem) for elem in self.extended[type]] |
... | ... | |
150 | 150 |
if 'subdir' in i.keys(): |
151 | 151 |
continue |
152 | 152 |
self.assertTrue(item in i.keys()) |
153 |
|
|
153 |
|
|
154 | 154 |
def _assert_xml(self, data, type, size): |
155 | 155 |
convert = lambda s: s.lower() |
156 | 156 |
info = [convert(elem) for elem in self.extended[type]] |
... | ... | |
164 | 164 |
for e in entities: |
165 | 165 |
for item in info: |
166 | 166 |
self.assertTrue(e.getElementsByTagName(item)) |
167 |
|
|
167 |
|
|
168 | 168 |
def assert_raises_fault(self, status, callableObj, *args, **kwargs): |
169 | 169 |
""" |
170 | 170 |
asserts that a Fault with a specific status is raised |
... | ... | |
178 | 178 |
self.failUnless(f.status in status) |
179 | 179 |
else: |
180 | 180 |
self.failUnless(f.status == status) |
181 |
|
|
181 |
|
|
182 | 182 |
def assert_not_raises_fault(self, status, callableObj, *args, **kwargs): |
183 | 183 |
""" |
184 | 184 |
asserts that a Fault with a specific status is not raised |
... | ... | |
188 | 188 |
r = callableObj(*args, **kwargs) |
189 | 189 |
except Fault, f: |
190 | 190 |
self.failIfEqual(f.status, status) |
191 |
|
|
191 |
|
|
192 | 192 |
def assert_container_exists(self, container): |
193 | 193 |
""" |
194 | 194 |
asserts the existence of a container |
... | ... | |
197 | 197 |
self.client.retrieve_container_metadata(container) |
198 | 198 |
except Fault, f: |
199 | 199 |
self.failIf(f.status == 404) |
200 |
|
|
200 |
|
|
201 | 201 |
def assert_container_not_exists(self, container): |
202 | 202 |
""" |
203 | 203 |
asserts there is no such a container |
204 | 204 |
""" |
205 | 205 |
self.assert_raises_fault(404, self.client.retrieve_container_metadata, |
206 | 206 |
container) |
207 |
|
|
207 |
|
|
208 | 208 |
def assert_object_exists(self, container, object): |
209 | 209 |
""" |
210 | 210 |
asserts the existence of an object |
... | ... | |
213 | 213 |
self.client.retrieve_object_metadata(container, object) |
214 | 214 |
except Fault, f: |
215 | 215 |
self.failIf(f.status == 404) |
216 |
|
|
216 |
|
|
217 | 217 |
def assert_object_not_exists(self, container, object): |
218 | 218 |
""" |
219 | 219 |
asserts there is no such an object |
220 | 220 |
""" |
221 | 221 |
self.assert_raises_fault(404, self.client.retrieve_object_metadata, |
222 | 222 |
container, object) |
223 |
|
|
223 |
|
|
224 | 224 |
def assert_versionlist_structure(self, versionlist): |
225 | 225 |
self.assertTrue(type(versionlist) == types.ListType) |
226 | 226 |
for elem in versionlist: |
227 | 227 |
self.assertTrue(type(elem) == types.ListType) |
228 | 228 |
self.assertEqual(len(elem), 2) |
229 |
|
|
229 |
|
|
230 | 230 |
def upload_random_data(self, container, name, length=1024, type=None, |
231 | 231 |
enc=None, **meta): |
232 | 232 |
data = get_random_data(length) |
233 | 233 |
return self.upload_data(container, name, data, type, enc, **meta) |
234 |
|
|
234 |
|
|
235 | 235 |
def upload_data(self, container, name, data, type=None, enc=None, etag=None, |
236 | 236 |
**meta): |
237 | 237 |
obj = {} |
... | ... | |
239 | 239 |
try: |
240 | 240 |
obj['data'] = data |
241 | 241 |
obj['hash'] = compute_md5_hash(obj['data']) |
242 |
|
|
242 |
|
|
243 | 243 |
args = {} |
244 | 244 |
args['etag'] = etag if etag else obj['hash'] |
245 |
|
|
245 |
|
|
246 | 246 |
try: |
247 | 247 |
guess = mimetypes.guess_type(name) |
248 | 248 |
type = type if type else guess[0] |
... | ... | |
251 | 251 |
pass |
252 | 252 |
args['content_type'] = type if type else 'plain/text' |
253 | 253 |
args['content_encoding'] = enc if enc else None |
254 |
|
|
254 |
|
|
255 | 255 |
obj['meta'] = args |
256 |
|
|
256 |
|
|
257 | 257 |
path = '/%s/%s' % (container, name) |
258 | 258 |
self.client.create_object(container, name, f=StringIO(obj['data']), |
259 | 259 |
meta=meta, **args) |
260 |
|
|
260 |
|
|
261 | 261 |
return obj |
262 | 262 |
except IOError: |
263 | 263 |
return |
... | ... | |
268 | 268 |
self.containers = ['apples', 'bananas', 'kiwis', 'oranges', 'pears'] |
269 | 269 |
for item in self.containers: |
270 | 270 |
self.client.create_container(item) |
271 |
|
|
271 |
|
|
272 | 272 |
meta = {'foo':'bar'} |
273 | 273 |
self.client.update_account_metadata(**meta) |
274 | 274 |
#self.updated_meta = self.initial_meta.update(meta) |
275 |
|
|
275 |
|
|
276 | 276 |
def test_get_account_meta(self): |
277 | 277 |
meta = self.client.retrieve_account_metadata() |
278 |
|
|
278 |
|
|
279 | 279 |
containers = self.client.list_containers() |
280 | 280 |
l = str(len(containers)) |
281 | 281 |
self.assertEqual(meta['x-account-container-count'], l) |
... | ... | |
284 | 284 |
m = self.client.retrieve_container_metadata(c) |
285 | 285 |
size = size + int(m['x-container-bytes-used']) |
286 | 286 |
self.assertEqual(meta['x-account-bytes-used'], str(size)) |
287 |
|
|
287 |
|
|
288 | 288 |
def test_get_account_403(self): |
289 | 289 |
self.assert_raises_fault(403, |
290 | 290 |
self.invalid_client.retrieve_account_metadata) |
291 |
|
|
291 |
|
|
292 | 292 |
def test_get_account_meta_until(self): |
293 | 293 |
t = datetime.datetime.utcnow() |
294 | 294 |
past = t - datetime.timedelta(minutes=-15) |
295 | 295 |
past = int(_time.mktime(past.timetuple())) |
296 |
|
|
296 |
|
|
297 | 297 |
meta = {'premium':True} |
298 | 298 |
self.client.update_account_metadata(**meta) |
299 | 299 |
meta = self.client.retrieve_account_metadata(restricted=True, |
300 | 300 |
until=past) |
301 | 301 |
self.assertTrue('premium' not in meta) |
302 |
|
|
302 |
|
|
303 | 303 |
meta = self.client.retrieve_account_metadata(restricted=True) |
304 | 304 |
self.assertTrue('premium' in meta) |
305 |
|
|
305 |
|
|
306 | 306 |
def test_get_account_meta_until_invalid_date(self): |
307 | 307 |
meta = {'premium':True} |
308 | 308 |
self.client.update_account_metadata(**meta) |
309 | 309 |
meta = self.client.retrieve_account_metadata(restricted=True, |
310 | 310 |
until='kshfksfh') |
311 | 311 |
self.assertTrue('premium' in meta) |
312 |
|
|
312 |
|
|
313 | 313 |
class AccountGet(BaseTestCase): |
314 | 314 |
def setUp(self): |
315 | 315 |
BaseTestCase.setUp(self) |
... | ... | |
317 | 317 |
self.containers = ['apples', 'bananas', 'kiwis', 'oranges', 'pears'] |
318 | 318 |
for item in self.containers: |
319 | 319 |
self.client.create_container(item) |
320 |
|
|
320 |
|
|
321 | 321 |
def test_list(self): |
322 | 322 |
#list containers |
323 | 323 |
containers = self.client.list_containers() |
324 | 324 |
self.assertEquals(self.containers, containers) |
325 |
|
|
325 |
|
|
326 | 326 |
def test_list_403(self): |
327 | 327 |
self.assert_raises_fault(403, self.invalid_client.list_containers) |
328 |
|
|
328 |
|
|
329 | 329 |
def test_list_with_limit(self): |
330 | 330 |
limit = 2 |
331 | 331 |
containers = self.client.list_containers(limit=limit) |
332 | 332 |
self.assertEquals(len(containers), limit) |
333 | 333 |
self.assertEquals(self.containers[:2], containers) |
334 |
|
|
334 |
|
|
335 | 335 |
def test_list_with_marker(self): |
336 | 336 |
l = 2 |
337 | 337 |
m = 'bananas' |
338 | 338 |
containers = self.client.list_containers(limit=l, marker=m) |
339 | 339 |
i = self.containers.index(m) + 1 |
340 | 340 |
self.assertEquals(self.containers[i:(i+l)], containers) |
341 |
|
|
341 |
|
|
342 | 342 |
m = 'oranges' |
343 | 343 |
containers = self.client.list_containers(limit=l, marker=m) |
344 | 344 |
i = self.containers.index(m) + 1 |
345 | 345 |
self.assertEquals(self.containers[i:(i+l)], containers) |
346 |
|
|
346 |
|
|
347 | 347 |
def test_list_json_with_marker(self): |
348 | 348 |
l = 2 |
349 | 349 |
m = 'bananas' |
... | ... | |
351 | 351 |
self.assert_extended(containers, 'json', 'container', l) |
352 | 352 |
self.assertEqual(containers[0]['name'], 'kiwis') |
353 | 353 |
self.assertEqual(containers[1]['name'], 'oranges') |
354 |
|
|
354 |
|
|
355 | 355 |
def test_list_xml_with_marker(self): |
356 | 356 |
l = 2 |
357 | 357 |
m = 'oranges' |
... | ... | |
360 | 360 |
nodes = xml.getElementsByTagName('name') |
361 | 361 |
self.assertEqual(len(nodes), 1) |
362 | 362 |
self.assertEqual(nodes[0].childNodes[0].data, 'pears') |
363 |
|
|
363 |
|
|
364 | 364 |
def test_if_modified_since(self): |
365 | 365 |
t = datetime.datetime.utcnow() |
366 | 366 |
t2 = t - datetime.timedelta(minutes=10) |
367 |
|
|
367 |
|
|
368 | 368 |
#add a new container |
369 | 369 |
self.client.create_container('dummy') |
370 |
|
|
370 |
|
|
371 | 371 |
for f in DATE_FORMATS: |
372 | 372 |
past = t2.strftime(f) |
373 | 373 |
try: |
... | ... | |
375 | 375 |
self.assertEqual(len(c), len(self.containers) + 1) |
376 | 376 |
except Fault, f: |
377 | 377 |
self.failIf(f.status == 304) #fail if not modified |
378 |
|
|
378 |
|
|
379 | 379 |
def test_if_modified_since_invalid_date(self): |
380 | 380 |
c = self.client.list_containers(if_modified_since='') |
381 | 381 |
self.assertEqual(len(c), len(self.containers)) |
382 |
|
|
382 |
|
|
383 | 383 |
def test_if_not_modified_since(self): |
384 | 384 |
now = datetime.datetime.utcnow() |
385 | 385 |
since = now + datetime.timedelta(1) |
386 |
|
|
386 |
|
|
387 | 387 |
for f in DATE_FORMATS: |
388 | 388 |
args = {'if_modified_since':'%s' %since.strftime(f)} |
389 |
|
|
389 |
|
|
390 | 390 |
#assert not modified |
391 | 391 |
self.assert_raises_fault(304, self.client.list_containers, **args) |
392 |
|
|
392 |
|
|
393 | 393 |
def test_if_unmodified_since(self): |
394 | 394 |
now = datetime.datetime.utcnow() |
395 | 395 |
since = now + datetime.timedelta(1) |
396 |
|
|
396 |
|
|
397 | 397 |
for f in DATE_FORMATS: |
398 | 398 |
c = self.client.list_containers(if_unmodified_since=since.strftime(f)) |
399 |
|
|
399 |
|
|
400 | 400 |
#assert success |
401 | 401 |
self.assertEqual(self.containers, c) |
402 |
|
|
402 |
|
|
403 | 403 |
def test_if_unmodified_since_precondition_failed(self): |
404 | 404 |
t = datetime.datetime.utcnow() |
405 | 405 |
t2 = t - datetime.timedelta(minutes=10) |
406 |
|
|
406 |
|
|
407 | 407 |
#add a new container |
408 | 408 |
self.client.create_container('dummy') |
409 |
|
|
409 |
|
|
410 | 410 |
for f in DATE_FORMATS: |
411 | 411 |
past = t2.strftime(f) |
412 |
|
|
412 |
|
|
413 | 413 |
args = {'if_unmodified_since':'%s' %past} |
414 |
|
|
414 |
|
|
415 | 415 |
#assert precondition failed |
416 | 416 |
self.assert_raises_fault(412, self.client.list_containers, **args) |
417 |
|
|
417 |
|
|
418 | 418 |
class AccountPost(BaseTestCase): |
419 | 419 |
def setUp(self): |
420 | 420 |
BaseTestCase.setUp(self) |
421 | 421 |
self.containers = ['apples', 'bananas', 'kiwis', 'oranges', 'pears'] |
422 | 422 |
for item in self.containers: |
423 | 423 |
self.client.create_container(item) |
424 |
|
|
424 |
|
|
425 | 425 |
meta = {'foo':'bar'} |
426 | 426 |
self.client.update_account_metadata(**meta) |
427 | 427 |
self.updated_meta = self.initial_meta.update(meta) |
428 |
|
|
428 |
|
|
429 | 429 |
def test_update_meta(self): |
430 | 430 |
with AssertMappingInvariant(self.client.retrieve_account_groups): |
431 | 431 |
meta = {'test':'test', 'tost':'tost'} |
432 | 432 |
self.client.update_account_metadata(**meta) |
433 |
|
|
433 |
|
|
434 | 434 |
meta.update(self.initial_meta) |
435 | 435 |
self.assertEqual(meta, |
436 | 436 |
self.client.retrieve_account_metadata( |
437 | 437 |
restricted=True)) |
438 |
|
|
438 |
|
|
439 | 439 |
def test_invalid_account_update_meta(self): |
440 | 440 |
meta = {'test':'test', 'tost':'tost'} |
441 | 441 |
self.assert_raises_fault(403, |
442 | 442 |
self.invalid_client.update_account_metadata, |
443 | 443 |
**meta) |
444 |
|
|
444 |
|
|
445 | 445 |
def test_reset_meta(self): |
446 | 446 |
with AssertMappingInvariant(self.client.retrieve_account_groups): |
447 | 447 |
meta = {'test':'test', 'tost':'tost'} |
448 | 448 |
self.client.update_account_metadata(**meta) |
449 |
|
|
449 |
|
|
450 | 450 |
meta = {'test':'test33'} |
451 | 451 |
self.client.reset_account_metadata(**meta) |
452 |
|
|
452 |
|
|
453 | 453 |
self.assertEqual(meta, self.client.retrieve_account_metadata(restricted=True)) |
454 |
|
|
454 |
|
|
455 | 455 |
def test_delete_meta(self): |
456 | 456 |
with AssertMappingInvariant(self.client.retrieve_account_groups): |
457 | 457 |
meta = {'test':'test', 'tost':'tost'} |
458 | 458 |
self.client.update_account_metadata(**meta) |
459 |
|
|
459 |
|
|
460 | 460 |
self.client.delete_account_metadata(meta.keys()) |
461 |
|
|
461 |
|
|
462 | 462 |
account_meta = self.client.retrieve_account_metadata(restricted=True) |
463 | 463 |
for m in meta: |
464 | 464 |
self.assertTrue(m not in account_meta.keys()) |
465 |
|
|
465 |
|
|
466 | 466 |
def test_set_account_groups(self): |
467 | 467 |
with AssertMappingInvariant(self.client.retrieve_account_metadata): |
468 | 468 |
groups = {'pithosdev':'verigak,gtsouk,chazapis'} |
469 | 469 |
self.client.set_account_groups(**groups) |
470 |
|
|
470 |
|
|
471 | 471 |
self.assertEqual(set(groups['pithosdev']), |
472 | 472 |
set(self.client.retrieve_account_groups()['pithosdev'])) |
473 |
|
|
473 |
|
|
474 | 474 |
more_groups = {'clientsdev':'pkanavos,mvasilak'} |
475 | 475 |
self.client.set_account_groups(**more_groups) |
476 |
|
|
476 |
|
|
477 | 477 |
groups.update(more_groups) |
478 | 478 |
self.assertEqual(set(groups['clientsdev']), |
479 | 479 |
set(self.client.retrieve_account_groups()['clientsdev'])) |
480 |
|
|
480 |
|
|
481 | 481 |
def test_reset_account_groups(self): |
482 | 482 |
with AssertMappingInvariant(self.client.retrieve_account_metadata): |
483 | 483 |
groups = {'pithosdev':'verigak,gtsouk,chazapis', |
484 | 484 |
'clientsdev':'pkanavos,mvasilak'} |
485 | 485 |
self.client.set_account_groups(**groups) |
486 |
|
|
486 |
|
|
487 | 487 |
self.assertEqual(set(groups['pithosdev'].split(',')), |
488 | 488 |
set(self.client.retrieve_account_groups()['pithosdev'].split(','))) |
489 | 489 |
self.assertEqual(set(groups['clientsdev'].split(',')), |
490 | 490 |
set(self.client.retrieve_account_groups()['clientsdev'].split(','))) |
491 |
|
|
491 |
|
|
492 | 492 |
groups = {'pithosdev':'verigak,gtsouk,chazapis,papagian'} |
493 | 493 |
self.client.reset_account_groups(**groups) |
494 |
|
|
494 |
|
|
495 | 495 |
self.assertEqual(set(groups['pithosdev'].split(',')), |
496 | 496 |
set(self.client.retrieve_account_groups()['pithosdev'].split(','))) |
497 |
|
|
497 |
|
|
498 | 498 |
def test_delete_account_groups(self): |
499 | 499 |
with AssertMappingInvariant(self.client.retrieve_account_metadata): |
500 | 500 |
groups = {'pithosdev':'verigak,gtsouk,chazapis', |
501 | 501 |
'clientsdev':'pkanavos,mvasilak'} |
502 | 502 |
self.client.set_account_groups(**groups) |
503 |
|
|
503 |
|
|
504 | 504 |
self.client.unset_account_groups(groups.keys()) |
505 |
|
|
505 |
|
|
506 | 506 |
self.assertEqual({}, self.client.retrieve_account_groups()) |
507 |
|
|
507 |
|
|
508 | 508 |
class ContainerHead(BaseTestCase): |
509 | 509 |
def setUp(self): |
510 | 510 |
BaseTestCase.setUp(self) |
511 | 511 |
self.container = 'apples' |
512 | 512 |
self.client.create_container(self.container) |
513 |
|
|
513 |
|
|
514 | 514 |
def test_get_meta(self): |
515 | 515 |
meta = {'trash':'true'} |
516 | 516 |
t1 = datetime.datetime.utcnow() |
... | ... | |
521 | 521 |
self.assertEqual(headers['x-container-bytes-used'], str(len(o['data']))) |
522 | 522 |
t2 = datetime.datetime.strptime(headers['last-modified'], DATE_FORMATS[2]) |
523 | 523 |
delta = (t2 - t1) |
524 |
threashold = datetime.timedelta(seconds=1)
|
|
524 |
threashold = datetime.timedelta(seconds=1) |
|
525 | 525 |
self.assertTrue(delta < threashold) |
526 | 526 |
self.assertTrue(headers['x-container-object-meta']) |
527 | 527 |
self.assertTrue('Trash' in headers['x-container-object-meta']) |
... | ... | |
537 | 537 |
self.obj.append(self.upload_random_data(self.container[0], o)) |
538 | 538 |
for o in o_names[8:]: |
539 | 539 |
self.obj.append(self.upload_random_data(self.container[1], o)) |
540 |
|
|
540 |
|
|
541 | 541 |
def test_list_objects(self): |
542 | 542 |
objects = self.client.list_objects(self.container[0]) |
543 | 543 |
l = [elem['name'] for elem in self.obj[:8]] |
544 | 544 |
l.sort() |
545 | 545 |
self.assertEqual(objects, l) |
546 |
|
|
546 |
|
|
547 | 547 |
def test_list_objects_containing_slash(self): |
548 | 548 |
self.client.create_container('test') |
549 | 549 |
self.upload_random_data('test', '/objectname') |
550 |
|
|
550 |
|
|
551 | 551 |
objects = self.client.list_objects('test') |
552 | 552 |
self.assertEqual(objects, ['/objectname']) |
553 |
|
|
553 |
|
|
554 | 554 |
objects = self.client.list_objects('test', format='json') |
555 | 555 |
self.assertEqual(objects[0]['name'], '/objectname') |
556 |
|
|
556 |
|
|
557 | 557 |
objects = self.client.list_objects('test', format='xml') |
558 | 558 |
self.assert_extended(objects, 'xml', 'object') |
559 | 559 |
node_name = objects.getElementsByTagName('name')[0] |
... | ... | |
564 | 564 |
l = [elem['name'] for elem in self.obj[:8]] |
565 | 565 |
l.sort() |
566 | 566 |
self.assertEqual(objects, l[:2]) |
567 |
|
|
567 |
|
|
568 | 568 |
markers = ['How To Win Friends And Influence People.pdf', |
569 | 569 |
'moms_birthday.jpg'] |
570 | 570 |
limit = 4 |
... | ... | |
577 | 577 |
end = start + limit |
578 | 578 |
end = end if len(l) >= end else len(l) |
579 | 579 |
self.assertEqual(objects, l[start:end]) |
580 |
|
|
580 |
|
|
581 | 581 |
#takes too long |
582 | 582 |
def _test_list_limit_exceeds(self): |
583 | 583 |
self.client.create_container('pithos') |
584 |
|
|
584 |
|
|
585 | 585 |
for i in range(10001): |
586 | 586 |
self.client.create_zero_length_object('pithos', i) |
587 |
|
|
587 |
|
|
588 | 588 |
self.assertEqual(10000, len(self.client.list_objects('pithos'))) |
589 |
|
|
589 |
|
|
590 | 590 |
def test_list_empty_params(self): |
591 | 591 |
objects = self.client.get('/%s/%s' % (get_user(), self.container[0]))[2] |
592 | 592 |
if objects: |
593 | 593 |
objects = objects.strip().split('\n') |
594 | 594 |
self.assertEqual(objects, |
595 | 595 |
self.client.list_objects(self.container[0])) |
596 |
|
|
596 |
|
|
597 | 597 |
def test_list_pseudo_hierarchical_folders(self): |
598 | 598 |
objects = self.client.list_objects(self.container[1], prefix='photos', |
599 | 599 |
delimiter='/') |
600 | 600 |
self.assertEquals(['photos/animals/', 'photos/me.jpg', |
601 | 601 |
'photos/plants/'], objects) |
602 |
|
|
602 |
|
|
603 | 603 |
objects = self.client.list_objects(self.container[1], |
604 | 604 |
prefix='photos/animals', |
605 | 605 |
delimiter='/') |
606 | 606 |
l = ['photos/animals/cats/', 'photos/animals/dogs/'] |
607 | 607 |
self.assertEquals(l, objects) |
608 |
|
|
608 |
|
|
609 | 609 |
objects = self.client.list_objects(self.container[1], path='photos') |
610 | 610 |
self.assertEquals(['photos/me.jpg'], objects) |
611 |
|
|
611 |
|
|
612 | 612 |
def test_extended_list_json(self): |
613 | 613 |
objects = self.client.list_objects(self.container[1], format='json', |
614 | 614 |
limit=2, prefix='photos/animals', |
615 | 615 |
delimiter='/') |
616 | 616 |
self.assertEqual(objects[0]['subdir'], 'photos/animals/cats/') |
617 | 617 |
self.assertEqual(objects[1]['subdir'], 'photos/animals/dogs/') |
618 |
|
|
618 |
|
|
619 | 619 |
def test_extended_list_xml(self): |
620 | 620 |
xml = self.client.list_objects(self.container[1], format='xml', limit=4, |
621 | 621 |
prefix='photos', delimiter='/') |
... | ... | |
624 | 624 |
self.assertEqual(len(dirs), 2) |
625 | 625 |
self.assertEqual(dirs[0].attributes['name'].value, 'photos/animals/') |
626 | 626 |
self.assertEqual(dirs[1].attributes['name'].value, 'photos/plants/') |
627 |
|
|
627 |
|
|
628 | 628 |
objects = xml.getElementsByTagName('name') |
629 | 629 |
self.assertEqual(len(objects), 1) |
630 | 630 |
self.assertEqual(objects[0].childNodes[0].data, 'photos/me.jpg') |
631 |
|
|
631 |
|
|
632 | 632 |
def test_list_meta_double_matching(self): |
633 | 633 |
meta = {'quality':'aaa', 'stock':'true'} |
634 | 634 |
self.client.update_object_metadata(self.container[0], |
... | ... | |
636 | 636 |
obj = self.client.list_objects(self.container[0], meta='Quality,Stock') |
637 | 637 |
self.assertEqual(len(obj), 1) |
638 | 638 |
self.assertTrue(obj, self.obj[0]['name']) |
639 |
|
|
639 |
|
|
640 | 640 |
def test_list_using_meta(self): |
641 | 641 |
meta = {'quality':'aaa'} |
642 | 642 |
for o in self.obj[:2]: |
... | ... | |
646 | 646 |
for o in self.obj[3:5]: |
647 | 647 |
self.client.update_object_metadata(self.container[0], o['name'], |
648 | 648 |
**meta) |
649 |
|
|
649 |
|
|
650 | 650 |
obj = self.client.list_objects(self.container[0], meta='Quality') |
651 | 651 |
self.assertEqual(len(obj), 2) |
652 | 652 |
self.assertTrue(obj, [o['name'] for o in self.obj[:2]]) |
653 |
|
|
653 |
|
|
654 | 654 |
# test case insensitive |
655 | 655 |
obj = self.client.list_objects(self.container[0], meta='quality') |
656 | 656 |
self.assertEqual(len(obj), 2) |
657 | 657 |
self.assertTrue(obj, [o['name'] for o in self.obj[:2]]) |
658 |
|
|
658 |
|
|
659 | 659 |
# test multiple matches |
660 | 660 |
obj = self.client.list_objects(self.container[0], meta='Quality,Stock') |
661 | 661 |
self.assertEqual(len(obj), 4) |
662 | 662 |
self.assertTrue(obj, [o['name'] for o in self.obj[:4]]) |
663 |
|
|
663 |
|
|
664 | 664 |
# test non 1-1 multiple match |
665 | 665 |
obj = self.client.list_objects(self.container[0], meta='Quality,aaaa') |
666 | 666 |
self.assertEqual(len(obj), 2) |
667 | 667 |
self.assertTrue(obj, [o['name'] for o in self.obj[:2]]) |
668 |
|
|
668 |
|
|
669 | 669 |
def test_if_modified_since(self): |
670 | 670 |
t = datetime.datetime.utcnow() |
671 | 671 |
t2 = t - datetime.timedelta(minutes=10) |
672 |
|
|
672 |
|
|
673 | 673 |
#add a new object |
674 | 674 |
self.upload_random_data(self.container[0], o_names[0]) |
675 |
|
|
675 |
|
|
676 | 676 |
for f in DATE_FORMATS: |
677 | 677 |
past = t2.strftime(f) |
678 | 678 |
try: |
... | ... | |
682 | 682 |
self.client.list_objects(self.container[0])) |
683 | 683 |
except Fault, f: |
684 | 684 |
self.failIf(f.status == 304) #fail if not modified |
685 |
|
|
685 |
|
|
686 | 686 |
def test_if_modified_since_invalid_date(self): |
687 | 687 |
headers = {'if-modified-since':''} |
688 | 688 |
o = self.client.list_objects(self.container[0], if_modified_since='') |
689 | 689 |
self.assertEqual(o, self.client.list_objects(self.container[0])) |
690 |
|
|
690 |
|
|
691 | 691 |
def test_if_not_modified_since(self): |
692 | 692 |
now = datetime.datetime.utcnow() |
693 | 693 |
since = now + datetime.timedelta(1) |
694 |
|
|
694 |
|
|
695 | 695 |
for f in DATE_FORMATS: |
696 | 696 |
args = {'if_modified_since':'%s' %since.strftime(f)} |
697 |
|
|
697 |
|
|
698 | 698 |
#assert not modified |
699 | 699 |
self.assert_raises_fault(304, self.client.list_objects, |
700 | 700 |
self.container[0], **args) |
701 |
|
|
701 |
|
|
702 | 702 |
def test_if_unmodified_since(self): |
703 | 703 |
now = datetime.datetime.utcnow() |
704 | 704 |
since = now + datetime.timedelta(1) |
705 |
|
|
705 |
|
|
706 | 706 |
for f in DATE_FORMATS: |
707 | 707 |
obj = self.client.list_objects(self.container[0], |
708 | 708 |
if_unmodified_since=since.strftime(f)) |
709 |
|
|
709 |
|
|
710 | 710 |
#assert unmodified |
711 | 711 |
self.assertEqual(obj, self.client.list_objects(self.container[0])) |
712 |
|
|
712 |
|
|
713 | 713 |
def test_if_unmodified_since_precondition_failed(self): |
714 | 714 |
t = datetime.datetime.utcnow() |
715 | 715 |
t2 = t - datetime.timedelta(minutes=10) |
716 |
|
|
716 |
|
|
717 | 717 |
#add a new container |
718 | 718 |
self.client.create_container('dummy') |
719 |
|
|
719 |
|
|
720 | 720 |
for f in DATE_FORMATS: |
721 | 721 |
past = t2.strftime(f) |
722 |
|
|
722 |
|
|
723 | 723 |
args = {'if_unmodified_since':'%s' %past} |
724 |
|
|
724 |
|
|
725 | 725 |
#assert precondition failed |
726 | 726 |
self.assert_raises_fault(412, self.client.list_objects, |
727 | 727 |
self.container[0], **args) |
... | ... | |
730 | 730 |
def setUp(self): |
731 | 731 |
BaseTestCase.setUp(self) |
732 | 732 |
self.containers = ['c1', 'c2'] |
733 |
|
|
733 |
|
|
734 | 734 |
def test_create(self): |
735 | 735 |
self.client.create_container(self.containers[0]) |
736 | 736 |
containers = self.client.list_containers() |
737 | 737 |
self.assertTrue(self.containers[0] in containers) |
738 | 738 |
self.assert_container_exists(self.containers[0]) |
739 |
|
|
739 |
|
|
740 | 740 |
def test_create_twice(self): |
741 | 741 |
self.client.create_container(self.containers[0]) |
742 | 742 |
self.assertTrue(not self.client.create_container(self.containers[0])) |
743 |
|
|
743 |
|
|
744 | 744 |
def test_quota(self): |
745 | 745 |
self.client.create_container(self.containers[0]) |
746 |
|
|
746 |
|
|
747 | 747 |
policy = {'quota':100} |
748 | 748 |
self.client.set_container_policies('c1', **policy) |
749 |
|
|
749 |
|
|
750 | 750 |
meta = self.client.retrieve_container_metadata('c1') |
751 | 751 |
self.assertTrue('x-container-policy-quota' in meta) |
752 | 752 |
self.assertEqual(meta['x-container-policy-quota'], '100') |
753 |
|
|
753 |
|
|
754 | 754 |
args = ['c1', 'o1'] |
755 | 755 |
kwargs = {'length':101} |
756 | 756 |
self.assert_raises_fault(413, self.upload_random_data, *args, **kwargs) |
757 |
|
|
757 |
|
|
758 | 758 |
#reset quota |
759 | 759 |
policy = {'quota':0} |
760 | 760 |
self.client.set_container_policies('c1', **policy) |
761 |
|
|
761 |
|
|
762 | 762 |
class ContainerPost(BaseTestCase): |
763 | 763 |
def setUp(self): |
764 | 764 |
BaseTestCase.setUp(self) |
765 | 765 |
self.container = 'apples' |
766 | 766 |
self.client.create_container(self.container) |
767 |
|
|
767 |
|
|
768 | 768 |
def test_update_meta(self): |
769 | 769 |
meta = {'test':'test33', |
770 | 770 |
'tost':'tost22'} |
... | ... | |
781 | 781 |
self.containers = ['c1', 'c2'] |
782 | 782 |
for c in self.containers: |
783 | 783 |
self.client.create_container(c) |
784 |
|
|
784 |
|
|
785 | 785 |
def test_delete(self): |
786 | 786 |
status = self.client.delete_container(self.containers[0])[0] |
787 | 787 |
self.assertEqual(status, 204) |
788 |
|
|
788 |
|
|
789 | 789 |
def test_delete_non_empty(self): |
790 | 790 |
self.upload_random_data(self.containers[1], o_names[0]) |
791 | 791 |
self.assert_raises_fault(409, self.client.delete_container, |
792 | 792 |
self.containers[1]) |
793 |
|
|
793 |
|
|
794 | 794 |
def test_delete_invalid(self): |
795 | 795 |
self.assert_raises_fault(404, self.client.delete_container, 'c3') |
796 | 796 |
|
... | ... | |
801 | 801 |
#create some containers |
802 | 802 |
for c in self.containers: |
803 | 803 |
self.client.create_container(c) |
804 |
|
|
804 |
|
|
805 | 805 |
#upload a file |
806 | 806 |
names = ('obj1', 'obj2') |
807 | 807 |
self.objects = [] |
808 | 808 |
for n in names: |
809 | 809 |
self.objects.append(self.upload_random_data(self.containers[1], n)) |
810 |
|
|
810 |
|
|
811 | 811 |
def test_versions(self): |
812 | 812 |
c = self.containers[1] |
813 | 813 |
o = self.objects[0] |
814 | 814 |
b = self.client.retrieve_object_versionlist(c, o['name'])['versions'] |
815 | 815 |
self.assert_versionlist_structure(b) |
816 |
|
|
816 |
|
|
817 | 817 |
#update meta |
818 | 818 |
meta = {'quality':'AAA', 'stock':True} |
819 | 819 |
self.client.update_object_metadata(c, o['name'], **meta) |
820 |
|
|
820 |
|
|
821 | 821 |
a = self.client.retrieve_object_versionlist(c, o['name'])['versions'] |
822 | 822 |
self.assert_versionlist_structure(a) |
823 | 823 |
self.assertEqual(len(b)+1, len(a)) |
824 | 824 |
self.assertEqual(b, a[:-1]) |
825 |
|
|
825 |
|
|
826 | 826 |
#get exact previous version metadata |
827 | 827 |
v = a[-2][0] |
828 | 828 |
v_meta = self.client.retrieve_object_metadata(c, o['name'], |
... | ... | |
830 | 830 |
version=v) |
831 | 831 |
for k in meta.keys(): |
832 | 832 |
self.assertTrue(k not in v_meta) |
833 |
|
|
833 |
|
|
834 | 834 |
#update obejct |
835 | 835 |
data = get_random_data() |
836 | 836 |
self.client.update_object(c, o['name'], StringIO(data)) |
837 |
|
|
837 |
|
|
838 | 838 |
aa = self.client.retrieve_object_versionlist(c, o['name'])['versions'] |
839 | 839 |
self.assert_versionlist_structure(aa) |
840 | 840 |
self.assertEqual(len(a)+1, len(aa)) |
841 | 841 |
self.assertEqual(a, aa[:-1]) |
842 |
|
|
842 |
|
|
843 | 843 |
#get exact previous version |
844 | 844 |
v = aa[-3][0] |
845 | 845 |
v_data = self.client.retrieve_object_version(c, o['name'], version=v) |
846 | 846 |
self.assertEqual(o['data'], v_data) |
847 | 847 |
self.assertEqual(self.client.retrieve_object(c, o['name']), |
848 | 848 |
'%s%s' %(v_data, data)) |
849 |
|
|
849 |
|
|
850 | 850 |
def test_get(self): |
851 | 851 |
#perform get |
852 | 852 |
o = self.client.retrieve_object(self.containers[1], |
853 | 853 |
self.objects[0]['name'], |
854 | 854 |
self.objects[0]['meta']) |
855 | 855 |
self.assertEqual(o, self.objects[0]['data']) |
856 |
|
|
856 |
|
|
857 | 857 |
def test_objects_with_trailing_spaces(self): |
858 | 858 |
self.client.create_container('test') |
859 | 859 |
#create 'a' object |
... | ... | |
861 | 861 |
#look for 'a ' object |
862 | 862 |
self.assert_raises_fault(404, self.client.retrieve_object, |
863 | 863 |
'test', 'a ') |
864 |
|
|
864 |
|
|
865 | 865 |
#delete 'a' object |
866 | 866 |
self.client.delete_object('test', 'a') |
867 | 867 |
self.assert_raises_fault(404, self.client.retrieve_object, |
868 | 868 |
'test', 'a') |
869 |
|
|
869 |
|
|
870 | 870 |
#create 'a ' object |
871 | 871 |
self.upload_random_data('test', 'a ') |
872 | 872 |
#look for 'a' object |
873 | 873 |
self.assert_raises_fault(404, self.client.retrieve_object, |
874 | 874 |
'test', 'a') |
875 |
|
|
875 |
|
|
876 | 876 |
def test_get_invalid(self): |
877 | 877 |
self.assert_raises_fault(404, self.client.retrieve_object, |
878 | 878 |
self.containers[0], self.objects[0]['name']) |
879 |
|
|
879 |
|
|
880 | 880 |
def test_get_partial(self): |
881 | 881 |
#perform get with range |
882 | 882 |
status, headers, data = self.client.request_object(self.containers[1], |
883 | 883 |
self.objects[0]['name'], |
884 | 884 |
range='bytes=0-499') |
885 |
|
|
885 |
|
|
886 | 886 |
#assert successful partial content |
887 | 887 |
self.assertEqual(status, 206) |
888 |
|
|
888 |
|
|
889 | 889 |
#assert content-type |
890 | 890 |
self.assertEqual(headers['content-type'], |
891 | 891 |
self.objects[0]['meta']['content_type']) |
892 |
|
|
892 |
|
|
893 | 893 |
#assert content length |
894 | 894 |
self.assertEqual(int(headers['content-length']), 500) |
895 |
|
|
895 |
|
|
896 | 896 |
#assert content |
897 | 897 |
self.assertEqual(self.objects[0]['data'][:500], data) |
898 |
|
|
898 |
|
|
899 | 899 |
def test_get_final_500(self): |
900 | 900 |
#perform get with range |
901 | 901 |
headers = {'range':'bytes=-500'} |
902 | 902 |
status, headers, data = self.client.request_object(self.containers[1], |
903 | 903 |
self.objects[0]['name'], |
904 | 904 |
range='bytes=-500') |
905 |
|
|
905 |
|
|
906 | 906 |
#assert successful partial content |
907 | 907 |
self.assertEqual(status, 206) |
908 |
|
|
908 |
|
|
909 | 909 |
#assert content-type |
910 | 910 |
self.assertEqual(headers['content-type'], |
911 | 911 |
self.objects[0]['meta']['content_type']) |
912 |
|
|
912 |
|
|
913 | 913 |
#assert content length |
914 | 914 |
self.assertEqual(int(headers['content-length']), 500) |
915 |
|
|
915 |
|
|
916 | 916 |
#assert content |
917 | 917 |
self.assertTrue(self.objects[0]['data'][-500:], data) |
918 |
|
|
918 |
|
|
919 | 919 |
def test_get_rest(self): |
920 | 920 |
#perform get with range |
921 | 921 |
offset = len(self.objects[0]['data']) - 500 |
922 | 922 |
status, headers, data = self.client.request_object(self.containers[1], |
923 | 923 |
self.objects[0]['name'], |
924 | 924 |
range='bytes=%s-' %offset) |
925 |
|
|
925 |
|
|
926 | 926 |
#assert successful partial content |
927 | 927 |
self.assertEqual(status, 206) |
928 |
|
|
928 |
|
|
929 | 929 |
#assert content-type |
930 | 930 |
self.assertEqual(headers['content-type'], |
931 | 931 |
self.objects[0]['meta']['content_type']) |
932 |
|
|
932 |
|
|
933 | 933 |
#assert content length |
934 | 934 |
self.assertEqual(int(headers['content-length']), 500) |
935 |
|
|
935 |
|
|
936 | 936 |
#assert content |
937 | 937 |
self.assertTrue(self.objects[0]['data'][-500:], data) |
938 |
|
|
938 |
|
|
939 | 939 |
def test_get_range_not_satisfiable(self): |
940 | 940 |
#perform get with range |
941 | 941 |
offset = len(self.objects[0]['data']) + 1 |
942 |
|
|
942 |
|
|
943 | 943 |
#assert range not satisfiable |
944 | 944 |
self.assert_raises_fault(416, self.client.retrieve_object, |
945 | 945 |
self.containers[1], self.objects[0]['name'], |
946 | 946 |
range='bytes=0-%s' %offset) |
947 |
|
|
947 |
|
|
948 | 948 |
def test_multiple_range(self): |
949 | 949 |
#perform get with multiple range |
950 | 950 |
ranges = ['0-499', '-500', '1000-'] |
... | ... | |
952 | 952 |
status, headers, data = self.client.request_object(self.containers[1], |
953 | 953 |
self.objects[0]['name'], |
954 | 954 |
range=bytes) |
955 |
|
|
955 |
|
|
956 | 956 |
# assert partial content |
957 | 957 |
self.assertEqual(status, 206) |
958 |
|
|
958 |
|
|
959 | 959 |
# assert Content-Type of the reply will be multipart/byteranges |
960 | 960 |
self.assertTrue(headers['content-type']) |
961 | 961 |
content_type_parts = headers['content-type'].split() |
962 | 962 |
self.assertEqual(content_type_parts[0], ('multipart/byteranges;')) |
963 |
|
|
963 |
|
|
964 | 964 |
boundary = '--%s' %content_type_parts[1].split('=')[-1:][0] |
965 | 965 |
cparts = data.split(boundary)[1:-1] |
966 |
|
|
966 |
|
|
967 | 967 |
# assert content parts are exactly 2 |
968 | 968 |
self.assertEqual(len(cparts), len(ranges)) |
969 |
|
|
969 |
|
|
970 | 970 |
# for each content part assert headers |
971 | 971 |
i = 0 |
972 | 972 |
for cpart in cparts: |
... | ... | |
974 | 974 |
headers = content[1:3] |
975 | 975 |
content_range = headers[0].split(': ') |
976 | 976 |
self.assertEqual(content_range[0], 'Content-Range') |
977 |
|
|
977 |
|
|
978 | 978 |
r = ranges[i].split('-') |
979 | 979 |
if not r[0] and not r[1]: |
980 | 980 |
pass |
... | ... | |
992 | 992 |
self.assertEqual(len(fdata), len(sdata)) |
993 | 993 |
self.assertEquals(fdata, sdata) |
994 | 994 |
i+=1 |
995 |
|
|
995 |
|
|
996 | 996 |
def test_multiple_range_not_satisfiable(self): |
997 | 997 |
#perform get with multiple range |
998 | 998 |
out_of_range = len(self.objects[0]['data']) + 1 |
999 | 999 |
ranges = ['0-499', '-500', '%d-' %out_of_range] |
1000 | 1000 |
bytes = 'bytes=%s' % ','.join(ranges) |
1001 |
|
|
1001 |
|
|
1002 | 1002 |
# assert partial content |
1003 | 1003 |
self.assert_raises_fault(416, self.client.retrieve_object, |
1004 | 1004 |
self.containers[1], |
1005 | 1005 |
self.objects[0]['name'], range=bytes) |
1006 |
|
|
1006 |
|
|
1007 | 1007 |
def test_get_with_if_match(self): |
1008 | 1008 |
#perform get with If-Match |
1009 | 1009 |
etag = self.objects[0]['hash'] |
... | ... | |
1012 | 1012 |
if_match=etag) |
1013 | 1013 |
#assert get success |
1014 | 1014 |
self.assertEqual(status, 200) |
1015 |
|
|
1015 |
|
|
1016 | 1016 |
#assert content-type |
1017 | 1017 |
self.assertEqual(headers['content-type'], |
1018 | 1018 |
self.objects[0]['meta']['content_type']) |
1019 |
|
|
1019 |
|
|
1020 | 1020 |
#assert response content |
1021 | 1021 |
self.assertEqual(self.objects[0]['data'], data) |
1022 |
|
|
1022 |
|
|
1023 | 1023 |
def test_get_with_if_match_star(self): |
1024 | 1024 |
#perform get with If-Match * |
1025 | 1025 |
headers = {'if-match':'*'} |
... | ... | |
1028 | 1028 |
**headers) |
1029 | 1029 |
#assert get success |
1030 | 1030 |
self.assertEqual(status, 200) |
1031 |
|
|
1031 |
|
|
1032 | 1032 |
#assert content-type |
1033 | 1033 |
self.assertEqual(headers['content-type'], |
1034 | 1034 |
self.objects[0]['meta']['content_type']) |
1035 |
|
|
1035 |
|
|
1036 | 1036 |
#assert response content |
1037 | 1037 |
self.assertEqual(self.objects[0]['data'], data) |
1038 |
|
|
1038 |
|
|
1039 | 1039 |
def test_get_with_multiple_if_match(self): |
1040 | 1040 |
#perform get with If-Match |
1041 | 1041 |
etags = [i['hash'] for i in self.objects if i] |
... | ... | |
1045 | 1045 |
if_match=etags) |
1046 | 1046 |
#assert get success |
1047 | 1047 |
self.assertEqual(status, 200) |
1048 |
|
|
1048 |
|
|
1049 | 1049 |
#assert content-type |
1050 | 1050 |
self.assertEqual(headers['content-type'], |
1051 | 1051 |
self.objects[0]['meta']['content_type']) |
1052 |
|
|
1052 |
|
|
1053 | 1053 |
#assert content-type |
1054 | 1054 |
self.assertEqual(headers['content-type'], |
1055 | 1055 |
self.objects[0]['meta']['content_type']) |
1056 |
|
|
1056 |
|
|
1057 | 1057 |
#assert response content |
1058 | 1058 |
self.assertEqual(self.objects[0]['data'], data) |
1059 |
|
|
1059 |
|
|
1060 | 1060 |
def test_if_match_precondition_failed(self): |
1061 | 1061 |
#assert precondition failed |
1062 | 1062 |
self.assert_raises_fault(412, self.client.retrieve_object, |
1063 | 1063 |
self.containers[1], |
1064 | 1064 |
self.objects[0]['name'], if_match='123') |
1065 |
|
|
1065 |
|
|
1066 | 1066 |
def test_if_none_match(self): |
1067 | 1067 |
#perform get with If-None-Match |
1068 | 1068 |
status, headers, data = self.client.request_object(self.containers[1], |
1069 | 1069 |
self.objects[0]['name'], |
1070 | 1070 |
if_none_match='123') |
1071 |
|
|
1071 |
|
|
1072 | 1072 |
#assert get success |
1073 | 1073 |
self.assertEqual(status, 200) |
1074 |
|
|
1074 |
|
|
1075 | 1075 |
#assert content-type |
1076 | 1076 |
self.assertEqual(headers['content_type'], |
1077 | 1077 |
self.objects[0]['meta']['content_type']) |
1078 |
|
|
1078 |
|
|
1079 | 1079 |
def test_if_none_match(self): |
1080 | 1080 |
#perform get with If-None-Match * and assert not modified |
1081 | 1081 |
self.assert_raises_fault(304, self.client.retrieve_object, |
1082 | 1082 |
self.containers[1], |
1083 | 1083 |
self.objects[0]['name'], |
1084 | 1084 |
if_none_match='*') |
1085 |
|
|
1085 |
|
|
1086 | 1086 |
def test_if_none_match_not_modified(self): |
1087 | 1087 |
#perform get with If-None-Match and assert not modified |
1088 | 1088 |
self.assert_raises_fault(304, self.client.retrieve_object, |
1089 | 1089 |
self.containers[1], |
1090 | 1090 |
self.objects[0]['name'], |
1091 | 1091 |
if_none_match=self.objects[0]['hash']) |
1092 |
|
|
1092 |
|
|
1093 | 1093 |
meta = self.client.retrieve_object_metadata(self.containers[1], |
1094 | 1094 |
self.objects[0]['name']) |
1095 | 1095 |
self.assertEqual(meta['etag'], self.objects[0]['hash']) |
1096 |
|
|
1096 |
|
|
1097 | 1097 |
def test_if_modified_since(self): |
1098 | 1098 |
t = datetime.datetime.utcnow() |
1099 | 1099 |
t2 = t - datetime.timedelta(minutes=10) |
1100 |
|
|
1100 |
|
|
1101 | 1101 |
#modify the object |
1102 | 1102 |
self.upload_data(self.containers[1], |
1103 | 1103 |
self.objects[0]['name'], |
1104 | 1104 |
self.objects[0]['data'][:200]) |
1105 |
|
|
1105 |
|
|
1106 | 1106 |
for f in DATE_FORMATS: |
1107 | 1107 |
past = t2.strftime(f) |
1108 |
|
|
1108 |
|
|
1109 | 1109 |
headers = {'if-modified-since':'%s' %past} |
1110 | 1110 |
try: |
1111 | 1111 |
o = self.client.retrieve_object(self.containers[1], |
... | ... | |
1116 | 1116 |
self.objects[0]['name'])) |
1117 | 1117 |
except Fault, f: |
1118 | 1118 |
self.failIf(f.status == 304) |
1119 |
|
|
1119 |
|
|
1120 | 1120 |
def test_if_modified_since_invalid_date(self): |
1121 | 1121 |
o = self.client.retrieve_object(self.containers[1], |
1122 | 1122 |
self.objects[0]['name'], |
1123 | 1123 |
if_modified_since='') |
1124 | 1124 |
self.assertEqual(o, self.client.retrieve_object(self.containers[1], |
1125 | 1125 |
self.objects[0]['name'])) |
1126 |
|
|
1126 |
|
|
1127 | 1127 |
def test_if_not_modified_since(self): |
1128 | 1128 |
now = datetime.datetime.utcnow() |
1129 | 1129 |
since = now + datetime.timedelta(1) |
1130 |
|
|
1130 |
|
|
1131 | 1131 |
for f in DATE_FORMATS: |
1132 | 1132 |
#assert not modified |
1133 | 1133 |
self.assert_raises_fault(304, self.client.retrieve_object, |
1134 | 1134 |
self.containers[1], self.objects[0]['name'], |
1135 | 1135 |
if_modified_since=since.strftime(f)) |
1136 |
|
|
1136 |
|
|
1137 | 1137 |
def test_if_unmodified_since(self): |
1138 | 1138 |
now = datetime.datetime.utcnow() |
1139 | 1139 |
since = now + datetime.timedelta(1) |
1140 |
|
|
1140 |
|
|
1141 | 1141 |
for f in DATE_FORMATS: |
1142 | 1142 |
t = since.strftime(f) |
1143 | 1143 |
status, headers, data = self.client.request_object(self.containers[1], |
... | ... | |
1146 | 1146 |
#assert success |
1147 | 1147 |
self.assertEqual(status, 200) |
1148 | 1148 |
self.assertEqual(self.objects[0]['data'], data) |
1149 |
|
|
1149 |
|
|
1150 | 1150 |
#assert content-type |
1151 | 1151 |
self.assertEqual(headers['content-type'], |
1152 | 1152 |
self.objects[0]['meta']['content_type']) |
1153 |
|
|
1153 |
|
|
1154 | 1154 |
def test_if_unmodified_since_precondition_failed(self): |
1155 | 1155 |
t = datetime.datetime.utcnow() |
1156 | 1156 |
t2 = t - datetime.timedelta(minutes=10) |
1157 |
|
|
1157 |
|
|
1158 | 1158 |
#modify the object |
1159 | 1159 |
self.upload_data(self.containers[1], |
1160 | 1160 |
self.objects[0]['name'], |
1161 | 1161 |
self.objects[0]['data'][:200]) |
1162 |
|
|
1162 |
|
|
1163 | 1163 |
for f in DATE_FORMATS: |
1164 | 1164 |
past = t2.strftime(f) |
1165 | 1165 |
#assert precondition failed |
1166 | 1166 |
self.assert_raises_fault(412, self.client.retrieve_object, |
1167 | 1167 |
self.containers[1], self.objects[0]['name'], |
1168 | 1168 |
if_unmodified_since=past) |
1169 |
|
|
1169 |
|
|
1170 | 1170 |
def test_hashes(self): |
1171 | 1171 |
l = 8388609 |
1172 | 1172 |
fname = 'largefile' |
... | ... | |
1192 | 1192 |
BaseTestCase.setUp(self) |
1193 | 1193 |
self.container = 'c1' |
1194 | 1194 |
self.client.create_container(self.container) |
1195 |
|
|
1195 |
|
|
1196 | 1196 |
def test_upload(self): |
1197 | 1197 |
name = o_names[0] |
1198 | 1198 |
meta = {'test':'test1'} |
1199 | 1199 |
o = self.upload_random_data(self.container, name, **meta) |
1200 |
|
|
1200 |
|
|
1201 | 1201 |
headers = self.client.retrieve_object_metadata(self.container, |
1202 | 1202 |
name, |
1203 | 1203 |
restricted=True) |
1204 | 1204 |
self.assertTrue('test' in headers.keys()) |
1205 | 1205 |
self.assertEqual(headers['test'], meta['test']) |
1206 |
|
|
1206 |
|
|
1207 | 1207 |
#assert uploaded content |
1208 | 1208 |
status, h, data = self.client.request_object(self.container, name) |
1209 | 1209 |
self.assertEqual(len(o['data']), int(h['content-length'])) |
1210 | 1210 |
self.assertEqual(o['data'], data) |
1211 |
|
|
1211 |
|
|
1212 | 1212 |
#assert content-type |
1213 | 1213 |
self.assertEqual(h['content-type'], o['meta']['content_type']) |
1214 |
|
|
1214 |
|
|
1215 | 1215 |
def _test_maximum_upload_size_exceeds(self): |
1216 | 1216 |
name = o_names[0] |
1217 | 1217 |
meta = {'test':'test1'} |
... | ... | |
1219 | 1219 |
length=1024*1024*100 |
1220 | 1220 |
self.assert_raises_fault(400, self.upload_random_data, self.container, |
1221 | 1221 |
name, length, **meta) |
1222 |
|
|
1222 |
|
|
1223 | 1223 |
def test_upload_with_name_containing_slash(self): |
1224 | 1224 |
name = '/%s' % o_names[0] |
1225 | 1225 |
meta = {'test':'test1'} |
1226 | 1226 |
o = self.upload_random_data(self.container, name, **meta) |
1227 |
|
|
1227 |
|
|
1228 | 1228 |
self.assertEqual(o['data'], |
1229 | 1229 |
self.client.retrieve_object(self.container, name)) |
1230 |
|
|
1230 |
|
|
1231 | 1231 |
self.assertTrue(name in self.client.list_objects(self.container)) |
1232 |
|
|
1232 |
|
|
1233 | 1233 |
def test_create_directory_marker(self): |
1234 | 1234 |
self.client.create_directory_marker(self.container, 'foo') |
1235 | 1235 |
meta = self.client.retrieve_object_metadata(self.container, 'foo') |
... | ... | |
1238 | 1238 |
|
1239 | 1239 |
def test_upload_unprocessable_entity(self): |
1240 | 1240 |
meta={'etag':'123', 'test':'test1'} |
1241 |
|
|
1241 |
|
|
1242 | 1242 |
#assert unprocessable entity |
1243 | 1243 |
self.assert_raises_fault(422, self.upload_random_data, self.container, |
1244 | 1244 |
o_names[0], **meta) |
1245 |
|
|
1245 |
|
|
1246 | 1246 |
def test_chunked_transfer(self): |
1247 | 1247 |
data = get_random_data() |
1248 | 1248 |
objname = 'object' |
1249 | 1249 |
self.client.create_object_using_chunks(self.container, objname, |
1250 | 1250 |
StringIO(data)) |
1251 |
|
|
1251 |
|
|
1252 | 1252 |
uploaded_data = self.client.retrieve_object(self.container, objname) |
1253 | 1253 |
self.assertEqual(data, uploaded_data) |
1254 |
|
|
1254 |
|
|
1255 | 1255 |
def test_manifestation(self): |
1256 | 1256 |
prefix = 'myobject/' |
1257 | 1257 |
data = '' |
... | ... | |
1259 | 1259 |
part = '%s%d' %(prefix, i) |
1260 | 1260 |
o = self.upload_random_data(self.container, part) |
1261 | 1261 |
data += o['data'] |
1262 |
|
|
1262 |
|
|
1263 | 1263 |
manifest = '%s/%s' %(self.container, prefix) |
1264 | 1264 |
self.client.create_manifestation(self.container, 'large-object', manifest) |
1265 |
|
|
1265 |
|
|
1266 | 1266 |
self.assert_object_exists(self.container, 'large-object') |
1267 | 1267 |
self.assertEqual(data, self.client.retrieve_object(self.container, |
1268 | 1268 |
'large-object')) |
1269 |
|
|
1269 |
|
|
1270 | 1270 |
#wrong manifestation |
1271 | 1271 |
self.client.create_manifestation(self.container, 'large-object', |
1272 | 1272 |
'%s/invalid' % self.container) |
1273 | 1273 |
self.assertEqual('', self.client.retrieve_object(self.container, |
1274 | 1274 |
'large-object')) |
1275 |
|
|
1275 |
|
|
1276 | 1276 |
def test_create_zero_length_object(self): |
1277 | 1277 |
c = self.container |
1278 | 1278 |
o = 'object' |
... | ... | |
1280 | 1280 |
zero_meta = self.client.retrieve_object_metadata(c, o) |
1281 | 1281 |
zero_hash = self.client.retrieve_object_hashmap(c, o)["hashes"] |
1282 | 1282 |
zero_data = self.client.retrieve_object(c, o) |
1283 |
|
|
1283 |
|
|
1284 | 1284 |
self.assertEqual(int(zero_meta['content-length']), 0) |
1285 | 1285 |
hasher = newhasher('sha256') |
1286 | 1286 |
hasher.update("") |
1287 | 1287 |
emptyhash = hasher.digest() |
1288 | 1288 |
self.assertEqual(zero_hash, [hexlify(emptyhash)]) |
1289 | 1289 |
self.assertEqual(zero_data, '') |
1290 |
|
|
1290 |
|
|
1291 | 1291 |
def test_create_object_by_hashmap(self): |
1292 | 1292 |
c = self.container |
1293 | 1293 |
o = 'object' |
... | ... | |
1305 | 1305 |
for c in self.containers: |
1306 | 1306 |
self.client.create_container(c) |
1307 | 1307 |
self.obj = self.upload_random_data(self.containers[0], o_names[0]) |
1308 |
|
|
1308 |
|
|
1309 | 1309 |
def test_copy(self): |
1310 | 1310 |
with AssertMappingInvariant(self.client.retrieve_object_metadata, |
1311 | 1311 |
self.containers[0], self.obj['name']): |
... | ... | |
1316 | 1316 |
self.containers[0], |
1317 | 1317 |
'testcopy', |
1318 | 1318 |
meta)[0] |
1319 |
|
|
1319 |
|
|
1320 | 1320 |
#assert copy success |
1321 | 1321 |
self.assertEqual(status, 201) |
1322 |
|
|
1322 |
|
|
1323 | 1323 |
#assert access the new object |
1324 | 1324 |
headers = self.client.retrieve_object_metadata(self.containers[0], |
1325 | 1325 |
'testcopy') |
1326 | 1326 |
self.assertTrue('x-object-meta-test' in headers.keys()) |
1327 | 1327 |
self.assertTrue(headers['x-object-meta-test'], 'testcopy') |
1328 |
|
|
1328 |
|
|
1329 | 1329 |
#assert etag is the same |
1330 | 1330 |
self.assertEqual(headers['etag'], self.obj['hash']) |
1331 |
|
|
1331 |
|
|
1332 | 1332 |
#assert src object still exists |
1333 | 1333 |
self.assert_object_exists(self.containers[0], self.obj['name']) |
1334 |
|
|
1334 |
|
|
1335 | 1335 |
def test_copy_from_different_container(self): |
1336 | 1336 |
with AssertMappingInvariant(self.client.retrieve_object_metadata, |
1337 | 1337 |
self.containers[0], self.obj['name']): |
... | ... | |
1342 | 1342 |
'testcopy', |
1343 | 1343 |
meta)[0] |
1344 | 1344 |
self.assertEqual(status, 201) |
1345 |
|
|
1345 |
|
|
1346 | 1346 |
# assert updated metadata |
1347 | 1347 |
meta = self.client.retrieve_object_metadata(self.containers[1], |
1348 | 1348 |
'testcopy', |
1349 | 1349 |
restricted=True) |
1350 | 1350 |
self.assertTrue('test' in meta.keys()) |
1351 | 1351 |
self.assertTrue(meta['test'], 'testcopy') |
1352 |
|
|
1352 |
|
|
1353 | 1353 |
#assert src object still exists |
1354 | 1354 |
self.assert_object_exists(self.containers[0], self.obj['name']) |
1355 |
|
|
1355 |
|
|
1356 | 1356 |
def test_copy_invalid(self): |
1357 | 1357 |
#copy from invalid object |
1358 | 1358 |
meta = {'test':'testcopy'} |
1359 | 1359 |
self.assert_raises_fault(404, self.client.copy_object, self.containers[0], |
1360 | 1360 |
'test.py', self.containers[1], 'testcopy', meta) |
1361 |
|
|
1361 |
|
|
1362 | 1362 |
#copy from invalid container |
1363 | 1363 |
meta = {'test':'testcopy'} |
1364 | 1364 |
self.assert_raises_fault(404, self.client.copy_object, self.containers[1], |
... | ... | |
1372 | 1372 |
for c in self.containers: |
1373 | 1373 |
self.client.create_container(c) |
1374 | 1374 |
self.obj = self.upload_random_data(self.containers[0], o_names[0]) |
1375 |
|
|
1375 |
|
|
1376 | 1376 |
def test_move(self): |
1377 | 1377 |
meta = self.client.retrieve_object_metadata(self.containers[0], |
1378 | 1378 |
self.obj['name']) |
1379 | 1379 |
self.assertTrue('x-object-uuid' in meta) |
1380 | 1380 |
uuid = meta['x-object-uuid'] |
1381 |
|
|
1381 |
|
|
1382 | 1382 |
#perform move |
1383 | 1383 |
meta = {'test':'testcopy'} |
1384 | 1384 |
src_path = '/'.join(('/', self.containers[0], self.obj['name'])) |
1385 | 1385 |
status = self.client.move_object(self.containers[0], self.obj['name'], |
1386 | 1386 |
self.containers[0], 'testcopy', |
1387 | 1387 |
meta)[0] |
1388 |
|
|
1388 |
|
|
1389 | 1389 |
#assert successful move |
1390 | 1390 |
self.assertEqual(status, 201) |
1391 |
|
|
1391 |
|
|
1392 | 1392 |
#assert updated metadata |
1393 | 1393 |
meta = self.client.retrieve_object_metadata(self.containers[0], |
1394 | 1394 |
'testcopy') |
1395 | 1395 |
self.assertTrue('x-object-meta-test' in meta.keys()) |
1396 | 1396 |
self.assertTrue(meta['x-object-meta-test'], 'testcopy') |
1397 |
|
|
1397 |
|
|
1398 | 1398 |
#assert same uuid |
1399 | 1399 |
self.assertTrue(meta['x-object-uuid'], uuid) |
1400 |
|
|
1400 |
|
|
1401 | 1401 |
#assert src object no more exists |
1402 | 1402 |
self.assert_object_not_exists(self.containers[0], self.obj['name']) |
1403 | 1403 |
|
... | ... | |
1410 | 1410 |
self.obj = [] |
1411 | 1411 |
for i in range(2): |
1412 | 1412 |
self.obj.append(self.upload_random_data(self.containers[0], o_names[i])) |
1413 |
|
|
1413 |
|
|
1414 | 1414 |
def test_update_meta(self): |
1415 | 1415 |
with AssertUUidInvariant(self.client.retrieve_object_metadata, |
1416 | 1416 |
self.containers[0], |
... | ... | |
1422 | 1422 |
**more)[0] |
1423 | 1423 |
#assert request accepted |
1424 | 1424 |
self.assertEqual(status, 202) |
1425 |
|
|
1425 |
|
|
1426 | 1426 |
#assert old metadata are still there |
1427 | 1427 |
headers = self.client.retrieve_object_metadata(self.containers[0], |
1428 | 1428 |
self.obj[0]['name'], |
... | ... | |
1431 | 1431 |
for k,v in more.items(): |
1432 | 1432 |
self.assertTrue(k in headers.keys()) |
1433 | 1433 |
self.assertTrue(headers[k], v) |
1434 |
|
|
1434 |
|
|
1435 | 1435 |
#out of limits |
1436 | 1436 |
more = {'f' * 114: 'b' * 257} |
Also available in: Unified diff