Revision aa197ee4 api/tests.py

b/api/tests.py
40 40

  
41 41
    def test_api_version(self):
42 42
        """Check API version."""
43
        
43

  
44 44
        response = self.client.get('/api/v1.1/')
45 45
        self.assertEqual(response.status_code, 200)
46 46
        api_version = json.loads(response.content)['version']
......
49 49

  
50 50
    def test_server_list(self):
51 51
        """Test if the expected list of servers is returned."""
52
        
52

  
53 53
        response = self.client.get('/api/v1.1/servers')
54 54
        vms_from_api = json.loads(response.content)['servers']['values']
55 55
        vms_from_db = VirtualMachine.objects.filter(deleted=False)
......
62 62

  
63 63
    def test_server_details(self):
64 64
        """Test if the expected server is returned."""
65
        
65

  
66 66
        response = self.client.get('/api/v1.1/servers/%d' % self.test_server_id)
67 67
        vm_from_api = json.loads(response.content)['server']
68 68
        vm_from_db = VirtualMachine.objects.get(id=self.test_server_id)
......
76 76

  
77 77
    def test_servers_details(self):
78 78
        """Test if the servers details are returned."""
79
        
79

  
80 80
        response = self.client.get('/api/v1.1/servers/detail')
81 81

  
82 82
        # Make sure both DB and API responses are sorted by id,
......
110 110

  
111 111
    def test_wrong_server(self):
112 112
        """Test 404 response if server does not exist."""
113
        
113

  
114 114
        response = self.client.get('/api/v1.1/servers/%d' % self.test_wrong_server_id)
115 115
        self.assertEqual(response.status_code, 404)
116 116

  
117 117
    def test_create_server_empty(self):
118 118
        """Test if the create server call returns a 400 badRequest if
119 119
           no attributes are specified."""
120
        
120

  
121 121
        response = self.client.post('/api/v1.1/servers', {})
122 122
        self.assertEqual(response.status_code, 400)
123 123

  
124 124
    def test_create_server(self):
125 125
        """Test if the create server call returns the expected response
126 126
           if a valid request has been speficied."""
127
        
127

  
128 128
        request = {
129 129
                    "server": {
130 130
                        "name": "new-server-test",
......
145 145

  
146 146
    def test_server_polling(self):
147 147
        """Test if the server polling works as expected."""
148
        
148

  
149 149
        response = self.client.get('/api/v1.1/servers/detail')
150 150
        vms_from_api_initial = json.loads(response.content)['servers']['values']
151 151
        ts = mktime(parsedate(response['Date']))
......
165 165
                        "personality": []
166 166
                    }
167 167
        }
168
        
168

  
169 169
        path = '/api/v1.1/servers'
170 170
        response = self.client.post(path, json.dumps(request), content_type='application/json')
171 171
        self.assertEqual(response.status_code, 202)
......
178 178

  
179 179
    def test_reboot_server(self):
180 180
        """Test if the specified server is rebooted."""
181
        
182 181
        request = {'reboot': {'type': 'HARD'}}
183 182
        path = '/api/v1.1/servers/%d/action' % self.test_server_id
184 183
        response = self.client.post(path, json.dumps(request), content_type='application/json')
......
190 189

  
191 190
    def test_shutdown_server(self):
192 191
        """Test if the specified server is shutdown."""
193
        
192

  
194 193
        request = {'shutdown': {}}
195 194
        path = '/api/v1.1/servers/%d/action' % self.test_server_id
196 195
        response = self.client.post(path, json.dumps(request), content_type='application/json')
......
202 201

  
203 202
    def test_start_server(self):
204 203
        """Test if the specified server is started."""
205
        
204

  
206 205
        request = {'start': {}}
207 206
        path = '/api/v1.1/servers/%d/action' % self.test_server_id
208 207
        response = self.client.post(path, json.dumps(request), content_type='application/json')
......
222 221

  
223 222
    def test_flavor_list(self):
224 223
        """Test if the expected list of flavors is returned by."""
225
        
224

  
226 225
        response = self.client.get('/api/v1.1/flavors')
227 226
        flavors_from_api = json.loads(response.content)['flavors']['values']
228 227
        flavors_from_db = Flavor.objects.all()
......
235 234

  
236 235
    def test_flavors_details(self):
237 236
        """Test if the flavors details are returned."""
238
        
237

  
239 238
        response = self.client.get('/api/v1.1/flavors/detail')
240 239
        flavors_from_db = Flavor.objects.all()
241 240
        flavors_from_api = json.loads(response.content)['flavors']['values']
......
264 263

  
265 264
    def test_flavor_details(self):
266 265
        """Test if the expected flavor is returned."""
267
        
266

  
268 267
        response = self.client.get('/api/v1.1/flavors/%d' % self.test_flavor_id)
269 268
        flavor_from_api = json.loads(response.content)['flavor']
270 269
        flavor_from_db = Flavor.objects.get(id=self.test_flavor_id)
......
277 276

  
278 277
    def test_wrong_flavor(self):
279 278
        """Test 404 result when requesting a flavor that does not exist."""
280
        
279

  
281 280
        response = self.client.get('/api/v1.1/flavors/%d' % self.test_wrong_flavor_id)
282 281
        self.assertTrue(response.status_code in [404, 503])
283 282

  
284 283
    def test_image_list(self):
285 284
        """Test if the expected list of images is returned by the API."""
286
        
285

  
287 286
        response = self.client.get('/api/v1.1/images')
288 287
        images_from_api = json.loads(response.content)['images']['values']
289 288
        images_from_db = Image.objects.all()
......
296 295

  
297 296
    def test_wrong_image(self):
298 297
        """Test 404 result if a non existent image is requested."""
299
        
298

  
300 299
        response = self.client.get('/api/v1.1/images/%d' % self.test_wrong_image_id)
301 300
        self.assertEqual(response.status_code, 404)
302 301

  
303 302
    def test_server_metadata(self):
304 303
        """Test server's metadata (add, edit)."""
305
        
304

  
306 305
        key = 'name'
307 306
        request = {'meta': {key: 'a fancy name'}}
308
        
307

  
309 308
        path = '/api/v1.1/servers/%d/meta/%s' % (self.test_server_id, key)
310 309
        response = self.client.put(path, json.dumps(request), content_type='application/json')
311 310
        self.assertEqual(response.status_code, 201)
......
375 374
        self.callable = callable
376 375
        self.args = args
377 376
        self.kwargs = kwargs
378
    
377

  
379 378
    def __enter__(self):
380 379
        self.value = self.callable(*self.args, **self.kwargs)
381 380
        return self.value
382
    
381

  
383 382
    def __exit__(self, type, value, tb):
384 383
        assert self.value == self.callable(*self.args, **self.kwargs)
385 384

  
......
392 391
    SERVER_METADATA = 0
393 392
    IMAGE_METADATA = 0
394 393
    NETWORKS = 0
395
    
394

  
396 395
    def setUp(self):
397 396
        self.client = AaiClient()
398 397
        create_users(self.USERS)
......
402 401
        create_servers(self.SERVERS)
403 402
        create_server_metadata(self.SERVER_METADATA)
404 403
        create_networks(self.NETWORKS)
405
    
404

  
406 405
    def assertFault(self, response, status_code, name):
407 406
        self.assertEqual(response.status_code, status_code)
408 407
        fault = json.loads(response.content)
409 408
        self.assertEqual(fault.keys(), [name])
410
    
409

  
411 410
    def assertBadRequest(self, response):
412 411
        self.assertFault(response, 400, 'badRequest')
413 412

  
414 413
    def assertItemNotFound(self, response):
415 414
        self.assertFault(response, 404, 'itemNotFound')
416
    
417
    
415

  
416

  
418 417
    def list_images(self, detail=False):
419 418
        path = '/api/v1.1/images'
420 419
        if detail:
......
425 424
        self.assertEqual(reply.keys(), ['images'])
426 425
        self.assertEqual(reply['images'].keys(), ['values'])
427 426
        return reply['images']['values']
428
    
427

  
429 428
    def list_metadata(self, path):
430 429
        response = self.client.get(path)
431 430
        self.assertTrue(response.status_code in (200, 203))
......
433 432
        self.assertEqual(reply.keys(), ['metadata'])
434 433
        self.assertEqual(reply['metadata'].keys(), ['values'])
435 434
        return reply['metadata']['values']
436
    
435

  
437 436
    def list_server_metadata(self, server_id):
438 437
        path = '/api/v1.1/servers/%d/meta' % server_id
439 438
        return self.list_metadata(path)
440
    
439

  
441 440
    def list_image_metadata(self, image_id):
442 441
        path = '/api/v1.1/images/%d/meta' % image_id
443 442
        return self.list_metadata(path)
444
    
443

  
445 444
    def update_metadata(self, path, metadata):
446 445
        data = json.dumps({'metadata': metadata})
447 446
        response = self.client.post(path, data, content_type='application/json')
......
449 448
        reply = json.loads(response.content)
450 449
        self.assertEqual(reply.keys(), ['metadata'])
451 450
        return reply['metadata']
452
    
451

  
453 452
    def update_server_metadata(self, server_id, metadata):
454 453
        path = '/api/v1.1/servers/%d/meta' % server_id
455 454
        return self.update_metadata(path, metadata)
456
    
455

  
457 456
    def update_image_metadata(self, image_id, metadata):
458 457
        path = '/api/v1.1/images/%d/meta' % image_id
459 458
        return self.update_metadata(path, metadata)
460
    
459

  
461 460
    def create_server_meta(self, server_id, meta):
462 461
        key = meta.keys()[0]
463 462
        path = '/api/v1.1/servers/%d/meta/%s' % (server_id, key)
......
468 467
        self.assertEqual(reply.keys(), ['meta'])
469 468
        response_meta = reply['meta']
470 469
        self.assertEqual(response_meta, meta)
471
    
470

  
472 471
    def get_all_server_metadata(self):
473 472
        metadata = defaultdict(dict)
474 473
        for m in VirtualMachineMetadata.objects.all():
475 474
            metadata[m.vm.id][m.meta_key] = m.meta_value
476 475
        return metadata
477
    
476

  
478 477
    def get_all_image_metadata(self):
479 478
        metadata = defaultdict(dict)
480 479
        for m in ImageMetadata.objects.all():
481 480
            metadata[m.image.id][m.meta_key] = m.meta_value
482 481
        return metadata
483
    
482

  
484 483
    def list_networks(self, detail=False):
485 484
        path = '/api/v1.1/networks'
486 485
        if detail:
......
491 490
        self.assertEqual(reply.keys(), ['networks'])
492 491
        self.assertEqual(reply['networks'].keys(), ['values'])
493 492
        return reply['networks']['values']
494
    
493

  
495 494
    def create_network(self, name):
496 495
        path = '/api/v1.1/networks'
497 496
        data = json.dumps({'network': {'name': name}})
......
500 499
        reply = json.loads(response.content)
501 500
        self.assertEqual(reply.keys(), ['network'])
502 501
        return reply
503
    
502

  
504 503
    def get_network_details(self, network_id):
505 504
        path = '/api/v1.1/networks/%d' % network_id
506 505
        response = self.client.get(path)
......
508 507
        reply = json.loads(response.content)
509 508
        self.assertEqual(reply.keys(), ['network'])
510 509
        return reply['network']
511
    
510

  
512 511
    def update_network_name(self, network_id, new_name):
513 512
        path = '/api/v1.1/networks/%d' % network_id
514 513
        data = json.dumps({'network': {'name': new_name}})
515 514
        response = self.client.put(path, data, content_type='application/json')
516 515
        self.assertEqual(response.status_code, 204)
517
    
516

  
518 517
    def delete_network(self, network_id):
519 518
        path = '/api/v1.1/networks/%d' % network_id
520 519
        response = self.client.delete(path)
521 520
        self.assertEqual(response.status_code, 204)
522
    
521

  
523 522
    def add_to_network(self, network_id, server_id):
524 523
        path = '/api/v1.1/networks/%d/action' % network_id
525 524
        data = json.dumps({'add': {'serverRef': server_id}})
526 525
        response = self.client.post(path, data, content_type='application/json')
527 526
        self.assertEqual(response.status_code, 202)
528
    
527

  
529 528
    def remove_from_network(self, network_id, server_id):
530 529
        path = '/api/v1.1/networks/%d/action' % network_id
531 530
        data = json.dumps({'remove': {'serverRef': server_id}})
......
535 534

  
536 535
def popdict(l, **kwargs):
537 536
    """Pops a dict from list `l` based on the predicates given as `kwargs`."""
538
    
537

  
539 538
    for i in range(len(l)):
540 539
        item = l[i]
541 540
        match = True
......
551 550

  
552 551
class ListImages(BaseTestCase):
553 552
    IMAGES = 10
554
    
553

  
555 554
    def test_list_images(self):
556 555
        images = self.list_images()
557 556
        keys = set(['id', 'name'])
......
562 561
            self.assertEqual(image['id'], img.id)
563 562
            self.assertEqual(image['name'], img.name)
564 563
        self.assertEqual(images, [])
565
    
564

  
566 565
    def test_list_images_detail(self):
567 566
        images = self.list_images(detail=True)
568 567
        keys = set(['id', 'name', 'updated', 'created', 'status', 'progress'])
......
580 579
class ListServerMetadata(BaseTestCase):
581 580
    SERVERS = 5
582 581
    SERVER_METADATA = 100
583
    
582

  
584 583
    def test_list_metadata(self):
585 584
        with AssertInvariant(self.get_all_server_metadata) as metadata:
586 585
            for vm in VirtualMachine.objects.all():
587 586
                response_metadata = self.list_server_metadata(vm.id)
588 587
                self.assertEqual(response_metadata, metadata[vm.id])
589
    
588

  
590 589
    def test_invalid_server(self):
591 590
        with AssertInvariant(self.get_all_server_metadata):
592 591
            response = self.client.get('/api/v1.1/servers/0/meta')
......
595 594

  
596 595
class UpdateServerMetadata(BaseTestCase):
597 596
    SERVER_METADATA = 10
598
    
597

  
599 598
    def test_update_metadata(self):
600 599
        metadata = self.get_all_server_metadata()
601 600
        server_id = choice(metadata.keys())
......
606 605
        self.assertEqual(response_metadata, new_metadata)
607 606
        metadata[server_id].update(new_metadata)
608 607
        self.assertEqual(metadata, self.get_all_server_metadata())
609
    
608

  
610 609
    def test_does_not_create(self):
611 610
        with AssertInvariant(self.get_all_server_metadata) as metadata:
612 611
            server_id = choice(metadata.keys())
613 612
            new_metadata = {'Foo': 'Bar'}
614 613
            response_metadata = self.update_server_metadata(server_id, new_metadata)
615 614
            self.assertEqual(response_metadata, {})
616
    
615

  
617 616
    def test_invalid_data(self):
618 617
        with AssertInvariant(self.get_all_server_metadata) as metadata:
619 618
            server_id = choice(metadata.keys())
620 619
            path = '/api/v1.1/servers/%d/meta' % server_id
621 620
            response = self.client.post(path, 'metadata', content_type='application/json')
622 621
            self.assertBadRequest(response)
623
    
622

  
624 623
    def test_invalid_server(self):
625 624
        with AssertInvariant(self.get_all_server_metadata):
626 625
            path = '/api/v1.1/servers/0/meta'
......
632 631
class GetServerMetadataItem(BaseTestCase):
633 632
    SERVERS = 5
634 633
    SERVER_METADATA = 100
635
    
634

  
636 635
    def test_get_metadata_item(self):
637 636
        with AssertInvariant(self.get_all_server_metadata) as metadata:
638 637
            server_id = choice(metadata.keys())
......
642 641
            self.assertTrue(response.status_code in (200, 203))
643 642
            reply = json.loads(response.content)
644 643
            self.assertEqual(reply['meta'], {key: metadata[server_id][key]})
645
    
644

  
646 645
    def test_invalid_key(self):
647 646
        with AssertInvariant(self.get_all_server_metadata) as metadata:
648 647
            server_id = choice(metadata.keys())
649 648
            response = self.client.get('/api/v1.1/servers/%d/meta/foo' % server_id)
650 649
            self.assertItemNotFound(response)
651
    
650

  
652 651
    def test_invalid_server(self):
653 652
        with AssertInvariant(self.get_all_server_metadata):
654 653
            response = self.client.get('/api/v1.1/servers/0/meta/foo')
......
657 656

  
658 657
class CreateServerMetadataItem(BaseTestCase):
659 658
    SERVER_METADATA = 10
660
    
659

  
661 660
    def test_create_metadata(self):
662 661
        metadata = self.get_all_server_metadata()
663 662
        server_id = choice(metadata.keys())
......
665 664
        self.create_server_meta(server_id, meta)
666 665
        metadata[server_id].update(meta)
667 666
        self.assertEqual(metadata, self.get_all_server_metadata())
668
    
667

  
669 668
    def test_update_metadata(self):
670 669
        metadata = self.get_all_server_metadata()
671 670
        server_id = choice(metadata.keys())
......
674 673
        self.create_server_meta(server_id, meta)
675 674
        metadata[server_id].update(meta)
676 675
        self.assertEqual(metadata, self.get_all_server_metadata())
677
    
676

  
678 677
    def test_invalid_server(self):
679 678
        with AssertInvariant(self.get_all_server_metadata):
680 679
            path = '/api/v1.1/servers/0/meta/foo'
681 680
            data = json.dumps({'meta': {'foo': 'bar'}})
682 681
            response = self.client.put(path, data, content_type='application/json')
683 682
            self.assertItemNotFound(response)
684
    
683

  
685 684
    def test_invalid_key(self):
686 685
        with AssertInvariant(self.get_all_server_metadata) as metadata:
687 686
            server_id = choice(metadata.keys())
......
689 688
            data = json.dumps({'meta': {'foo': 'bar'}})
690 689
            response = self.client.put(path, data, content_type='application/json')
691 690
            self.assertBadRequest(response)
692
    
691

  
693 692
    def test_invalid_data(self):
694 693
        with AssertInvariant(self.get_all_server_metadata) as metadata:
695 694
            server_id = choice(metadata.keys())
......
700 699

  
701 700
class DeleteServerMetadataItem(BaseTestCase):
702 701
    SERVER_METADATA = 10
703
    
702

  
704 703
    def test_delete_metadata(self):
705 704
        metadata = self.get_all_server_metadata()
706 705
        server_id = choice(metadata.keys())
......
710 709
        self.assertEqual(response.status_code, 204)
711 710
        metadata[server_id].pop(key)
712 711
        self.assertEqual(metadata, self.get_all_server_metadata())
713
    
712

  
714 713
    def test_invalid_server(self):
715 714
        with AssertInvariant(self.get_all_server_metadata):
716 715
            response = self.client.delete('/api/v1.1/servers/9/meta/Key1')
717 716
            self.assertItemNotFound(response)
718
    
717

  
719 718
    def test_invalid_key(self):
720 719
        with AssertInvariant(self.get_all_server_metadata) as metadata:
721 720
            server_id = choice(metadata.keys())
......
855 854
class ListNetworks(BaseTestCase):
856 855
    SERVERS = 5
857 856
    NETWORKS = 5
858
    
857

  
859 858
    def setUp(self):
860 859
        BaseTestCase.setUp(self)
861 860
        machines = VirtualMachine.objects.all()
......
863 862
            n = randint(0, self.SERVERS)
864 863
            network.machines.add(*sample(machines, n))
865 864
            network.save()
866
    
865

  
867 866
    def test_list_networks(self):
868 867
        networks = self.list_networks()
869 868
        for net in Network.objects.all():
870 869
            network = popdict(networks, id=net.id)
871 870
            self.assertEqual(network['name'], net.name)
872 871
        self.assertEqual(networks, [])
873
    
872

  
874 873
    def test_list_networks_detail(self):
875 874
        networks = self.list_networks(detail=True)
876 875
        for net in Network.objects.all():
......
894 893
class GetNetworkDetails(BaseTestCase):
895 894
    SERVERS = 5
896 895
    NETWORKS = 1
897
    
896

  
898 897
    def test_get_network_details(self):
899 898
        servers = VirtualMachine.objects.all()
900 899
        network = Network.objects.all()[0]
901
        
900

  
902 901
        net = self.get_network_details(network.id)
903 902
        self.assertEqual(net['name'], network.name)
904 903
        self.assertEqual(net['servers']['values'], [])
905
        
904

  
906 905
        server_id = choice(servers).id
907 906
        self.add_to_network(network.id, server_id)
908 907
        net = self.get_network_details(network.id)
......
912 911

  
913 912
class UpdateNetworkName(BaseTestCase):
914 913
    NETWORKS = 5
915
    
914

  
916 915
    def test_update_network_name(self):
917 916
        networks = self.list_networks(detail=True)
918 917
        network = choice(networks)
919 918
        network_id = network['id']
920 919
        new_name = network['name'] + '_2'
921 920
        self.update_network_name(network_id, new_name)
922
        
921

  
923 922
        network['name'] = new_name
924 923
        self.assertEqual(self.get_network_details(network_id), network)
925 924

  
926 925

  
927 926
class DeleteNetwork(BaseTestCase):
928 927
    NETWORKS = 5
929
    
928

  
930 929
    def test_delete_network(self):
931 930
        networks = self.list_networks()
932 931
        network = choice(networks)
933 932
        network_id = network['id']
934 933
        self.delete_network(network_id)
935
        
934

  
936 935
        response = self.client.get('/api/v1.1/networks/%d' % network_id)
937 936
        self.assertItemNotFound(response)
938
        
937

  
939 938
        networks.remove(network)
940 939
        self.assertEqual(self.list_networks(), networks)
941 940

  
......
943 942
class NetworkActions(BaseTestCase):
944 943
    SERVERS = 20
945 944
    NETWORKS = 1
946
    
945

  
947 946
    def test_add_remove_server(self):
948 947
        server_ids = [vm.id for vm in VirtualMachine.objects.all()]
949 948
        network = self.list_networks(detail=True)[0]
950 949
        network_id = network['id']
951
        
950

  
952 951
        to_add = set(sample(server_ids, 10))
953 952
        for server_id in to_add:
954 953
            self.add_to_network(network_id, server_id)
955 954
            net = self.get_network_details(network_id)
956 955
            self.assertTrue(server_id in net['servers']['values'])
957
        
956

  
958 957
        net = self.get_network_details(network_id)
959 958
        self.assertEqual(set(net['servers']['values']), to_add)
960
        
959

  
961 960
        to_remove = set(sample(to_add, 5))
962 961
        for server_id in to_remove:
963 962
            self.remove_from_network(network_id, server_id)
964 963
            net = self.get_network_details(network_id)
965 964
            self.assertTrue(server_id not in net['servers']['values'])
966
        
965

  
967 966
        net = self.get_network_details(network_id)
968 967
        self.assertEqual(set(net['servers']['values']), to_add - to_remove)
969 968

  

Also available in: Unified diff