Revision 6ee6677e snf-pithos-app/pithos/api/test/__init__.py
b/snf-pithos-app/pithos/api/test/__init__.py | ||
---|---|---|
36 | 36 |
|
37 | 37 |
from urlparse import urlunsplit, urlsplit |
38 | 38 |
from xml.dom import minidom |
39 |
from urllib import quote, unquote |
|
39 | 40 |
|
40 | 41 |
from snf_django.utils.testing import with_settings, astakos_user |
41 | 42 |
|
... | ... | |
127 | 128 |
pithos_settings.BACKEND_DB_CONNECTION = db_connection |
128 | 129 |
|
129 | 130 |
|
131 |
def filter_headers(headers, prefix): |
|
132 |
meta = {} |
|
133 |
for k, v in headers.iteritems(): |
|
134 |
if not k.startswith(prefix): |
|
135 |
continue |
|
136 |
meta[unquote(k[len(prefix):])] = unquote(v) |
|
137 |
return meta |
|
138 |
|
|
139 |
|
|
130 | 140 |
class PithosTestSuiteRunner(DjangoTestSuiteRunner): |
131 | 141 |
def setup_databases(self, **kwargs): |
132 | 142 |
old_names, mirrors = super(PithosTestSuiteRunner, |
... | ... | |
161 | 171 |
self.delete_container_content(c['name']) |
162 | 172 |
self.delete_container(c['name']) |
163 | 173 |
|
164 |
def head(self, url, user='user', *args, **kwargs):
|
|
174 |
def head(self, url, user='user', data={}, follow=False, **extra):
|
|
165 | 175 |
with astakos_user(user): |
166 |
response = self.client.head(url, *args, **kwargs) |
|
176 |
extra = dict((quote(k), quote(v)) for k, v in extra.items()) |
|
177 |
response = self.client.head(url, data, follow, **extra) |
|
167 | 178 |
return response |
168 | 179 |
|
169 |
def get(self, url, user='user', *args, **kwargs):
|
|
180 |
def get(self, url, user='user', data={}, follow=False, **extra):
|
|
170 | 181 |
with astakos_user(user): |
171 |
response = self.client.get(url, *args, **kwargs) |
|
182 |
extra = dict((quote(k), quote(v)) for k, v in extra.items()) |
|
183 |
response = self.client.get(url, data, follow, **extra) |
|
172 | 184 |
return response |
173 | 185 |
|
174 |
def delete(self, url, user='user', *args, **kwargs):
|
|
186 |
def delete(self, url, user='user', data={}, follow=False, **extra):
|
|
175 | 187 |
with astakos_user(user): |
176 |
response = self.client.delete(url, *args, **kwargs) |
|
188 |
extra = dict((quote(k), quote(v)) for k, v in extra.items()) |
|
189 |
response = self.client.delete(url, data, follow, **extra) |
|
177 | 190 |
return response |
178 | 191 |
|
179 |
def post(self, url, user='user', *args, **kwargs): |
|
192 |
def post(self, url, user='user', data={}, |
|
193 |
content_type='application/octet-stream', follow=False, **extra): |
|
180 | 194 |
with astakos_user(user): |
181 |
kwargs.setdefault('content_type', 'application/octet-stream') |
|
182 |
response = self.client.post(url, *args, **kwargs) |
|
195 |
extra = dict((quote(k), quote(v)) for k, v in extra.items()) |
|
196 |
response = self.client.post(url, data, content_type, follow, |
|
197 |
**extra) |
|
183 | 198 |
return response |
184 | 199 |
|
185 |
def put(self, url, user='user', *args, **kwargs): |
|
200 |
def put(self, url, user='user', data={}, |
|
201 |
content_type='application/octet-stream', follow=False, **extra): |
|
186 | 202 |
with astakos_user(user): |
187 |
kwargs.setdefault('content_type', 'application/octet-stream') |
|
188 |
response = self.client.put(url, *args, **kwargs) |
|
203 |
extra = dict((quote(k), quote(v)) for k, v in extra.items()) |
|
204 |
response = self.client.put(url, data, content_type, follow, |
|
205 |
**extra) |
|
189 | 206 |
return response |
190 | 207 |
|
191 |
def update_account_meta(self, meta): |
|
192 |
kwargs = dict( |
|
193 |
('HTTP_X_ACCOUNT_META_%s' % k, str(v)) for k, v in meta.items()) |
|
194 |
url = join_urls(self.pithos_path, self.user) |
|
195 |
r = self.post('%s?update=' % url, **kwargs) |
|
196 |
self.assertEqual(r.status_code, 202) |
|
197 |
account_meta = self.get_account_meta() |
|
198 |
(self.assertTrue('X-Account-Meta-%s' % k in account_meta) for |
|
199 |
k in meta.keys()) |
|
200 |
(self.assertEqual(account_meta['X-Account-Meta-%s' % k], v) for |
|
201 |
k, v in meta.items()) |
|
202 |
|
|
203 |
def reset_account_meta(self, meta): |
|
208 |
def update_account_meta(self, meta, user=None): |
|
209 |
user = user or self.user |
|
204 | 210 |
kwargs = dict( |
205 | 211 |
('HTTP_X_ACCOUNT_META_%s' % k, str(v)) for k, v in meta.items()) |
206 |
url = join_urls(self.pithos_path, self.user)
|
|
207 |
r = self.post(url, **kwargs)
|
|
212 |
url = join_urls(self.pithos_path, user) |
|
213 |
r = self.post('%s?update=' % url, user=user, **kwargs)
|
|
208 | 214 |
self.assertEqual(r.status_code, 202) |
209 | 215 |
account_meta = self.get_account_meta() |
210 |
(self.assertTrue('X-Account-Meta-%s' % k in account_meta) for |
|
211 |
k in meta.keys()) |
|
212 |
(self.assertEqual(account_meta['X-Account-Meta-%s' % k], v) for |
|
213 |
k, v in meta.items()) |
|
216 |
(self.assertTrue(k in account_meta) for k in meta.keys()) |
|
217 |
(self.assertEqual(account_meta[k], v) for k, v in meta.items()) |
|
214 | 218 |
|
215 |
def delete_account_meta(self, meta): |
|
216 |
transform = lambda k: 'HTTP_%s' % k.replace('-', '_').upper() |
|
219 |
def delete_account_meta(self, meta, user=None): |
|
220 |
user = user or self.user |
|
221 |
transform = lambda k: 'HTTP_X_ACCOUNT_META_%s' % k.replace('-', '_').upper() |
|
217 | 222 |
kwargs = dict((transform(k), '') for k, v in meta.items()) |
218 |
url = join_urls(self.pithos_path, self.user)
|
|
219 |
r = self.post('%s?update=' % url, **kwargs) |
|
223 |
url = join_urls(self.pithos_path, user) |
|
224 |
r = self.post('%s?update=' % url, user=user, **kwargs)
|
|
220 | 225 |
self.assertEqual(r.status_code, 202) |
221 | 226 |
account_meta = self.get_account_meta() |
222 |
(self.assertTrue('X-Account-Meta-%s' % k not in account_meta) for |
|
223 |
k in meta.keys()) |
|
227 |
(self.assertTrue(k not in account_meta) for k in meta.keys()) |
|
224 | 228 |
return r |
225 | 229 |
|
226 |
def delete_account_groups(self, groups): |
|
227 |
url = join_urls(self.pithos_path, self.user) |
|
228 |
r = self.post('%s?update=' % url, **groups) |
|
230 |
def delete_account_groups(self, groups, user=None): |
|
231 |
user = user or self.user |
|
232 |
url = join_urls(self.pithos_path, user) |
|
233 |
transform = lambda k: 'HTTP_X_ACCOUNT_GROUP_%s' % k.replace('-', '_').upper() |
|
234 |
kwargs = dict((transform(k), '') for k, v in groups.items()) |
|
235 |
r = self.post('%s?update=' % url, user=user, **kwargs) |
|
229 | 236 |
self.assertEqual(r.status_code, 202) |
237 |
account_groups = self.get_account_groups() |
|
238 |
(self.assertTrue(k not in account_groups) for k in groups.keys()) |
|
230 | 239 |
return r |
231 | 240 |
|
232 |
def get_account_info(self, until=None): |
|
233 |
url = join_urls(self.pithos_path, self.user) |
|
241 |
def get_account_info(self, until=None, user=None): |
|
242 |
user = user or self.user |
|
243 |
url = join_urls(self.pithos_path, user) |
|
234 | 244 |
if until is not None: |
235 | 245 |
parts = list(urlsplit(url)) |
236 | 246 |
parts[3] = urlencode({ |
237 | 247 |
'until': until |
238 | 248 |
}) |
239 | 249 |
url = urlunsplit(parts) |
240 |
r = self.head(url) |
|
250 |
r = self.head(url, user=user)
|
|
241 | 251 |
self.assertEqual(r.status_code, 204) |
242 | 252 |
return r |
243 | 253 |
|
244 |
def get_account_meta(self, until=None): |
|
245 |
r = self.get_account_info(until=until) |
|
254 |
def get_account_meta(self, until=None, user=None): |
|
255 |
prefix = 'X-Account-Meta-' |
|
256 |
r = self.get_account_info(until=until, user=user) |
|
246 | 257 |
headers = dict(r._headers.values()) |
247 |
map(headers.pop, |
|
248 |
[k for k in headers.keys() |
|
249 |
if not k.startswith('X-Account-Meta-')]) |
|
250 |
return headers |
|
258 |
return filter_headers(headers, prefix) |
|
251 | 259 |
|
252 |
def get_account_groups(self, until=None): |
|
253 |
r = self.get_account_info(until=until) |
|
260 |
def get_account_groups(self, until=None, user=None): |
|
261 |
prefix = 'X-Account-Group-' |
|
262 |
r = self.get_account_info(until=until, user=user) |
|
254 | 263 |
headers = dict(r._headers.values()) |
255 |
map(headers.pop, |
|
256 |
[k for k in headers.keys() |
|
257 |
if not k.startswith('X-Account-Group-')]) |
|
258 |
return headers |
|
264 |
return filter_headers(headers, prefix) |
|
259 | 265 |
|
260 |
def get_container_info(self, container, until=None): |
|
261 |
url = join_urls(self.pithos_path, self.user, container) |
|
266 |
def get_container_info(self, container, until=None, user=None): |
|
267 |
user = user or self.user |
|
268 |
url = join_urls(self.pithos_path, user, container) |
|
262 | 269 |
if until is not None: |
263 | 270 |
parts = list(urlsplit(url)) |
264 | 271 |
parts[3] = urlencode({ |
265 | 272 |
'until': until |
266 | 273 |
}) |
267 | 274 |
url = urlunsplit(parts) |
268 |
r = self.head(url) |
|
275 |
r = self.head(url, user=user)
|
|
269 | 276 |
self.assertEqual(r.status_code, 204) |
270 | 277 |
return r |
271 | 278 |
|
272 |
def get_container_meta(self, container, until=None): |
|
273 |
r = self.get_container_info(container, until=until) |
|
279 |
def get_container_meta(self, container, until=None, user=None): |
|
280 |
prefix = 'X-Container-Meta-' |
|
281 |
r = self.get_container_info(container, until=until, user=user) |
|
274 | 282 |
headers = dict(r._headers.values()) |
275 |
map(headers.pop, |
|
276 |
[k for k in headers.keys() |
|
277 |
if not k.startswith('X-Container-Meta-')]) |
|
278 |
return headers |
|
283 |
return filter_headers(headers, prefix) |
|
279 | 284 |
|
280 |
def update_container_meta(self, container, meta): |
|
285 |
def update_container_meta(self, container, meta, user=None): |
|
286 |
user = user or self.user |
|
281 | 287 |
kwargs = dict( |
282 | 288 |
('HTTP_X_CONTAINER_META_%s' % k, str(v)) for k, v in meta.items()) |
283 |
url = join_urls(self.pithos_path, self.user, container)
|
|
284 |
r = self.post('%s?update=' % url, **kwargs) |
|
289 |
url = join_urls(self.pithos_path, user, container) |
|
290 |
r = self.post('%s?update=' % url, user=user, **kwargs)
|
|
285 | 291 |
self.assertEqual(r.status_code, 202) |
286 | 292 |
container_meta = self.get_container_meta(container) |
287 | 293 |
(self.assertTrue('X-Container-Meta-%s' % k in container_meta) for |
... | ... | |
289 | 295 |
(self.assertEqual(container_meta['X-Container-Meta-%s' % k], v) for |
290 | 296 |
k, v in meta.items()) |
291 | 297 |
|
292 |
def list_containers(self, format='json', headers={}, **params): |
|
293 |
_url = join_urls(self.pithos_path, self.user) |
|
298 |
def list_containers(self, format='json', headers={}, user=None, **params): |
|
299 |
user = user or self.user |
|
300 |
_url = join_urls(self.pithos_path, user) |
|
294 | 301 |
parts = list(urlsplit(_url)) |
295 | 302 |
params['format'] = format |
296 | 303 |
parts[3] = urlencode(params) |
297 | 304 |
url = urlunsplit(parts) |
298 | 305 |
_headers = dict(('HTTP_%s' % k.upper(), str(v)) |
299 | 306 |
for k, v in headers.items()) |
300 |
r = self.get(url, **_headers) |
|
307 |
r = self.get(url, user=user, **_headers)
|
|
301 | 308 |
|
302 | 309 |
if format is None: |
303 | 310 |
containers = r.content.split('\n') |
... | ... | |
313 | 320 |
elif format == 'xml': |
314 | 321 |
return minidom.parseString(r.content) |
315 | 322 |
|
316 |
def delete_container_content(self, cname): |
|
317 |
url = join_urls(self.pithos_path, self.user, cname) |
|
318 |
r = self.delete('%s?delimiter=/' % url) |
|
323 |
def delete_container_content(self, cname, user=None): |
|
324 |
user = user or self.user |
|
325 |
url = join_urls(self.pithos_path, user, cname) |
|
326 |
r = self.delete('%s?delimiter=/' % url, user=user) |
|
319 | 327 |
self.assertEqual(r.status_code, 204) |
320 | 328 |
return r |
321 | 329 |
|
322 |
def delete_container(self, cname): |
|
323 |
url = join_urls(self.pithos_path, self.user, cname) |
|
324 |
r = self.delete(url) |
|
330 |
def delete_container(self, cname, user=None): |
|
331 |
user = user or self.user |
|
332 |
url = join_urls(self.pithos_path, user, cname) |
|
333 |
r = self.delete(url, user=user) |
|
325 | 334 |
self.assertEqual(r.status_code, 204) |
326 | 335 |
return r |
327 | 336 |
|
328 |
def create_container(self, cname=None): |
|
337 |
def create_container(self, cname=None, user=None):
|
|
329 | 338 |
cname = cname or get_random_name() |
330 |
url = join_urls(self.pithos_path, self.user, cname) |
|
331 |
r = self.put(url, data='') |
|
339 |
user = user or self.user |
|
340 |
url = join_urls(self.pithos_path, user, cname) |
|
341 |
r = self.put(url, user=user, data='') |
|
332 | 342 |
self.assertTrue(r.status_code in (202, 201)) |
333 | 343 |
return cname, r |
334 | 344 |
|
335 | 345 |
def upload_object(self, cname, oname=None, length=None, verify=True, |
336 |
**meta): |
|
346 |
user=None, **meta):
|
|
337 | 347 |
oname = oname or get_random_name() |
338 | 348 |
length = length or random.randint(TEST_BLOCK_SIZE, 2 * TEST_BLOCK_SIZE) |
349 |
user = user or self.user |
|
339 | 350 |
data = get_random_data(length=length) |
340 | 351 |
headers = dict(('HTTP_X_OBJECT_META_%s' % k.upper(), v) |
341 | 352 |
for k, v in meta.iteritems()) |
342 |
url = join_urls(self.pithos_path, self.user, cname, oname)
|
|
343 |
r = self.put(url, data=data, **headers) |
|
353 |
url = join_urls(self.pithos_path, user, cname, oname) |
|
354 |
r = self.put(url, user=user, data=data, **headers)
|
|
344 | 355 |
if verify: |
345 | 356 |
self.assertEqual(r.status_code, 201) |
346 | 357 |
return oname, data, r |
347 | 358 |
|
348 | 359 |
def update_object_data(self, cname, oname=None, length=None, |
349 | 360 |
content_type=None, content_range=None, |
350 |
verify=True, **meta): |
|
361 |
verify=True, user=None, **meta):
|
|
351 | 362 |
oname = oname or get_random_name() |
352 | 363 |
length = length or random.randint(TEST_BLOCK_SIZE, 2 * TEST_BLOCK_SIZE) |
353 | 364 |
content_type = content_type or 'application/octet-stream' |
365 |
user = user or self.user |
|
354 | 366 |
data = get_random_data(length=length) |
355 | 367 |
headers = dict(('HTTP_X_OBJECT_META_%s' % k.upper(), v) |
356 | 368 |
for k, v in meta.iteritems()) |
357 | 369 |
if content_range: |
358 | 370 |
headers['HTTP_CONTENT_RANGE'] = content_range |
359 |
url = join_urls(self.pithos_path, self.user, cname, oname) |
|
360 |
r = self.post(url, data=data, content_type=content_type, **headers) |
|
371 |
url = join_urls(self.pithos_path, user, cname, oname) |
|
372 |
r = self.post(url, user=user, data=data, content_type=content_type, |
|
373 |
**headers) |
|
361 | 374 |
if verify: |
362 | 375 |
self.assertEqual(r.status_code, 204) |
363 | 376 |
return oname, data, r |
364 | 377 |
|
365 | 378 |
def append_object_data(self, cname, oname=None, length=None, |
366 |
content_type=None): |
|
379 |
content_type=None, user=None):
|
|
367 | 380 |
return self.update_object_data(cname, oname=oname, |
368 | 381 |
length=length, |
369 | 382 |
content_type=content_type, |
370 |
content_range='bytes */*') |
|
383 |
content_range='bytes */*', |
|
384 |
user=user) |
|
371 | 385 |
|
372 |
def create_folder(self, cname, oname=None, **headers): |
|
386 |
def create_folder(self, cname, oname=None, user=None, **headers): |
|
387 |
user = user or self.user |
|
373 | 388 |
oname = oname or get_random_name() |
374 |
url = join_urls(self.pithos_path, self.user, cname, oname)
|
|
375 |
r = self.put(url, data='', content_type='application/directory',
|
|
376 |
**headers) |
|
389 |
url = join_urls(self.pithos_path, user, cname, oname) |
|
390 |
r = self.put(url, user=user, data='',
|
|
391 |
content_type='application/directory', **headers)
|
|
377 | 392 |
self.assertEqual(r.status_code, 201) |
378 | 393 |
return oname, r |
379 | 394 |
|
380 |
def list_objects(self, cname, prefix=None): |
|
381 |
url = join_urls(self.pithos_path, self.user, cname) |
|
395 |
def list_objects(self, cname, prefix=None, user=None): |
|
396 |
user = user or self.user |
|
397 |
url = join_urls(self.pithos_path, user, cname) |
|
382 | 398 |
path = '%s?format=json' % url |
383 | 399 |
if prefix is not None: |
384 | 400 |
path = '%s&prefix=%s' % (path, prefix) |
385 |
r = self.get(path) |
|
401 |
r = self.get(path, user=user)
|
|
386 | 402 |
self.assertTrue(r.status_code in (200, 204)) |
387 | 403 |
try: |
388 | 404 |
objects = json.loads(r.content) |
... | ... | |
390 | 406 |
self.fail('json format expected') |
391 | 407 |
return objects |
392 | 408 |
|
393 |
def get_object_info(self, container, object, version=None, until=None): |
|
394 |
url = join_urls(self.pithos_path, self.user, container, object) |
|
409 |
def get_object_info(self, container, object, version=None, until=None, |
|
410 |
user=None): |
|
411 |
user = user or self.user |
|
412 |
url = join_urls(self.pithos_path, user, container, object) |
|
395 | 413 |
if until is not None: |
396 | 414 |
parts = list(urlsplit(url)) |
397 | 415 |
parts[3] = urlencode({ |
... | ... | |
400 | 418 |
url = urlunsplit(parts) |
401 | 419 |
if version: |
402 | 420 |
url = '%s?version=%s' % (url, version) |
403 |
r = self.head(url) |
|
421 |
r = self.head(url, user=user)
|
|
404 | 422 |
self.assertEqual(r.status_code, 200) |
405 | 423 |
return r |
406 | 424 |
|
407 |
def get_object_meta(self, container, object, version=None, until=None): |
|
408 |
r = self.get_object_info(container, object, version, until=until) |
|
425 |
def get_object_meta(self, container, object, version=None, until=None, |
|
426 |
user=None): |
|
427 |
prefix = 'X-Object-Meta-' |
|
428 |
r = self.get_object_info(container, object, version, until=until, |
|
429 |
user=user) |
|
409 | 430 |
headers = dict(r._headers.values()) |
410 |
map(headers.pop, |
|
411 |
[k for k in headers.keys() |
|
412 |
if not k.startswith('X-Object-Meta-')]) |
|
413 |
return headers |
|
431 |
return filter_headers(headers, prefix) |
|
414 | 432 |
|
415 |
def update_object_meta(self, container, object, meta): |
|
433 |
def update_object_meta(self, container, object, meta, user=None): |
|
434 |
user = user or self.user |
|
416 | 435 |
kwargs = dict( |
417 | 436 |
('HTTP_X_OBJECT_META_%s' % k, str(v)) for k, v in meta.items()) |
418 |
url = join_urls(self.pithos_path, self.user, container, object)
|
|
419 |
r = self.post('%s?update=' % url, content_type='', **kwargs) |
|
437 |
url = join_urls(self.pithos_path, user, container, object) |
|
438 |
r = self.post('%s?update=' % url, user=user, content_type='', **kwargs)
|
|
420 | 439 |
self.assertEqual(r.status_code, 202) |
421 | 440 |
object_meta = self.get_object_meta(container, object) |
422 | 441 |
(self.assertTrue('X-Objecr-Meta-%s' % k in object_meta) for |
Also available in: Unified diff