Revision 53b1eea6 api/tests.py
b/api/tests.py | ||
---|---|---|
2 | 2 |
# Copyright (c) 2010 Greek Research and Technology Network |
3 | 3 |
# |
4 | 4 |
|
5 |
from __future__ import with_statement |
|
6 |
|
|
7 |
from collections import defaultdict |
|
5 | 8 |
from email.utils import parsedate |
6 | 9 |
from random import choice, randint, sample |
7 | 10 |
from time import mktime |
... | ... | |
365 | 368 |
state='ACTIVE', |
366 | 369 |
owner=choice(users)) |
367 | 370 |
|
371 |
def create_image_metadata(n=1): |
|
372 |
images = Image.objects.all() |
|
373 |
for i in range(n): |
|
374 |
ImageMetadata.objects.create( |
|
375 |
meta_key='Key%d' % (i + 1), |
|
376 |
meta_value='Value %d' % (i + 1), |
|
377 |
image = choice(images)) |
|
378 |
|
|
368 | 379 |
def create_servers(n=1): |
369 | 380 |
users = SynnefoUser.objects.all() |
370 | 381 |
flavors = Flavor.objects.all() |
... | ... | |
388 | 399 |
vm = choice(servers)) |
389 | 400 |
|
390 | 401 |
|
402 |
class AssertInvariant(object): |
|
403 |
def __init__(self, callable, *args, **kwargs): |
|
404 |
self.callable = callable |
|
405 |
self.args = args |
|
406 |
self.kwargs = kwargs |
|
407 |
|
|
408 |
def __enter__(self): |
|
409 |
self.value = self.callable(*self.args, **self.kwargs) |
|
410 |
return self.value |
|
411 |
|
|
412 |
def __exit__(self, type, value, tb): |
|
413 |
assert self.value == self.callable(*self.args, **self.kwargs) |
|
414 |
|
|
415 |
|
|
391 | 416 |
class BaseTestCase(TestCase): |
392 | 417 |
USERS = 1 |
393 | 418 |
FLAVORS = 1 |
394 | 419 |
IMAGES = 1 |
395 | 420 |
SERVERS = 1 |
396 | 421 |
SERVER_METADATA = 0 |
422 |
IMAGE_METADATA = 0 |
|
397 | 423 |
|
398 | 424 |
def setUp(self): |
399 | 425 |
self.client = Client() |
400 | 426 |
create_users(self.USERS) |
401 | 427 |
create_flavors(self.FLAVORS) |
402 | 428 |
create_images(self.IMAGES) |
429 |
create_image_metadata(self.IMAGE_METADATA) |
|
403 | 430 |
create_servers(self.SERVERS) |
404 | 431 |
create_server_metadata(self.SERVER_METADATA) |
405 | 432 |
|
... | ... | |
414 | 441 |
def assertItemNotFound(self, response): |
415 | 442 |
self.assertFault(response, 404, 'itemNotFound') |
416 | 443 |
|
417 |
def get_server_metadata(self, server_id): |
|
418 |
vm_meta = VirtualMachineMetadata.objects.filter(vm=int(server_id)) |
|
419 |
return dict((m.meta_key, m.meta_value) for m in vm_meta) |
|
420 | 444 |
|
421 |
def verify_server_metadata(self, server_id, metadata): |
|
422 |
server_metadata = self.get_server_metadata(server_id) |
|
423 |
self.assertEqual(server_metadata, metadata) |
|
424 |
|
|
425 |
|
|
426 |
class ListServerMetadata(BaseTestCase): |
|
427 |
SERVERS = 4 |
|
428 |
|
|
429 |
def list_metadata(self, server_id): |
|
430 |
response = self.client.get('/api/v1.1/servers/%d/meta' % server_id) |
|
445 |
def list_metadata(self, path): |
|
446 |
response = self.client.get(path) |
|
431 | 447 |
self.assertTrue(response.status_code in (200, 203)) |
432 | 448 |
reply = json.loads(response.content) |
433 | 449 |
self.assertEqual(reply.keys(), ['metadata']) |
434 | 450 |
self.assertEqual(reply['metadata'].keys(), ['values']) |
435 | 451 |
return reply['metadata']['values'] |
436 | 452 |
|
437 |
def verify_all_metadata(self): |
|
438 |
for vm in VirtualMachine.objects.all(): |
|
439 |
server_metadata = self.get_server_metadata(vm.id) |
|
440 |
response_metadata = self.list_metadata(vm.id) |
|
441 |
self.assertEqual(response_metadata, server_metadata) |
|
453 |
def list_server_metadata(self, server_id): |
|
454 |
path = '/api/v1.1/servers/%d/meta' % server_id |
|
455 |
return self.list_metadata(path) |
|
442 | 456 |
|
443 |
def test_list_metadata(self): |
|
444 |
self.verify_all_metadata() |
|
445 |
create_server_metadata(100) |
|
446 |
self.verify_all_metadata() |
|
447 |
|
|
448 |
def test_invalid_server(self): |
|
449 |
response = self.client.get('/api/v1.1/servers/100/meta') |
|
450 |
self.assertItemNotFound(response) |
|
451 |
|
|
452 |
|
|
453 |
class UpdateServerMetadata(BaseTestCase): |
|
454 |
SERVER_METADATA = 10 |
|
457 |
def list_image_metadata(self, image_id): |
|
458 |
path = '/api/v1.1/images/%d/meta' % image_id |
|
459 |
return self.list_metadata(path) |
|
455 | 460 |
|
456 |
def update_meta(self, metadata): |
|
457 |
path = '/api/v1.1/servers/1/meta' |
|
461 |
def update_metadata(self, path, metadata): |
|
458 | 462 |
data = json.dumps({'metadata': metadata}) |
459 | 463 |
response = self.client.post(path, data, content_type='application/json') |
460 | 464 |
self.assertEqual(response.status_code, 201) |
... | ... | |
462 | 466 |
self.assertEqual(reply.keys(), ['metadata']) |
463 | 467 |
return reply['metadata'] |
464 | 468 |
|
469 |
def update_server_metadata(self, server_id, metadata): |
|
470 |
path = '/api/v1.1/servers/%d/meta' % server_id |
|
471 |
return self.update_metadata(path, metadata) |
|
472 |
|
|
473 |
def update_image_metadata(self, image_id, metadata): |
|
474 |
path = '/api/v1.1/images/%d/meta' % image_id |
|
475 |
return self.update_metadata(path, metadata) |
|
476 |
|
|
477 |
def create_server_meta(self, server_id, meta): |
|
478 |
key = meta.keys()[0] |
|
479 |
path = '/api/v1.1/servers/%d/meta/%s' % (server_id, key) |
|
480 |
data = json.dumps({'meta': meta}) |
|
481 |
response = self.client.put(path, data, content_type='application/json') |
|
482 |
self.assertEqual(response.status_code, 201) |
|
483 |
reply = json.loads(response.content) |
|
484 |
self.assertEqual(reply.keys(), ['meta']) |
|
485 |
response_meta = reply['meta'] |
|
486 |
self.assertEqual(response_meta, meta) |
|
487 |
|
|
488 |
def get_all_server_metadata(self): |
|
489 |
metadata = defaultdict(dict) |
|
490 |
for m in VirtualMachineMetadata.objects.all(): |
|
491 |
metadata[m.vm.id][m.meta_key] = m.meta_value |
|
492 |
return metadata |
|
493 |
|
|
494 |
def get_all_image_metadata(self): |
|
495 |
metadata = defaultdict(dict) |
|
496 |
for m in ImageMetadata.objects.all(): |
|
497 |
metadata[m.image.id][m.meta_key] = m.meta_value |
|
498 |
return metadata |
|
499 |
|
|
500 |
|
|
501 |
class ListServerMetadata(BaseTestCase): |
|
502 |
SERVERS = 5 |
|
503 |
SERVER_METADATA = 100 |
|
504 |
|
|
505 |
def test_list_metadata(self): |
|
506 |
with AssertInvariant(self.get_all_server_metadata) as metadata: |
|
507 |
for vm in VirtualMachine.objects.all(): |
|
508 |
response_metadata = self.list_server_metadata(vm.id) |
|
509 |
self.assertEqual(response_metadata, metadata[vm.id]) |
|
510 |
|
|
511 |
def test_invalid_server(self): |
|
512 |
with AssertInvariant(self.get_all_server_metadata): |
|
513 |
response = self.client.get('/api/v1.1/servers/0/meta') |
|
514 |
self.assertItemNotFound(response) |
|
515 |
|
|
516 |
|
|
517 |
class UpdateServerMetadata(BaseTestCase): |
|
518 |
SERVER_METADATA = 10 |
|
519 |
|
|
465 | 520 |
def test_update_metadata(self): |
466 |
metadata = self.get_server_metadata(1) |
|
521 |
metadata = self.get_all_server_metadata() |
|
522 |
server_id = choice(metadata.keys()) |
|
467 | 523 |
new_metadata = {} |
468 |
for key in sample(metadata.keys(), 3): |
|
524 |
for key in sample(metadata[server_id].keys(), 3):
|
|
469 | 525 |
new_metadata[key] = 'New %s value' % key |
470 |
response_metadata = self.update_meta(new_metadata)
|
|
526 |
response_metadata = self.update_server_metadata(server_id, new_metadata)
|
|
471 | 527 |
self.assertEqual(response_metadata, new_metadata) |
472 |
metadata.update(new_metadata) |
|
473 |
self.verify_server_metadata(1, metadata)
|
|
528 |
metadata[server_id].update(new_metadata)
|
|
529 |
self.assertEqual(metadata, self.get_all_server_metadata())
|
|
474 | 530 |
|
475 | 531 |
def test_does_not_create(self): |
476 |
metadata = self.get_server_metadata(1)
|
|
477 |
new_metadata = {'Foo': 'Bar'}
|
|
478 |
response_metadata = self.update_meta(new_metadata)
|
|
479 |
self.assertEqual(response_metadata, {})
|
|
480 |
self.verify_server_metadata(1, metadata)
|
|
532 |
with AssertInvariant(self.get_all_server_metadata) as metadata:
|
|
533 |
server_id = choice(metadata.keys())
|
|
534 |
new_metadata = {'Foo': 'Bar'}
|
|
535 |
response_metadata = self.update_server_metadata(server_id, new_metadata)
|
|
536 |
self.assertEqual(response_metadata, {})
|
|
481 | 537 |
|
482 | 538 |
def test_invalid_data(self): |
483 |
metadata = self.get_server_metadata(1)
|
|
484 |
path = '/api/v1.1/servers/1/meta'
|
|
485 |
response = self.client.post(path, 'metadata', content_type='application/json')
|
|
486 |
self.assertBadRequest(response)
|
|
487 |
self.verify_server_metadata(1, metadata)
|
|
539 |
with AssertInvariant(self.get_all_server_metadata) as metadata:
|
|
540 |
server_id = choice(metadata.keys())
|
|
541 |
path = '/api/v1.1/servers/%d/meta' % server_id
|
|
542 |
response = self.client.post(path, 'metadata', content_type='application/json')
|
|
543 |
self.assertBadRequest(response)
|
|
488 | 544 |
|
489 | 545 |
def test_invalid_server(self): |
490 |
metadata = self.get_server_metadata(1) |
|
491 |
path = '/api/v1.1/servers/2/meta' |
|
492 |
data = json.dumps({'metadata': {'Key1': 'A Value'}}) |
|
493 |
response = self.client.post(path, data, content_type='application/json') |
|
494 |
self.assertItemNotFound(response) |
|
495 |
self.verify_server_metadata(1, metadata) |
|
546 |
with AssertInvariant(self.get_all_server_metadata): |
|
547 |
path = '/api/v1.1/servers/0/meta' |
|
548 |
data = json.dumps({'metadata': {'Key1': 'A Value'}}) |
|
549 |
response = self.client.post(path, data, content_type='application/json') |
|
550 |
self.assertItemNotFound(response) |
|
496 | 551 |
|
497 | 552 |
|
498 | 553 |
class GetServerMetadataItem(BaseTestCase): |
499 |
SERVER_METADATA = 10 |
|
554 |
SERVERS = 5 |
|
555 |
SERVER_METADATA = 100 |
|
500 | 556 |
|
501 | 557 |
def test_get_metadata_item(self): |
502 |
metadata = self.get_server_metadata(1)
|
|
503 |
key = choice(metadata.keys())
|
|
504 |
path = '/api/v1.1/servers/1/meta/' + key
|
|
505 |
response = self.client.get(path)
|
|
506 |
self.assertTrue(response.status_code in (200, 203))
|
|
507 |
reply = json.loads(response.content)
|
|
508 |
self.assertEqual(reply['meta'], {key: metadata[key]})
|
|
509 |
self.verify_server_metadata(1, metadata)
|
|
558 |
with AssertInvariant(self.get_all_server_metadata) as metadata:
|
|
559 |
server_id = choice(metadata.keys())
|
|
560 |
key = choice(metadata[server_id].keys())
|
|
561 |
path = '/api/v1.1/servers/%d/meta/%s' % (server_id, key)
|
|
562 |
response = self.client.get(path)
|
|
563 |
self.assertTrue(response.status_code in (200, 203))
|
|
564 |
reply = json.loads(response.content)
|
|
565 |
self.assertEqual(reply['meta'], {key: metadata[server_id][key]})
|
|
510 | 566 |
|
511 | 567 |
def test_invalid_key(self): |
512 |
metadata = self.get_server_metadata(1)
|
|
513 |
response = self.client.get('/api/v1.1/servers/1/meta/foo')
|
|
514 |
self.assertItemNotFound(response)
|
|
515 |
self.verify_server_metadata(1, metadata)
|
|
568 |
with AssertInvariant(self.get_all_server_metadata) as metadata:
|
|
569 |
server_id = choice(metadata.keys())
|
|
570 |
response = self.client.get('/api/v1.1/servers/%d/meta/foo' % server_id)
|
|
571 |
self.assertItemNotFound(response)
|
|
516 | 572 |
|
517 | 573 |
def test_invalid_server(self): |
518 |
metadata = self.get_server_metadata(1) |
|
519 |
response = self.client.get('/api/v1.1/servers/2/meta/foo') |
|
520 |
self.assertItemNotFound(response) |
|
521 |
self.verify_server_metadata(1, metadata) |
|
574 |
with AssertInvariant(self.get_all_server_metadata): |
|
575 |
response = self.client.get('/api/v1.1/servers/0/meta/foo') |
|
576 |
self.assertItemNotFound(response) |
|
522 | 577 |
|
523 | 578 |
|
524 | 579 |
class CreateServerMetadataItem(BaseTestCase): |
525 | 580 |
SERVER_METADATA = 10 |
526 | 581 |
|
527 |
def create_meta(self, meta): |
|
528 |
key = meta.keys()[0] |
|
529 |
path = '/api/v1.1/servers/1/meta/' + key |
|
530 |
data = json.dumps({'meta': meta}) |
|
531 |
response = self.client.put(path, data, content_type='application/json') |
|
532 |
self.assertEqual(response.status_code, 201) |
|
533 |
reply = json.loads(response.content) |
|
534 |
self.assertEqual(reply.keys(), ['meta']) |
|
535 |
response_meta = reply['meta'] |
|
536 |
self.assertEqual(response_meta, meta) |
|
537 |
|
|
538 | 582 |
def test_create_metadata(self): |
539 |
metadata = self.get_server_metadata(1) |
|
583 |
metadata = self.get_all_server_metadata() |
|
584 |
server_id = choice(metadata.keys()) |
|
540 | 585 |
meta = {'Foo': 'Bar'} |
541 |
self.create_meta(meta)
|
|
542 |
metadata.update(meta) |
|
543 |
self.verify_server_metadata(1, metadata)
|
|
586 |
self.create_server_meta(server_id, meta)
|
|
587 |
metadata[server_id].update(meta)
|
|
588 |
self.assertEqual(metadata, self.get_all_server_metadata())
|
|
544 | 589 |
|
545 | 590 |
def test_update_metadata(self): |
546 |
metadata = self.get_server_metadata(1) |
|
547 |
key = choice(metadata.keys()) |
|
591 |
metadata = self.get_all_server_metadata() |
|
592 |
server_id = choice(metadata.keys()) |
|
593 |
key = choice(metadata[server_id].keys()) |
|
548 | 594 |
meta = {key: 'New Value'} |
549 |
self.create_meta(meta)
|
|
550 |
metadata.update(meta) |
|
551 |
self.verify_server_metadata(1, metadata)
|
|
595 |
self.create_server_meta(server_id, meta)
|
|
596 |
metadata[server_id].update(meta)
|
|
597 |
self.assertEqual(metadata, self.get_all_server_metadata())
|
|
552 | 598 |
|
553 | 599 |
def test_invalid_server(self): |
554 |
metadata = self.get_server_metadata(1) |
|
555 |
path = '/api/v1.1/servers/2/meta/foo' |
|
556 |
data = json.dumps({'meta': {'foo': 'bar'}}) |
|
557 |
response = self.client.put(path, data, content_type='application/json') |
|
558 |
self.assertItemNotFound(response) |
|
559 |
self.verify_server_metadata(1, metadata) |
|
600 |
with AssertInvariant(self.get_all_server_metadata): |
|
601 |
path = '/api/v1.1/servers/0/meta/foo' |
|
602 |
data = json.dumps({'meta': {'foo': 'bar'}}) |
|
603 |
response = self.client.put(path, data, content_type='application/json') |
|
604 |
self.assertItemNotFound(response) |
|
560 | 605 |
|
561 | 606 |
def test_invalid_key(self): |
562 |
metadata = self.get_server_metadata(1) |
|
563 |
path = '/api/v1.1/servers/1/meta/baz' |
|
564 |
data = json.dumps({'meta': {'foo': 'bar'}}) |
|
565 |
response = self.client.put(path, data, content_type='application/json') |
|
566 |
self.assertBadRequest(response) |
|
567 |
self.verify_server_metadata(1, metadata) |
|
607 |
with AssertInvariant(self.get_all_server_metadata): |
|
608 |
path = '/api/v1.1/servers/1/meta/baz' |
|
609 |
data = json.dumps({'meta': {'foo': 'bar'}}) |
|
610 |
response = self.client.put(path, data, content_type='application/json') |
|
611 |
self.assertBadRequest(response) |
|
568 | 612 |
|
569 | 613 |
def test_invalid_data(self): |
570 |
metadata = self.get_server_metadata(1) |
|
571 |
path = '/api/v1.1/servers/1/meta/foo' |
|
572 |
response = self.client.put(path, 'meta', content_type='application/json') |
|
573 |
self.assertBadRequest(response) |
|
574 |
self.verify_server_metadata(1, metadata) |
|
614 |
with AssertInvariant(self.get_all_server_metadata): |
|
615 |
path = '/api/v1.1/servers/1/meta/foo' |
|
616 |
response = self.client.put(path, 'meta', content_type='application/json') |
|
617 |
self.assertBadRequest(response) |
|
575 | 618 |
|
576 | 619 |
|
577 | 620 |
class DeleteServerMetadataItem(BaseTestCase): |
578 | 621 |
SERVER_METADATA = 10 |
579 | 622 |
|
580 | 623 |
def test_delete_metadata(self): |
581 |
metadata = self.get_server_metadata(1) |
|
582 |
key = choice(metadata.keys()) |
|
583 |
path = '/api/v1.1/servers/1/meta/' + key |
|
624 |
metadata = self.get_all_server_metadata() |
|
625 |
server_id = choice(metadata.keys()) |
|
626 |
key = choice(metadata[server_id].keys()) |
|
627 |
path = '/api/v1.1/servers/%d/meta/%s' % (server_id, key) |
|
584 | 628 |
response = self.client.delete(path) |
585 | 629 |
self.assertEqual(response.status_code, 204) |
586 |
metadata.pop(key) |
|
587 |
self.verify_server_metadata(1, metadata)
|
|
630 |
metadata[server_id].pop(key)
|
|
631 |
self.assertEqual(metadata, self.get_all_server_metadata())
|
|
588 | 632 |
|
589 | 633 |
def test_invalid_server(self): |
590 |
metadata = self.get_server_metadata(1) |
|
591 |
response = self.client.delete('/api/v1.1/servers/2/meta/Key1') |
|
592 |
self.assertItemNotFound(response) |
|
593 |
self.verify_server_metadata(1, metadata) |
|
634 |
with AssertInvariant(self.get_all_server_metadata): |
|
635 |
response = self.client.delete('/api/v1.1/servers/9/meta/Key1') |
|
636 |
self.assertItemNotFound(response) |
|
594 | 637 |
|
595 | 638 |
def test_invalid_key(self): |
596 |
metadata = self.get_server_metadata(1) |
|
597 |
response = self.client.delete('/api/v1.1/servers/1/meta/foo') |
|
598 |
self.assertItemNotFound(response) |
|
599 |
self.verify_server_metadata(1, metadata) |
|
639 |
with AssertInvariant(self.get_all_server_metadata) as metadata: |
|
640 |
server_id = choice(metadata.keys()) |
|
641 |
path = '/api/v1.1/servers/%d/meta/foo' % server_id |
|
642 |
response = self.client.delete(path) |
|
643 |
self.assertItemNotFound(response) |
|
644 |
|
|
645 |
|
|
646 |
class ListImageMetadata(BaseTestCase): |
|
647 |
IMAGES = 5 |
|
648 |
IMAGE_METADATA = 100 |
|
649 |
|
|
650 |
def test_list_metadata(self): |
|
651 |
with AssertInvariant(self.get_all_image_metadata) as metadata: |
|
652 |
for image in Image.objects.all(): |
|
653 |
response_metadata = self.list_image_metadata(image.id) |
|
654 |
self.assertEqual(response_metadata, metadata[image.id]) |
|
655 |
|
|
656 |
def test_invalid_image(self): |
|
657 |
with AssertInvariant(self.get_all_image_metadata): |
|
658 |
response = self.client.get('/api/v1.1/images/0/meta') |
|
659 |
self.assertItemNotFound(response) |
|
660 |
|
|
661 |
class UpdateImageMetadata(BaseTestCase): |
|
662 |
IMAGE_METADATA = 10 |
|
663 |
|
|
664 |
def test_update_metadata(self): |
|
665 |
metadata = self.get_all_image_metadata() |
|
666 |
image_id = choice(metadata.keys()) |
|
667 |
new_metadata = {} |
|
668 |
for key in sample(metadata[image_id].keys(), 3): |
|
669 |
new_metadata[key] = 'New %s value' % key |
|
670 |
response_metadata = self.update_image_metadata(image_id, new_metadata) |
|
671 |
self.assertEqual(response_metadata, new_metadata) |
|
672 |
metadata[image_id].update(new_metadata) |
|
673 |
self.assertEqual(metadata, self.get_all_image_metadata()) |
|
674 |
|
|
675 |
def test_does_not_create(self): |
|
676 |
with AssertInvariant(self.get_all_image_metadata) as metadata: |
|
677 |
image_id = choice(metadata.keys()) |
|
678 |
new_metadata = {'Foo': 'Bar'} |
|
679 |
response_metadata = self.update_image_metadata(image_id, new_metadata) |
|
680 |
self.assertEqual(response_metadata, {}) |
|
681 |
|
|
682 |
def test_invalid_data(self): |
|
683 |
with AssertInvariant(self.get_all_image_metadata) as metadata: |
|
684 |
image_id = choice(metadata.keys()) |
|
685 |
path = '/api/v1.1/images/%d/meta' % image_id |
|
686 |
response = self.client.post(path, 'metadata', content_type='application/json') |
|
687 |
self.assertBadRequest(response) |
|
688 |
|
|
689 |
def test_invalid_server(self): |
|
690 |
with AssertInvariant(self.get_all_image_metadata): |
|
691 |
path = '/api/v1.1/images/0/meta' |
|
692 |
data = json.dumps({'metadata': {'Key1': 'A Value'}}) |
|
693 |
response = self.client.post(path, data, content_type='application/json') |
|
694 |
self.assertItemNotFound(response) |
Also available in: Unified diff