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