~cloudbuilders/nova/os-keypair-integration

« back to all changes in this revision

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

  • Committer: Jesse Andrews
  • Date: 2011-08-26 21:57:53 UTC
  • mfrom: (1455.1.45 nova)
  • Revision ID: anotherjesse@gmail.com-20110826215753-0sfp6dubujsl23wa
merge trunk

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
40
from nova.compute import power_state
46
49
 
47
50
 
48
51
FAKE_UUID = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
 
52
NS = "{http://docs.openstack.org/compute/api/v1.1}"
 
53
ATOMNS = "{http://www.w3.org/2005/Atom}"
49
54
 
50
55
 
51
56
def fake_gen_uuid():
145
150
def stub_instance(id, user_id='fake', project_id='fake', private_address=None,
146
151
                  public_addresses=None, host=None, power_state=0,
147
152
                  reservation_id="", uuid=FAKE_UUID, image_ref="10",
148
 
                  flavor_id="1", interfaces=None, name=None, key_name=''):
 
153
                  flavor_id="1", interfaces=None, name=None, key_name='',
 
154
                  access_ipv4=None, access_ipv6=None):
149
155
    metadata = []
150
156
    metadata.append(InstanceMetadata(key='seq', value=id))
151
157
 
202
208
        "display_description": "",
203
209
        "locked": False,
204
210
        "metadata": metadata,
 
211
        "access_ip_v4": access_ipv4,
 
212
        "access_ip_v6": access_ipv6,
205
213
        "uuid": uuid,
206
214
        "virtual_interfaces": interfaces}
207
215
 
231
239
 
232
240
 
233
241
class ServersTest(test.TestCase):
234
 
 
235
242
    def setUp(self):
236
243
        self.maxDiff = None
237
244
        super(ServersTest, self).setUp()
263
270
        self.stubs.Set(nova.compute.API, "get_actions", fake_compute_api)
264
271
 
265
272
        self.webreq = common.webob_factory('/v1.0/servers')
 
273
        self.config_drive = None
266
274
 
267
275
    def test_get_server_by_id(self):
268
276
        req = webob.Request.blank('/v1.0/servers/1')
302
310
        self.assertEqual(res_dict['server']['name'], 'server1')
303
311
 
304
312
    def test_get_server_by_id_v1_1(self):
305
 
        image_bookmark = "http://localhost/images/10"
306
 
        flavor_ref = "http://localhost/v1.1/flavors/1"
 
313
        image_bookmark = "http://localhost/fake/images/10"
 
314
        flavor_ref = "http://localhost/v1.1/fake/flavors/1"
307
315
        flavor_id = "1"
308
 
        flavor_bookmark = "http://localhost/flavors/1"
 
316
        flavor_bookmark = "http://localhost/fake/flavors/1"
309
317
 
310
318
        public_ip = '192.168.0.3'
311
319
        private_ip = '172.19.0.1'
327
335
            interfaces=interfaces)
328
336
        self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
329
337
 
330
 
        req = webob.Request.blank('/v1.1/servers/1')
 
338
        req = webob.Request.blank('/v1.1/fake/servers/1')
331
339
        res = req.get_response(fakes.wsgi_app())
332
340
        res_dict = json.loads(res.body)
333
341
        expected_server = {
339
347
                "progress": 0,
340
348
                "name": "server1",
341
349
                "status": "BUILD",
 
350
                "accessIPv4": "",
 
351
                "accessIPv6": "",
342
352
                "hostId": '',
343
353
                "key_name": '',
344
354
                "image": {
376
386
                "metadata": {
377
387
                    "seq": "1",
378
388
                },
 
389
                "config_drive": None,
379
390
                "links": [
380
391
                    {
381
392
                        "rel": "self",
382
393
                        #FIXME(wwolf) Do we want the links to be id or uuid?
383
 
                        "href": "http://localhost/v1.1/servers/1",
 
394
                        "href": "http://localhost/v1.1/fake/servers/1",
384
395
                    },
385
396
                    {
386
397
                        "rel": "bookmark",
387
 
                        "href": "http://localhost/servers/1",
 
398
                        "href": "http://localhost/fake/servers/1",
388
399
                    },
389
400
                ],
390
401
            }
393
404
        self.assertDictMatch(res_dict, expected_server)
394
405
 
395
406
    def test_get_server_by_id_v1_1_xml(self):
396
 
        image_bookmark = "http://localhost/images/10"
397
 
        flavor_ref = "http://localhost/v1.1/flavors/1"
 
407
        image_bookmark = "http://localhost/fake/images/10"
 
408
        flavor_ref = "http://localhost/v1.1/fake/flavors/1"
398
409
        flavor_id = "1"
399
 
        flavor_bookmark = "http://localhost/flavors/1"
400
 
        server_href = "http://localhost/v1.1/servers/1"
401
 
        server_bookmark = "http://localhost/servers/1"
 
410
        flavor_bookmark = "http://localhost/fake/flavors/1"
 
411
        server_href = "http://localhost/v1.1/fake/servers/1"
 
412
        server_bookmark = "http://localhost/fake/servers/1"
402
413
 
403
414
        public_ip = '192.168.0.3'
404
415
        private_ip = '172.19.0.1'
420
431
            interfaces=interfaces)
421
432
        self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
422
433
 
423
 
        req = webob.Request.blank('/v1.1/servers/1')
 
434
        req = webob.Request.blank('/v1.1/fake/servers/1')
424
435
        req.headers['Accept'] = 'application/xml'
425
436
        res = req.get_response(fakes.wsgi_app())
426
437
        actual = minidom.parseString(res.body.replace('  ', ''))
437
448
                created="%(expected_created)s"
438
449
                hostId=""
439
450
                status="BUILD"
 
451
                accessIPv4=""
 
452
                accessIPv6=""
440
453
                progress="0">
441
454
            <atom:link href="%(server_href)s" rel="self"/>
442
455
            <atom:link href="%(server_bookmark)s" rel="bookmark"/>
465
478
        self.assertEqual(expected.toxml(), actual.toxml())
466
479
 
467
480
    def test_get_server_with_active_status_by_id_v1_1(self):
468
 
        image_bookmark = "http://localhost/images/10"
469
 
        flavor_ref = "http://localhost/v1.1/flavors/1"
 
481
        image_bookmark = "http://localhost/fake/images/10"
 
482
        flavor_ref = "http://localhost/v1.1/fake/flavors/1"
470
483
        flavor_id = "1"
471
 
        flavor_bookmark = "http://localhost/flavors/1"
 
484
        flavor_bookmark = "http://localhost/fake/flavors/1"
472
485
        private_ip = "192.168.0.3"
473
486
        public_ip = "1.2.3.4"
474
487
 
490
503
            interfaces=interfaces, power_state=1)
491
504
        self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
492
505
 
493
 
        req = webob.Request.blank('/v1.1/servers/1')
 
506
        req = webob.Request.blank('/v1.1/fake/servers/1')
494
507
        res = req.get_response(fakes.wsgi_app())
495
508
        res_dict = json.loads(res.body)
496
509
        expected_server = {
502
515
                "progress": 100,
503
516
                "name": "server1",
504
517
                "status": "ACTIVE",
 
518
                "accessIPv4": "",
 
519
                "accessIPv6": "",
505
520
                "hostId": '',
506
521
                "key_name": '',
507
522
                "image": {
539
554
                "metadata": {
540
555
                    "seq": "1",
541
556
                },
 
557
                "config_drive": None,
542
558
                "links": [
543
559
                    {
544
560
                        "rel": "self",
545
 
                        "href": "http://localhost/v1.1/servers/1",
 
561
                        "href": "http://localhost/v1.1/fake/servers/1",
546
562
                    },
547
563
                    {
548
564
                        "rel": "bookmark",
549
 
                        "href": "http://localhost/servers/1",
 
565
                        "href": "http://localhost/fake/servers/1",
550
566
                    },
551
567
                ],
552
568
            }
556
572
 
557
573
    def test_get_server_with_id_image_ref_by_id_v1_1(self):
558
574
        image_ref = "10"
559
 
        image_bookmark = "http://localhost/images/10"
560
 
        flavor_ref = "http://localhost/v1.1/flavors/1"
 
575
        image_bookmark = "http://localhost/fake/images/10"
 
576
        flavor_ref = "http://localhost/v1.1/fake/flavors/1"
561
577
        flavor_id = "1"
562
 
        flavor_bookmark = "http://localhost/flavors/1"
 
578
        flavor_bookmark = "http://localhost/fake/flavors/1"
563
579
        private_ip = "192.168.0.3"
564
580
        public_ip = "1.2.3.4"
565
581
 
582
598
            flavor_id=flavor_id)
583
599
        self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
584
600
 
585
 
        req = webob.Request.blank('/v1.1/servers/1')
 
601
        req = webob.Request.blank('/v1.1/fake/servers/1')
586
602
        res = req.get_response(fakes.wsgi_app())
587
603
        res_dict = json.loads(res.body)
588
604
        expected_server = {
594
610
                "progress": 100,
595
611
                "name": "server1",
596
612
                "status": "ACTIVE",
 
613
                "accessIPv4": "",
 
614
                "accessIPv6": "",
597
615
                "hostId": '',
598
616
                "key_name": '',
599
617
                "image": {
631
649
                "metadata": {
632
650
                    "seq": "1",
633
651
                },
 
652
                "config_drive": None,
634
653
                "links": [
635
654
                    {
636
655
                        "rel": "self",
637
 
                        "href": "http://localhost/v1.1/servers/1",
 
656
                        "href": "http://localhost/v1.1/fake/servers/1",
638
657
                    },
639
658
                    {
640
659
                        "rel": "bookmark",
641
 
                        "href": "http://localhost/servers/1",
 
660
                        "href": "http://localhost/fake/servers/1",
642
661
                    },
643
662
                ],
644
663
            }
760
779
        (ip,) = private_node.getElementsByTagName('ip')
761
780
        self.assertEquals(ip.getAttribute('addr'), private)
762
781
 
 
782
    # NOTE(bcwaldon): lp830817
 
783
    def test_get_server_by_id_malformed_networks_v1_1(self):
 
784
        ifaces = [
 
785
            {
 
786
                'network': None,
 
787
                'fixed_ips': [
 
788
                    {'address': '192.168.0.3'},
 
789
                    {'address': '192.168.0.4'},
 
790
                ],
 
791
            },
 
792
        ]
 
793
        new_return_server = return_server_with_attributes(interfaces=ifaces)
 
794
        self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
 
795
 
 
796
        req = webob.Request.blank('/v1.1/fake/servers/1')
 
797
        res = req.get_response(fakes.wsgi_app())
 
798
        self.assertEqual(res.status_int, 200)
 
799
        res_dict = json.loads(res.body)
 
800
        self.assertEqual(res_dict['server']['id'], 1)
 
801
        self.assertEqual(res_dict['server']['name'], 'server1')
 
802
 
763
803
    def test_get_server_by_id_with_addresses_v1_1(self):
764
804
        self.flags(use_ipv6=True)
765
805
        interfaces = [
783
823
            interfaces=interfaces)
784
824
        self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
785
825
 
786
 
        req = webob.Request.blank('/v1.1/servers/1')
 
826
        req = webob.Request.blank('/v1.1/fake/servers/1')
787
827
        res = req.get_response(fakes.wsgi_app())
788
828
 
789
829
        res_dict = json.loads(res.body)
827
867
            interfaces=interfaces)
828
868
        self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
829
869
 
830
 
        req = webob.Request.blank('/v1.1/servers/1')
 
870
        req = webob.Request.blank('/v1.1/fake/servers/1')
831
871
        res = req.get_response(fakes.wsgi_app())
832
872
 
833
873
        res_dict = json.loads(res.body)
877
917
                       'virtual_interface_get_by_instance',
878
918
                       _return_vifs)
879
919
 
880
 
        req = webob.Request.blank('/v1.1/servers/1/ips')
 
920
        req = webob.Request.blank('/v1.1/fake/servers/1/ips')
881
921
        res = req.get_response(fakes.wsgi_app())
882
922
        res_dict = json.loads(res.body)
883
923
 
927
967
                       'virtual_interface_get_by_instance',
928
968
                       _return_vifs)
929
969
 
930
 
        req = webob.Request.blank('/v1.1/servers/1/ips/network_2')
 
970
        req = webob.Request.blank('/v1.1/fake/servers/1/ips/network_2')
931
971
        res = req.get_response(fakes.wsgi_app())
932
972
        self.assertEqual(res.status_int, 200)
933
973
        res_dict = json.loads(res.body)
947
987
                       'virtual_interface_get_by_instance',
948
988
                       _return_vifs)
949
989
 
950
 
        req = webob.Request.blank('/v1.1/servers/1/ips/network_0')
 
990
        req = webob.Request.blank('/v1.1/fake/servers/1/ips/network_0')
951
991
        res = req.get_response(fakes.wsgi_app())
952
992
        self.assertEqual(res.status_int, 404)
953
993
 
957
997
                       'virtual_interface_get_by_instance',
958
998
                       _return_vifs)
959
999
 
960
 
        req = webob.Request.blank('/v1.1/servers/600/ips')
 
1000
        req = webob.Request.blank('/v1.1/fake/servers/600/ips')
961
1001
        res = req.get_response(fakes.wsgi_app())
962
1002
        self.assertEqual(res.status_int, 404)
963
1003
 
1026
1066
                i += 1
1027
1067
 
1028
1068
    def test_get_server_list_v1_1(self):
1029
 
        req = webob.Request.blank('/v1.1/servers')
 
1069
        req = webob.Request.blank('/v1.1/fake/servers')
1030
1070
        res = req.get_response(fakes.wsgi_app())
1031
1071
        res_dict = json.loads(res.body)
1032
1072
 
1039
1079
            expected_links = [
1040
1080
                {
1041
1081
                    "rel": "self",
1042
 
                    "href": "http://localhost/v1.1/servers/%s" % s['id'],
 
1082
                    "href": "http://localhost/v1.1/fake/servers/%s" % s['id'],
1043
1083
                },
1044
1084
                {
1045
1085
                    "rel": "bookmark",
1046
 
                    "href": "http://localhost/servers/%s" % s['id'],
 
1086
                    "href": "http://localhost/fake/servers/%s" % s['id'],
1047
1087
                },
1048
1088
            ]
1049
1089
 
1090
1130
        self.assertTrue(res.body.find('offset param') > -1)
1091
1131
 
1092
1132
    def test_get_servers_with_marker(self):
1093
 
        req = webob.Request.blank('/v1.1/servers?marker=2')
 
1133
        req = webob.Request.blank('/v1.1/fake/servers?marker=2')
1094
1134
        res = req.get_response(fakes.wsgi_app())
1095
1135
        servers = json.loads(res.body)['servers']
1096
1136
        self.assertEqual([s['name'] for s in servers], ["server3", "server4"])
1097
1137
 
1098
1138
    def test_get_servers_with_limit_and_marker(self):
1099
 
        req = webob.Request.blank('/v1.1/servers?limit=2&marker=1')
 
1139
        req = webob.Request.blank('/v1.1/fake/servers?limit=2&marker=1')
1100
1140
        res = req.get_response(fakes.wsgi_app())
1101
1141
        servers = json.loads(res.body)['servers']
1102
1142
        self.assertEqual([s['name'] for s in servers], ['server2', 'server3'])
1103
1143
 
1104
1144
    def test_get_servers_with_bad_marker(self):
1105
 
        req = webob.Request.blank('/v1.1/servers?limit=2&marker=asdf')
 
1145
        req = webob.Request.blank('/v1.1/fake/servers?limit=2&marker=asdf')
1106
1146
        res = req.get_response(fakes.wsgi_app())
1107
1147
        self.assertEqual(res.status_int, 400)
1108
1148
        self.assertTrue(res.body.find('marker param') > -1)
1128
1168
 
1129
1169
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1130
1170
 
1131
 
        req = webob.Request.blank('/v1.1/servers?unknownoption=whee')
 
1171
        req = webob.Request.blank('/v1.1/fake/servers?unknownoption=whee')
1132
1172
        res = req.get_response(fakes.wsgi_app())
1133
1173
        self.assertEqual(res.status_int, 200)
1134
1174
        servers = json.loads(res.body)['servers']
1145
1185
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1146
1186
        self.flags(allow_admin_api=False)
1147
1187
 
1148
 
        req = webob.Request.blank('/v1.1/servers?image=12345')
 
1188
        req = webob.Request.blank('/v1.1/fake/servers?image=12345')
1149
1189
        res = req.get_response(fakes.wsgi_app())
1150
1190
        # The following assert will fail if either of the asserts in
1151
1191
        # fake_get_all() fail
1165
1205
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1166
1206
        self.flags(allow_admin_api=False)
1167
1207
 
1168
 
        req = webob.Request.blank('/v1.1/servers?flavor=12345')
 
1208
        req = webob.Request.blank('/v1.1/fake/servers?flavor=12345')
1169
1209
        res = req.get_response(fakes.wsgi_app())
1170
1210
        # The following assert will fail if either of the asserts in
1171
1211
        # fake_get_all() fail
1185
1225
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1186
1226
        self.flags(allow_admin_api=False)
1187
1227
 
1188
 
        req = webob.Request.blank('/v1.1/servers?status=active')
 
1228
        req = webob.Request.blank('/v1.1/fake/servers?status=active')
1189
1229
        res = req.get_response(fakes.wsgi_app())
1190
1230
        # The following assert will fail if either of the asserts in
1191
1231
        # fake_get_all() fail
1199
1239
 
1200
1240
        self.flags(allow_admin_api=False)
1201
1241
 
1202
 
        req = webob.Request.blank('/v1.1/servers?status=running')
 
1242
        req = webob.Request.blank('/v1.1/fake/servers?status=running')
1203
1243
        res = req.get_response(fakes.wsgi_app())
1204
1244
        # The following assert will fail if either of the asserts in
1205
1245
        # fake_get_all() fail
1216
1256
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1217
1257
        self.flags(allow_admin_api=False)
1218
1258
 
1219
 
        req = webob.Request.blank('/v1.1/servers?name=whee.*')
 
1259
        req = webob.Request.blank('/v1.1/fake/servers?name=whee.*')
1220
1260
        res = req.get_response(fakes.wsgi_app())
1221
1261
        # The following assert will fail if either of the asserts in
1222
1262
        # fake_get_all() fail
1247
1287
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1248
1288
 
1249
1289
        query_str = "name=foo&ip=10.*&status=active&unknown_option=meow"
1250
 
        req = webob.Request.blank('/v1.1/servers?%s' % query_str)
 
1290
        req = webob.Request.blank('/v1.1/fake/servers?%s' % query_str)
1251
1291
        # Request admin context
1252
1292
        context = nova.context.RequestContext('testuser', 'testproject',
1253
1293
                is_admin=True)
1281
1321
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1282
1322
 
1283
1323
        query_str = "name=foo&ip=10.*&status=active&unknown_option=meow"
1284
 
        req = webob.Request.blank('/v1.1/servers?%s' % query_str)
 
1324
        req = webob.Request.blank('/v1.1/fake/servers?%s' % query_str)
1285
1325
        # Request admin context
1286
1326
        context = nova.context.RequestContext('testuser', 'testproject',
1287
1327
                is_admin=False)
1314
1354
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1315
1355
 
1316
1356
        query_str = "name=foo&ip=10.*&status=active&unknown_option=meow"
1317
 
        req = webob.Request.blank('/v1.1/servers?%s' % query_str)
 
1357
        req = webob.Request.blank('/v1.1/fake/servers?%s' % query_str)
1318
1358
        # Request admin context
1319
1359
        context = nova.context.RequestContext('testuser', 'testproject',
1320
1360
                is_admin=True)
1340
1380
 
1341
1381
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1342
1382
 
1343
 
        req = webob.Request.blank('/v1.1/servers?ip=10\..*')
 
1383
        req = webob.Request.blank('/v1.1/fake/servers?ip=10\..*')
1344
1384
        # Request admin context
1345
1385
        context = nova.context.RequestContext('testuser', 'testproject',
1346
1386
                is_admin=True)
1366
1406
 
1367
1407
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
1368
1408
 
1369
 
        req = webob.Request.blank('/v1.1/servers?ip6=ffff.*')
 
1409
        req = webob.Request.blank('/v1.1/fake/servers?ip6=ffff.*')
1370
1410
        # Request admin context
1371
1411
        context = nova.context.RequestContext('testuser', 'testproject',
1372
1412
                is_admin=True)
1387
1427
                    'display_name': 'server_test',
1388
1428
                    'uuid': FAKE_UUID,
1389
1429
                    'instance_type': dict(inst_type),
 
1430
                    'access_ip_v4': '1.2.3.4',
 
1431
                    'access_ip_v6': 'fead::1234',
1390
1432
                    'image_ref': image_ref,
1391
1433
                    "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0),
1392
1434
                    "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0),
 
1435
                    "config_drive": self.config_drive,
1393
1436
                   }
1394
1437
 
1395
1438
        def server_update(context, id, params):
1415
1458
        self.stubs.Set(nova.db.api, 'instance_create', instance_create)
1416
1459
        self.stubs.Set(nova.rpc, 'cast', fake_method)
1417
1460
        self.stubs.Set(nova.rpc, 'call', fake_method)
1418
 
        self.stubs.Set(nova.db.api, 'instance_update',
1419
 
            server_update)
 
1461
        self.stubs.Set(nova.db.api, 'instance_update', server_update)
1420
1462
        self.stubs.Set(nova.db.api, 'queue_get_for', queue_get_for)
1421
1463
        self.stubs.Set(nova.network.manager.VlanManager, 'allocate_fixed_ip',
1422
1464
            fake_method)
1587
1629
        res = req.get_response(fakes.wsgi_app())
1588
1630
        self.assertEqual(res.status_int, 400)
1589
1631
 
 
1632
    def test_create_instance_with_access_ip_v1_1(self):
 
1633
        self._setup_for_create_instance()
 
1634
 
 
1635
        # proper local hrefs must start with 'http://localhost/v1.1/'
 
1636
        image_href = 'http://localhost/v1.1/123/images/2'
 
1637
        flavor_ref = 'http://localhost/123/flavors/3'
 
1638
        access_ipv4 = '1.2.3.4'
 
1639
        access_ipv6 = 'fead::1234'
 
1640
        expected_flavor = {
 
1641
            "id": "3",
 
1642
            "links": [
 
1643
                {
 
1644
                    "rel": "bookmark",
 
1645
                    "href": 'http://localhost/123/flavors/3',
 
1646
                },
 
1647
            ],
 
1648
        }
 
1649
        expected_image = {
 
1650
            "id": "2",
 
1651
            "links": [
 
1652
                {
 
1653
                    "rel": "bookmark",
 
1654
                    "href": 'http://localhost/123/images/2',
 
1655
                },
 
1656
            ],
 
1657
        }
 
1658
        body = {
 
1659
            'server': {
 
1660
                'name': 'server_test',
 
1661
                'imageRef': image_href,
 
1662
                'flavorRef': flavor_ref,
 
1663
                'accessIPv4': access_ipv4,
 
1664
                'accessIPv6': access_ipv6,
 
1665
                'metadata': {
 
1666
                    'hello': 'world',
 
1667
                    'open': 'stack',
 
1668
                },
 
1669
                'personality': [
 
1670
                    {
 
1671
                        "path": "/etc/banner.txt",
 
1672
                        "contents": "MQ==",
 
1673
                    },
 
1674
                ],
 
1675
            },
 
1676
        }
 
1677
 
 
1678
        req = webob.Request.blank('/v1.1/123/servers')
 
1679
        req.method = 'POST'
 
1680
        req.body = json.dumps(body)
 
1681
        req.headers["content-type"] = "application/json"
 
1682
 
 
1683
        res = req.get_response(fakes.wsgi_app())
 
1684
 
 
1685
        self.assertEqual(res.status_int, 202)
 
1686
        server = json.loads(res.body)['server']
 
1687
        self.assertEqual(16, len(server['adminPass']))
 
1688
        self.assertEqual(1, server['id'])
 
1689
        self.assertEqual(0, server['progress'])
 
1690
        self.assertEqual('server_test', server['name'])
 
1691
        self.assertEqual(expected_flavor, server['flavor'])
 
1692
        self.assertEqual(expected_image, server['image'])
 
1693
        self.assertEqual(access_ipv4, server['accessIPv4'])
 
1694
        self.assertEqual(access_ipv6, server['accessIPv6'])
 
1695
 
1590
1696
    def test_create_instance_v1_1(self):
1591
1697
        self._setup_for_create_instance()
1592
1698
 
1593
1699
        # proper local hrefs must start with 'http://localhost/v1.1/'
1594
1700
        image_href = 'http://localhost/v1.1/images/2'
1595
 
        flavor_ref = 'http://localhost/flavors/3'
 
1701
        flavor_ref = 'http://localhost/123/flavors/3'
1596
1702
        expected_flavor = {
1597
1703
            "id": "3",
1598
1704
            "links": [
1599
1705
                {
1600
1706
                    "rel": "bookmark",
1601
 
                    "href": 'http://localhost/flavors/3',
 
1707
                    "href": 'http://localhost/fake/flavors/3',
1602
1708
                },
1603
1709
            ],
1604
1710
        }
1607
1713
            "links": [
1608
1714
                {
1609
1715
                    "rel": "bookmark",
1610
 
                    "href": 'http://localhost/images/2',
 
1716
                    "href": 'http://localhost/fake/images/2',
1611
1717
                },
1612
1718
            ],
1613
1719
        }
1629
1735
            },
1630
1736
        }
1631
1737
 
1632
 
        req = webob.Request.blank('/v1.1/servers')
 
1738
        req = webob.Request.blank('/v1.1/fake/servers')
1633
1739
        req.method = 'POST'
1634
1740
        req.body = json.dumps(body)
1635
1741
        req.headers["content-type"] = "application/json"
1644
1750
        self.assertEqual('server_test', server['name'])
1645
1751
        self.assertEqual(expected_flavor, server['flavor'])
1646
1752
        self.assertEqual(expected_image, server['image'])
 
1753
        self.assertEqual('1.2.3.4', server['accessIPv4'])
 
1754
        self.assertEqual('fead::1234', server['accessIPv6'])
1647
1755
 
1648
1756
    def test_create_instance_v1_1_invalid_key_name(self):
1649
1757
        self._setup_for_create_instance()
1689
1797
            name='server_test', imageRef=image_href, flavorRef=flavor_ref,
1690
1798
            metadata={'hello': 'world', 'open': 'stack'},
1691
1799
            personality={}))
1692
 
        req = webob.Request.blank('/v1.1/servers')
 
1800
        req = webob.Request.blank('/v1.1/fake/servers')
1693
1801
        req.method = 'POST'
1694
1802
        req.body = json.dumps(body)
1695
1803
        req.headers["content-type"] = "application/json"
1699
1807
    def test_create_instance_v1_1_invalid_flavor_id_int(self):
1700
1808
        self._setup_for_create_instance()
1701
1809
 
1702
 
        image_href = 'http://localhost/v1.1/images/2'
 
1810
        image_href = 'http://localhost/v1.1/123/images/2'
1703
1811
        flavor_ref = -1
1704
1812
        body = dict(server=dict(
1705
1813
            name='server_test', imageRef=image_href, flavorRef=flavor_ref,
1706
1814
            metadata={'hello': 'world', 'open': 'stack'},
1707
1815
            personality={}))
1708
 
        req = webob.Request.blank('/v1.1/servers')
 
1816
        req = webob.Request.blank('/v1.1/123/servers')
1709
1817
        req.method = 'POST'
1710
1818
        req.body = json.dumps(body)
1711
1819
        req.headers["content-type"] = "application/json"
1721
1829
            name='server_test', imageRef=image_href, flavorRef=flavor_ref,
1722
1830
            metadata={'hello': 'world', 'open': 'stack'},
1723
1831
            personality={}))
1724
 
        req = webob.Request.blank('/v1.1/servers')
1725
 
        req.method = 'POST'
1726
 
        req.body = json.dumps(body)
1727
 
        req.headers["content-type"] = "application/json"
1728
 
        res = req.get_response(fakes.wsgi_app())
1729
 
        self.assertEqual(res.status_int, 400)
 
1832
        req = webob.Request.blank('/v1.1/fake/servers')
 
1833
        req.method = 'POST'
 
1834
        req.body = json.dumps(body)
 
1835
        req.headers["content-type"] = "application/json"
 
1836
        res = req.get_response(fakes.wsgi_app())
 
1837
        self.assertEqual(res.status_int, 400)
 
1838
 
 
1839
    def test_create_instance_with_config_drive_v1_1(self):
 
1840
        self.config_drive = True
 
1841
        self._setup_for_create_instance()
 
1842
 
 
1843
        image_href = 'http://localhost/v1.1/123/images/2'
 
1844
        flavor_ref = 'http://localhost/v1.1/123/flavors/3'
 
1845
        body = {
 
1846
            'server': {
 
1847
                'name': 'config_drive_test',
 
1848
                'imageRef': image_href,
 
1849
                'flavorRef': flavor_ref,
 
1850
                'metadata': {
 
1851
                    'hello': 'world',
 
1852
                    'open': 'stack',
 
1853
                },
 
1854
                'personality': {},
 
1855
                'config_drive': True,
 
1856
            },
 
1857
        }
 
1858
 
 
1859
        req = webob.Request.blank('/v1.1/123/servers')
 
1860
        req.method = 'POST'
 
1861
        req.body = json.dumps(body)
 
1862
        req.headers["content-type"] = "application/json"
 
1863
 
 
1864
        res = req.get_response(fakes.wsgi_app())
 
1865
        print res
 
1866
        self.assertEqual(res.status_int, 202)
 
1867
        server = json.loads(res.body)['server']
 
1868
        self.assertEqual(1, server['id'])
 
1869
        self.assertTrue(server['config_drive'])
 
1870
 
 
1871
    def test_create_instance_with_config_drive_as_id_v1_1(self):
 
1872
        self.config_drive = 2
 
1873
        self._setup_for_create_instance()
 
1874
 
 
1875
        image_href = 'http://localhost/v1.1/123/images/2'
 
1876
        flavor_ref = 'http://localhost/v1.1/123/flavors/3'
 
1877
        body = {
 
1878
            'server': {
 
1879
                'name': 'config_drive_test',
 
1880
                'imageRef': image_href,
 
1881
                'flavorRef': flavor_ref,
 
1882
                'metadata': {
 
1883
                    'hello': 'world',
 
1884
                    'open': 'stack',
 
1885
                },
 
1886
                'personality': {},
 
1887
                'config_drive': 2,
 
1888
            },
 
1889
        }
 
1890
 
 
1891
        req = webob.Request.blank('/v1.1/123/servers')
 
1892
        req.method = 'POST'
 
1893
        req.body = json.dumps(body)
 
1894
        req.headers["content-type"] = "application/json"
 
1895
 
 
1896
        res = req.get_response(fakes.wsgi_app())
 
1897
 
 
1898
        self.assertEqual(res.status_int, 202)
 
1899
        server = json.loads(res.body)['server']
 
1900
        self.assertEqual(1, server['id'])
 
1901
        self.assertTrue(server['config_drive'])
 
1902
        self.assertEqual(2, server['config_drive'])
 
1903
 
 
1904
    def test_create_instance_with_bad_config_drive_v1_1(self):
 
1905
        self.config_drive = "asdf"
 
1906
        self._setup_for_create_instance()
 
1907
 
 
1908
        image_href = 'http://localhost/v1.1/123/images/2'
 
1909
        flavor_ref = 'http://localhost/v1.1/123/flavors/3'
 
1910
        body = {
 
1911
            'server': {
 
1912
                'name': 'config_drive_test',
 
1913
                'imageRef': image_href,
 
1914
                'flavorRef': flavor_ref,
 
1915
                'metadata': {
 
1916
                    'hello': 'world',
 
1917
                    'open': 'stack',
 
1918
                },
 
1919
                'personality': {},
 
1920
                'config_drive': 'asdf',
 
1921
            },
 
1922
        }
 
1923
 
 
1924
        req = webob.Request.blank('/v1.1/123/servers')
 
1925
        req.method = 'POST'
 
1926
        req.body = json.dumps(body)
 
1927
        req.headers["content-type"] = "application/json"
 
1928
 
 
1929
        res = req.get_response(fakes.wsgi_app())
 
1930
        self.assertEqual(res.status_int, 400)
 
1931
 
 
1932
    def test_create_instance_without_config_drive_v1_1(self):
 
1933
        self._setup_for_create_instance()
 
1934
 
 
1935
        image_href = 'http://localhost/v1.1/123/images/2'
 
1936
        flavor_ref = 'http://localhost/v1.1/123/flavors/3'
 
1937
        body = {
 
1938
            'server': {
 
1939
                'name': 'config_drive_test',
 
1940
                'imageRef': image_href,
 
1941
                'flavorRef': flavor_ref,
 
1942
                'metadata': {
 
1943
                    'hello': 'world',
 
1944
                    'open': 'stack',
 
1945
                },
 
1946
                'personality': {},
 
1947
                'config_drive': True,
 
1948
            },
 
1949
        }
 
1950
 
 
1951
        req = webob.Request.blank('/v1.1/123/servers')
 
1952
        req.method = 'POST'
 
1953
        req.body = json.dumps(body)
 
1954
        req.headers["content-type"] = "application/json"
 
1955
 
 
1956
        res = req.get_response(fakes.wsgi_app())
 
1957
        self.assertEqual(res.status_int, 202)
 
1958
        server = json.loads(res.body)['server']
 
1959
        self.assertEqual(1, server['id'])
 
1960
        self.assertFalse(server['config_drive'])
1730
1961
 
1731
1962
    def test_create_instance_v1_1_bad_href(self):
1732
1963
        self._setup_for_create_instance()
1737
1968
            name='server_test', imageRef=image_href, flavorRef=flavor_ref,
1738
1969
            metadata={'hello': 'world', 'open': 'stack'},
1739
1970
            personality={}))
1740
 
        req = webob.Request.blank('/v1.1/servers')
 
1971
        req = webob.Request.blank('/v1.1/fake/servers')
1741
1972
        req.method = 'POST'
1742
1973
        req.body = json.dumps(body)
1743
1974
        req.headers["content-type"] = "application/json"
1754
1985
            "links": [
1755
1986
                {
1756
1987
                    "rel": "bookmark",
1757
 
                    "href": 'http://localhost/flavors/3',
 
1988
                    "href": 'http://localhost/fake/flavors/3',
1758
1989
                },
1759
1990
            ],
1760
1991
        }
1763
1994
            "links": [
1764
1995
                {
1765
1996
                    "rel": "bookmark",
1766
 
                    "href": 'http://localhost/images/2',
 
1997
                    "href": 'http://localhost/fake/images/2',
1767
1998
                },
1768
1999
            ],
1769
2000
        }
1775
2006
            },
1776
2007
        }
1777
2008
 
1778
 
        req = webob.Request.blank('/v1.1/servers')
 
2009
        req = webob.Request.blank('/v1.1/fake/servers')
1779
2010
        req.method = 'POST'
1780
2011
        req.body = json.dumps(body)
1781
2012
        req.headers["content-type"] = "application/json"
1822
2053
            },
1823
2054
        }
1824
2055
 
1825
 
        req = webob.Request.blank('/v1.1/servers')
 
2056
        req = webob.Request.blank('/v1.1/fake/servers')
1826
2057
        req.method = 'POST'
1827
2058
        req.body = json.dumps(body)
1828
2059
        req.headers['content-type'] = "application/json"
1843
2074
            },
1844
2075
        }
1845
2076
 
1846
 
        req = webob.Request.blank('/v1.1/servers')
 
2077
        req = webob.Request.blank('/v1.1/fake/servers')
1847
2078
        req.method = 'POST'
1848
2079
        req.body = json.dumps(body)
1849
2080
        req.headers['content-type'] = "application/json"
1850
2081
        res = req.get_response(fakes.wsgi_app())
1851
2082
        self.assertEqual(res.status_int, 400)
1852
2083
 
 
2084
    def test_create_instance_whitespace_name(self):
 
2085
        self._setup_for_create_instance()
 
2086
 
 
2087
        body = {
 
2088
            'server': {
 
2089
                'name': '    ',
 
2090
                'imageId': 3,
 
2091
                'flavorId': 1,
 
2092
                'metadata': {
 
2093
                    'hello': 'world',
 
2094
                    'open': 'stack',
 
2095
                },
 
2096
                'personality': {},
 
2097
            },
 
2098
        }
 
2099
 
 
2100
        req = webob.Request.blank('/v1.0/servers')
 
2101
        req.method = 'POST'
 
2102
        req.body = json.dumps(body)
 
2103
        req.headers["content-type"] = "application/json"
 
2104
        res = req.get_response(fakes.wsgi_app())
 
2105
        self.assertEqual(res.status_int, 400)
 
2106
 
1853
2107
    def test_update_server_no_body(self):
1854
2108
        req = webob.Request.blank('/v1.0/servers/1')
1855
2109
        req.method = 'PUT'
1917
2171
        self.assertEqual(mock_method.password, 'bacon')
1918
2172
 
1919
2173
    def test_update_server_no_body_v1_1(self):
1920
 
        req = webob.Request.blank('/v1.0/servers/1')
 
2174
        req = webob.Request.blank('/v1.1/fake/servers/1')
1921
2175
        req.method = 'PUT'
1922
2176
        res = req.get_response(fakes.wsgi_app())
1923
2177
        self.assertEqual(res.status_int, 400)
1924
2178
 
 
2179
    def test_update_server_all_attributes_v1_1(self):
 
2180
        self.stubs.Set(nova.db.api, 'instance_get',
 
2181
                return_server_with_attributes(name='server_test',
 
2182
                                              access_ipv4='0.0.0.0',
 
2183
                                              access_ipv6='beef::0123'))
 
2184
        req = webob.Request.blank('/v1.1/123/servers/1')
 
2185
        req.method = 'PUT'
 
2186
        req.content_type = 'application/json'
 
2187
        body = {'server': {
 
2188
                  'name': 'server_test',
 
2189
                  'accessIPv4': '0.0.0.0',
 
2190
                  'accessIPv6': 'beef::0123',
 
2191
               }}
 
2192
        req.body = json.dumps(body)
 
2193
        res = req.get_response(fakes.wsgi_app())
 
2194
        self.assertEqual(res.status_int, 200)
 
2195
        res_dict = json.loads(res.body)
 
2196
        self.assertEqual(res_dict['server']['id'], 1)
 
2197
        self.assertEqual(res_dict['server']['name'], 'server_test')
 
2198
        self.assertEqual(res_dict['server']['accessIPv4'], '0.0.0.0')
 
2199
        self.assertEqual(res_dict['server']['accessIPv6'], 'beef::0123')
 
2200
 
1925
2201
    def test_update_server_name_v1_1(self):
1926
2202
        self.stubs.Set(nova.db.api, 'instance_get',
1927
2203
                return_server_with_attributes(name='server_test'))
1928
 
        req = webob.Request.blank('/v1.1/servers/1')
 
2204
        req = webob.Request.blank('/v1.1/fake/servers/1')
1929
2205
        req.method = 'PUT'
1930
2206
        req.content_type = 'application/json'
1931
2207
        req.body = json.dumps({'server': {'name': 'server_test'}})
1935
2211
        self.assertEqual(res_dict['server']['id'], 1)
1936
2212
        self.assertEqual(res_dict['server']['name'], 'server_test')
1937
2213
 
 
2214
    def test_update_server_access_ipv4_v1_1(self):
 
2215
        self.stubs.Set(nova.db.api, 'instance_get',
 
2216
                return_server_with_attributes(access_ipv4='0.0.0.0'))
 
2217
        req = webob.Request.blank('/v1.1/123/servers/1')
 
2218
        req.method = 'PUT'
 
2219
        req.content_type = 'application/json'
 
2220
        req.body = json.dumps({'server': {'accessIPv4': '0.0.0.0'}})
 
2221
        res = req.get_response(fakes.wsgi_app())
 
2222
        self.assertEqual(res.status_int, 200)
 
2223
        res_dict = json.loads(res.body)
 
2224
        self.assertEqual(res_dict['server']['id'], 1)
 
2225
        self.assertEqual(res_dict['server']['accessIPv4'], '0.0.0.0')
 
2226
 
 
2227
    def test_update_server_access_ipv6_v1_1(self):
 
2228
        self.stubs.Set(nova.db.api, 'instance_get',
 
2229
                return_server_with_attributes(access_ipv6='beef::0123'))
 
2230
        req = webob.Request.blank('/v1.1/123/servers/1')
 
2231
        req.method = 'PUT'
 
2232
        req.content_type = 'application/json'
 
2233
        req.body = json.dumps({'server': {'accessIPv6': 'beef::0123'}})
 
2234
        res = req.get_response(fakes.wsgi_app())
 
2235
        self.assertEqual(res.status_int, 200)
 
2236
        res_dict = json.loads(res.body)
 
2237
        self.assertEqual(res_dict['server']['id'], 1)
 
2238
        self.assertEqual(res_dict['server']['accessIPv6'], 'beef::0123')
 
2239
 
1938
2240
    def test_update_server_adminPass_ignored_v1_1(self):
1939
2241
        inst_dict = dict(name='server_test', adminPass='bacon')
1940
2242
        self.body = json.dumps(dict(server=inst_dict))
1948
2250
        self.stubs.Set(nova.db.api, 'instance_get',
1949
2251
                return_server_with_attributes(name='server_test'))
1950
2252
 
1951
 
        req = webob.Request.blank('/v1.1/servers/1')
 
2253
        req = webob.Request.blank('/v1.1/fake/servers/1')
1952
2254
        req.method = 'PUT'
1953
2255
        req.content_type = "application/json"
1954
2256
        req.body = self.body
1981
2283
        self.assertEqual(res.status_int, 501)
1982
2284
 
1983
2285
    def test_server_backup_schedule_deprecated_v1_1(self):
1984
 
        req = webob.Request.blank('/v1.1/servers/1/backup_schedule')
 
2286
        req = webob.Request.blank('/v1.1/fake/servers/1/backup_schedule')
1985
2287
        res = req.get_response(fakes.wsgi_app())
1986
2288
        self.assertEqual(res.status_int, 404)
1987
2289
 
2021
2323
            "links": [
2022
2324
                {
2023
2325
                    "rel": "bookmark",
2024
 
                    "href": 'http://localhost/flavors/1',
 
2326
                    "href": 'http://localhost/fake/flavors/1',
2025
2327
                },
2026
2328
            ],
2027
2329
        }
2030
2332
            "links": [
2031
2333
                {
2032
2334
                    "rel": "bookmark",
2033
 
                    "href": 'http://localhost/images/10',
 
2335
                    "href": 'http://localhost/fake/images/10',
2034
2336
                },
2035
2337
            ],
2036
2338
        }
2037
 
        req = webob.Request.blank('/v1.1/servers/detail')
 
2339
        req = webob.Request.blank('/v1.1/fake/servers/detail')
2038
2340
        res = req.get_response(fakes.wsgi_app())
2039
2341
        res_dict = json.loads(res.body)
2040
2342
 
2193
2495
        self.assertEqual(res.status_int, 422)
2194
2496
 
2195
2497
    def test_delete_server_instance_v1_1(self):
2196
 
        req = webob.Request.blank('/v1.1/servers/1')
 
2498
        req = webob.Request.blank('/v1.1/fake/servers/1')
2197
2499
        req.method = 'DELETE'
2198
2500
 
2199
2501
        self.server_delete_called = False
2534
2836
        }
2535
2837
        self.assertEquals(request['body'], expected)
2536
2838
 
 
2839
    def test_access_ipv4(self):
 
2840
        serial_request = """
 
2841
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
2842
        name="new-server-test"
 
2843
        imageRef="1"
 
2844
        flavorRef="2"
 
2845
        accessIPv4="1.2.3.4"/>"""
 
2846
        request = self.deserializer.deserialize(serial_request, 'create')
 
2847
        expected = {
 
2848
            "server": {
 
2849
                "name": "new-server-test",
 
2850
                "imageRef": "1",
 
2851
                "flavorRef": "2",
 
2852
                "accessIPv4": "1.2.3.4",
 
2853
            },
 
2854
        }
 
2855
        self.assertEquals(request['body'], expected)
 
2856
 
 
2857
    def test_access_ipv6(self):
 
2858
        serial_request = """
 
2859
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
2860
        name="new-server-test"
 
2861
        imageRef="1"
 
2862
        flavorRef="2"
 
2863
        accessIPv6="fead::1234"/>"""
 
2864
        request = self.deserializer.deserialize(serial_request, 'create')
 
2865
        expected = {
 
2866
            "server": {
 
2867
                "name": "new-server-test",
 
2868
                "imageRef": "1",
 
2869
                "flavorRef": "2",
 
2870
                "accessIPv6": "fead::1234",
 
2871
            },
 
2872
        }
 
2873
        self.assertEquals(request['body'], expected)
 
2874
 
 
2875
    def test_access_ip(self):
 
2876
        serial_request = """
 
2877
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
2878
        name="new-server-test"
 
2879
        imageRef="1"
 
2880
        flavorRef="2"
 
2881
        accessIPv4="1.2.3.4"
 
2882
        accessIPv6="fead::1234"/>"""
 
2883
        request = self.deserializer.deserialize(serial_request, 'create')
 
2884
        expected = {
 
2885
            "server": {
 
2886
                "name": "new-server-test",
 
2887
                "imageRef": "1",
 
2888
                "flavorRef": "2",
 
2889
                "accessIPv4": "1.2.3.4",
 
2890
                "accessIPv6": "fead::1234",
 
2891
            },
 
2892
        }
 
2893
        self.assertEquals(request['body'], expected)
 
2894
 
2537
2895
    def test_admin_pass(self):
2538
2896
        serial_request = """
2539
2897
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
2685
3043
        }
2686
3044
        self.assertEquals(request['body'], expected)
2687
3045
 
 
3046
    def test_request_with_empty_networks(self):
 
3047
        serial_request = """
 
3048
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
3049
 name="new-server-test" imageRef="1" flavorRef="1">
 
3050
    <networks/>
 
3051
</server>"""
 
3052
        request = self.deserializer.deserialize(serial_request, 'create')
 
3053
        expected = {"server": {
 
3054
                "name": "new-server-test",
 
3055
                "imageRef": "1",
 
3056
                "flavorRef": "1",
 
3057
                "networks": []
 
3058
                }}
 
3059
        self.assertEquals(request['body'], expected)
 
3060
 
 
3061
    def test_request_with_one_network(self):
 
3062
        serial_request = """
 
3063
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
3064
 name="new-server-test" imageRef="1" flavorRef="1">
 
3065
    <networks>
 
3066
       <network uuid="1" fixed_ip="10.0.1.12"/>
 
3067
    </networks>
 
3068
</server>"""
 
3069
        request = self.deserializer.deserialize(serial_request, 'create')
 
3070
        expected = {"server": {
 
3071
                "name": "new-server-test",
 
3072
                "imageRef": "1",
 
3073
                "flavorRef": "1",
 
3074
                "networks": [{"uuid": "1", "fixed_ip": "10.0.1.12"}],
 
3075
                }}
 
3076
        self.assertEquals(request['body'], expected)
 
3077
 
 
3078
    def test_request_with_two_networks(self):
 
3079
        serial_request = """
 
3080
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
3081
 name="new-server-test" imageRef="1" flavorRef="1">
 
3082
    <networks>
 
3083
       <network uuid="1" fixed_ip="10.0.1.12"/>
 
3084
       <network uuid="2" fixed_ip="10.0.2.12"/>
 
3085
    </networks>
 
3086
</server>"""
 
3087
        request = self.deserializer.deserialize(serial_request, 'create')
 
3088
        expected = {"server": {
 
3089
                "name": "new-server-test",
 
3090
                "imageRef": "1",
 
3091
                "flavorRef": "1",
 
3092
                "networks": [{"uuid": "1", "fixed_ip": "10.0.1.12"},
 
3093
                             {"uuid": "2", "fixed_ip": "10.0.2.12"}],
 
3094
                }}
 
3095
        self.assertEquals(request['body'], expected)
 
3096
 
 
3097
    def test_request_with_second_network_node_ignored(self):
 
3098
        serial_request = """
 
3099
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
3100
 name="new-server-test" imageRef="1" flavorRef="1">
 
3101
    <networks>
 
3102
       <network uuid="1" fixed_ip="10.0.1.12"/>
 
3103
    </networks>
 
3104
    <networks>
 
3105
       <network uuid="2" fixed_ip="10.0.2.12"/>
 
3106
    </networks>
 
3107
</server>"""
 
3108
        request = self.deserializer.deserialize(serial_request, 'create')
 
3109
        expected = {"server": {
 
3110
                "name": "new-server-test",
 
3111
                "imageRef": "1",
 
3112
                "flavorRef": "1",
 
3113
                "networks": [{"uuid": "1", "fixed_ip": "10.0.1.12"}],
 
3114
                }}
 
3115
        self.assertEquals(request['body'], expected)
 
3116
 
 
3117
    def test_request_with_one_network_missing_id(self):
 
3118
        serial_request = """
 
3119
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
3120
 name="new-server-test" imageRef="1" flavorRef="1">
 
3121
    <networks>
 
3122
       <network fixed_ip="10.0.1.12"/>
 
3123
    </networks>
 
3124
</server>"""
 
3125
        request = self.deserializer.deserialize(serial_request, 'create')
 
3126
        expected = {"server": {
 
3127
                "name": "new-server-test",
 
3128
                "imageRef": "1",
 
3129
                "flavorRef": "1",
 
3130
                "networks": [{"fixed_ip": "10.0.1.12"}],
 
3131
                }}
 
3132
        self.assertEquals(request['body'], expected)
 
3133
 
 
3134
    def test_request_with_one_network_missing_fixed_ip(self):
 
3135
        serial_request = """
 
3136
<server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
3137
 name="new-server-test" imageRef="1" flavorRef="1">
 
3138
    <networks>
 
3139
       <network uuid="1"/>
 
3140
    </networks>
 
3141
</server>"""
 
3142
        request = self.deserializer.deserialize(serial_request, 'create')
 
3143
        expected = {"server": {
 
3144
                "name": "new-server-test",
 
3145
                "imageRef": "1",
 
3146
                "flavorRef": "1",
 
3147
                "networks": [{"uuid": "1"}],
 
3148
                }}
 
3149
        self.assertEquals(request['body'], expected)
 
3150
 
 
3151
    def test_request_with_one_network_empty_id(self):
 
3152
        serial_request = """
 
3153
    <server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
3154
     name="new-server-test" imageRef="1" flavorRef="1">
 
3155
        <networks>
 
3156
           <network uuid="" fixed_ip="10.0.1.12"/>
 
3157
        </networks>
 
3158
    </server>"""
 
3159
        request = self.deserializer.deserialize(serial_request, 'create')
 
3160
        expected = {"server": {
 
3161
                "name": "new-server-test",
 
3162
                "imageRef": "1",
 
3163
                "flavorRef": "1",
 
3164
                "networks": [{"uuid": "", "fixed_ip": "10.0.1.12"}],
 
3165
                }}
 
3166
        self.assertEquals(request['body'], expected)
 
3167
 
 
3168
    def test_request_with_one_network_empty_fixed_ip(self):
 
3169
        serial_request = """
 
3170
    <server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
3171
     name="new-server-test" imageRef="1" flavorRef="1">
 
3172
        <networks>
 
3173
           <network uuid="1" fixed_ip=""/>
 
3174
        </networks>
 
3175
    </server>"""
 
3176
        request = self.deserializer.deserialize(serial_request, 'create')
 
3177
        expected = {"server": {
 
3178
                "name": "new-server-test",
 
3179
                "imageRef": "1",
 
3180
                "flavorRef": "1",
 
3181
                "networks": [{"uuid": "1", "fixed_ip": ""}],
 
3182
                }}
 
3183
        self.assertEquals(request['body'], expected)
 
3184
 
 
3185
    def test_request_with_networks_duplicate_ids(self):
 
3186
        serial_request = """
 
3187
    <server xmlns="http://docs.openstack.org/compute/api/v1.1"
 
3188
     name="new-server-test" imageRef="1" flavorRef="1">
 
3189
        <networks>
 
3190
           <network uuid="1" fixed_ip="10.0.1.12"/>
 
3191
           <network uuid="1" fixed_ip="10.0.2.12"/>
 
3192
        </networks>
 
3193
    </server>"""
 
3194
        request = self.deserializer.deserialize(serial_request, 'create')
 
3195
        expected = {"server": {
 
3196
                "name": "new-server-test",
 
3197
                "imageRef": "1",
 
3198
                "flavorRef": "1",
 
3199
                "networks": [{"uuid": "1", "fixed_ip": "10.0.1.12"},
 
3200
                             {"uuid": "1", "fixed_ip": "10.0.2.12"}],
 
3201
                }}
 
3202
        self.assertEquals(request['body'], expected)
 
3203
 
2688
3204
 
2689
3205
class TestAddressesXMLSerialization(test.TestCase):
2690
3206
 
2755
3271
 
2756
3272
            def __init__(self):
2757
3273
                self.injected_files = None
 
3274
                self.networks = None
2758
3275
 
2759
3276
            def create(self, *args, **kwargs):
2760
3277
                if 'injected_files' in kwargs:
2761
3278
                    self.injected_files = kwargs['injected_files']
2762
3279
                else:
2763
3280
                    self.injected_files = None
 
3281
 
2764
3282
                return [{'id': '1234', 'display_name': 'fakeinstance',
2765
3283
                         'uuid': FAKE_UUID}]
2766
3284
 
3082
3600
            "display_description": "",
3083
3601
            "locked": False,
3084
3602
            "metadata": [],
 
3603
            "accessIPv4": "1.2.3.4",
 
3604
            "accessIPv6": "fead::1234",
3085
3605
            #"address": ,
3086
3606
            #"floating_ips": [{"address":ip} for ip in public_addresses]}
3087
3607
            "uuid": "deadbeef-feed-edee-beef-d0ea7beefedd"}
3088
3608
 
3089
3609
        return instance
3090
3610
 
3091
 
    def _get_view_builder(self):
 
3611
    def _get_view_builder(self, project_id=""):
3092
3612
        base_url = "http://localhost/v1.1"
3093
3613
        views = nova.api.openstack.views
3094
3614
        address_builder = views.addresses.ViewBuilderV11()
3095
 
        flavor_builder = views.flavors.ViewBuilderV11(base_url)
3096
 
        image_builder = views.images.ViewBuilderV11(base_url)
 
3615
        flavor_builder = views.flavors.ViewBuilderV11(base_url, project_id)
 
3616
        image_builder = views.images.ViewBuilderV11(base_url, project_id)
3097
3617
 
3098
3618
        view_builder = nova.api.openstack.views.servers.ViewBuilderV11(
3099
3619
            address_builder,
3100
3620
            flavor_builder,
3101
3621
            image_builder,
3102
 
            base_url)
 
3622
            base_url,
 
3623
            project_id,
 
3624
        )
3103
3625
        return view_builder
3104
3626
 
3105
3627
    def test_build_server(self):
3118
3640
                        "href": "http://localhost/servers/1",
3119
3641
                    },
3120
3642
                ],
 
3643
                "config_drive": None,
3121
3644
            }
3122
3645
        }
3123
3646
 
3124
3647
        output = self.view_builder.build(self.instance, False)
3125
3648
        self.assertDictMatch(output, expected_server)
3126
3649
 
 
3650
    def test_build_server_with_project_id(self):
 
3651
        expected_server = {
 
3652
            "server": {
 
3653
                "id": 1,
 
3654
                "uuid": self.instance['uuid'],
 
3655
                "name": "test_server",
 
3656
                "config_drive": None,
 
3657
                "links": [
 
3658
                    {
 
3659
                        "rel": "self",
 
3660
                        "href": "http://localhost/v1.1/fake/servers/1",
 
3661
                    },
 
3662
                    {
 
3663
                        "rel": "bookmark",
 
3664
                        "href": "http://localhost/fake/servers/1",
 
3665
                    },
 
3666
                ],
 
3667
            }
 
3668
        }
 
3669
 
 
3670
        view_builder = self._get_view_builder(project_id='fake')
 
3671
        output = view_builder.build(self.instance, False)
 
3672
        self.assertDictMatch(output, expected_server)
 
3673
 
3127
3674
    def test_build_server_detail(self):
3128
3675
        image_bookmark = "http://localhost/images/5"
3129
3676
        flavor_bookmark = "http://localhost/flavors/1"
3136
3683
                "progress": 0,
3137
3684
                "name": "test_server",
3138
3685
                "status": "BUILD",
 
3686
                "accessIPv4": "",
 
3687
                "accessIPv6": "",
3139
3688
                "hostId": '',
3140
3689
                "key_name": '',
3141
3690
                "image": {
3158
3707
                },
3159
3708
                "addresses": {},
3160
3709
                "metadata": {},
 
3710
                "config_drive": None,
3161
3711
                "links": [
3162
3712
                    {
3163
3713
                        "rel": "self",
3188
3738
                "progress": 100,
3189
3739
                "name": "test_server",
3190
3740
                "status": "ACTIVE",
 
3741
                "accessIPv4": "",
 
3742
                "accessIPv6": "",
3191
3743
                "hostId": '',
3192
3744
                "key_name": '',
3193
3745
                "image": {
3210
3762
                },
3211
3763
                "addresses": {},
3212
3764
                "metadata": {},
 
3765
                "config_drive": None,
 
3766
                "links": [
 
3767
                    {
 
3768
                        "rel": "self",
 
3769
                        "href": "http://localhost/v1.1/servers/1",
 
3770
                    },
 
3771
                    {
 
3772
                        "rel": "bookmark",
 
3773
                        "href": "http://localhost/servers/1",
 
3774
                    },
 
3775
                ],
 
3776
            }
 
3777
        }
 
3778
 
 
3779
        output = self.view_builder.build(self.instance, True)
 
3780
        self.assertDictMatch(output, expected_server)
 
3781
 
 
3782
    def test_build_server_detail_with_accessipv4(self):
 
3783
 
 
3784
        self.instance['access_ip_v4'] = '1.2.3.4'
 
3785
 
 
3786
        image_bookmark = "http://localhost/images/5"
 
3787
        flavor_bookmark = "http://localhost/flavors/1"
 
3788
        expected_server = {
 
3789
            "server": {
 
3790
                "id": 1,
 
3791
                "uuid": self.instance['uuid'],
 
3792
                "updated": "2010-11-11T11:00:00Z",
 
3793
                "created": "2010-10-10T12:00:00Z",
 
3794
                "progress": 0,
 
3795
                "name": "test_server",
 
3796
                "status": "BUILD",
 
3797
                "hostId": '',
 
3798
                "image": {
 
3799
                    "id": "5",
 
3800
                    "links": [
 
3801
                        {
 
3802
                            "rel": "bookmark",
 
3803
                            "href": image_bookmark,
 
3804
                        },
 
3805
                    ],
 
3806
                },
 
3807
                "flavor": {
 
3808
                    "id": "1",
 
3809
                    "links": [
 
3810
                                              {
 
3811
                            "rel": "bookmark",
 
3812
                            "href": flavor_bookmark,
 
3813
                        },
 
3814
                    ],
 
3815
                },
 
3816
                "addresses": {},
 
3817
                "metadata": {},
 
3818
                "config_drive": None,
 
3819
                "accessIPv4": "1.2.3.4",
 
3820
                "accessIPv6": "",
 
3821
                "links": [
 
3822
                    {
 
3823
                        "rel": "self",
 
3824
                        "href": "http://localhost/v1.1/servers/1",
 
3825
                    },
 
3826
                    {
 
3827
                        "rel": "bookmark",
 
3828
                        "href": "http://localhost/servers/1",
 
3829
                    },
 
3830
                ],
 
3831
            }
 
3832
        }
 
3833
 
 
3834
        output = self.view_builder.build(self.instance, True)
 
3835
        self.assertDictMatch(output, expected_server)
 
3836
 
 
3837
    def test_build_server_detail_with_accessipv6(self):
 
3838
 
 
3839
        self.instance['access_ip_v6'] = 'fead::1234'
 
3840
 
 
3841
        image_bookmark = "http://localhost/images/5"
 
3842
        flavor_bookmark = "http://localhost/flavors/1"
 
3843
        expected_server = {
 
3844
            "server": {
 
3845
                "id": 1,
 
3846
                "uuid": self.instance['uuid'],
 
3847
                "updated": "2010-11-11T11:00:00Z",
 
3848
                "created": "2010-10-10T12:00:00Z",
 
3849
                "progress": 0,
 
3850
                "name": "test_server",
 
3851
                "status": "BUILD",
 
3852
                "hostId": '',
 
3853
                "image": {
 
3854
                    "id": "5",
 
3855
                    "links": [
 
3856
                        {
 
3857
                            "rel": "bookmark",
 
3858
                            "href": image_bookmark,
 
3859
                        },
 
3860
                    ],
 
3861
                },
 
3862
                "flavor": {
 
3863
                    "id": "1",
 
3864
                    "links": [
 
3865
                                              {
 
3866
                            "rel": "bookmark",
 
3867
                            "href": flavor_bookmark,
 
3868
                        },
 
3869
                    ],
 
3870
                },
 
3871
                "addresses": {},
 
3872
                "metadata": {},
 
3873
                "config_drive": None,
 
3874
                "accessIPv4": "",
 
3875
                "accessIPv6": "fead::1234",
3213
3876
                "links": [
3214
3877
                    {
3215
3878
                        "rel": "self",
3244
3907
                "progress": 0,
3245
3908
                "name": "test_server",
3246
3909
                "status": "BUILD",
 
3910
                "accessIPv4": "",
 
3911
                "accessIPv6": "",
3247
3912
                "hostId": '',
3248
3913
                "key_name": '',
3249
3914
                "image": {
3269
3934
                    "Open": "Stack",
3270
3935
                    "Number": "1",
3271
3936
                },
 
3937
                "config_drive": None,
3272
3938
                "links": [
3273
3939
                    {
3274
3940
                        "rel": "self",
3312
3978
                "status": "BUILD",
3313
3979
                "hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
3314
3980
                "key_name": '',
 
3981
                "accessIPv4": "1.2.3.4",
 
3982
                "accessIPv6": "fead::1234",
3315
3983
                "image": {
3316
3984
                    "id": "5",
3317
3985
                    "links": [
3370
4038
        }
3371
4039
 
3372
4040
        output = serializer.serialize(fixture, 'show')
3373
 
        actual = minidom.parseString(output.replace("  ", ""))
 
4041
        print output
 
4042
        root = etree.XML(output)
 
4043
        xmlutil.validate_schema(root, 'server')
3374
4044
 
3375
4045
        expected_server_href = self.SERVER_HREF
3376
4046
        expected_server_bookmark = self.SERVER_BOOKMARK
3378
4048
        expected_flavor_bookmark = self.FLAVOR_BOOKMARK
3379
4049
        expected_now = self.TIMESTAMP
3380
4050
        expected_uuid = FAKE_UUID
3381
 
        expected = minidom.parseString("""
3382
 
        <server id="1"
3383
 
                uuid="%(expected_uuid)s"
3384
 
                xmlns="http://docs.openstack.org/compute/api/v1.1"
3385
 
                xmlns:atom="http://www.w3.org/2005/Atom"
3386
 
                name="test_server"
3387
 
                updated="%(expected_now)s"
3388
 
                created="%(expected_now)s"
3389
 
                hostId="e4d909c290d0fb1ca068ffaddf22cbd0"
3390
 
                status="BUILD"
3391
 
                progress="0">
3392
 
            <atom:link href="%(expected_server_href)s" rel="self"/>
3393
 
            <atom:link href="%(expected_server_bookmark)s" rel="bookmark"/>
3394
 
            <image id="5">
3395
 
                <atom:link rel="bookmark" href="%(expected_image_bookmark)s"/>
3396
 
            </image>
3397
 
            <flavor id="1">
3398
 
                <atom:link rel="bookmark" href="%(expected_flavor_bookmark)s"/>
3399
 
            </flavor>
3400
 
            <metadata>
3401
 
                <meta key="Open">
3402
 
                    Stack
3403
 
                </meta>
3404
 
                <meta key="Number">
3405
 
                    1
3406
 
                </meta>
3407
 
            </metadata>
3408
 
            <addresses>
3409
 
                <network id="network_one">
3410
 
                    <ip version="4" addr="67.23.10.138"/>
3411
 
                    <ip version="6" addr="::babe:67.23.10.138"/>
3412
 
                </network>
3413
 
                <network id="network_two">
3414
 
                    <ip version="4" addr="67.23.10.139"/>
3415
 
                    <ip version="6" addr="::babe:67.23.10.139"/>
3416
 
                </network>
3417
 
            </addresses>
3418
 
        </server>
3419
 
        """.replace("  ", "") % (locals()))
3420
 
 
3421
 
        self.assertEqual(expected.toxml(), actual.toxml())
 
4051
        server_dict = fixture['server']
 
4052
 
 
4053
        for key in ['name', 'id', 'uuid', 'created', 'accessIPv4',
 
4054
                    'updated', 'progress', 'status', 'hostId',
 
4055
                    'accessIPv6']:
 
4056
            self.assertEqual(root.get(key), str(server_dict[key]))
 
4057
 
 
4058
        link_nodes = root.findall('{0}link'.format(ATOMNS))
 
4059
        self.assertEqual(len(link_nodes), 2)
 
4060
        for i, link in enumerate(server_dict['links']):
 
4061
            for key, value in link.items():
 
4062
                self.assertEqual(link_nodes[i].get(key), value)
 
4063
 
 
4064
        metadata_root = root.find('{0}metadata'.format(NS))
 
4065
        metadata_elems = metadata_root.findall('{0}meta'.format(NS))
 
4066
        self.assertEqual(len(metadata_elems), 2)
 
4067
        for i, metadata_elem in enumerate(metadata_elems):
 
4068
            (meta_key, meta_value) = server_dict['metadata'].items()[i]
 
4069
            self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
 
4070
            self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
 
4071
 
 
4072
        image_root = root.find('{0}image'.format(NS))
 
4073
        self.assertEqual(image_root.get('id'), server_dict['image']['id'])
 
4074
        link_nodes = image_root.findall('{0}link'.format(ATOMNS))
 
4075
        self.assertEqual(len(link_nodes), 1)
 
4076
        for i, link in enumerate(server_dict['image']['links']):
 
4077
            for key, value in link.items():
 
4078
                self.assertEqual(link_nodes[i].get(key), value)
 
4079
 
 
4080
        flavor_root = root.find('{0}flavor'.format(NS))
 
4081
        self.assertEqual(flavor_root.get('id'), server_dict['flavor']['id'])
 
4082
        link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
 
4083
        self.assertEqual(len(link_nodes), 1)
 
4084
        for i, link in enumerate(server_dict['flavor']['links']):
 
4085
            for key, value in link.items():
 
4086
                self.assertEqual(link_nodes[i].get(key), value)
 
4087
 
 
4088
        addresses_root = root.find('{0}addresses'.format(NS))
 
4089
        addresses_dict = server_dict['addresses']
 
4090
        network_elems = addresses_root.findall('{0}network'.format(NS))
 
4091
        self.assertEqual(len(network_elems), 2)
 
4092
        for i, network_elem in enumerate(network_elems):
 
4093
            network = addresses_dict.items()[i]
 
4094
            self.assertEqual(str(network_elem.get('id')), str(network[0]))
 
4095
            ip_elems = network_elem.findall('{0}ip'.format(NS))
 
4096
            for z, ip_elem in enumerate(ip_elems):
 
4097
                ip = network[1][z]
 
4098
                self.assertEqual(str(ip_elem.get('version')),
 
4099
                                 str(ip['version']))
 
4100
                self.assertEqual(str(ip_elem.get('addr')),
 
4101
                                 str(ip['addr']))
3422
4102
 
3423
4103
    def test_create(self):
3424
4104
        serializer = servers.ServerXMLSerializer()
3432
4112
                "progress": 0,
3433
4113
                "name": "test_server",
3434
4114
                "status": "BUILD",
 
4115
                "accessIPv4": "1.2.3.4",
 
4116
                "accessIPv6": "fead::1234",
3435
4117
                "hostId": "e4d909c290d0fb1ca068ffaddf22cbd0",
3436
4118
                "adminPass": "test_password",
3437
4119
                "image": {
3492
4174
        }
3493
4175
 
3494
4176
        output = serializer.serialize(fixture, 'create')
3495
 
        actual = minidom.parseString(output.replace("  ", ""))
 
4177
        print output
 
4178
        root = etree.XML(output)
 
4179
        xmlutil.validate_schema(root, 'server')
3496
4180
 
3497
4181
        expected_server_href = self.SERVER_HREF
3498
4182
        expected_server_bookmark = self.SERVER_BOOKMARK
3500
4184
        expected_flavor_bookmark = self.FLAVOR_BOOKMARK
3501
4185
        expected_now = self.TIMESTAMP
3502
4186
        expected_uuid = FAKE_UUID
3503
 
        expected = minidom.parseString("""
3504
 
        <server id="1"
3505
 
                uuid="%(expected_uuid)s"
3506
 
                xmlns="http://docs.openstack.org/compute/api/v1.1"
3507
 
                xmlns:atom="http://www.w3.org/2005/Atom"
3508
 
                name="test_server"
3509
 
                updated="%(expected_now)s"
3510
 
                created="%(expected_now)s"
3511
 
                hostId="e4d909c290d0fb1ca068ffaddf22cbd0"
3512
 
                status="BUILD"
3513
 
                adminPass="test_password"
3514
 
                progress="0">
3515
 
            <atom:link href="%(expected_server_href)s" rel="self"/>
3516
 
            <atom:link href="%(expected_server_bookmark)s" rel="bookmark"/>
3517
 
            <image id="5">
3518
 
                <atom:link rel="bookmark" href="%(expected_image_bookmark)s"/>
3519
 
            </image>
3520
 
            <flavor id="1">
3521
 
                <atom:link rel="bookmark" href="%(expected_flavor_bookmark)s"/>
3522
 
            </flavor>
3523
 
            <metadata>
3524
 
                <meta key="Open">
3525
 
                    Stack
3526
 
                </meta>
3527
 
                <meta key="Number">
3528
 
                    1
3529
 
                </meta>
3530
 
            </metadata>
3531
 
            <addresses>
3532
 
                <network id="network_one">
3533
 
                    <ip version="4" addr="67.23.10.138"/>
3534
 
                    <ip version="6" addr="::babe:67.23.10.138"/>
3535
 
                </network>
3536
 
                <network id="network_two">
3537
 
                    <ip version="4" addr="67.23.10.139"/>
3538
 
                    <ip version="6" addr="::babe:67.23.10.139"/>
3539
 
                </network>
3540
 
            </addresses>
3541
 
        </server>
3542
 
        """.replace("  ", "") % (locals()))
3543
 
 
3544
 
        self.assertEqual(expected.toxml(), actual.toxml())
 
4187
        server_dict = fixture['server']
 
4188
 
 
4189
        for key in ['name', 'id', 'uuid', 'created', 'accessIPv4',
 
4190
                    'updated', 'progress', 'status', 'hostId',
 
4191
                    'accessIPv6', 'adminPass']:
 
4192
            self.assertEqual(root.get(key), str(server_dict[key]))
 
4193
 
 
4194
        link_nodes = root.findall('{0}link'.format(ATOMNS))
 
4195
        self.assertEqual(len(link_nodes), 2)
 
4196
        for i, link in enumerate(server_dict['links']):
 
4197
            for key, value in link.items():
 
4198
                self.assertEqual(link_nodes[i].get(key), value)
 
4199
 
 
4200
        metadata_root = root.find('{0}metadata'.format(NS))
 
4201
        metadata_elems = metadata_root.findall('{0}meta'.format(NS))
 
4202
        self.assertEqual(len(metadata_elems), 2)
 
4203
        for i, metadata_elem in enumerate(metadata_elems):
 
4204
            (meta_key, meta_value) = server_dict['metadata'].items()[i]
 
4205
            self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
 
4206
            self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
 
4207
 
 
4208
        image_root = root.find('{0}image'.format(NS))
 
4209
        self.assertEqual(image_root.get('id'), server_dict['image']['id'])
 
4210
        link_nodes = image_root.findall('{0}link'.format(ATOMNS))
 
4211
        self.assertEqual(len(link_nodes), 1)
 
4212
        for i, link in enumerate(server_dict['image']['links']):
 
4213
            for key, value in link.items():
 
4214
                self.assertEqual(link_nodes[i].get(key), value)
 
4215
 
 
4216
        flavor_root = root.find('{0}flavor'.format(NS))
 
4217
        self.assertEqual(flavor_root.get('id'), server_dict['flavor']['id'])
 
4218
        link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
 
4219
        self.assertEqual(len(link_nodes), 1)
 
4220
        for i, link in enumerate(server_dict['flavor']['links']):
 
4221
            for key, value in link.items():
 
4222
                self.assertEqual(link_nodes[i].get(key), value)
 
4223
 
 
4224
        addresses_root = root.find('{0}addresses'.format(NS))
 
4225
        addresses_dict = server_dict['addresses']
 
4226
        network_elems = addresses_root.findall('{0}network'.format(NS))
 
4227
        self.assertEqual(len(network_elems), 2)
 
4228
        for i, network_elem in enumerate(network_elems):
 
4229
            network = addresses_dict.items()[i]
 
4230
            self.assertEqual(str(network_elem.get('id')), str(network[0]))
 
4231
            ip_elems = network_elem.findall('{0}ip'.format(NS))
 
4232
            for z, ip_elem in enumerate(ip_elems):
 
4233
                ip = network[1][z]
 
4234
                self.assertEqual(str(ip_elem.get('version')),
 
4235
                                 str(ip['version']))
 
4236
                self.assertEqual(str(ip_elem.get('addr')),
 
4237
                                 str(ip['addr']))
3545
4238
 
3546
4239
    def test_index(self):
3547
4240
        serializer = servers.ServerXMLSerializer()
3582
4275
        ]}
3583
4276
 
3584
4277
        output = serializer.serialize(fixture, 'index')
3585
 
        actual = minidom.parseString(output.replace("  ", ""))
3586
 
 
3587
 
        expected = minidom.parseString("""
3588
 
        <servers xmlns="http://docs.openstack.org/compute/api/v1.1"
3589
 
                 xmlns:atom="http://www.w3.org/2005/Atom">
3590
 
        <server id="1" name="test_server">
3591
 
            <atom:link href="%(expected_server_href)s" rel="self"/>
3592
 
            <atom:link href="%(expected_server_bookmark)s" rel="bookmark"/>
3593
 
        </server>
3594
 
        <server id="2" name="test_server_2">
3595
 
            <atom:link href="%(expected_server_href_2)s" rel="self"/>
3596
 
            <atom:link href="%(expected_server_bookmark_2)s" rel="bookmark"/>
3597
 
        </server>
3598
 
        </servers>
3599
 
        """.replace("  ", "") % (locals()))
3600
 
 
3601
 
        self.assertEqual(expected.toxml(), actual.toxml())
 
4278
        print output
 
4279
        root = etree.XML(output)
 
4280
        xmlutil.validate_schema(root, 'servers_index')
 
4281
        server_elems = root.findall('{0}server'.format(NS))
 
4282
        self.assertEqual(len(server_elems), 2)
 
4283
        for i, server_elem in enumerate(server_elems):
 
4284
            server_dict = fixture['servers'][i]
 
4285
            for key in ['name', 'id']:
 
4286
                self.assertEqual(server_elem.get(key), str(server_dict[key]))
 
4287
 
 
4288
            link_nodes = server_elem.findall('{0}link'.format(ATOMNS))
 
4289
            self.assertEqual(len(link_nodes), 2)
 
4290
            for i, link in enumerate(server_dict['links']):
 
4291
                for key, value in link.items():
 
4292
                    self.assertEqual(link_nodes[i].get(key), value)
3602
4293
 
3603
4294
    def test_detail(self):
3604
4295
        serializer = servers.ServerXMLSerializer()
3621
4312
                "progress": 0,
3622
4313
                "name": "test_server",
3623
4314
                "status": "BUILD",
 
4315
                "accessIPv4": "1.2.3.4",
 
4316
                "accessIPv6": "fead::1234",
3624
4317
                "hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
3625
4318
                "image": {
3626
4319
                    "id": "5",
3674
4367
                "progress": 100,
3675
4368
                "name": "test_server_2",
3676
4369
                "status": "ACTIVE",
 
4370
                "accessIPv4": "1.2.3.4",
 
4371
                "accessIPv6": "fead::1234",
3677
4372
                "hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
3678
4373
                "image": {
3679
4374
                    "id": "5",
3722
4417
        ]}
3723
4418
 
3724
4419
        output = serializer.serialize(fixture, 'detail')
3725
 
        actual = minidom.parseString(output.replace("  ", ""))
3726
 
 
3727
 
        expected = minidom.parseString("""
3728
 
        <servers xmlns="http://docs.openstack.org/compute/api/v1.1"
3729
 
                 xmlns:atom="http://www.w3.org/2005/Atom">
3730
 
        <server id="1"
3731
 
                uuid="%(expected_uuid)s"
3732
 
                name="test_server"
3733
 
                updated="%(expected_now)s"
3734
 
                created="%(expected_now)s"
3735
 
                hostId="e4d909c290d0fb1ca068ffaddf22cbd0"
3736
 
                status="BUILD"
3737
 
                progress="0">
3738
 
            <atom:link href="%(expected_server_href)s" rel="self"/>
3739
 
            <atom:link href="%(expected_server_bookmark)s" rel="bookmark"/>
3740
 
            <image id="5">
3741
 
                <atom:link rel="bookmark" href="%(expected_image_bookmark)s"/>
3742
 
            </image>
3743
 
            <flavor id="1">
3744
 
                <atom:link rel="bookmark" href="%(expected_flavor_bookmark)s"/>
3745
 
            </flavor>
3746
 
            <metadata>
3747
 
                <meta key="Number">
3748
 
                    1
3749
 
                </meta>
3750
 
            </metadata>
3751
 
            <addresses>
3752
 
                <network id="network_one">
3753
 
                    <ip version="4" addr="67.23.10.138"/>
3754
 
                    <ip version="6" addr="::babe:67.23.10.138"/>
3755
 
                </network>
3756
 
            </addresses>
3757
 
        </server>
3758
 
        <server id="2"
3759
 
                uuid="%(expected_uuid)s"
3760
 
                name="test_server_2"
3761
 
                updated="%(expected_now)s"
3762
 
                created="%(expected_now)s"
3763
 
                hostId="e4d909c290d0fb1ca068ffaddf22cbd0"
3764
 
                status="ACTIVE"
3765
 
                progress="100">
3766
 
            <atom:link href="%(expected_server_href_2)s" rel="self"/>
3767
 
            <atom:link href="%(expected_server_bookmark_2)s" rel="bookmark"/>
3768
 
            <image id="5">
3769
 
                <atom:link rel="bookmark" href="%(expected_image_bookmark)s"/>
3770
 
            </image>
3771
 
            <flavor id="1">
3772
 
                <atom:link rel="bookmark" href="%(expected_flavor_bookmark)s"/>
3773
 
            </flavor>
3774
 
            <metadata>
3775
 
                <meta key="Number">
3776
 
                    2
3777
 
                </meta>
3778
 
            </metadata>
3779
 
            <addresses>
3780
 
                <network id="network_one">
3781
 
                    <ip version="4" addr="67.23.10.138"/>
3782
 
                    <ip version="6" addr="::babe:67.23.10.138"/>
3783
 
                </network>
3784
 
            </addresses>
3785
 
        </server>
3786
 
        </servers>
3787
 
        """.replace("  ", "") % (locals()))
3788
 
 
3789
 
        self.assertEqual(expected.toxml(), actual.toxml())
 
4420
        print output
 
4421
        root = etree.XML(output)
 
4422
        xmlutil.validate_schema(root, 'servers')
 
4423
        server_elems = root.findall('{0}server'.format(NS))
 
4424
        self.assertEqual(len(server_elems), 2)
 
4425
        for i, server_elem in enumerate(server_elems):
 
4426
            server_dict = fixture['servers'][i]
 
4427
 
 
4428
            for key in ['name', 'id', 'uuid', 'created', 'accessIPv4',
 
4429
                        'updated', 'progress', 'status', 'hostId',
 
4430
                        'accessIPv6']:
 
4431
                self.assertEqual(server_elem.get(key), str(server_dict[key]))
 
4432
 
 
4433
            link_nodes = server_elem.findall('{0}link'.format(ATOMNS))
 
4434
            self.assertEqual(len(link_nodes), 2)
 
4435
            for i, link in enumerate(server_dict['links']):
 
4436
                for key, value in link.items():
 
4437
                    self.assertEqual(link_nodes[i].get(key), value)
 
4438
 
 
4439
            metadata_root = server_elem.find('{0}metadata'.format(NS))
 
4440
            metadata_elems = metadata_root.findall('{0}meta'.format(NS))
 
4441
            for i, metadata_elem in enumerate(metadata_elems):
 
4442
                (meta_key, meta_value) = server_dict['metadata'].items()[i]
 
4443
                self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
 
4444
                self.assertEqual(str(metadata_elem.text).strip(),
 
4445
                                 str(meta_value))
 
4446
 
 
4447
            image_root = server_elem.find('{0}image'.format(NS))
 
4448
            self.assertEqual(image_root.get('id'), server_dict['image']['id'])
 
4449
            link_nodes = image_root.findall('{0}link'.format(ATOMNS))
 
4450
            self.assertEqual(len(link_nodes), 1)
 
4451
            for i, link in enumerate(server_dict['image']['links']):
 
4452
                for key, value in link.items():
 
4453
                    self.assertEqual(link_nodes[i].get(key), value)
 
4454
 
 
4455
            flavor_root = server_elem.find('{0}flavor'.format(NS))
 
4456
            self.assertEqual(flavor_root.get('id'),
 
4457
                             server_dict['flavor']['id'])
 
4458
            link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
 
4459
            self.assertEqual(len(link_nodes), 1)
 
4460
            for i, link in enumerate(server_dict['flavor']['links']):
 
4461
                for key, value in link.items():
 
4462
                    self.assertEqual(link_nodes[i].get(key), value)
 
4463
 
 
4464
            addresses_root = server_elem.find('{0}addresses'.format(NS))
 
4465
            addresses_dict = server_dict['addresses']
 
4466
            network_elems = addresses_root.findall('{0}network'.format(NS))
 
4467
            for i, network_elem in enumerate(network_elems):
 
4468
                network = addresses_dict.items()[i]
 
4469
                self.assertEqual(str(network_elem.get('id')), str(network[0]))
 
4470
                ip_elems = network_elem.findall('{0}ip'.format(NS))
 
4471
                for z, ip_elem in enumerate(ip_elems):
 
4472
                    ip = network[1][z]
 
4473
                    self.assertEqual(str(ip_elem.get('version')),
 
4474
                                     str(ip['version']))
 
4475
                    self.assertEqual(str(ip_elem.get('addr')),
 
4476
                                     str(ip['addr']))
 
4477
 
 
4478
    def test_update(self):
 
4479
        serializer = servers.ServerXMLSerializer()
 
4480
 
 
4481
        fixture = {
 
4482
            "server": {
 
4483
                "id": 1,
 
4484
                "uuid": FAKE_UUID,
 
4485
                'created': self.TIMESTAMP,
 
4486
                'updated': self.TIMESTAMP,
 
4487
                "progress": 0,
 
4488
                "name": "test_server",
 
4489
                "status": "BUILD",
 
4490
                "hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
 
4491
                "accessIPv4": "1.2.3.4",
 
4492
                "accessIPv6": "fead::1234",
 
4493
                "image": {
 
4494
                    "id": "5",
 
4495
                    "links": [
 
4496
                        {
 
4497
                            "rel": "bookmark",
 
4498
                            "href": self.IMAGE_BOOKMARK,
 
4499
                        },
 
4500
                    ],
 
4501
                },
 
4502
                "flavor": {
 
4503
                    "id": "1",
 
4504
                    "links": [
 
4505
                        {
 
4506
                            "rel": "bookmark",
 
4507
                            "href": self.FLAVOR_BOOKMARK,
 
4508
                        },
 
4509
                    ],
 
4510
                },
 
4511
                "addresses": {
 
4512
                    "network_one": [
 
4513
                        {
 
4514
                            "version": 4,
 
4515
                            "addr": "67.23.10.138",
 
4516
                        },
 
4517
                        {
 
4518
                            "version": 6,
 
4519
                            "addr": "::babe:67.23.10.138",
 
4520
                        },
 
4521
                    ],
 
4522
                    "network_two": [
 
4523
                        {
 
4524
                            "version": 4,
 
4525
                            "addr": "67.23.10.139",
 
4526
                        },
 
4527
                        {
 
4528
                            "version": 6,
 
4529
                            "addr": "::babe:67.23.10.139",
 
4530
                        },
 
4531
                    ],
 
4532
                },
 
4533
                "metadata": {
 
4534
                    "Open": "Stack",
 
4535
                    "Number": "1",
 
4536
                },
 
4537
                'links': [
 
4538
                    {
 
4539
                        'href': self.SERVER_HREF,
 
4540
                        'rel': 'self',
 
4541
                    },
 
4542
                    {
 
4543
                        'href': self.SERVER_BOOKMARK,
 
4544
                        'rel': 'bookmark',
 
4545
                    },
 
4546
                ],
 
4547
            }
 
4548
        }
 
4549
 
 
4550
        output = serializer.serialize(fixture, 'update')
 
4551
        print output
 
4552
        root = etree.XML(output)
 
4553
        xmlutil.validate_schema(root, 'server')
 
4554
 
 
4555
        expected_server_href = self.SERVER_HREF
 
4556
        expected_server_bookmark = self.SERVER_BOOKMARK
 
4557
        expected_image_bookmark = self.IMAGE_BOOKMARK
 
4558
        expected_flavor_bookmark = self.FLAVOR_BOOKMARK
 
4559
        expected_now = self.TIMESTAMP
 
4560
        expected_uuid = FAKE_UUID
 
4561
        server_dict = fixture['server']
 
4562
 
 
4563
        for key in ['name', 'id', 'uuid', 'created', 'accessIPv4',
 
4564
                    'updated', 'progress', 'status', 'hostId',
 
4565
                    'accessIPv6']:
 
4566
            self.assertEqual(root.get(key), str(server_dict[key]))
 
4567
 
 
4568
        link_nodes = root.findall('{0}link'.format(ATOMNS))
 
4569
        self.assertEqual(len(link_nodes), 2)
 
4570
        for i, link in enumerate(server_dict['links']):
 
4571
            for key, value in link.items():
 
4572
                self.assertEqual(link_nodes[i].get(key), value)
 
4573
 
 
4574
        metadata_root = root.find('{0}metadata'.format(NS))
 
4575
        metadata_elems = metadata_root.findall('{0}meta'.format(NS))
 
4576
        self.assertEqual(len(metadata_elems), 2)
 
4577
        for i, metadata_elem in enumerate(metadata_elems):
 
4578
            (meta_key, meta_value) = server_dict['metadata'].items()[i]
 
4579
            self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
 
4580
            self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
 
4581
 
 
4582
        image_root = root.find('{0}image'.format(NS))
 
4583
        self.assertEqual(image_root.get('id'), server_dict['image']['id'])
 
4584
        link_nodes = image_root.findall('{0}link'.format(ATOMNS))
 
4585
        self.assertEqual(len(link_nodes), 1)
 
4586
        for i, link in enumerate(server_dict['image']['links']):
 
4587
            for key, value in link.items():
 
4588
                self.assertEqual(link_nodes[i].get(key), value)
 
4589
 
 
4590
        flavor_root = root.find('{0}flavor'.format(NS))
 
4591
        self.assertEqual(flavor_root.get('id'), server_dict['flavor']['id'])
 
4592
        link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
 
4593
        self.assertEqual(len(link_nodes), 1)
 
4594
        for i, link in enumerate(server_dict['flavor']['links']):
 
4595
            for key, value in link.items():
 
4596
                self.assertEqual(link_nodes[i].get(key), value)
 
4597
 
 
4598
        addresses_root = root.find('{0}addresses'.format(NS))
 
4599
        addresses_dict = server_dict['addresses']
 
4600
        network_elems = addresses_root.findall('{0}network'.format(NS))
 
4601
        self.assertEqual(len(network_elems), 2)
 
4602
        for i, network_elem in enumerate(network_elems):
 
4603
            network = addresses_dict.items()[i]
 
4604
            self.assertEqual(str(network_elem.get('id')), str(network[0]))
 
4605
            ip_elems = network_elem.findall('{0}ip'.format(NS))
 
4606
            for z, ip_elem in enumerate(ip_elems):
 
4607
                ip = network[1][z]
 
4608
                self.assertEqual(str(ip_elem.get('version')),
 
4609
                                 str(ip['version']))
 
4610
                self.assertEqual(str(ip_elem.get('addr')),
 
4611
                                 str(ip['addr']))
 
4612
 
 
4613
    def test_action(self):
 
4614
        serializer = servers.ServerXMLSerializer()
 
4615
 
 
4616
        fixture = {
 
4617
            "server": {
 
4618
                "id": 1,
 
4619
                "uuid": FAKE_UUID,
 
4620
                'created': self.TIMESTAMP,
 
4621
                'updated': self.TIMESTAMP,
 
4622
                "progress": 0,
 
4623
                "name": "test_server",
 
4624
                "status": "BUILD",
 
4625
                "accessIPv4": "1.2.3.4",
 
4626
                "accessIPv6": "fead::1234",
 
4627
                "hostId": "e4d909c290d0fb1ca068ffaddf22cbd0",
 
4628
                "adminPass": "test_password",
 
4629
                "image": {
 
4630
                    "id": "5",
 
4631
                    "links": [
 
4632
                        {
 
4633
                            "rel": "bookmark",
 
4634
                            "href": self.IMAGE_BOOKMARK,
 
4635
                        },
 
4636
                    ],
 
4637
                },
 
4638
                "flavor": {
 
4639
                    "id": "1",
 
4640
                    "links": [
 
4641
                        {
 
4642
                            "rel": "bookmark",
 
4643
                            "href": self.FLAVOR_BOOKMARK,
 
4644
                        },
 
4645
                    ],
 
4646
                },
 
4647
                "addresses": {
 
4648
                    "network_one": [
 
4649
                        {
 
4650
                            "version": 4,
 
4651
                            "addr": "67.23.10.138",
 
4652
                        },
 
4653
                        {
 
4654
                            "version": 6,
 
4655
                            "addr": "::babe:67.23.10.138",
 
4656
                        },
 
4657
                    ],
 
4658
                    "network_two": [
 
4659
                        {
 
4660
                            "version": 4,
 
4661
                            "addr": "67.23.10.139",
 
4662
                        },
 
4663
                        {
 
4664
                            "version": 6,
 
4665
                            "addr": "::babe:67.23.10.139",
 
4666
                        },
 
4667
                    ],
 
4668
                },
 
4669
                "metadata": {
 
4670
                    "Open": "Stack",
 
4671
                    "Number": "1",
 
4672
                },
 
4673
                'links': [
 
4674
                    {
 
4675
                        'href': self.SERVER_HREF,
 
4676
                        'rel': 'self',
 
4677
                    },
 
4678
                    {
 
4679
                        'href': self.SERVER_BOOKMARK,
 
4680
                        'rel': 'bookmark',
 
4681
                    },
 
4682
                ],
 
4683
            }
 
4684
        }
 
4685
 
 
4686
        output = serializer.serialize(fixture, 'action')
 
4687
        root = etree.XML(output)
 
4688
        xmlutil.validate_schema(root, 'server')
 
4689
 
 
4690
        expected_server_href = self.SERVER_HREF
 
4691
        expected_server_bookmark = self.SERVER_BOOKMARK
 
4692
        expected_image_bookmark = self.IMAGE_BOOKMARK
 
4693
        expected_flavor_bookmark = self.FLAVOR_BOOKMARK
 
4694
        expected_now = self.TIMESTAMP
 
4695
        expected_uuid = FAKE_UUID
 
4696
        server_dict = fixture['server']
 
4697
 
 
4698
        for key in ['name', 'id', 'uuid', 'created', 'accessIPv4',
 
4699
                    'updated', 'progress', 'status', 'hostId',
 
4700
                    'accessIPv6', 'adminPass']:
 
4701
            self.assertEqual(root.get(key), str(server_dict[key]))
 
4702
 
 
4703
        link_nodes = root.findall('{0}link'.format(ATOMNS))
 
4704
        self.assertEqual(len(link_nodes), 2)
 
4705
        for i, link in enumerate(server_dict['links']):
 
4706
            for key, value in link.items():
 
4707
                self.assertEqual(link_nodes[i].get(key), value)
 
4708
 
 
4709
        metadata_root = root.find('{0}metadata'.format(NS))
 
4710
        metadata_elems = metadata_root.findall('{0}meta'.format(NS))
 
4711
        self.assertEqual(len(metadata_elems), 2)
 
4712
        for i, metadata_elem in enumerate(metadata_elems):
 
4713
            (meta_key, meta_value) = server_dict['metadata'].items()[i]
 
4714
            self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
 
4715
            self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
 
4716
 
 
4717
        image_root = root.find('{0}image'.format(NS))
 
4718
        self.assertEqual(image_root.get('id'), server_dict['image']['id'])
 
4719
        link_nodes = image_root.findall('{0}link'.format(ATOMNS))
 
4720
        self.assertEqual(len(link_nodes), 1)
 
4721
        for i, link in enumerate(server_dict['image']['links']):
 
4722
            for key, value in link.items():
 
4723
                self.assertEqual(link_nodes[i].get(key), value)
 
4724
 
 
4725
        flavor_root = root.find('{0}flavor'.format(NS))
 
4726
        self.assertEqual(flavor_root.get('id'), server_dict['flavor']['id'])
 
4727
        link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
 
4728
        self.assertEqual(len(link_nodes), 1)
 
4729
        for i, link in enumerate(server_dict['flavor']['links']):
 
4730
            for key, value in link.items():
 
4731
                self.assertEqual(link_nodes[i].get(key), value)
 
4732
 
 
4733
        addresses_root = root.find('{0}addresses'.format(NS))
 
4734
        addresses_dict = server_dict['addresses']
 
4735
        network_elems = addresses_root.findall('{0}network'.format(NS))
 
4736
        self.assertEqual(len(network_elems), 2)
 
4737
        for i, network_elem in enumerate(network_elems):
 
4738
            network = addresses_dict.items()[i]
 
4739
            self.assertEqual(str(network_elem.get('id')), str(network[0]))
 
4740
            ip_elems = network_elem.findall('{0}ip'.format(NS))
 
4741
            for z, ip_elem in enumerate(ip_elems):
 
4742
                ip = network[1][z]
 
4743
                self.assertEqual(str(ip_elem.get('version')),
 
4744
                                 str(ip['version']))
 
4745
                self.assertEqual(str(ip_elem.get('addr')),
 
4746
                                 str(ip['addr']))