~nttdata/nova/volume-cleanup-2

« back to all changes in this revision

Viewing changes to nova/tests/api/openstack/test_servers.py

  • Committer: Kei Masumoto
  • Date: 2011-09-17 16:21:58 UTC
  • mfrom: (1130.13.31 milestone-proposed)
  • Revision ID: masumotok@nttdata.co.jp-20110917162158-5w8zom7nrajkgii1
merged source from lp:~hudson-openstack/nova/milestone-proposed

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
2
 
3
3
# Copyright 2010-2011 OpenStack LLC.
 
4
# Copyright 2011 Piston Cloud Computing, Inc.
4
5
# All Rights Reserved.
5
6
#
6
7
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
19
20
import datetime
20
21
import json
21
22
import unittest
 
23
from lxml import etree
22
24
from xml.dom import minidom
23
25
 
24
26
import webob
32
34
from nova.api.openstack import create_instance_helper
33
35
from nova.api.openstack import servers
34
36
from nova.api.openstack import wsgi
 
37
from nova.api.openstack import xmlutil
35
38
import nova.compute.api
36
39
from nova.compute import instance_types
37
 
from nova.compute import power_state
 
40
from nova.compute import task_states
 
41
from nova.compute import vm_states
38
42
import nova.db.api
39
43
import nova.scheduler.api
40
44
from nova.db.sqlalchemy.models import Instance
46
50
 
47
51
 
48
52
FAKE_UUID = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
 
53
NS = "{http://docs.openstack.org/compute/api/v1.1}"
 
54
ATOMNS = "{http://www.w3.org/2005/Atom}"
49
55
 
50
56
 
51
57
def fake_gen_uuid():
86
92
    return _return_server
87
93
 
88
94
 
89
 
def return_server_with_power_state(power_state):
 
95
def return_server_with_state(vm_state, task_state=None):
90
96
    def _return_server(context, id):
91
 
        return stub_instance(id, power_state=power_state)
 
97
        return stub_instance(id, vm_state=vm_state, task_state=task_state)
92
98
    return _return_server
93
99
 
94
100
 
95
 
def return_server_with_uuid_and_power_state(power_state):
 
101
def return_server_with_uuid_and_state(vm_state, task_state):
96
102
    def _return_server(context, id):
97
 
        return stub_instance(id, uuid=FAKE_UUID, power_state=power_state)
 
103
        return stub_instance(id,
 
104
                             uuid=FAKE_UUID,
 
105
                             vm_state=vm_state,
 
106
                             task_state=task_state)
98
107
    return _return_server
99
108
 
100
109
 
143
152
 
144
153
 
145
154
def stub_instance(id, user_id='fake', project_id='fake', private_address=None,
146
 
                  public_addresses=None, host=None, power_state=0,
 
155
                  public_addresses=None, host=None,
 
156
                  vm_state=None, task_state=None,
147
157
                  reservation_id="", uuid=FAKE_UUID, image_ref="10",
148
 
                  flavor_id="1", interfaces=None, name=None):
 
158
                  flavor_id="1", interfaces=None, name=None, key_name='',
 
159
                  access_ipv4=None, access_ipv6=None):
149
160
    metadata = []
150
161
    metadata.append(InstanceMetadata(key='seq', value=id))
151
162
 
160
171
    if host is not None:
161
172
        host = str(host)
162
173
 
 
174
    if key_name:
 
175
        key_data = 'FAKE'
 
176
    else:
 
177
        key_data = ''
 
178
 
163
179
    # ReservationID isn't sent back, hack it in there.
164
180
    server_name = name or "server%s" % id
165
181
    if reservation_id != "":
176
192
        "kernel_id": "",
177
193
        "ramdisk_id": "",
178
194
        "launch_index": 0,
179
 
        "key_name": "",
180
 
        "key_data": "",
181
 
        "state": power_state,
182
 
        "state_description": "",
 
195
        "key_name": key_name,
 
196
        "key_data": key_data,
 
197
        "vm_state": vm_state or vm_states.BUILDING,
 
198
        "task_state": task_state,
183
199
        "memory_mb": 0,
184
200
        "vcpus": 0,
185
201
        "local_gb": 0,
197
213
        "display_description": "",
198
214
        "locked": False,
199
215
        "metadata": metadata,
 
216
        "access_ip_v4": access_ipv4,
 
217
        "access_ip_v6": access_ipv6,
200
218
        "uuid": uuid,
201
219
        "virtual_interfaces": interfaces}
202
220
 
226
244
 
227
245
 
228
246
class ServersTest(test.TestCase):
229
 
 
230
247
    def setUp(self):
231
248
        self.maxDiff = None
232
249
        super(ServersTest, self).setUp()
258
275
        self.stubs.Set(nova.compute.API, "get_actions", fake_compute_api)
259
276
 
260
277
        self.webreq = common.webob_factory('/v1.0/servers')
 
278
        self.config_drive = None
261
279
 
262
280
    def test_get_server_by_id(self):
263
281
        req = webob.Request.blank('/v1.0/servers/1')
297
315
        self.assertEqual(res_dict['server']['name'], 'server1')
298
316
 
299
317
    def test_get_server_by_id_v1_1(self):
300
 
        image_bookmark = "http://localhost/images/10"
301
 
        flavor_ref = "http://localhost/v1.1/flavors/1"
 
318
        image_bookmark = "http://localhost/fake/images/10"
 
319
        flavor_ref = "http://localhost/v1.1/fake/flavors/1"
302
320
        flavor_id = "1"
303
 
        flavor_bookmark = "http://localhost/flavors/1"
 
321
        flavor_bookmark = "http://localhost/fake/flavors/1"
304
322
 
305
323
        public_ip = '192.168.0.3'
306
324
        private_ip = '172.19.0.1'
322
340
            interfaces=interfaces)
323
341
        self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
324
342
 
325
 
        req = webob.Request.blank('/v1.1/servers/1')
 
343
        req = webob.Request.blank('/v1.1/fake/servers/1')
326
344
        res = req.get_response(fakes.wsgi_app())
327
345
        res_dict = json.loads(res.body)
328
346
        expected_server = {
329
347
            "server": {
330
348
                "id": 1,
331
349
                "uuid": FAKE_UUID,
 
350
                "user_id": "fake",
 
351
                "tenant_id": "fake",
332
352
                "updated": "2010-11-11T11:00:00Z",
333
353
                "created": "2010-10-10T12:00:00Z",
334
354
                "progress": 0,
335
355
                "name": "server1",
336
356
                "status": "BUILD",
 
357
                "accessIPv4": "",
 
358
                "accessIPv6": "",
337
359
                "hostId": '',
 
360
                "key_name": '',
338
361
                "image": {
339
362
                    "id": "10",
340
363
                    "links": [
370
393
                "metadata": {
371
394
                    "seq": "1",
372
395
                },
 
396
                "config_drive": None,
373
397
                "links": [
374
398
                    {
375
399
                        "rel": "self",
376
400
                        #FIXME(wwolf) Do we want the links to be id or uuid?
377
 
                        "href": "http://localhost/v1.1/servers/1",
 
401
                        "href": "http://localhost/v1.1/fake/servers/1",
378
402
                    },
379
403
                    {
380
404
                        "rel": "bookmark",
381
 
                        "href": "http://localhost/servers/1",
 
405
                        "href": "http://localhost/fake/servers/1",
382
406
                    },
383
407
                ],
384
408
            }
387
411
        self.assertDictMatch(res_dict, expected_server)
388
412
 
389
413
    def test_get_server_by_id_v1_1_xml(self):
390
 
        image_bookmark = "http://localhost/images/10"
391
 
        flavor_ref = "http://localhost/v1.1/flavors/1"
 
414
        image_bookmark = "http://localhost/fake/images/10"
 
415
        flavor_ref = "http://localhost/v1.1/fake/flavors/1"
392
416
        flavor_id = "1"
393
 
        flavor_bookmark = "http://localhost/flavors/1"
394
 
        server_href = "http://localhost/v1.1/servers/1"
395
 
        server_bookmark = "http://localhost/servers/1"
 
417
        flavor_bookmark = "http://localhost/fake/flavors/1"
 
418
        server_href = "http://localhost/v1.1/fake/servers/1"
 
419
        server_bookmark = "http://localhost/fake/servers/1"
396
420
 
397
421
        public_ip = '192.168.0.3'
398
422
        private_ip = '172.19.0.1'
414
438
            interfaces=interfaces)
415
439
        self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
416
440
 
417
 
        req = webob.Request.blank('/v1.1/servers/1')
 
441
        req = webob.Request.blank('/v1.1/fake/servers/1')
418
442
        req.headers['Accept'] = 'application/xml'
419
443
        res = req.get_response(fakes.wsgi_app())
420
444
        actual = minidom.parseString(res.body.replace('  ', ''))
424
448
        expected = minidom.parseString("""
425
449
        <server id="1"
426
450
                uuid="%(expected_uuid)s"
 
451
                userId="fake"
 
452
                tenantId="fake"
427
453
                xmlns="http://docs.openstack.org/compute/api/v1.1"
428
454
                xmlns:atom="http://www.w3.org/2005/Atom"
429
455
                name="server1"
431
457
                created="%(expected_created)s"
432
458
                hostId=""
433
459
                status="BUILD"
 
460
                accessIPv4=""
 
461
                accessIPv6=""
434
462
                progress="0">
435
463
            <atom:link href="%(server_href)s" rel="self"/>
436
464
            <atom:link href="%(server_bookmark)s" rel="bookmark"/>
459
487
        self.assertEqual(expected.toxml(), actual.toxml())
460
488
 
461
489
    def test_get_server_with_active_status_by_id_v1_1(self):
462
 
        image_bookmark = "http://localhost/images/10"
463
 
        flavor_ref = "http://localhost/v1.1/flavors/1"
 
490
        image_bookmark = "http://localhost/fake/images/10"
 
491
        flavor_ref = "http://localhost/v1.1/fake/flavors/1"
464
492
        flavor_id = "1"
465
 
        flavor_bookmark = "http://localhost/flavors/1"
 
493
        flavor_bookmark = "http://localhost/fake/flavors/1"
466
494
        private_ip = "192.168.0.3"
467
495
        public_ip = "1.2.3.4"
468
496
 
481
509
            },
482
510
        ]
483
511
        new_return_server = return_server_with_attributes(
484
 
            interfaces=interfaces, power_state=1)
 
512
            interfaces=interfaces, vm_state=vm_states.ACTIVE)
485
513
        self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
486
514
 
487
 
        req = webob.Request.blank('/v1.1/servers/1')
 
515
        req = webob.Request.blank('/v1.1/fake/servers/1')
488
516
        res = req.get_response(fakes.wsgi_app())
489
517
        res_dict = json.loads(res.body)
490
518
        expected_server = {
491
519
            "server": {
492
520
                "id": 1,
493
521
                "uuid": FAKE_UUID,
 
522
                "user_id": "fake",
 
523
                "tenant_id": "fake",
494
524
                "updated": "2010-11-11T11:00:00Z",
495
525
                "created": "2010-10-10T12:00:00Z",
496
526
                "progress": 100,
497
527
                "name": "server1",
498
528
                "status": "ACTIVE",
 
529
                "accessIPv4": "",
 
530
                "accessIPv6": "",
499
531
                "hostId": '',
 
532
                "key_name": '',
500
533
                "image": {
501
534
                    "id": "10",
502
535
                    "links": [
532
565
                "metadata": {
533
566
                    "seq": "1",
534
567
                },
 
568
                "config_drive": None,
535
569
                "links": [
536
570
                    {
537
571
                        "rel": "self",
538
 
                        "href": "http://localhost/v1.1/servers/1",
 
572
                        "href": "http://localhost/v1.1/fake/servers/1",
539
573
                    },
540
574
                    {
541
575
                        "rel": "bookmark",
542
 
                        "href": "http://localhost/servers/1",
 
576
                        "href": "http://localhost/fake/servers/1",
543
577
                    },
544
578
                ],
545
579
            }
549
583
 
550
584
    def test_get_server_with_id_image_ref_by_id_v1_1(self):
551
585
        image_ref = "10"
552
 
        image_bookmark = "http://localhost/images/10"
553
 
        flavor_ref = "http://localhost/v1.1/flavors/1"
 
586
        image_bookmark = "http://localhost/fake/images/10"
 
587
        flavor_ref = "http://localhost/v1.1/fake/flavors/1"
554
588
        flavor_id = "1"
555
 
        flavor_bookmark = "http://localhost/flavors/1"
 
589
        flavor_bookmark = "http://localhost/fake/flavors/1"
556
590
        private_ip = "192.168.0.3"
557
591
        public_ip = "1.2.3.4"
558
592
 
571
605
            },
572
606
        ]
573
607
        new_return_server = return_server_with_attributes(
574
 
            interfaces=interfaces, power_state=1, image_ref=image_ref,
575
 
            flavor_id=flavor_id)
 
608
            interfaces=interfaces, vm_state=vm_states.ACTIVE,
 
609
            image_ref=image_ref, flavor_id=flavor_id)
576
610
        self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
577
611
 
578
 
        req = webob.Request.blank('/v1.1/servers/1')
 
612
        req = webob.Request.blank('/v1.1/fake/servers/1')
579
613
        res = req.get_response(fakes.wsgi_app())
580
614
        res_dict = json.loads(res.body)
581
615
        expected_server = {
582
616
            "server": {
583
617
                "id": 1,
584
618
                "uuid": FAKE_UUID,
 
619
                "user_id": "fake",
 
620
                "tenant_id": "fake",
585
621
                "updated": "2010-11-11T11:00:00Z",
586
622
                "created": "2010-10-10T12:00:00Z",
587
623
                "progress": 100,
588
624
                "name": "server1",
589
625
                "status": "ACTIVE",
 
626
                "accessIPv4": "",
 
627
                "accessIPv6": "",
590
628
                "hostId": '',
 
629
                "key_name": '',
591
630
                "image": {
592
631
                    "id": "10",
593
632
                    "links": [
623
662
                "metadata": {
624
663
                    "seq": "1",
625
664
                },
 
665
                "config_drive": None,
626
666
                "links": [
627
667
                    {
628
668
                        "rel": "self",
629
 
                        "href": "http://localhost/v1.1/servers/1",
 
669
                        "href": "http://localhost/v1.1/fake/servers/1",
630
670
                    },
631
671
                    {
632
672
                        "rel": "bookmark",
633
 
                        "href": "http://localhost/servers/1",
 
673
                        "href": "http://localhost/fake/servers/1",
634
674
                    },
635
675
                ],
636
676
            }
752
792
        (ip,) = private_node.getElementsByTagName('ip')
753
793
        self.assertEquals(ip.getAttribute('addr'), private)
754
794
 
 
795
    # NOTE(bcwaldon): lp830817
 
796
    def test_get_server_by_id_malformed_networks_v1_1(self):
 
797
        ifaces = [
 
798
            {
 
799
                'network': None,
 
800
                'fixed_ips': [
 
801
                    {'address': '192.168.0.3'},
 
802
                    {'address': '192.168.0.4'},
 
803
                ],
 
804
            },
 
805
        ]
 
806
        new_return_server = return_server_with_attributes(interfaces=ifaces)
 
807
        self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
 
808
 
 
809
        req = webob.Request.blank('/v1.1/fake/servers/1')
 
810
        res = req.get_response(fakes.wsgi_app())
 
811
        self.assertEqual(res.status_int, 200)
 
812
        res_dict = json.loads(res.body)
 
813
        self.assertEqual(res_dict['server']['id'], 1)
 
814
        self.assertEqual(res_dict['server']['name'], 'server1')
 
815
 
755
816
    def test_get_server_by_id_with_addresses_v1_1(self):
756
817
        self.flags(use_ipv6=True)
757
818
        interfaces = [
775
836
            interfaces=interfaces)
776
837
        self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
777
838
 
778
 
        req = webob.Request.blank('/v1.1/servers/1')
 
839
        req = webob.Request.blank('/v1.1/fake/servers/1')
779
840
        res = req.get_response(fakes.wsgi_app())
780
841
 
781
842
        res_dict = json.loads(res.body)
819
880
            interfaces=interfaces)
820
881
        self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
821
882
 
822
 
        req = webob.Request.blank('/v1.1/servers/1')
 
883
        req = webob.Request.blank('/v1.1/fake/servers/1')
823
884
        res = req.get_response(fakes.wsgi_app())
824
885
 
825
886
        res_dict = json.loads(res.body)
869
930
                       'virtual_interface_get_by_instance',
870
931
                       _return_vifs)
871
932
 
872
 
        req = webob.Request.blank('/v1.1/servers/1/ips')
 
933
        req = webob.Request.blank('/v1.1/fake/servers/1/ips')
873
934
        res = req.get_response(fakes.wsgi_app())
874
935
        res_dict = json.loads(res.body)
875
936
 
919
980
                       'virtual_interface_get_by_instance',
920
981
                       _return_vifs)
921
982
 
922
 
        req = webob.Request.blank('/v1.1/servers/1/ips/network_2')
 
983
        req = webob.Request.blank('/v1.1/fake/servers/1/ips/network_2')
923
984
        res = req.get_response(fakes.wsgi_app())
924
985
        self.assertEqual(res.status_int, 200)
925
986
        res_dict = json.loads(res.body)
939
1000
                       'virtual_interface_get_by_instance',
940
1001
                       _return_vifs)
941
1002
 
942
 
        req = webob.Request.blank('/v1.1/servers/1/ips/network_0')
 
1003
        req = webob.Request.blank('/v1.1/fake/servers/1/ips/network_0')
943
1004
        res = req.get_response(fakes.wsgi_app())
944
1005
        self.assertEqual(res.status_int, 404)
945
1006
 
949
1010
                       'virtual_interface_get_by_instance',
950
1011
                       _return_vifs)
951
1012
 
952
 
        req = webob.Request.blank('/v1.1/servers/600/ips')
 
1013
        req = webob.Request.blank('/v1.1/fake/servers/600/ips')
953
1014
        res = req.get_response(fakes.wsgi_app())
954
1015
        self.assertEqual(res.status_int, 404)
955
1016
 
1018
1079
                i += 1
1019
1080
 
1020
1081
    def test_get_server_list_v1_1(self):
1021
 
        req = webob.Request.blank('/v1.1/servers')
 
1082
        req = webob.Request.blank('/v1.1/fake/servers')
1022
1083
        res = req.get_response(fakes.wsgi_app())
1023
1084
        res_dict = json.loads(res.body)
1024
1085
 
1031
1092
            expected_links = [
1032
1093
                {
1033
1094
                    "rel": "self",
1034
 
                    "href": "http://localhost/v1.1/servers/%s" % s['id'],
 
1095
                    "href": "http://localhost/v1.1/fake/servers/%s" % s['id'],
1035
1096
                },
1036
1097
                {
1037
1098
                    "rel": "bookmark",
1038
 
                    "href": "http://localhost/servers/%s" % s['id'],
 
1099
                    "href": "http://localhost/fake/servers/%s" % s['id'],
1039
1100
                },
1040
1101
            ]
1041
1102
 
1082
1143
        self.assertTrue(res.body.find('offset param') > -1)
1083
1144
 
1084
1145
    def test_get_servers_with_marker(self):
1085
 
        req = webob.Request.blank('/v1.1/servers?marker=2')
 
1146
        req = webob.Request.blank('/v1.1/fake/servers?marker=2')
1086
1147
        res = req.get_response(fakes.wsgi_app())
1087
1148
        servers = json.loads(res.body)['servers']
1088
1149
        self.assertEqual([s['name'] for s in servers], ["server3", "server4"])
1089
1150
 
1090
1151
    def test_get_servers_with_limit_and_marker(self):
1091
 
        req = webob.Request.blank('/v1.1/servers?limit=2&marker=1')
 
1152
        req = webob.Request.blank('/v1.1/fake/servers?limit=2&marker=1')
1092
1153
        res = req.get_response(fakes.wsgi_app())
1093
1154
        servers = json.loads(res.body)['servers']
1094
1155
        self.assertEqual([s['name'] for s in servers], ['server2', 'server3'])
1095
1156
 
1096
1157
    def test_get_servers_with_bad_marker(self):
1097
 
        req = webob.Request.blank('/v1.1/servers?limit=2&marker=asdf')
 
1158
        req = webob.Request.blank('/v1.1/fake/servers?limit=2&marker=asdf')
1098
1159
        res = req.get_response(fakes.wsgi_app())
1099
1160
        self.assertEqual(res.status_int, 400)
1100
1161
        self.assertTrue(res.body.find('marker param') > -1)
1120
1181
 
1121
1182
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1122
1183
 
1123
 
        req = webob.Request.blank('/v1.1/servers?unknownoption=whee')
 
1184
        req = webob.Request.blank('/v1.1/fake/servers?unknownoption=whee')
1124
1185
        res = req.get_response(fakes.wsgi_app())
1125
1186
        self.assertEqual(res.status_int, 200)
1126
1187
        servers = json.loads(res.body)['servers']
1137
1198
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1138
1199
        self.flags(allow_admin_api=False)
1139
1200
 
1140
 
        req = webob.Request.blank('/v1.1/servers?image=12345')
 
1201
        req = webob.Request.blank('/v1.1/fake/servers?image=12345')
1141
1202
        res = req.get_response(fakes.wsgi_app())
1142
1203
        # The following assert will fail if either of the asserts in
1143
1204
        # fake_get_all() fail
1146
1207
        self.assertEqual(len(servers), 1)
1147
1208
        self.assertEqual(servers[0]['id'], 100)
1148
1209
 
 
1210
    def test_tenant_id_filter_converts_to_project_id_for_admin(self):
 
1211
        def fake_get_all(context, filters=None):
 
1212
            self.assertNotEqual(filters, None)
 
1213
            self.assertEqual(filters['project_id'], 'faketenant')
 
1214
            self.assertFalse(filters.get('tenant_id'))
 
1215
            return [stub_instance(100)]
 
1216
 
 
1217
        self.stubs.Set(nova.db.api, 'instance_get_all_by_filters',
 
1218
                       fake_get_all)
 
1219
        self.flags(allow_admin_api=True)
 
1220
 
 
1221
        req = webob.Request.blank('/v1.1/fake/servers?tenant_id=faketenant')
 
1222
        # Use admin context
 
1223
        context = nova.context.RequestContext('testuser', 'testproject',
 
1224
                is_admin=True)
 
1225
        res = req.get_response(fakes.wsgi_app(fake_auth_context=context))
 
1226
        res_dict = json.loads(res.body)
 
1227
        # Failure in fake_get_all returns non 200 status code
 
1228
        self.assertEqual(res.status_int, 200)
 
1229
 
1149
1230
    def test_get_servers_allows_flavor_v1_1(self):
1150
1231
        def fake_get_all(compute_self, context, search_opts=None):
1151
1232
            self.assertNotEqual(search_opts, None)
1157
1238
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1158
1239
        self.flags(allow_admin_api=False)
1159
1240
 
1160
 
        req = webob.Request.blank('/v1.1/servers?flavor=12345')
 
1241
        req = webob.Request.blank('/v1.1/fake/servers?flavor=12345')
1161
1242
        res = req.get_response(fakes.wsgi_app())
1162
1243
        # The following assert will fail if either of the asserts in
1163
1244
        # fake_get_all() fail
1169
1250
    def test_get_servers_allows_status_v1_1(self):
1170
1251
        def fake_get_all(compute_self, context, search_opts=None):
1171
1252
            self.assertNotEqual(search_opts, None)
1172
 
            self.assertTrue('state' in search_opts)
1173
 
            self.assertEqual(set(search_opts['state']),
1174
 
                    set([power_state.RUNNING, power_state.BLOCKED]))
 
1253
            self.assertTrue('vm_state' in search_opts)
 
1254
            self.assertEqual(search_opts['vm_state'], vm_states.ACTIVE)
1175
1255
            return [stub_instance(100)]
1176
1256
 
1177
1257
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1178
1258
        self.flags(allow_admin_api=False)
1179
1259
 
1180
 
        req = webob.Request.blank('/v1.1/servers?status=active')
 
1260
        req = webob.Request.blank('/v1.1/fake/servers?status=active')
1181
1261
        res = req.get_response(fakes.wsgi_app())
1182
1262
        # The following assert will fail if either of the asserts in
1183
1263
        # fake_get_all() fail
1188
1268
 
1189
1269
    def test_get_servers_invalid_status_v1_1(self):
1190
1270
        """Test getting servers by invalid status"""
1191
 
 
1192
1271
        self.flags(allow_admin_api=False)
1193
 
 
1194
 
        req = webob.Request.blank('/v1.1/servers?status=running')
 
1272
        req = webob.Request.blank('/v1.1/fake/servers?status=running')
1195
1273
        res = req.get_response(fakes.wsgi_app())
1196
 
        # The following assert will fail if either of the asserts in
1197
 
        # fake_get_all() fail
1198
1274
        self.assertEqual(res.status_int, 400)
1199
1275
        self.assertTrue(res.body.find('Invalid server status') > -1)
1200
1276
 
1208
1284
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1209
1285
        self.flags(allow_admin_api=False)
1210
1286
 
1211
 
        req = webob.Request.blank('/v1.1/servers?name=whee.*')
 
1287
        req = webob.Request.blank('/v1.1/fake/servers?name=whee.*')
1212
1288
        res = req.get_response(fakes.wsgi_app())
1213
1289
        # The following assert will fail if either of the asserts in
1214
1290
        # fake_get_all() fail
1217
1293
        self.assertEqual(len(servers), 1)
1218
1294
        self.assertEqual(servers[0]['id'], 100)
1219
1295
 
 
1296
    def test_get_servers_allows_changes_since_v1_1(self):
 
1297
        def fake_get_all(compute_self, context, search_opts=None):
 
1298
            self.assertNotEqual(search_opts, None)
 
1299
            self.assertTrue('changes-since' in search_opts)
 
1300
            changes_since = datetime.datetime(2011, 1, 24, 17, 8, 1)
 
1301
            self.assertEqual(search_opts['changes-since'], changes_since)
 
1302
            self.assertTrue('deleted' not in search_opts)
 
1303
            return [stub_instance(100)]
 
1304
 
 
1305
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
 
1306
 
 
1307
        params = 'changes-since=2011-01-24T17:08:01Z'
 
1308
        req = webob.Request.blank('/v1.1/fake/servers?%s' % params)
 
1309
        res = req.get_response(fakes.wsgi_app())
 
1310
        self.assertEqual(res.status_int, 200)
 
1311
        servers = json.loads(res.body)['servers']
 
1312
        self.assertEqual(len(servers), 1)
 
1313
        self.assertEqual(servers[0]['id'], 100)
 
1314
 
 
1315
    def test_get_servers_allows_changes_since_bad_value_v1_1(self):
 
1316
        params = 'changes-since=asdf'
 
1317
        req = webob.Request.blank('/v1.1/fake/servers?%s' % params)
 
1318
        res = req.get_response(fakes.wsgi_app())
 
1319
        self.assertEqual(res.status_int, 400)
 
1320
 
1220
1321
    def test_get_servers_unknown_or_admin_options1(self):
1221
1322
        """Test getting servers by admin-only or unknown options.
1222
1323
        This tests when admin_api is off.  Make sure the admin and
1239
1340
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1240
1341
 
1241
1342
        query_str = "name=foo&ip=10.*&status=active&unknown_option=meow"
1242
 
        req = webob.Request.blank('/v1.1/servers?%s' % query_str)
 
1343
        req = webob.Request.blank('/v1.1/fake/servers?%s' % query_str)
1243
1344
        # Request admin context
1244
1345
        context = nova.context.RequestContext('testuser', 'testproject',
1245
1346
                is_admin=True)
1273
1374
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1274
1375
 
1275
1376
        query_str = "name=foo&ip=10.*&status=active&unknown_option=meow"
1276
 
        req = webob.Request.blank('/v1.1/servers?%s' % query_str)
 
1377
        req = webob.Request.blank('/v1.1/fake/servers?%s' % query_str)
1277
1378
        # Request admin context
1278
1379
        context = nova.context.RequestContext('testuser', 'testproject',
1279
1380
                is_admin=False)
1306
1407
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1307
1408
 
1308
1409
        query_str = "name=foo&ip=10.*&status=active&unknown_option=meow"
1309
 
        req = webob.Request.blank('/v1.1/servers?%s' % query_str)
 
1410
        req = webob.Request.blank('/v1.1/fake/servers?%s' % query_str)
1310
1411
        # Request admin context
1311
1412
        context = nova.context.RequestContext('testuser', 'testproject',
1312
1413
                is_admin=True)
1332
1433
 
1333
1434
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1334
1435
 
1335
 
        req = webob.Request.blank('/v1.1/servers?ip=10\..*')
 
1436
        req = webob.Request.blank('/v1.1/fake/servers?ip=10\..*')
1336
1437
        # Request admin context
1337
1438
        context = nova.context.RequestContext('testuser', 'testproject',
1338
1439
                is_admin=True)
1358
1459
 
1359
1460
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1360
1461
 
1361
 
        req = webob.Request.blank('/v1.1/servers?ip6=ffff.*')
 
1462
        req = webob.Request.blank('/v1.1/fake/servers?ip6=ffff.*')
1362
1463
        # Request admin context
1363
1464
        context = nova.context.RequestContext('testuser', 'testproject',
1364
1465
                is_admin=True)
1379
1480
                    'display_name': 'server_test',
1380
1481
                    'uuid': FAKE_UUID,
1381
1482
                    'instance_type': dict(inst_type),
 
1483
                    'access_ip_v4': '1.2.3.4',
 
1484
                    'access_ip_v6': 'fead::1234',
1382
1485
                    'image_ref': image_ref,
 
1486
                    'user_id': 'fake',
 
1487
                    'project_id': 'fake',
1383
1488
                    "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0),
1384
1489
                    "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0),
 
1490
                    "config_drive": self.config_drive,
1385
1491
                   }
1386
1492
 
1387
1493
        def server_update(context, id, params):
1407
1513
        self.stubs.Set(nova.db.api, 'instance_create', instance_create)
1408
1514
        self.stubs.Set(nova.rpc, 'cast', fake_method)
1409
1515
        self.stubs.Set(nova.rpc, 'call', fake_method)
1410
 
        self.stubs.Set(nova.db.api, 'instance_update',
1411
 
            server_update)
 
1516
        self.stubs.Set(nova.db.api, 'instance_update', server_update)
1412
1517
        self.stubs.Set(nova.db.api, 'queue_get_for', queue_get_for)
1413
1518
        self.stubs.Set(nova.network.manager.VlanManager, 'allocate_fixed_ip',
1414
1519
            fake_method)
1579
1684
        res = req.get_response(fakes.wsgi_app())
1580
1685
        self.assertEqual(res.status_int, 400)
1581
1686
 
 
1687
    def test_create_instance_with_access_ip_v1_1(self):
 
1688
        self._setup_for_create_instance()
 
1689
 
 
1690
        # proper local hrefs must start with 'http://localhost/v1.1/'
 
1691
        image_href = 'http://localhost/v1.1/123/images/2'
 
1692
        flavor_ref = 'http://localhost/123/flavors/3'
 
1693
        access_ipv4 = '1.2.3.4'
 
1694
        access_ipv6 = 'fead::1234'
 
1695
        expected_flavor = {
 
1696
            "id": "3",
 
1697
            "links": [
 
1698
                {
 
1699
                    "rel": "bookmark",
 
1700
                    "href": 'http://localhost/123/flavors/3',
 
1701
                },
 
1702
            ],
 
1703
        }
 
1704
        expected_image = {
 
1705
            "id": "2",
 
1706
            "links": [
 
1707
                {
 
1708
                    "rel": "bookmark",
 
1709
                    "href": 'http://localhost/123/images/2',
 
1710
                },
 
1711
            ],
 
1712
        }
 
1713
        body = {
 
1714
            'server': {
 
1715
                'name': 'server_test',
 
1716
                'imageRef': image_href,
 
1717
                'flavorRef': flavor_ref,
 
1718
                'accessIPv4': access_ipv4,
 
1719
                'accessIPv6': access_ipv6,
 
1720
                'metadata': {
 
1721
                    'hello': 'world',
 
1722
                    'open': 'stack',
 
1723
                },
 
1724
                'personality': [
 
1725
                    {
 
1726
                        "path": "/etc/banner.txt",
 
1727
                        "contents": "MQ==",
 
1728
                    },
 
1729
                ],
 
1730
            },
 
1731
        }
 
1732
 
 
1733
        req = webob.Request.blank('/v1.1/123/servers')
 
1734
        req.method = 'POST'
 
1735
        req.body = json.dumps(body)
 
1736
        req.headers["content-type"] = "application/json"
 
1737
 
 
1738
        res = req.get_response(fakes.wsgi_app())
 
1739
 
 
1740
        self.assertEqual(res.status_int, 202)
 
1741
        server = json.loads(res.body)['server']
 
1742
        self.assertEqual(16, len(server['adminPass']))
 
1743
        self.assertEqual(1, server['id'])
 
1744
        self.assertEqual(0, server['progress'])
 
1745
        self.assertEqual('server_test', server['name'])
 
1746
        self.assertEqual(expected_flavor, server['flavor'])
 
1747
        self.assertEqual(expected_image, server['image'])
 
1748
        self.assertEqual(access_ipv4, server['accessIPv4'])
 
1749
        self.assertEqual(access_ipv6, server['accessIPv6'])
 
1750
 
1582
1751
    def test_create_instance_v1_1(self):
1583
1752
        self._setup_for_create_instance()
1584
1753
 
1585
1754
        # proper local hrefs must start with 'http://localhost/v1.1/'
1586
1755
        image_href = 'http://localhost/v1.1/images/2'
1587
 
        flavor_ref = 'http://localhost/flavors/3'
 
1756
        flavor_ref = 'http://localhost/123/flavors/3'
1588
1757
        expected_flavor = {
1589
1758
            "id": "3",
1590
1759
            "links": [
1591
1760
                {
1592
1761
                    "rel": "bookmark",
1593
 
                    "href": 'http://localhost/flavors/3',
 
1762
                    "href": 'http://localhost/fake/flavors/3',
1594
1763
                },
1595
1764
            ],
1596
1765
        }
1599
1768
            "links": [
1600
1769
                {
1601
1770
                    "rel": "bookmark",
1602
 
                    "href": 'http://localhost/images/2',
 
1771
                    "href": 'http://localhost/fake/images/2',
1603
1772
                },
1604
1773
            ],
1605
1774
        }
1621
1790
            },
1622
1791
        }
1623
1792
 
1624
 
        req = webob.Request.blank('/v1.1/servers')
 
1793
        req = webob.Request.blank('/v1.1/fake/servers')
1625
1794
        req.method = 'POST'
1626
1795
        req.body = json.dumps(body)
1627
1796
        req.headers["content-type"] = "application/json"
1632
1801
        server = json.loads(res.body)['server']
1633
1802
        self.assertEqual(16, len(server['adminPass']))
1634
1803
        self.assertEqual(1, server['id'])
 
1804
        self.assertEqual("BUILD", server["status"])
1635
1805
        self.assertEqual(0, server['progress'])
1636
1806
        self.assertEqual('server_test', server['name'])
1637
1807
        self.assertEqual(expected_flavor, server['flavor'])
1638
1808
        self.assertEqual(expected_image, server['image'])
 
1809
        self.assertEqual('1.2.3.4', server['accessIPv4'])
 
1810
        self.assertEqual('fead::1234', server['accessIPv6'])
 
1811
 
 
1812
    def test_create_instance_v1_1_invalid_key_name(self):
 
1813
        self._setup_for_create_instance()
 
1814
 
 
1815
        image_href = 'http://localhost/v1.1/images/2'
 
1816
        flavor_ref = 'http://localhost/flavors/3'
 
1817
        body = dict(server=dict(
 
1818
            name='server_test', imageRef=image_href, flavorRef=flavor_ref,
 
1819
            key_name='nonexistentkey'))
 
1820
        req = webob.Request.blank('/v1.1/fake/servers')
 
1821
        req.method = 'POST'
 
1822
        req.body = json.dumps(body)
 
1823
        req.headers["content-type"] = "application/json"
 
1824
        res = req.get_response(fakes.wsgi_app())
 
1825
        self.assertEqual(res.status_int, 400)
 
1826
 
 
1827
    def test_create_instance_v1_1_valid_key_name(self):
 
1828
        self._setup_for_create_instance()
 
1829
 
 
1830
        image_href = 'http://localhost/v1.1/images/2'
 
1831
        flavor_ref = 'http://localhost/flavors/3'
 
1832
        body = dict(server=dict(
 
1833
            name='server_test', imageRef=image_href, flavorRef=flavor_ref,
 
1834
            key_name='key'))
 
1835
        req = webob.Request.blank('/v1.1/fake/servers')
 
1836
        req.method = 'POST'
 
1837
        req.body = json.dumps(body)
 
1838
        req.headers["content-type"] = "application/json"
 
1839
        res = req.get_response(fakes.wsgi_app())
 
1840
        self.assertEqual(res.status_int, 202)
1639
1841
 
1640
1842
    def test_create_instance_v1_1_invalid_flavor_href(self):
1641
1843
        self._setup_for_create_instance()
1646
1848
            name='server_test', imageRef=image_href, flavorRef=flavor_ref,
1647
1849
            metadata={'hello': 'world', 'open': 'stack'},
1648
1850
            personality={}))
1649
 
        req = webob.Request.blank('/v1.1/servers')
 
1851
        req = webob.Request.blank('/v1.1/fake/servers')
1650
1852
        req.method = 'POST'
1651
1853
        req.body = json.dumps(body)
1652
1854
        req.headers["content-type"] = "application/json"
1656
1858
    def test_create_instance_v1_1_invalid_flavor_id_int(self):
1657
1859
        self._setup_for_create_instance()
1658
1860
 
1659
 
        image_href = 'http://localhost/v1.1/images/2'
 
1861
        image_href = 'http://localhost/v1.1/123/images/2'
1660
1862
        flavor_ref = -1
1661
1863
        body = dict(server=dict(
1662
1864
            name='server_test', imageRef=image_href, flavorRef=flavor_ref,
1663
1865
            metadata={'hello': 'world', 'open': 'stack'},
1664
1866
            personality={}))
1665
 
        req = webob.Request.blank('/v1.1/servers')
 
1867
        req = webob.Request.blank('/v1.1/123/servers')
1666
1868
        req.method = 'POST'
1667
1869
        req.body = json.dumps(body)
1668
1870
        req.headers["content-type"] = "application/json"
1678
1880
            name='server_test', imageRef=image_href, flavorRef=flavor_ref,
1679
1881
            metadata={'hello': 'world', 'open': 'stack'},
1680
1882
            personality={}))
1681
 
        req = webob.Request.blank('/v1.1/servers')
1682
 
        req.method = 'POST'
1683
 
        req.body = json.dumps(body)
1684
 
        req.headers["content-type"] = "application/json"
1685
 
        res = req.get_response(fakes.wsgi_app())
1686
 
        self.assertEqual(res.status_int, 400)
 
1883
        req = webob.Request.blank('/v1.1/fake/servers')
 
1884
        req.method = 'POST'
 
1885
        req.body = json.dumps(body)
 
1886
        req.headers["content-type"] = "application/json"
 
1887
        res = req.get_response(fakes.wsgi_app())
 
1888
        self.assertEqual(res.status_int, 400)
 
1889
 
 
1890
    def test_create_instance_with_config_drive_v1_1(self):
 
1891
        self.config_drive = True
 
1892
        self._setup_for_create_instance()
 
1893
 
 
1894
        image_href = 'http://localhost/v1.1/123/images/2'
 
1895
        flavor_ref = 'http://localhost/v1.1/123/flavors/3'
 
1896
        body = {
 
1897
            'server': {
 
1898
                'name': 'config_drive_test',
 
1899
                'imageRef': image_href,
 
1900
                'flavorRef': flavor_ref,
 
1901
                'metadata': {
 
1902
                    'hello': 'world',
 
1903
                    'open': 'stack',
 
1904
                },
 
1905
                'personality': {},
 
1906
                'config_drive': True,
 
1907
            },
 
1908
        }
 
1909
 
 
1910
        req = webob.Request.blank('/v1.1/123/servers')
 
1911
        req.method = 'POST'
 
1912
        req.body = json.dumps(body)
 
1913
        req.headers["content-type"] = "application/json"
 
1914
 
 
1915
        res = req.get_response(fakes.wsgi_app())
 
1916
        print res
 
1917
        self.assertEqual(res.status_int, 202)
 
1918
        server = json.loads(res.body)['server']
 
1919
        self.assertEqual(1, server['id'])
 
1920
        self.assertTrue(server['config_drive'])
 
1921
 
 
1922
    def test_create_instance_with_config_drive_as_id_v1_1(self):
 
1923
        self.config_drive = 2
 
1924
        self._setup_for_create_instance()
 
1925
 
 
1926
        image_href = 'http://localhost/v1.1/123/images/2'
 
1927
        flavor_ref = 'http://localhost/v1.1/123/flavors/3'
 
1928
        body = {
 
1929
            'server': {
 
1930
                'name': 'config_drive_test',
 
1931
                'imageRef': image_href,
 
1932
                'flavorRef': flavor_ref,
 
1933
                'metadata': {
 
1934
                    'hello': 'world',
 
1935
                    'open': 'stack',
 
1936
                },
 
1937
                'personality': {},
 
1938
                'config_drive': 2,
 
1939
            },
 
1940
        }
 
1941
 
 
1942
        req = webob.Request.blank('/v1.1/123/servers')
 
1943
        req.method = 'POST'
 
1944
        req.body = json.dumps(body)
 
1945
        req.headers["content-type"] = "application/json"
 
1946
 
 
1947
        res = req.get_response(fakes.wsgi_app())
 
1948
 
 
1949
        self.assertEqual(res.status_int, 202)
 
1950
        server = json.loads(res.body)['server']
 
1951
        self.assertEqual(1, server['id'])
 
1952
        self.assertTrue(server['config_drive'])
 
1953
        self.assertEqual(2, server['config_drive'])
 
1954
 
 
1955
    def test_create_instance_with_bad_config_drive_v1_1(self):
 
1956
        self.config_drive = "asdf"
 
1957
        self._setup_for_create_instance()
 
1958
 
 
1959
        image_href = 'http://localhost/v1.1/123/images/2'
 
1960
        flavor_ref = 'http://localhost/v1.1/123/flavors/3'
 
1961
        body = {
 
1962
            'server': {
 
1963
                'name': 'config_drive_test',
 
1964
                'imageRef': image_href,
 
1965
                'flavorRef': flavor_ref,
 
1966
                'metadata': {
 
1967
                    'hello': 'world',
 
1968
                    'open': 'stack',
 
1969
                },
 
1970
                'personality': {},
 
1971
                'config_drive': 'asdf',
 
1972
            },
 
1973
        }
 
1974
 
 
1975
        req = webob.Request.blank('/v1.1/123/servers')
 
1976
        req.method = 'POST'
 
1977
        req.body = json.dumps(body)
 
1978
        req.headers["content-type"] = "application/json"
 
1979
 
 
1980
        res = req.get_response(fakes.wsgi_app())
 
1981
        self.assertEqual(res.status_int, 400)
 
1982
 
 
1983
    def test_create_instance_without_config_drive_v1_1(self):
 
1984
        self._setup_for_create_instance()
 
1985
 
 
1986
        image_href = 'http://localhost/v1.1/123/images/2'
 
1987
        flavor_ref = 'http://localhost/v1.1/123/flavors/3'
 
1988
        body = {
 
1989
            'server': {
 
1990
                'name': 'config_drive_test',
 
1991
                'imageRef': image_href,
 
1992
                'flavorRef': flavor_ref,
 
1993
                'metadata': {
 
1994
                    'hello': 'world',
 
1995
                    'open': 'stack',
 
1996
                },
 
1997
                'personality': {},
 
1998
                'config_drive': True,
 
1999
            },
 
2000
        }
 
2001
 
 
2002
        req = webob.Request.blank('/v1.1/123/servers')
 
2003
        req.method = 'POST'
 
2004
        req.body = json.dumps(body)
 
2005
        req.headers["content-type"] = "application/json"
 
2006
 
 
2007
        res = req.get_response(fakes.wsgi_app())
 
2008
        self.assertEqual(res.status_int, 202)
 
2009
        server = json.loads(res.body)['server']
 
2010
        self.assertEqual(1, server['id'])
 
2011
        self.assertFalse(server['config_drive'])
1687
2012
 
1688
2013
    def test_create_instance_v1_1_bad_href(self):
1689
2014
        self._setup_for_create_instance()
1694
2019
            name='server_test', imageRef=image_href, flavorRef=flavor_ref,
1695
2020
            metadata={'hello': 'world', 'open': 'stack'},
1696
2021
            personality={}))
1697
 
        req = webob.Request.blank('/v1.1/servers')
 
2022
        req = webob.Request.blank('/v1.1/fake/servers')
1698
2023
        req.method = 'POST'
1699
2024
        req.body = json.dumps(body)
1700
2025
        req.headers["content-type"] = "application/json"
1711
2036
            "links": [
1712
2037
                {
1713
2038
                    "rel": "bookmark",
1714
 
                    "href": 'http://localhost/flavors/3',
 
2039
                    "href": 'http://localhost/fake/flavors/3',
1715
2040
                },
1716
2041
            ],
1717
2042
        }
1720
2045
            "links": [
1721
2046
                {
1722
2047
                    "rel": "bookmark",
1723
 
                    "href": 'http://localhost/images/2',
 
2048
                    "href": 'http://localhost/fake/images/2',
1724
2049
                },
1725
2050
            ],
1726
2051
        }
1732
2057
            },
1733
2058
        }
1734
2059
 
1735
 
        req = webob.Request.blank('/v1.1/servers')
 
2060
        req = webob.Request.blank('/v1.1/fake/servers')
1736
2061
        req.method = 'POST'
1737
2062
        req.body = json.dumps(body)
1738
2063
        req.headers["content-type"] = "application/json"
1779
2104
            },
1780
2105
        }
1781
2106
 
1782
 
        req = webob.Request.blank('/v1.1/servers')
 
2107
        req = webob.Request.blank('/v1.1/fake/servers')
1783
2108
        req.method = 'POST'
1784
2109
        req.body = json.dumps(body)
1785
2110
        req.headers['content-type'] = "application/json"
1800
2125
            },
1801
2126
        }
1802
2127
 
1803
 
        req = webob.Request.blank('/v1.1/servers')
 
2128
        req = webob.Request.blank('/v1.1/fake/servers')
1804
2129
        req.method = 'POST'
1805
2130
        req.body = json.dumps(body)
1806
2131
        req.headers['content-type'] = "application/json"
1807
2132
        res = req.get_response(fakes.wsgi_app())
1808
2133
        self.assertEqual(res.status_int, 400)
1809
2134
 
 
2135
    def test_create_instance_whitespace_name(self):
 
2136
        self._setup_for_create_instance()
 
2137
 
 
2138
        body = {
 
2139
            'server': {
 
2140
                'name': '    ',
 
2141
                'imageId': 3,
 
2142
                'flavorId': 1,
 
2143
                'metadata': {
 
2144
                    'hello': 'world',
 
2145
                    'open': 'stack',
 
2146
                },
 
2147
                'personality': {},
 
2148
            },
 
2149
        }
 
2150
 
 
2151
        req = webob.Request.blank('/v1.0/servers')
 
2152
        req.method = 'POST'
 
2153
        req.body = json.dumps(body)
 
2154
        req.headers["content-type"] = "application/json"
 
2155
        res = req.get_response(fakes.wsgi_app())
 
2156
        self.assertEqual(res.status_int, 400)
 
2157
 
1810
2158
    def test_update_server_no_body(self):
1811
2159
        req = webob.Request.blank('/v1.0/servers/1')
1812
2160
        req.method = 'PUT'
1874
2222
        self.assertEqual(mock_method.password, 'bacon')
1875
2223
 
1876
2224
    def test_update_server_no_body_v1_1(self):
1877
 
        req = webob.Request.blank('/v1.0/servers/1')
 
2225
        req = webob.Request.blank('/v1.1/fake/servers/1')
1878
2226
        req.method = 'PUT'
1879
2227
        res = req.get_response(fakes.wsgi_app())
1880
2228
        self.assertEqual(res.status_int, 400)
1881
2229
 
 
2230
    def test_update_server_all_attributes_v1_1(self):
 
2231
        self.stubs.Set(nova.db.api, 'instance_get',
 
2232
                return_server_with_attributes(name='server_test',
 
2233
                                              access_ipv4='0.0.0.0',
 
2234
                                              access_ipv6='beef::0123'))
 
2235
        req = webob.Request.blank('/v1.1/123/servers/1')
 
2236
        req.method = 'PUT'
 
2237
        req.content_type = 'application/json'
 
2238
        body = {'server': {
 
2239
                  'name': 'server_test',
 
2240
                  'accessIPv4': '0.0.0.0',
 
2241
                  'accessIPv6': 'beef::0123',
 
2242
               }}
 
2243
        req.body = json.dumps(body)
 
2244
        res = req.get_response(fakes.wsgi_app())
 
2245
        self.assertEqual(res.status_int, 200)
 
2246
        res_dict = json.loads(res.body)
 
2247
        self.assertEqual(res_dict['server']['id'], 1)
 
2248
        self.assertEqual(res_dict['server']['name'], 'server_test')
 
2249
        self.assertEqual(res_dict['server']['accessIPv4'], '0.0.0.0')
 
2250
        self.assertEqual(res_dict['server']['accessIPv6'], 'beef::0123')
 
2251
 
1882
2252
    def test_update_server_name_v1_1(self):
1883
2253
        self.stubs.Set(nova.db.api, 'instance_get',
1884
2254
                return_server_with_attributes(name='server_test'))
1885
 
        req = webob.Request.blank('/v1.1/servers/1')
 
2255
        req = webob.Request.blank('/v1.1/fake/servers/1')
1886
2256
        req.method = 'PUT'
1887
2257
        req.content_type = 'application/json'
1888
2258
        req.body = json.dumps({'server': {'name': 'server_test'}})
1892
2262
        self.assertEqual(res_dict['server']['id'], 1)
1893
2263
        self.assertEqual(res_dict['server']['name'], 'server_test')
1894
2264
 
 
2265
    def test_update_server_access_ipv4_v1_1(self):
 
2266
        self.stubs.Set(nova.db.api, 'instance_get',
 
2267
                return_server_with_attributes(access_ipv4='0.0.0.0'))
 
2268
        req = webob.Request.blank('/v1.1/123/servers/1')
 
2269
        req.method = 'PUT'
 
2270
        req.content_type = 'application/json'
 
2271
        req.body = json.dumps({'server': {'accessIPv4': '0.0.0.0'}})
 
2272
        res = req.get_response(fakes.wsgi_app())
 
2273
        self.assertEqual(res.status_int, 200)
 
2274
        res_dict = json.loads(res.body)
 
2275
        self.assertEqual(res_dict['server']['id'], 1)
 
2276
        self.assertEqual(res_dict['server']['accessIPv4'], '0.0.0.0')
 
2277
 
 
2278
    def test_update_server_access_ipv6_v1_1(self):
 
2279
        self.stubs.Set(nova.db.api, 'instance_get',
 
2280
                return_server_with_attributes(access_ipv6='beef::0123'))
 
2281
        req = webob.Request.blank('/v1.1/123/servers/1')
 
2282
        req.method = 'PUT'
 
2283
        req.content_type = 'application/json'
 
2284
        req.body = json.dumps({'server': {'accessIPv6': 'beef::0123'}})
 
2285
        res = req.get_response(fakes.wsgi_app())
 
2286
        self.assertEqual(res.status_int, 200)
 
2287
        res_dict = json.loads(res.body)
 
2288
        self.assertEqual(res_dict['server']['id'], 1)
 
2289
        self.assertEqual(res_dict['server']['accessIPv6'], 'beef::0123')
 
2290
 
1895
2291
    def test_update_server_adminPass_ignored_v1_1(self):
1896
2292
        inst_dict = dict(name='server_test', adminPass='bacon')
1897
2293
        self.body = json.dumps(dict(server=inst_dict))
1905
2301
        self.stubs.Set(nova.db.api, 'instance_get',
1906
2302
                return_server_with_attributes(name='server_test'))
1907
2303
 
1908
 
        req = webob.Request.blank('/v1.1/servers/1')
 
2304
        req = webob.Request.blank('/v1.1/fake/servers/1')
1909
2305
        req.method = 'PUT'
1910
2306
        req.content_type = "application/json"
1911
2307
        req.body = self.body
1938
2334
        self.assertEqual(res.status_int, 501)
1939
2335
 
1940
2336
    def test_server_backup_schedule_deprecated_v1_1(self):
1941
 
        req = webob.Request.blank('/v1.1/servers/1/backup_schedule')
 
2337
        req = webob.Request.blank('/v1.1/fake/servers/1/backup_schedule')
1942
2338
        res = req.get_response(fakes.wsgi_app())
1943
2339
        self.assertEqual(res.status_int, 404)
1944
2340
 
1978
2374
            "links": [
1979
2375
                {
1980
2376
                    "rel": "bookmark",
1981
 
                    "href": 'http://localhost/flavors/1',
 
2377
                    "href": 'http://localhost/fake/flavors/1',
1982
2378
                },
1983
2379
            ],
1984
2380
        }
1987
2383
            "links": [
1988
2384
                {
1989
2385
                    "rel": "bookmark",
1990
 
                    "href": 'http://localhost/images/10',
 
2386
                    "href": 'http://localhost/fake/images/10',
1991
2387
                },
1992
2388
            ],
1993
2389
        }
1994
 
        req = webob.Request.blank('/v1.1/servers/detail')
 
2390
        req = webob.Request.blank('/v1.1/fake/servers/detail')
1995
2391
        res = req.get_response(fakes.wsgi_app())
1996
2392
        res_dict = json.loads(res.body)
1997
2393
 
2150
2546
        self.assertEqual(res.status_int, 422)
2151
2547
 
2152
2548
    def test_delete_server_instance_v1_1(self):
2153
 
        req = webob.Request.blank('/v1.1/servers/1')
 
2549
        req = webob.Request.blank('/v1.1/fake/servers/1')
2154
2550
        req.method = 'DELETE'
2155
2551
 
2156
2552
        self.server_delete_called = False
2165
2561
        self.assertEqual(res.status_int, 204)
2166
2562
        self.assertEqual(self.server_delete_called, True)
2167
2563
 
2168
 
    def test_shutdown_status(self):
2169
 
        new_server = return_server_with_power_state(power_state.SHUTDOWN)
2170
 
        self.stubs.Set(nova.db.api, 'instance_get', new_server)
2171
 
        req = webob.Request.blank('/v1.0/servers/1')
2172
 
        res = req.get_response(fakes.wsgi_app())
2173
 
        self.assertEqual(res.status_int, 200)
2174
 
        res_dict = json.loads(res.body)
2175
 
        self.assertEqual(res_dict['server']['status'], 'SHUTDOWN')
2176
 
 
2177
 
    def test_shutoff_status(self):
2178
 
        new_server = return_server_with_power_state(power_state.SHUTOFF)
2179
 
        self.stubs.Set(nova.db.api, 'instance_get', new_server)
2180
 
        req = webob.Request.blank('/v1.0/servers/1')
2181
 
        res = req.get_response(fakes.wsgi_app())
2182
 
        self.assertEqual(res.status_int, 200)
2183
 
        res_dict = json.loads(res.body)
2184
 
        self.assertEqual(res_dict['server']['status'], 'SHUTOFF')
 
2564
 
 
2565
class TestServerStatus(test.TestCase):
 
2566
 
 
2567
    def _get_with_state(self, vm_state, task_state=None):
 
2568
        new_server = return_server_with_state(vm_state, task_state)
 
2569
        self.stubs.Set(nova.db.api, 'instance_get', new_server)
 
2570
        request = webob.Request.blank('/v1.0/servers/1')
 
2571
        response = request.get_response(fakes.wsgi_app())
 
2572
        self.assertEqual(response.status_int, 200)
 
2573
        return json.loads(response.body)
 
2574
 
 
2575
    def test_active(self):
 
2576
        response = self._get_with_state(vm_states.ACTIVE)
 
2577
        self.assertEqual(response['server']['status'], 'ACTIVE')
 
2578
 
 
2579
    def test_reboot(self):
 
2580
        response = self._get_with_state(vm_states.ACTIVE,
 
2581
                                        task_states.REBOOTING)
 
2582
        self.assertEqual(response['server']['status'], 'REBOOT')
 
2583
 
 
2584
    def test_rebuild(self):
 
2585
        response = self._get_with_state(vm_states.REBUILDING)
 
2586
        self.assertEqual(response['server']['status'], 'REBUILD')
 
2587
 
 
2588
    def test_rebuild_error(self):
 
2589
        response = self._get_with_state(vm_states.ERROR)
 
2590
        self.assertEqual(response['server']['status'], 'ERROR')
 
2591
 
 
2592
    def test_resize(self):
 
2593
        response = self._get_with_state(vm_states.RESIZING)
 
2594
        self.assertEqual(response['server']['status'], 'RESIZE')
 
2595
 
 
2596
    def test_verify_resize(self):
 
2597
        response = self._get_with_state(vm_states.ACTIVE,
 
2598
                                        task_states.RESIZE_VERIFY)
 
2599
        self.assertEqual(response['server']['status'], 'VERIFY_RESIZE')
 
2600
 
 
2601
    def test_password_update(self):
 
2602
        response = self._get_with_state(vm_states.ACTIVE,
 
2603
                                        task_states.UPDATING_PASSWORD)
 
2604
        self.assertEqual(response['server']['status'], 'PASSWORD')
 
2605
 
 
2606
    def test_stopped(self):
 
2607
        response = self._get_with_state(vm_states.STOPPED)
 
2608
        self.assertEqual(response['server']['status'], 'STOPPED')
2185
2609
 
2186
2610
 
2187
2611
class TestServerCreateRequestXMLDeserializerV10(unittest.TestCase):
2491
2915
        }
2492
2916
        self.assertEquals(request['body'], expected)
2493
2917
 
 
2918
    def test_access_ipv4(self):
 
2919
        serial_request = """
 
2920
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
2921
        name="new-server-test"
 
2922
        imageRef="1"
 
2923
        flavorRef="2"
 
2924
        accessIPv4="1.2.3.4"/>"""
 
2925
        request = self.deserializer.deserialize(serial_request, 'create')
 
2926
        expected = {
 
2927
            "server": {
 
2928
                "name": "new-server-test",
 
2929
                "imageRef": "1",
 
2930
                "flavorRef": "2",
 
2931
                "accessIPv4": "1.2.3.4",
 
2932
            },
 
2933
        }
 
2934
        self.assertEquals(request['body'], expected)
 
2935
 
 
2936
    def test_access_ipv6(self):
 
2937
        serial_request = """
 
2938
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
2939
        name="new-server-test"
 
2940
        imageRef="1"
 
2941
        flavorRef="2"
 
2942
        accessIPv6="fead::1234"/>"""
 
2943
        request = self.deserializer.deserialize(serial_request, 'create')
 
2944
        expected = {
 
2945
            "server": {
 
2946
                "name": "new-server-test",
 
2947
                "imageRef": "1",
 
2948
                "flavorRef": "2",
 
2949
                "accessIPv6": "fead::1234",
 
2950
            },
 
2951
        }
 
2952
        self.assertEquals(request['body'], expected)
 
2953
 
 
2954
    def test_access_ip(self):
 
2955
        serial_request = """
 
2956
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
2957
        name="new-server-test"
 
2958
        imageRef="1"
 
2959
        flavorRef="2"
 
2960
        accessIPv4="1.2.3.4"
 
2961
        accessIPv6="fead::1234"/>"""
 
2962
        request = self.deserializer.deserialize(serial_request, 'create')
 
2963
        expected = {
 
2964
            "server": {
 
2965
                "name": "new-server-test",
 
2966
                "imageRef": "1",
 
2967
                "flavorRef": "2",
 
2968
                "accessIPv4": "1.2.3.4",
 
2969
                "accessIPv6": "fead::1234",
 
2970
            },
 
2971
        }
 
2972
        self.assertEquals(request['body'], expected)
 
2973
 
2494
2974
    def test_admin_pass(self):
2495
2975
        serial_request = """
2496
2976
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
2642
3122
        }
2643
3123
        self.assertEquals(request['body'], expected)
2644
3124
 
 
3125
    def test_request_with_empty_networks(self):
 
3126
        serial_request = """
 
3127
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
3128
 name="new-server-test" imageRef="1" flavorRef="1">
 
3129
    <networks/>
 
3130
</server>"""
 
3131
        request = self.deserializer.deserialize(serial_request, 'create')
 
3132
        expected = {"server": {
 
3133
                "name": "new-server-test",
 
3134
                "imageRef": "1",
 
3135
                "flavorRef": "1",
 
3136
                "networks": [],
 
3137
                }}
 
3138
        self.assertEquals(request['body'], expected)
 
3139
 
 
3140
    def test_request_with_one_network(self):
 
3141
        serial_request = """
 
3142
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
3143
 name="new-server-test" imageRef="1" flavorRef="1">
 
3144
    <networks>
 
3145
       <network uuid="1" fixed_ip="10.0.1.12"/>
 
3146
    </networks>
 
3147
</server>"""
 
3148
        request = self.deserializer.deserialize(serial_request, 'create')
 
3149
        expected = {"server": {
 
3150
                "name": "new-server-test",
 
3151
                "imageRef": "1",
 
3152
                "flavorRef": "1",
 
3153
                "networks": [{"uuid": "1", "fixed_ip": "10.0.1.12"}],
 
3154
                }}
 
3155
        self.assertEquals(request['body'], expected)
 
3156
 
 
3157
    def test_request_with_two_networks(self):
 
3158
        serial_request = """
 
3159
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
3160
 name="new-server-test" imageRef="1" flavorRef="1">
 
3161
    <networks>
 
3162
       <network uuid="1" fixed_ip="10.0.1.12"/>
 
3163
       <network uuid="2" fixed_ip="10.0.2.12"/>
 
3164
    </networks>
 
3165
</server>"""
 
3166
        request = self.deserializer.deserialize(serial_request, 'create')
 
3167
        expected = {"server": {
 
3168
                "name": "new-server-test",
 
3169
                "imageRef": "1",
 
3170
                "flavorRef": "1",
 
3171
                "networks": [{"uuid": "1", "fixed_ip": "10.0.1.12"},
 
3172
                             {"uuid": "2", "fixed_ip": "10.0.2.12"}],
 
3173
                }}
 
3174
        self.assertEquals(request['body'], expected)
 
3175
 
 
3176
    def test_request_with_second_network_node_ignored(self):
 
3177
        serial_request = """
 
3178
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
3179
 name="new-server-test" imageRef="1" flavorRef="1">
 
3180
    <networks>
 
3181
       <network uuid="1" fixed_ip="10.0.1.12"/>
 
3182
    </networks>
 
3183
    <networks>
 
3184
       <network uuid="2" fixed_ip="10.0.2.12"/>
 
3185
    </networks>
 
3186
</server>"""
 
3187
        request = self.deserializer.deserialize(serial_request, 'create')
 
3188
        expected = {"server": {
 
3189
                "name": "new-server-test",
 
3190
                "imageRef": "1",
 
3191
                "flavorRef": "1",
 
3192
                "networks": [{"uuid": "1", "fixed_ip": "10.0.1.12"}],
 
3193
                }}
 
3194
        self.assertEquals(request['body'], expected)
 
3195
 
 
3196
    def test_request_with_one_network_missing_id(self):
 
3197
        serial_request = """
 
3198
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
3199
 name="new-server-test" imageRef="1" flavorRef="1">
 
3200
    <networks>
 
3201
       <network fixed_ip="10.0.1.12"/>
 
3202
    </networks>
 
3203
</server>"""
 
3204
        request = self.deserializer.deserialize(serial_request, 'create')
 
3205
        expected = {"server": {
 
3206
                "name": "new-server-test",
 
3207
                "imageRef": "1",
 
3208
                "flavorRef": "1",
 
3209
                "networks": [{"fixed_ip": "10.0.1.12"}],
 
3210
                }}
 
3211
        self.assertEquals(request['body'], expected)
 
3212
 
 
3213
    def test_request_with_one_network_missing_fixed_ip(self):
 
3214
        serial_request = """
 
3215
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
3216
 name="new-server-test" imageRef="1" flavorRef="1">
 
3217
    <networks>
 
3218
       <network uuid="1"/>
 
3219
    </networks>
 
3220
</server>"""
 
3221
        request = self.deserializer.deserialize(serial_request, 'create')
 
3222
        expected = {"server": {
 
3223
                "name": "new-server-test",
 
3224
                "imageRef": "1",
 
3225
                "flavorRef": "1",
 
3226
                "networks": [{"uuid": "1"}],
 
3227
                }}
 
3228
        self.assertEquals(request['body'], expected)
 
3229
 
 
3230
    def test_request_with_one_network_empty_id(self):
 
3231
        serial_request = """
 
3232
    <server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
3233
     name="new-server-test" imageRef="1" flavorRef="1">
 
3234
        <networks>
 
3235
           <network uuid="" fixed_ip="10.0.1.12"/>
 
3236
        </networks>
 
3237
    </server>"""
 
3238
        request = self.deserializer.deserialize(serial_request, 'create')
 
3239
        expected = {"server": {
 
3240
                "name": "new-server-test",
 
3241
                "imageRef": "1",
 
3242
                "flavorRef": "1",
 
3243
                "networks": [{"uuid": "", "fixed_ip": "10.0.1.12"}],
 
3244
                }}
 
3245
        self.assertEquals(request['body'], expected)
 
3246
 
 
3247
    def test_request_with_one_network_empty_fixed_ip(self):
 
3248
        serial_request = """
 
3249
    <server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
3250
     name="new-server-test" imageRef="1" flavorRef="1">
 
3251
        <networks>
 
3252
           <network uuid="1" fixed_ip=""/>
 
3253
        </networks>
 
3254
    </server>"""
 
3255
        request = self.deserializer.deserialize(serial_request, 'create')
 
3256
        expected = {"server": {
 
3257
                "name": "new-server-test",
 
3258
                "imageRef": "1",
 
3259
                "flavorRef": "1",
 
3260
                "networks": [{"uuid": "1", "fixed_ip": ""}],
 
3261
                }}
 
3262
        self.assertEquals(request['body'], expected)
 
3263
 
 
3264
    def test_request_with_networks_duplicate_ids(self):
 
3265
        serial_request = """
 
3266
    <server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
3267
     name="new-server-test" imageRef="1" flavorRef="1">
 
3268
        <networks>
 
3269
           <network uuid="1" fixed_ip="10.0.1.12"/>
 
3270
           <network uuid="1" fixed_ip="10.0.2.12"/>
 
3271
        </networks>
 
3272
    </server>"""
 
3273
        request = self.deserializer.deserialize(serial_request, 'create')
 
3274
        expected = {"server": {
 
3275
                "name": "new-server-test",
 
3276
                "imageRef": "1",
 
3277
                "flavorRef": "1",
 
3278
                "networks": [{"uuid": "1", "fixed_ip": "10.0.1.12"},
 
3279
                             {"uuid": "1", "fixed_ip": "10.0.2.12"}],
 
3280
                }}
 
3281
        self.assertEquals(request['body'], expected)
 
3282
 
2645
3283
 
2646
3284
class TestAddressesXMLSerialization(test.TestCase):
2647
3285
 
2712
3350
 
2713
3351
            def __init__(self):
2714
3352
                self.injected_files = None
 
3353
                self.networks = None
 
3354
                self.db = db
2715
3355
 
2716
3356
            def create(self, *args, **kwargs):
2717
3357
                if 'injected_files' in kwargs:
2718
3358
                    self.injected_files = kwargs['injected_files']
2719
3359
                else:
2720
3360
                    self.injected_files = None
 
3361
 
2721
3362
                return [{'id': '1234', 'display_name': 'fakeinstance',
 
3363
                         'user_id': 'fake',
 
3364
                         'project_id': 'fake',
2722
3365
                         'uuid': FAKE_UUID}]
2723
3366
 
2724
3367
            def set_admin_password(self, *args, **kwargs):
2972
3615
        self.assertRaises(exception.NotFound, self._get_k_r, image_meta)
2973
3616
 
2974
3617
    def test_ami_no_ramdisk(self):
2975
 
        """If an ami is missing a ramdisk it should raise NotFound"""
 
3618
        """If an ami is missing a ramdisk, return kernel ID and None for
 
3619
        ramdisk ID
 
3620
        """
2976
3621
        image_meta = {'id': 1, 'status': 'active', 'container_format': 'ami',
2977
3622
                      'properties': {'kernel_id': 1}}
2978
 
        self.assertRaises(exception.NotFound, self._get_k_r, image_meta)
 
3623
        kernel_id, ramdisk_id = self._get_k_r(image_meta)
 
3624
        self.assertEqual(kernel_id, 1)
 
3625
        self.assertEqual(ramdisk_id, None)
2979
3626
 
2980
3627
    def test_ami_kernel_ramdisk_present(self):
2981
3628
        """Return IDs if both kernel and ramdisk are present"""
3010
3657
            "created_at": created_at,
3011
3658
            "updated_at": updated_at,
3012
3659
            "admin_pass": "",
3013
 
            "user_id": "",
3014
 
            "project_id": "",
 
3660
            "user_id": "fake",
 
3661
            "project_id": "fake",
3015
3662
            "image_ref": "5",
3016
3663
            "kernel_id": "",
3017
3664
            "ramdisk_id": "",
3018
3665
            "launch_index": 0,
3019
3666
            "key_name": "",
3020
3667
            "key_data": "",
3021
 
            "state": 0,
3022
 
            "state_description": "",
 
3668
            "vm_state": vm_states.BUILDING,
 
3669
            "task_state": None,
3023
3670
            "memory_mb": 0,
3024
3671
            "vcpus": 0,
3025
3672
            "local_gb": 0,
3036
3683
            "terminated_at": utils.utcnow(),
3037
3684
            "availability_zone": "",
3038
3685
            "display_name": "test_server",
3039
 
            "display_description": "",
3040
3686
            "locked": False,
3041
3687
            "metadata": [],
 
3688
            "accessIPv4": "1.2.3.4",
 
3689
            "accessIPv6": "fead::1234",
3042
3690
            #"address": ,
3043
3691
            #"floating_ips": [{"address":ip} for ip in public_addresses]}
3044
3692
            "uuid": "deadbeef-feed-edee-beef-d0ea7beefedd"}
3045
3693
 
3046
3694
        return instance
3047
3695
 
3048
 
    def _get_view_builder(self):
 
3696
    def _get_view_builder(self, project_id=""):
3049
3697
        base_url = "http://localhost/v1.1"
3050
3698
        views = nova.api.openstack.views
3051
3699
        address_builder = views.addresses.ViewBuilderV11()
3052
 
        flavor_builder = views.flavors.ViewBuilderV11(base_url)
3053
 
        image_builder = views.images.ViewBuilderV11(base_url)
 
3700
        flavor_builder = views.flavors.ViewBuilderV11(base_url, project_id)
 
3701
        image_builder = views.images.ViewBuilderV11(base_url, project_id)
3054
3702
 
3055
3703
        view_builder = nova.api.openstack.views.servers.ViewBuilderV11(
3056
3704
            address_builder,
3057
3705
            flavor_builder,
3058
3706
            image_builder,
3059
 
            base_url)
 
3707
            base_url,
 
3708
            project_id,
 
3709
        )
3060
3710
        return view_builder
3061
3711
 
3062
3712
    def test_build_server(self):
3081
3731
        output = self.view_builder.build(self.instance, False)
3082
3732
        self.assertDictMatch(output, expected_server)
3083
3733
 
 
3734
    def test_build_server_with_project_id(self):
 
3735
        expected_server = {
 
3736
            "server": {
 
3737
                "id": 1,
 
3738
                "uuid": self.instance['uuid'],
 
3739
                "name": "test_server",
 
3740
                "links": [
 
3741
                    {
 
3742
                        "rel": "self",
 
3743
                        "href": "http://localhost/v1.1/fake/servers/1",
 
3744
                    },
 
3745
                    {
 
3746
                        "rel": "bookmark",
 
3747
                        "href": "http://localhost/fake/servers/1",
 
3748
                    },
 
3749
                ],
 
3750
            }
 
3751
        }
 
3752
 
 
3753
        view_builder = self._get_view_builder(project_id='fake')
 
3754
        output = view_builder.build(self.instance, False)
 
3755
        self.assertDictMatch(output, expected_server)
 
3756
 
3084
3757
    def test_build_server_detail(self):
3085
3758
        image_bookmark = "http://localhost/images/5"
3086
3759
        flavor_bookmark = "http://localhost/flavors/1"
3088
3761
            "server": {
3089
3762
                "id": 1,
3090
3763
                "uuid": self.instance['uuid'],
 
3764
                "user_id": "fake",
 
3765
                "tenant_id": "fake",
3091
3766
                "updated": "2010-11-11T11:00:00Z",
3092
3767
                "created": "2010-10-10T12:00:00Z",
3093
3768
                "progress": 0,
3094
3769
                "name": "test_server",
3095
3770
                "status": "BUILD",
 
3771
                "accessIPv4": "",
 
3772
                "accessIPv6": "",
3096
3773
                "hostId": '',
 
3774
                "key_name": '',
3097
3775
                "image": {
3098
3776
                    "id": "5",
3099
3777
                    "links": [
3114
3792
                },
3115
3793
                "addresses": {},
3116
3794
                "metadata": {},
 
3795
                "config_drive": None,
3117
3796
                "links": [
3118
3797
                    {
3119
3798
                        "rel": "self",
3132
3811
 
3133
3812
    def test_build_server_detail_active_status(self):
3134
3813
        #set the power state of the instance to running
3135
 
        self.instance['state'] = 1
 
3814
        self.instance['vm_state'] = vm_states.ACTIVE
3136
3815
        image_bookmark = "http://localhost/images/5"
3137
3816
        flavor_bookmark = "http://localhost/flavors/1"
3138
3817
        expected_server = {
3139
3818
            "server": {
3140
3819
                "id": 1,
3141
3820
                "uuid": self.instance['uuid'],
 
3821
                "user_id": "fake",
 
3822
                "tenant_id": "fake",
3142
3823
                "updated": "2010-11-11T11:00:00Z",
3143
3824
                "created": "2010-10-10T12:00:00Z",
3144
3825
                "progress": 100,
3145
3826
                "name": "test_server",
3146
3827
                "status": "ACTIVE",
 
3828
                "accessIPv4": "",
 
3829
                "accessIPv6": "",
3147
3830
                "hostId": '',
 
3831
                "key_name": '',
3148
3832
                "image": {
3149
3833
                    "id": "5",
3150
3834
                    "links": [
3165
3849
                },
3166
3850
                "addresses": {},
3167
3851
                "metadata": {},
 
3852
                "config_drive": None,
 
3853
                "links": [
 
3854
                    {
 
3855
                        "rel": "self",
 
3856
                        "href": "http://localhost/v1.1/servers/1",
 
3857
                    },
 
3858
                    {
 
3859
                        "rel": "bookmark",
 
3860
                        "href": "http://localhost/servers/1",
 
3861
                    },
 
3862
                ],
 
3863
            }
 
3864
        }
 
3865
 
 
3866
        output = self.view_builder.build(self.instance, True)
 
3867
        self.assertDictMatch(output, expected_server)
 
3868
 
 
3869
    def test_build_server_detail_with_accessipv4(self):
 
3870
 
 
3871
        self.instance['access_ip_v4'] = '1.2.3.4'
 
3872
 
 
3873
        image_bookmark = "http://localhost/images/5"
 
3874
        flavor_bookmark = "http://localhost/flavors/1"
 
3875
        expected_server = {
 
3876
            "server": {
 
3877
                "id": 1,
 
3878
                "uuid": self.instance['uuid'],
 
3879
                "user_id": "fake",
 
3880
                "tenant_id": "fake",
 
3881
                "updated": "2010-11-11T11:00:00Z",
 
3882
                "created": "2010-10-10T12:00:00Z",
 
3883
                "progress": 0,
 
3884
                "name": "test_server",
 
3885
                "key_name": "",
 
3886
                "status": "BUILD",
 
3887
                "hostId": '',
 
3888
                "image": {
 
3889
                    "id": "5",
 
3890
                    "links": [
 
3891
                        {
 
3892
                            "rel": "bookmark",
 
3893
                            "href": image_bookmark,
 
3894
                        },
 
3895
                    ],
 
3896
                },
 
3897
                "flavor": {
 
3898
                    "id": "1",
 
3899
                    "links": [
 
3900
                                              {
 
3901
                            "rel": "bookmark",
 
3902
                            "href": flavor_bookmark,
 
3903
                        },
 
3904
                    ],
 
3905
                },
 
3906
                "addresses": {},
 
3907
                "metadata": {},
 
3908
                "config_drive": None,
 
3909
                "accessIPv4": "1.2.3.4",
 
3910
                "accessIPv6": "",
 
3911
                "links": [
 
3912
                    {
 
3913
                        "rel": "self",
 
3914
                        "href": "http://localhost/v1.1/servers/1",
 
3915
                    },
 
3916
                    {
 
3917
                        "rel": "bookmark",
 
3918
                        "href": "http://localhost/servers/1",
 
3919
                    },
 
3920
                ],
 
3921
            }
 
3922
        }
 
3923
 
 
3924
        output = self.view_builder.build(self.instance, True)
 
3925
        self.assertDictMatch(output, expected_server)
 
3926
 
 
3927
    def test_build_server_detail_with_accessipv6(self):
 
3928
 
 
3929
        self.instance['access_ip_v6'] = 'fead::1234'
 
3930
 
 
3931
        image_bookmark = "http://localhost/images/5"
 
3932
        flavor_bookmark = "http://localhost/flavors/1"
 
3933
        expected_server = {
 
3934
            "server": {
 
3935
                "id": 1,
 
3936
                "uuid": self.instance['uuid'],
 
3937
                "user_id": "fake",
 
3938
                "tenant_id": "fake",
 
3939
                "updated": "2010-11-11T11:00:00Z",
 
3940
                "created": "2010-10-10T12:00:00Z",
 
3941
                "progress": 0,
 
3942
                "name": "test_server",
 
3943
                "key_name": "",
 
3944
                "status": "BUILD",
 
3945
                "hostId": '',
 
3946
                "image": {
 
3947
                    "id": "5",
 
3948
                    "links": [
 
3949
                        {
 
3950
                            "rel": "bookmark",
 
3951
                            "href": image_bookmark,
 
3952
                        },
 
3953
                    ],
 
3954
                },
 
3955
                "flavor": {
 
3956
                    "id": "1",
 
3957
                    "links": [
 
3958
                                              {
 
3959
                            "rel": "bookmark",
 
3960
                            "href": flavor_bookmark,
 
3961
                        },
 
3962
                    ],
 
3963
                },
 
3964
                "addresses": {},
 
3965
                "metadata": {},
 
3966
                "config_drive": None,
 
3967
                "accessIPv4": "",
 
3968
                "accessIPv6": "fead::1234",
3168
3969
                "links": [
3169
3970
                    {
3170
3971
                        "rel": "self",
3194
3995
            "server": {
3195
3996
                "id": 1,
3196
3997
                "uuid": self.instance['uuid'],
 
3998
                "user_id": "fake",
 
3999
                "tenant_id": "fake",
3197
4000
                "updated": "2010-11-11T11:00:00Z",
3198
4001
                "created": "2010-10-10T12:00:00Z",
3199
4002
                "progress": 0,
3200
4003
                "name": "test_server",
3201
4004
                "status": "BUILD",
 
4005
                "accessIPv4": "",
 
4006
                "accessIPv6": "",
3202
4007
                "hostId": '',
 
4008
                "key_name": '',
3203
4009
                "image": {
3204
4010
                    "id": "5",
3205
4011
                    "links": [
3223
4029
                    "Open": "Stack",
3224
4030
                    "Number": "1",
3225
4031
                },
 
4032
                "config_drive": None,
3226
4033
                "links": [
3227
4034
                    {
3228
4035
                        "rel": "self",
3258
4065
        fixture = {
3259
4066
            "server": {
3260
4067
                "id": 1,
 
4068
                "user_id": "fake",
 
4069
                "tenant_id": "fake",
3261
4070
                "uuid": FAKE_UUID,
3262
4071
                'created': self.TIMESTAMP,
3263
4072
                'updated': self.TIMESTAMP,
3265
4074
                "name": "test_server",
3266
4075
                "status": "BUILD",
3267
4076
                "hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
 
4077
                "key_name": '',
 
4078
                "accessIPv4": "1.2.3.4",
 
4079
                "accessIPv6": "fead::1234",
3268
4080
                "image": {
3269
4081
                    "id": "5",
3270
4082
                    "links": [
3323
4135
        }
3324
4136
 
3325
4137
        output = serializer.serialize(fixture, 'show')
3326
 
        actual = minidom.parseString(output.replace("  ", ""))
 
4138
        print output
 
4139
        root = etree.XML(output)
 
4140
        xmlutil.validate_schema(root, 'server')
3327
4141
 
3328
4142
        expected_server_href = self.SERVER_HREF
3329
4143
        expected_server_bookmark = self.SERVER_BOOKMARK
3331
4145
        expected_flavor_bookmark = self.FLAVOR_BOOKMARK
3332
4146
        expected_now = self.TIMESTAMP
3333
4147
        expected_uuid = FAKE_UUID
3334
 
        expected = minidom.parseString("""
3335
 
        <server id="1"
3336
 
                uuid="%(expected_uuid)s"
3337
 
                xmlns="http://docs.openstack.org/compute/api/v1.1"
3338
 
                xmlns:atom="http://www.w3.org/2005/Atom"
3339
 
                name="test_server"
3340
 
                updated="%(expected_now)s"
3341
 
                created="%(expected_now)s"
3342
 
                hostId="e4d909c290d0fb1ca068ffaddf22cbd0"
3343
 
                status="BUILD"
3344
 
                progress="0">
3345
 
            <atom:link href="%(expected_server_href)s" rel="self"/>
3346
 
            <atom:link href="%(expected_server_bookmark)s" rel="bookmark"/>
3347
 
            <image id="5">
3348
 
                <atom:link rel="bookmark" href="%(expected_image_bookmark)s"/>
3349
 
            </image>
3350
 
            <flavor id="1">
3351
 
                <atom:link rel="bookmark" href="%(expected_flavor_bookmark)s"/>
3352
 
            </flavor>
3353
 
            <metadata>
3354
 
                <meta key="Open">
3355
 
                    Stack
3356
 
                </meta>
3357
 
                <meta key="Number">
3358
 
                    1
3359
 
                </meta>
3360
 
            </metadata>
3361
 
            <addresses>
3362
 
                <network id="network_one">
3363
 
                    <ip version="4" addr="67.23.10.138"/>
3364
 
                    <ip version="6" addr="::babe:67.23.10.138"/>
3365
 
                </network>
3366
 
                <network id="network_two">
3367
 
                    <ip version="4" addr="67.23.10.139"/>
3368
 
                    <ip version="6" addr="::babe:67.23.10.139"/>
3369
 
                </network>
3370
 
            </addresses>
3371
 
        </server>
3372
 
        """.replace("  ", "") % (locals()))
3373
 
 
3374
 
        self.assertEqual(expected.toxml(), actual.toxml())
 
4148
        server_dict = fixture['server']
 
4149
 
 
4150
        for key in ['name', 'id', 'uuid', 'created', 'accessIPv4',
 
4151
                    'updated', 'progress', 'status', 'hostId',
 
4152
                    'accessIPv6']:
 
4153
            self.assertEqual(root.get(key), str(server_dict[key]))
 
4154
 
 
4155
        link_nodes = root.findall('{0}link'.format(ATOMNS))
 
4156
        self.assertEqual(len(link_nodes), 2)
 
4157
        for i, link in enumerate(server_dict['links']):
 
4158
            for key, value in link.items():
 
4159
                self.assertEqual(link_nodes[i].get(key), value)
 
4160
 
 
4161
        metadata_root = root.find('{0}metadata'.format(NS))
 
4162
        metadata_elems = metadata_root.findall('{0}meta'.format(NS))
 
4163
        self.assertEqual(len(metadata_elems), 2)
 
4164
        for i, metadata_elem in enumerate(metadata_elems):
 
4165
            (meta_key, meta_value) = server_dict['metadata'].items()[i]
 
4166
            self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
 
4167
            self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
 
4168
 
 
4169
        image_root = root.find('{0}image'.format(NS))
 
4170
        self.assertEqual(image_root.get('id'), server_dict['image']['id'])
 
4171
        link_nodes = image_root.findall('{0}link'.format(ATOMNS))
 
4172
        self.assertEqual(len(link_nodes), 1)
 
4173
        for i, link in enumerate(server_dict['image']['links']):
 
4174
            for key, value in link.items():
 
4175
                self.assertEqual(link_nodes[i].get(key), value)
 
4176
 
 
4177
        flavor_root = root.find('{0}flavor'.format(NS))
 
4178
        self.assertEqual(flavor_root.get('id'), server_dict['flavor']['id'])
 
4179
        link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
 
4180
        self.assertEqual(len(link_nodes), 1)
 
4181
        for i, link in enumerate(server_dict['flavor']['links']):
 
4182
            for key, value in link.items():
 
4183
                self.assertEqual(link_nodes[i].get(key), value)
 
4184
 
 
4185
        addresses_root = root.find('{0}addresses'.format(NS))
 
4186
        addresses_dict = server_dict['addresses']
 
4187
        network_elems = addresses_root.findall('{0}network'.format(NS))
 
4188
        self.assertEqual(len(network_elems), 2)
 
4189
        for i, network_elem in enumerate(network_elems):
 
4190
            network = addresses_dict.items()[i]
 
4191
            self.assertEqual(str(network_elem.get('id')), str(network[0]))
 
4192
            ip_elems = network_elem.findall('{0}ip'.format(NS))
 
4193
            for z, ip_elem in enumerate(ip_elems):
 
4194
                ip = network[1][z]
 
4195
                self.assertEqual(str(ip_elem.get('version')),
 
4196
                                 str(ip['version']))
 
4197
                self.assertEqual(str(ip_elem.get('addr')),
 
4198
                                 str(ip['addr']))
3375
4199
 
3376
4200
    def test_create(self):
3377
4201
        serializer = servers.ServerXMLSerializer()
3380
4204
            "server": {
3381
4205
                "id": 1,
3382
4206
                "uuid": FAKE_UUID,
 
4207
                "user_id": "fake",
 
4208
                "tenant_id": "fake",
3383
4209
                'created': self.TIMESTAMP,
3384
4210
                'updated': self.TIMESTAMP,
3385
4211
                "progress": 0,
3386
4212
                "name": "test_server",
3387
4213
                "status": "BUILD",
 
4214
                "accessIPv4": "1.2.3.4",
 
4215
                "accessIPv6": "fead::1234",
3388
4216
                "hostId": "e4d909c290d0fb1ca068ffaddf22cbd0",
3389
4217
                "adminPass": "test_password",
3390
4218
                "image": {
3445
4273
        }
3446
4274
 
3447
4275
        output = serializer.serialize(fixture, 'create')
3448
 
        actual = minidom.parseString(output.replace("  ", ""))
 
4276
        print output
 
4277
        root = etree.XML(output)
 
4278
        xmlutil.validate_schema(root, 'server')
3449
4279
 
3450
4280
        expected_server_href = self.SERVER_HREF
3451
4281
        expected_server_bookmark = self.SERVER_BOOKMARK
3453
4283
        expected_flavor_bookmark = self.FLAVOR_BOOKMARK
3454
4284
        expected_now = self.TIMESTAMP
3455
4285
        expected_uuid = FAKE_UUID
3456
 
        expected = minidom.parseString("""
3457
 
        <server id="1"
3458
 
                uuid="%(expected_uuid)s"
3459
 
                xmlns="http://docs.openstack.org/compute/api/v1.1"
3460
 
                xmlns:atom="http://www.w3.org/2005/Atom"
3461
 
                name="test_server"
3462
 
                updated="%(expected_now)s"
3463
 
                created="%(expected_now)s"
3464
 
                hostId="e4d909c290d0fb1ca068ffaddf22cbd0"
3465
 
                status="BUILD"
3466
 
                adminPass="test_password"
3467
 
                progress="0">
3468
 
            <atom:link href="%(expected_server_href)s" rel="self"/>
3469
 
            <atom:link href="%(expected_server_bookmark)s" rel="bookmark"/>
3470
 
            <image id="5">
3471
 
                <atom:link rel="bookmark" href="%(expected_image_bookmark)s"/>
3472
 
            </image>
3473
 
            <flavor id="1">
3474
 
                <atom:link rel="bookmark" href="%(expected_flavor_bookmark)s"/>
3475
 
            </flavor>
3476
 
            <metadata>
3477
 
                <meta key="Open">
3478
 
                    Stack
3479
 
                </meta>
3480
 
                <meta key="Number">
3481
 
                    1
3482
 
                </meta>
3483
 
            </metadata>
3484
 
            <addresses>
3485
 
                <network id="network_one">
3486
 
                    <ip version="4" addr="67.23.10.138"/>
3487
 
                    <ip version="6" addr="::babe:67.23.10.138"/>
3488
 
                </network>
3489
 
                <network id="network_two">
3490
 
                    <ip version="4" addr="67.23.10.139"/>
3491
 
                    <ip version="6" addr="::babe:67.23.10.139"/>
3492
 
                </network>
3493
 
            </addresses>
3494
 
        </server>
3495
 
        """.replace("  ", "") % (locals()))
3496
 
 
3497
 
        self.assertEqual(expected.toxml(), actual.toxml())
 
4286
        server_dict = fixture['server']
 
4287
 
 
4288
        for key in ['name', 'id', 'uuid', 'created', 'accessIPv4',
 
4289
                    'updated', 'progress', 'status', 'hostId',
 
4290
                    'accessIPv6', 'adminPass']:
 
4291
            self.assertEqual(root.get(key), str(server_dict[key]))
 
4292
 
 
4293
        link_nodes = root.findall('{0}link'.format(ATOMNS))
 
4294
        self.assertEqual(len(link_nodes), 2)
 
4295
        for i, link in enumerate(server_dict['links']):
 
4296
            for key, value in link.items():
 
4297
                self.assertEqual(link_nodes[i].get(key), value)
 
4298
 
 
4299
        metadata_root = root.find('{0}metadata'.format(NS))
 
4300
        metadata_elems = metadata_root.findall('{0}meta'.format(NS))
 
4301
        self.assertEqual(len(metadata_elems), 2)
 
4302
        for i, metadata_elem in enumerate(metadata_elems):
 
4303
            (meta_key, meta_value) = server_dict['metadata'].items()[i]
 
4304
            self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
 
4305
            self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
 
4306
 
 
4307
        image_root = root.find('{0}image'.format(NS))
 
4308
        self.assertEqual(image_root.get('id'), server_dict['image']['id'])
 
4309
        link_nodes = image_root.findall('{0}link'.format(ATOMNS))
 
4310
        self.assertEqual(len(link_nodes), 1)
 
4311
        for i, link in enumerate(server_dict['image']['links']):
 
4312
            for key, value in link.items():
 
4313
                self.assertEqual(link_nodes[i].get(key), value)
 
4314
 
 
4315
        flavor_root = root.find('{0}flavor'.format(NS))
 
4316
        self.assertEqual(flavor_root.get('id'), server_dict['flavor']['id'])
 
4317
        link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
 
4318
        self.assertEqual(len(link_nodes), 1)
 
4319
        for i, link in enumerate(server_dict['flavor']['links']):
 
4320
            for key, value in link.items():
 
4321
                self.assertEqual(link_nodes[i].get(key), value)
 
4322
 
 
4323
        addresses_root = root.find('{0}addresses'.format(NS))
 
4324
        addresses_dict = server_dict['addresses']
 
4325
        network_elems = addresses_root.findall('{0}network'.format(NS))
 
4326
        self.assertEqual(len(network_elems), 2)
 
4327
        for i, network_elem in enumerate(network_elems):
 
4328
            network = addresses_dict.items()[i]
 
4329
            self.assertEqual(str(network_elem.get('id')), str(network[0]))
 
4330
            ip_elems = network_elem.findall('{0}ip'.format(NS))
 
4331
            for z, ip_elem in enumerate(ip_elems):
 
4332
                ip = network[1][z]
 
4333
                self.assertEqual(str(ip_elem.get('version')),
 
4334
                                 str(ip['version']))
 
4335
                self.assertEqual(str(ip_elem.get('addr')),
 
4336
                                 str(ip['addr']))
3498
4337
 
3499
4338
    def test_index(self):
3500
4339
        serializer = servers.ServerXMLSerializer()
3535
4374
        ]}
3536
4375
 
3537
4376
        output = serializer.serialize(fixture, 'index')
3538
 
        actual = minidom.parseString(output.replace("  ", ""))
3539
 
 
3540
 
        expected = minidom.parseString("""
3541
 
        <servers xmlns="http://docs.openstack.org/compute/api/v1.1"
3542
 
                 xmlns:atom="http://www.w3.org/2005/Atom">
3543
 
        <server id="1" name="test_server">
3544
 
            <atom:link href="%(expected_server_href)s" rel="self"/>
3545
 
            <atom:link href="%(expected_server_bookmark)s" rel="bookmark"/>
3546
 
        </server>
3547
 
        <server id="2" name="test_server_2">
3548
 
            <atom:link href="%(expected_server_href_2)s" rel="self"/>
3549
 
            <atom:link href="%(expected_server_bookmark_2)s" rel="bookmark"/>
3550
 
        </server>
3551
 
        </servers>
3552
 
        """.replace("  ", "") % (locals()))
3553
 
 
3554
 
        self.assertEqual(expected.toxml(), actual.toxml())
 
4377
        print output
 
4378
        root = etree.XML(output)
 
4379
        xmlutil.validate_schema(root, 'servers_index')
 
4380
        server_elems = root.findall('{0}server'.format(NS))
 
4381
        self.assertEqual(len(server_elems), 2)
 
4382
        for i, server_elem in enumerate(server_elems):
 
4383
            server_dict = fixture['servers'][i]
 
4384
            for key in ['name', 'id']:
 
4385
                self.assertEqual(server_elem.get(key), str(server_dict[key]))
 
4386
 
 
4387
            link_nodes = server_elem.findall('{0}link'.format(ATOMNS))
 
4388
            self.assertEqual(len(link_nodes), 2)
 
4389
            for i, link in enumerate(server_dict['links']):
 
4390
                for key, value in link.items():
 
4391
                    self.assertEqual(link_nodes[i].get(key), value)
3555
4392
 
3556
4393
    def test_detail(self):
3557
4394
        serializer = servers.ServerXMLSerializer()
3569
4406
            {
3570
4407
                "id": 1,
3571
4408
                "uuid": FAKE_UUID,
 
4409
                "user_id": "fake",
 
4410
                "tenant_id": "fake",
3572
4411
                'created': self.TIMESTAMP,
3573
4412
                'updated': self.TIMESTAMP,
3574
4413
                "progress": 0,
3575
4414
                "name": "test_server",
3576
4415
                "status": "BUILD",
 
4416
                "accessIPv4": "1.2.3.4",
 
4417
                "accessIPv6": "fead::1234",
3577
4418
                "hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
3578
4419
                "image": {
3579
4420
                    "id": "5",
3622
4463
            {
3623
4464
                "id": 2,
3624
4465
                "uuid": FAKE_UUID,
 
4466
                "user_id": 'fake',
 
4467
                "tenant_id": 'fake',
3625
4468
                'created': self.TIMESTAMP,
3626
4469
                'updated': self.TIMESTAMP,
3627
4470
                "progress": 100,
3628
4471
                "name": "test_server_2",
3629
4472
                "status": "ACTIVE",
 
4473
                "accessIPv4": "1.2.3.4",
 
4474
                "accessIPv6": "fead::1234",
3630
4475
                "hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
3631
4476
                "image": {
3632
4477
                    "id": "5",
3675
4520
        ]}
3676
4521
 
3677
4522
        output = serializer.serialize(fixture, 'detail')
3678
 
        actual = minidom.parseString(output.replace("  ", ""))
3679
 
 
3680
 
        expected = minidom.parseString("""
3681
 
        <servers xmlns="http://docs.openstack.org/compute/api/v1.1"
3682
 
                 xmlns:atom="http://www.w3.org/2005/Atom">
3683
 
        <server id="1"
3684
 
                uuid="%(expected_uuid)s"
3685
 
                name="test_server"
3686
 
                updated="%(expected_now)s"
3687
 
                created="%(expected_now)s"
3688
 
                hostId="e4d909c290d0fb1ca068ffaddf22cbd0"
3689
 
                status="BUILD"
3690
 
                progress="0">
3691
 
            <atom:link href="%(expected_server_href)s" rel="self"/>
3692
 
            <atom:link href="%(expected_server_bookmark)s" rel="bookmark"/>
3693
 
            <image id="5">
3694
 
                <atom:link rel="bookmark" href="%(expected_image_bookmark)s"/>
3695
 
            </image>
3696
 
            <flavor id="1">
3697
 
                <atom:link rel="bookmark" href="%(expected_flavor_bookmark)s"/>
3698
 
            </flavor>
3699
 
            <metadata>
3700
 
                <meta key="Number">
3701
 
                    1
3702
 
                </meta>
3703
 
            </metadata>
3704
 
            <addresses>
3705
 
                <network id="network_one">
3706
 
                    <ip version="4" addr="67.23.10.138"/>
3707
 
                    <ip version="6" addr="::babe:67.23.10.138"/>
3708
 
                </network>
3709
 
            </addresses>
3710
 
        </server>
3711
 
        <server id="2"
3712
 
                uuid="%(expected_uuid)s"
3713
 
                name="test_server_2"
3714
 
                updated="%(expected_now)s"
3715
 
                created="%(expected_now)s"
3716
 
                hostId="e4d909c290d0fb1ca068ffaddf22cbd0"
3717
 
                status="ACTIVE"
3718
 
                progress="100">
3719
 
            <atom:link href="%(expected_server_href_2)s" rel="self"/>
3720
 
            <atom:link href="%(expected_server_bookmark_2)s" rel="bookmark"/>
3721
 
            <image id="5">
3722
 
                <atom:link rel="bookmark" href="%(expected_image_bookmark)s"/>
3723
 
            </image>
3724
 
            <flavor id="1">
3725
 
                <atom:link rel="bookmark" href="%(expected_flavor_bookmark)s"/>
3726
 
            </flavor>
3727
 
            <metadata>
3728
 
                <meta key="Number">
3729
 
                    2
3730
 
                </meta>
3731
 
            </metadata>
3732
 
            <addresses>
3733
 
                <network id="network_one">
3734
 
                    <ip version="4" addr="67.23.10.138"/>
3735
 
                    <ip version="6" addr="::babe:67.23.10.138"/>
3736
 
                </network>
3737
 
            </addresses>
3738
 
        </server>
3739
 
        </servers>
3740
 
        """.replace("  ", "") % (locals()))
3741
 
 
3742
 
        self.assertEqual(expected.toxml(), actual.toxml())
 
4523
        print output
 
4524
        root = etree.XML(output)
 
4525
        xmlutil.validate_schema(root, 'servers')
 
4526
        server_elems = root.findall('{0}server'.format(NS))
 
4527
        self.assertEqual(len(server_elems), 2)
 
4528
        for i, server_elem in enumerate(server_elems):
 
4529
            server_dict = fixture['servers'][i]
 
4530
 
 
4531
            for key in ['name', 'id', 'uuid', 'created', 'accessIPv4',
 
4532
                        'updated', 'progress', 'status', 'hostId',
 
4533
                        'accessIPv6']:
 
4534
                self.assertEqual(server_elem.get(key), str(server_dict[key]))
 
4535
 
 
4536
            link_nodes = server_elem.findall('{0}link'.format(ATOMNS))
 
4537
            self.assertEqual(len(link_nodes), 2)
 
4538
            for i, link in enumerate(server_dict['links']):
 
4539
                for key, value in link.items():
 
4540
                    self.assertEqual(link_nodes[i].get(key), value)
 
4541
 
 
4542
            metadata_root = server_elem.find('{0}metadata'.format(NS))
 
4543
            metadata_elems = metadata_root.findall('{0}meta'.format(NS))
 
4544
            for i, metadata_elem in enumerate(metadata_elems):
 
4545
                (meta_key, meta_value) = server_dict['metadata'].items()[i]
 
4546
                self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
 
4547
                self.assertEqual(str(metadata_elem.text).strip(),
 
4548
                                 str(meta_value))
 
4549
 
 
4550
            image_root = server_elem.find('{0}image'.format(NS))
 
4551
            self.assertEqual(image_root.get('id'), server_dict['image']['id'])
 
4552
            link_nodes = image_root.findall('{0}link'.format(ATOMNS))
 
4553
            self.assertEqual(len(link_nodes), 1)
 
4554
            for i, link in enumerate(server_dict['image']['links']):
 
4555
                for key, value in link.items():
 
4556
                    self.assertEqual(link_nodes[i].get(key), value)
 
4557
 
 
4558
            flavor_root = server_elem.find('{0}flavor'.format(NS))
 
4559
            self.assertEqual(flavor_root.get('id'),
 
4560
                             server_dict['flavor']['id'])
 
4561
            link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
 
4562
            self.assertEqual(len(link_nodes), 1)
 
4563
            for i, link in enumerate(server_dict['flavor']['links']):
 
4564
                for key, value in link.items():
 
4565
                    self.assertEqual(link_nodes[i].get(key), value)
 
4566
 
 
4567
            addresses_root = server_elem.find('{0}addresses'.format(NS))
 
4568
            addresses_dict = server_dict['addresses']
 
4569
            network_elems = addresses_root.findall('{0}network'.format(NS))
 
4570
            for i, network_elem in enumerate(network_elems):
 
4571
                network = addresses_dict.items()[i]
 
4572
                self.assertEqual(str(network_elem.get('id')), str(network[0]))
 
4573
                ip_elems = network_elem.findall('{0}ip'.format(NS))
 
4574
                for z, ip_elem in enumerate(ip_elems):
 
4575
                    ip = network[1][z]
 
4576
                    self.assertEqual(str(ip_elem.get('version')),
 
4577
                                     str(ip['version']))
 
4578
                    self.assertEqual(str(ip_elem.get('addr')),
 
4579
                                     str(ip['addr']))
3743
4580
 
3744
4581
    def test_update(self):
3745
4582
        serializer = servers.ServerXMLSerializer()
3747
4584
        fixture = {
3748
4585
            "server": {
3749
4586
                "id": 1,
 
4587
                "user_id": "fake",
 
4588
                "tenant_id": "fake",
3750
4589
                "uuid": FAKE_UUID,
3751
4590
                'created': self.TIMESTAMP,
3752
4591
                'updated': self.TIMESTAMP,
3754
4593
                "name": "test_server",
3755
4594
                "status": "BUILD",
3756
4595
                "hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
 
4596
                "accessIPv4": "1.2.3.4",
 
4597
                "accessIPv6": "fead::1234",
3757
4598
                "image": {
3758
4599
                    "id": "5",
3759
4600
                    "links": [
3812
4653
        }
3813
4654
 
3814
4655
        output = serializer.serialize(fixture, 'update')
3815
 
        actual = minidom.parseString(output.replace("  ", ""))
3816
 
 
3817
 
        expected_server_href = self.SERVER_HREF
3818
 
        expected_server_bookmark = self.SERVER_BOOKMARK
3819
 
        expected_image_bookmark = self.IMAGE_BOOKMARK
3820
 
        expected_flavor_bookmark = self.FLAVOR_BOOKMARK
3821
 
        expected_now = self.TIMESTAMP
3822
 
        expected_uuid = FAKE_UUID
3823
 
        expected = minidom.parseString("""
3824
 
        <server id="1"
3825
 
                uuid="%(expected_uuid)s"
3826
 
                xmlns="http://docs.openstack.org/compute/api/v1.1"
3827
 
                xmlns:atom="http://www.w3.org/2005/Atom"
3828
 
                name="test_server"
3829
 
                updated="%(expected_now)s"
3830
 
                created="%(expected_now)s"
3831
 
                hostId="e4d909c290d0fb1ca068ffaddf22cbd0"
3832
 
                status="BUILD"
3833
 
                progress="0">
3834
 
            <atom:link href="%(expected_server_href)s" rel="self"/>
3835
 
            <atom:link href="%(expected_server_bookmark)s" rel="bookmark"/>
3836
 
            <image id="5">
3837
 
                <atom:link rel="bookmark" href="%(expected_image_bookmark)s"/>
3838
 
            </image>
3839
 
            <flavor id="1">
3840
 
                <atom:link rel="bookmark" href="%(expected_flavor_bookmark)s"/>
3841
 
            </flavor>
3842
 
            <metadata>
3843
 
                <meta key="Open">
3844
 
                    Stack
3845
 
                </meta>
3846
 
                <meta key="Number">
3847
 
                    1
3848
 
                </meta>
3849
 
            </metadata>
3850
 
            <addresses>
3851
 
                <network id="network_one">
3852
 
                    <ip version="4" addr="67.23.10.138"/>
3853
 
                    <ip version="6" addr="::babe:67.23.10.138"/>
3854
 
                </network>
3855
 
                <network id="network_two">
3856
 
                    <ip version="4" addr="67.23.10.139"/>
3857
 
                    <ip version="6" addr="::babe:67.23.10.139"/>
3858
 
                </network>
3859
 
            </addresses>
3860
 
        </server>
3861
 
        """.replace("  ", "") % (locals()))
3862
 
 
3863
 
        self.assertEqual(expected.toxml(), actual.toxml())
 
4656
        print output
 
4657
        root = etree.XML(output)
 
4658
        xmlutil.validate_schema(root, 'server')
 
4659
 
 
4660
        expected_server_href = self.SERVER_HREF
 
4661
        expected_server_bookmark = self.SERVER_BOOKMARK
 
4662
        expected_image_bookmark = self.IMAGE_BOOKMARK
 
4663
        expected_flavor_bookmark = self.FLAVOR_BOOKMARK
 
4664
        expected_now = self.TIMESTAMP
 
4665
        expected_uuid = FAKE_UUID
 
4666
        server_dict = fixture['server']
 
4667
 
 
4668
        for key in ['name', 'id', 'uuid', 'created', 'accessIPv4',
 
4669
                    'updated', 'progress', 'status', 'hostId',
 
4670
                    'accessIPv6']:
 
4671
            self.assertEqual(root.get(key), str(server_dict[key]))
 
4672
 
 
4673
        link_nodes = root.findall('{0}link'.format(ATOMNS))
 
4674
        self.assertEqual(len(link_nodes), 2)
 
4675
        for i, link in enumerate(server_dict['links']):
 
4676
            for key, value in link.items():
 
4677
                self.assertEqual(link_nodes[i].get(key), value)
 
4678
 
 
4679
        metadata_root = root.find('{0}metadata'.format(NS))
 
4680
        metadata_elems = metadata_root.findall('{0}meta'.format(NS))
 
4681
        self.assertEqual(len(metadata_elems), 2)
 
4682
        for i, metadata_elem in enumerate(metadata_elems):
 
4683
            (meta_key, meta_value) = server_dict['metadata'].items()[i]
 
4684
            self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
 
4685
            self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
 
4686
 
 
4687
        image_root = root.find('{0}image'.format(NS))
 
4688
        self.assertEqual(image_root.get('id'), server_dict['image']['id'])
 
4689
        link_nodes = image_root.findall('{0}link'.format(ATOMNS))
 
4690
        self.assertEqual(len(link_nodes), 1)
 
4691
        for i, link in enumerate(server_dict['image']['links']):
 
4692
            for key, value in link.items():
 
4693
                self.assertEqual(link_nodes[i].get(key), value)
 
4694
 
 
4695
        flavor_root = root.find('{0}flavor'.format(NS))
 
4696
        self.assertEqual(flavor_root.get('id'), server_dict['flavor']['id'])
 
4697
        link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
 
4698
        self.assertEqual(len(link_nodes), 1)
 
4699
        for i, link in enumerate(server_dict['flavor']['links']):
 
4700
            for key, value in link.items():
 
4701
                self.assertEqual(link_nodes[i].get(key), value)
 
4702
 
 
4703
        addresses_root = root.find('{0}addresses'.format(NS))
 
4704
        addresses_dict = server_dict['addresses']
 
4705
        network_elems = addresses_root.findall('{0}network'.format(NS))
 
4706
        self.assertEqual(len(network_elems), 2)
 
4707
        for i, network_elem in enumerate(network_elems):
 
4708
            network = addresses_dict.items()[i]
 
4709
            self.assertEqual(str(network_elem.get('id')), str(network[0]))
 
4710
            ip_elems = network_elem.findall('{0}ip'.format(NS))
 
4711
            for z, ip_elem in enumerate(ip_elems):
 
4712
                ip = network[1][z]
 
4713
                self.assertEqual(str(ip_elem.get('version')),
 
4714
                                 str(ip['version']))
 
4715
                self.assertEqual(str(ip_elem.get('addr')),
 
4716
                                 str(ip['addr']))
 
4717
 
 
4718
    def test_action(self):
 
4719
        serializer = servers.ServerXMLSerializer()
 
4720
 
 
4721
        fixture = {
 
4722
            "server": {
 
4723
                "id": 1,
 
4724
                "uuid": FAKE_UUID,
 
4725
                "user_id": "fake",
 
4726
                "tenant_id": "fake",
 
4727
                'created': self.TIMESTAMP,
 
4728
                'updated': self.TIMESTAMP,
 
4729
                "progress": 0,
 
4730
                "name": "test_server",
 
4731
                "status": "BUILD",
 
4732
                "accessIPv4": "1.2.3.4",
 
4733
                "accessIPv6": "fead::1234",
 
4734
                "hostId": "e4d909c290d0fb1ca068ffaddf22cbd0",
 
4735
                "adminPass": "test_password",
 
4736
                "image": {
 
4737
                    "id": "5",
 
4738
                    "links": [
 
4739
                        {
 
4740
                            "rel": "bookmark",
 
4741
                            "href": self.IMAGE_BOOKMARK,
 
4742
                        },
 
4743
                    ],
 
4744
                },
 
4745
                "flavor": {
 
4746
                    "id": "1",
 
4747
                    "links": [
 
4748
                        {
 
4749
                            "rel": "bookmark",
 
4750
                            "href": self.FLAVOR_BOOKMARK,
 
4751
                        },
 
4752
                    ],
 
4753
                },
 
4754
                "addresses": {
 
4755
                    "network_one": [
 
4756
                        {
 
4757
                            "version": 4,
 
4758
                            "addr": "67.23.10.138",
 
4759
                        },
 
4760
                        {
 
4761
                            "version": 6,
 
4762
                            "addr": "::babe:67.23.10.138",
 
4763
                        },
 
4764
                    ],
 
4765
                    "network_two": [
 
4766
                        {
 
4767
                            "version": 4,
 
4768
                            "addr": "67.23.10.139",
 
4769
                        },
 
4770
                        {
 
4771
                            "version": 6,
 
4772
                            "addr": "::babe:67.23.10.139",
 
4773
                        },
 
4774
                    ],
 
4775
                },
 
4776
                "metadata": {
 
4777
                    "Open": "Stack",
 
4778
                    "Number": "1",
 
4779
                },
 
4780
                'links': [
 
4781
                    {
 
4782
                        'href': self.SERVER_HREF,
 
4783
                        'rel': 'self',
 
4784
                    },
 
4785
                    {
 
4786
                        'href': self.SERVER_BOOKMARK,
 
4787
                        'rel': 'bookmark',
 
4788
                    },
 
4789
                ],
 
4790
            }
 
4791
        }
 
4792
 
 
4793
        output = serializer.serialize(fixture, 'action')
 
4794
        root = etree.XML(output)
 
4795
        xmlutil.validate_schema(root, 'server')
 
4796
 
 
4797
        expected_server_href = self.SERVER_HREF
 
4798
        expected_server_bookmark = self.SERVER_BOOKMARK
 
4799
        expected_image_bookmark = self.IMAGE_BOOKMARK
 
4800
        expected_flavor_bookmark = self.FLAVOR_BOOKMARK
 
4801
        expected_now = self.TIMESTAMP
 
4802
        expected_uuid = FAKE_UUID
 
4803
        server_dict = fixture['server']
 
4804
 
 
4805
        for key in ['name', 'id', 'uuid', 'created', 'accessIPv4',
 
4806
                    'updated', 'progress', 'status', 'hostId',
 
4807
                    'accessIPv6', 'adminPass']:
 
4808
            self.assertEqual(root.get(key), str(server_dict[key]))
 
4809
 
 
4810
        link_nodes = root.findall('{0}link'.format(ATOMNS))
 
4811
        self.assertEqual(len(link_nodes), 2)
 
4812
        for i, link in enumerate(server_dict['links']):
 
4813
            for key, value in link.items():
 
4814
                self.assertEqual(link_nodes[i].get(key), value)
 
4815
 
 
4816
        metadata_root = root.find('{0}metadata'.format(NS))
 
4817
        metadata_elems = metadata_root.findall('{0}meta'.format(NS))
 
4818
        self.assertEqual(len(metadata_elems), 2)
 
4819
        for i, metadata_elem in enumerate(metadata_elems):
 
4820
            (meta_key, meta_value) = server_dict['metadata'].items()[i]
 
4821
            self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
 
4822
            self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
 
4823
 
 
4824
        image_root = root.find('{0}image'.format(NS))
 
4825
        self.assertEqual(image_root.get('id'), server_dict['image']['id'])
 
4826
        link_nodes = image_root.findall('{0}link'.format(ATOMNS))
 
4827
        self.assertEqual(len(link_nodes), 1)
 
4828
        for i, link in enumerate(server_dict['image']['links']):
 
4829
            for key, value in link.items():
 
4830
                self.assertEqual(link_nodes[i].get(key), value)
 
4831
 
 
4832
        flavor_root = root.find('{0}flavor'.format(NS))
 
4833
        self.assertEqual(flavor_root.get('id'), server_dict['flavor']['id'])
 
4834
        link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
 
4835
        self.assertEqual(len(link_nodes), 1)
 
4836
        for i, link in enumerate(server_dict['flavor']['links']):
 
4837
            for key, value in link.items():
 
4838
                self.assertEqual(link_nodes[i].get(key), value)
 
4839
 
 
4840
        addresses_root = root.find('{0}addresses'.format(NS))
 
4841
        addresses_dict = server_dict['addresses']
 
4842
        network_elems = addresses_root.findall('{0}network'.format(NS))
 
4843
        self.assertEqual(len(network_elems), 2)
 
4844
        for i, network_elem in enumerate(network_elems):
 
4845
            network = addresses_dict.items()[i]
 
4846
            self.assertEqual(str(network_elem.get('id')), str(network[0]))
 
4847
            ip_elems = network_elem.findall('{0}ip'.format(NS))
 
4848
            for z, ip_elem in enumerate(ip_elems):
 
4849
                ip = network[1][z]
 
4850
                self.assertEqual(str(ip_elem.get('version')),
 
4851
                                 str(ip['version']))
 
4852
                self.assertEqual(str(ip_elem.get('addr')),
 
4853
                                 str(ip['addr']))