~ubuntu-branches/ubuntu/quantal/nova/quantal-proposed

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-01-20 11:54:15 UTC
  • mto: This revision was merged to the branch mainline in revision 62.
  • Revision ID: package-import@ubuntu.com-20120120115415-h2ujma9o536o1ut6
Tags: upstream-2012.1~e3~20120120.12170
ImportĀ upstreamĀ versionĀ 2012.1~e3~20120120.12170

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
2
 
 
3
# Copyright 2010-2011 OpenStack LLC.
 
4
# Copyright 2011 Piston Cloud Computing, Inc.
 
5
# All Rights Reserved.
 
6
#
 
7
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 
8
#    not use this file except in compliance with the License. You may obtain
 
9
#    a copy of the License at
 
10
#
 
11
#         http://www.apache.org/licenses/LICENSE-2.0
 
12
#
 
13
#    Unless required by applicable law or agreed to in writing, software
 
14
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
15
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 
16
#    License for the specific language governing permissions and limitations
 
17
#    under the License.
 
18
 
 
19
import datetime
 
20
import json
 
21
import urlparse
 
22
 
 
23
from lxml import etree
 
24
import webob
 
25
 
 
26
import nova.api.openstack.compute
 
27
from nova.api.openstack.compute import ips
 
28
from nova.api.openstack.compute import servers
 
29
from nova.api.openstack.compute import views
 
30
from nova.api.openstack import xmlutil
 
31
import nova.compute.api
 
32
from nova.compute import instance_types
 
33
from nova.compute import task_states
 
34
from nova.compute import vm_states
 
35
import nova.db
 
36
from nova.db.sqlalchemy.models import InstanceMetadata
 
37
from nova import flags
 
38
import nova.image.fake
 
39
import nova.rpc
 
40
import nova.scheduler.api
 
41
from nova import test
 
42
from nova.tests.api.openstack import fakes
 
43
from nova import utils
 
44
 
 
45
 
 
46
FLAGS = flags.FLAGS
 
47
FAKE_UUID = fakes.FAKE_UUID
 
48
FAKE_UUIDS = {0: FAKE_UUID}
 
49
NS = "{http://docs.openstack.org/compute/api/v1.1}"
 
50
ATOMNS = "{http://www.w3.org/2005/Atom}"
 
51
XPATH_NS = {
 
52
    'atom': 'http://www.w3.org/2005/Atom',
 
53
    'ns': 'http://docs.openstack.org/compute/api/v1.1'
 
54
}
 
55
 
 
56
 
 
57
def get_fake_uuid(token=0):
 
58
    if not token in FAKE_UUIDS:
 
59
        FAKE_UUIDS[token] = str(utils.gen_uuid())
 
60
    return FAKE_UUIDS[token]
 
61
 
 
62
 
 
63
def fake_gen_uuid():
 
64
    return FAKE_UUID
 
65
 
 
66
 
 
67
def return_server_by_id(context, id):
 
68
    return fakes.stub_instance(id)
 
69
 
 
70
 
 
71
def return_server_by_uuid(context, uuid):
 
72
    id = 1
 
73
    return fakes.stub_instance(id, uuid=uuid)
 
74
 
 
75
 
 
76
def return_server_with_attributes(**kwargs):
 
77
    def _return_server(context, instance_id):
 
78
        return fakes.stub_instance(instance_id, **kwargs)
 
79
    return _return_server
 
80
 
 
81
 
 
82
def return_server_with_attributes_by_uuid(**kwargs):
 
83
    def _return_server(context, uuid):
 
84
        return fakes.stub_instance(1, uuid=uuid, **kwargs)
 
85
    return _return_server
 
86
 
 
87
 
 
88
def return_server_with_state(vm_state, task_state=None):
 
89
    def _return_server(context, uuid):
 
90
        return fakes.stub_instance(1, uuid=uuid, vm_state=vm_state,
 
91
                             task_state=task_state)
 
92
    return _return_server
 
93
 
 
94
 
 
95
def return_server_with_uuid_and_state(vm_state, task_state):
 
96
    def _return_server(context, id):
 
97
        return fakes.stub_instance(id,
 
98
                             uuid=FAKE_UUID,
 
99
                             vm_state=vm_state,
 
100
                             task_state=task_state)
 
101
    return _return_server
 
102
 
 
103
 
 
104
def return_servers(context, *args, **kwargs):
 
105
    servers_list = []
 
106
    for i in xrange(5):
 
107
        server = fakes.stub_instance(i, 'fake', 'fake', uuid=get_fake_uuid(i))
 
108
        servers_list.append(server)
 
109
    return servers_list
 
110
 
 
111
 
 
112
def return_servers_by_reservation(context, reservation_id=""):
 
113
    return [fakes.stub_instance(i, reservation_id) for i in xrange(5)]
 
114
 
 
115
 
 
116
def return_servers_by_reservation_empty(context, reservation_id=""):
 
117
    return []
 
118
 
 
119
 
 
120
def return_servers_from_child_zones_empty(*args, **kwargs):
 
121
    return []
 
122
 
 
123
 
 
124
def return_servers_from_child_zones(*args, **kwargs):
 
125
    class Server(object):
 
126
        pass
 
127
 
 
128
    zones = []
 
129
    for zone in xrange(3):
 
130
        servers_list = []
 
131
        for server_id in xrange(5):
 
132
            server = Server()
 
133
            server._info = fakes.stub_instance(
 
134
                    server_id, reservation_id="child")
 
135
            servers_list.append(server)
 
136
 
 
137
        zones.append(("Zone%d" % zone, servers_list))
 
138
    return zones
 
139
 
 
140
 
 
141
def return_security_group(context, instance_id, security_group_id):
 
142
    pass
 
143
 
 
144
 
 
145
def instance_update(context, instance_id, values):
 
146
    return fakes.stub_instance(instance_id, name=values.get('display_name'))
 
147
 
 
148
 
 
149
def fake_compute_api(cls, req, id):
 
150
    return True
 
151
 
 
152
 
 
153
def find_host(self, context, instance_id):
 
154
    return "nova"
 
155
 
 
156
 
 
157
class MockSetAdminPassword(object):
 
158
    def __init__(self):
 
159
        self.instance_id = None
 
160
        self.password = None
 
161
 
 
162
    def __call__(self, context, instance_id, password):
 
163
        self.instance_id = instance_id
 
164
        self.password = password
 
165
 
 
166
 
 
167
class ServersControllerTest(test.TestCase):
 
168
    def setUp(self):
 
169
        self.maxDiff = None
 
170
        super(ServersControllerTest, self).setUp()
 
171
        self.flags(verbose=True, use_ipv6=False)
 
172
        fakes.stub_out_networking(self.stubs)
 
173
        fakes.stub_out_rate_limiting(self.stubs)
 
174
        fakes.stub_out_key_pair_funcs(self.stubs)
 
175
        fakes.stub_out_image_service(self.stubs)
 
176
        fakes.stub_out_nw_api(self.stubs)
 
177
        self.stubs.Set(nova.db, 'instance_get_all_by_filters',
 
178
                return_servers)
 
179
        self.stubs.Set(nova.db, 'instance_get', return_server_by_id)
 
180
        self.stubs.Set(nova.db, 'instance_get_by_uuid',
 
181
                       return_server_by_uuid)
 
182
        self.stubs.Set(nova.db, 'instance_get_all_by_project',
 
183
                       return_servers)
 
184
        self.stubs.Set(nova.db, 'instance_add_security_group',
 
185
                       return_security_group)
 
186
        self.stubs.Set(nova.db, 'instance_update', instance_update)
 
187
 
 
188
        self.config_drive = None
 
189
 
 
190
        self.controller = servers.Controller()
 
191
        self.ips_controller = ips.Controller()
 
192
 
 
193
        def nw_info(*args, **kwargs):
 
194
            return []
 
195
 
 
196
        floaters = nw_info
 
197
        fakes.stub_out_nw_api_get_instance_nw_info(self.stubs, nw_info)
 
198
        fakes.stub_out_nw_api_get_floating_ips_by_fixed_address(self.stubs,
 
199
                                                                floaters)
 
200
 
 
201
    def test_get_server_by_uuid(self):
 
202
        """
 
203
        The steps involved with resolving a UUID are pretty complicated;
 
204
        here's what's happening in this scenario:
 
205
 
 
206
        1. Show is calling `routing_get`
 
207
 
 
208
        2. `routing_get` is wrapped by `reroute_compute` which does the work
 
209
           of resolving requests to child zones.
 
210
 
 
211
        3. `reroute_compute` looks up the UUID by hitting the stub
 
212
           (returns_server_by_uuid)
 
213
 
 
214
        4. Since the stub return that the record exists, `reroute_compute`
 
215
           considers the request to be 'zone local', so it replaces the UUID
 
216
           in the argument list with an integer ID and then calls the inner
 
217
           function ('get').
 
218
 
 
219
        5. The call to `get` hits the other stub 'returns_server_by_id` which
 
220
           has the UUID set to FAKE_UUID
 
221
 
 
222
        So, counterintuitively, we call `get` twice on the `show` command.
 
223
        """
 
224
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
 
225
        res_dict = self.controller.show(req, FAKE_UUID)
 
226
        self.assertEqual(res_dict['server']['id'], FAKE_UUID)
 
227
 
 
228
    def test_get_server_by_id(self):
 
229
        self.flags(use_ipv6=True)
 
230
        image_bookmark = "http://localhost/fake/images/10"
 
231
        flavor_bookmark = "http://localhost/fake/flavors/1"
 
232
 
 
233
        uuid = FAKE_UUID
 
234
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % uuid)
 
235
        res_dict = self.controller.show(req, uuid)
 
236
        expected_server = {
 
237
            "server": {
 
238
                "id": uuid,
 
239
                "user_id": "fake",
 
240
                "tenant_id": "fake",
 
241
                "updated": "2010-11-11T11:00:00Z",
 
242
                "created": "2010-10-10T12:00:00Z",
 
243
                "progress": 0,
 
244
                "name": "server1",
 
245
                "status": "BUILD",
 
246
                "accessIPv4": "",
 
247
                "accessIPv6": "",
 
248
                "hostId": '',
 
249
                "key_name": '',
 
250
                "image": {
 
251
                    "id": "10",
 
252
                    "links": [
 
253
                        {
 
254
                            "rel": "bookmark",
 
255
                            "href": image_bookmark,
 
256
                        },
 
257
                    ],
 
258
                },
 
259
                "flavor": {
 
260
                    "id": "1",
 
261
                  "links": [
 
262
                                            {
 
263
                          "rel": "bookmark",
 
264
                          "href": flavor_bookmark,
 
265
                      },
 
266
                  ],
 
267
                },
 
268
                "addresses": {
 
269
                },
 
270
                "metadata": {
 
271
                    "seq": "1",
 
272
                },
 
273
                "config_drive": None,
 
274
                "links": [
 
275
                    {
 
276
                        "rel": "self",
 
277
                        "href": "http://localhost/v2/fake/servers/%s" % uuid,
 
278
                    },
 
279
                    {
 
280
                        "rel": "bookmark",
 
281
                        "href": "http://localhost/fake/servers/%s" % uuid,
 
282
                    },
 
283
                ],
 
284
            }
 
285
        }
 
286
 
 
287
        self.assertDictMatch(res_dict, expected_server)
 
288
 
 
289
    def test_get_server_with_active_status_by_id(self):
 
290
        image_bookmark = "http://localhost/fake/images/10"
 
291
        flavor_bookmark = "http://localhost/fake/flavors/1"
 
292
 
 
293
        new_return_server = return_server_with_attributes(
 
294
            vm_state=vm_states.ACTIVE, progress=100)
 
295
        self.stubs.Set(nova.db, 'instance_get', new_return_server)
 
296
 
 
297
        uuid = FAKE_UUID
 
298
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % uuid)
 
299
        res_dict = self.controller.show(req, uuid)
 
300
        expected_server = {
 
301
            "server": {
 
302
                "id": uuid,
 
303
                "user_id": "fake",
 
304
                "tenant_id": "fake",
 
305
                "updated": "2010-11-11T11:00:00Z",
 
306
                "created": "2010-10-10T12:00:00Z",
 
307
                "progress": 100,
 
308
                "name": "server1",
 
309
                "status": "ACTIVE",
 
310
                "accessIPv4": "",
 
311
                "accessIPv6": "",
 
312
                "hostId": '',
 
313
                "key_name": '',
 
314
                "image": {
 
315
                    "id": "10",
 
316
                    "links": [
 
317
                        {
 
318
                            "rel": "bookmark",
 
319
                            "href": image_bookmark,
 
320
                        },
 
321
                    ],
 
322
                },
 
323
                "flavor": {
 
324
                    "id": "1",
 
325
                  "links": [
 
326
                      {
 
327
                          "rel": "bookmark",
 
328
                          "href": flavor_bookmark,
 
329
                      },
 
330
                  ],
 
331
                },
 
332
                "addresses": {
 
333
                },
 
334
                "metadata": {
 
335
                    "seq": "1",
 
336
                },
 
337
                "config_drive": None,
 
338
                "links": [
 
339
                    {
 
340
                        "rel": "self",
 
341
                        "href": "http://localhost/v2/fake/servers/%s" % uuid,
 
342
                    },
 
343
                    {
 
344
                        "rel": "bookmark",
 
345
                        "href": "http://localhost/fake/servers/%s" % uuid,
 
346
                    },
 
347
                ],
 
348
            }
 
349
        }
 
350
 
 
351
        self.assertDictMatch(res_dict, expected_server)
 
352
 
 
353
    def test_get_server_with_id_image_ref_by_id(self):
 
354
        image_ref = "10"
 
355
        image_bookmark = "http://localhost/fake/images/10"
 
356
        flavor_id = "1"
 
357
        flavor_bookmark = "http://localhost/fake/flavors/1"
 
358
 
 
359
        new_return_server = return_server_with_attributes(
 
360
            vm_state=vm_states.ACTIVE, image_ref=image_ref,
 
361
            flavor_id=flavor_id, progress=100)
 
362
        self.stubs.Set(nova.db, 'instance_get', new_return_server)
 
363
 
 
364
        uuid = FAKE_UUID
 
365
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % uuid)
 
366
        res_dict = self.controller.show(req, uuid)
 
367
        expected_server = {
 
368
            "server": {
 
369
                "id": uuid,
 
370
                "user_id": "fake",
 
371
                "tenant_id": "fake",
 
372
                "updated": "2010-11-11T11:00:00Z",
 
373
                "created": "2010-10-10T12:00:00Z",
 
374
                "progress": 100,
 
375
                "name": "server1",
 
376
                "status": "ACTIVE",
 
377
                "accessIPv4": "",
 
378
                "accessIPv6": "",
 
379
                "hostId": '',
 
380
                "key_name": '',
 
381
                "image": {
 
382
                    "id": "10",
 
383
                    "links": [
 
384
                        {
 
385
                            "rel": "bookmark",
 
386
                            "href": image_bookmark,
 
387
                        },
 
388
                    ],
 
389
                },
 
390
                "flavor": {
 
391
                    "id": "1",
 
392
                  "links": [
 
393
                      {
 
394
                          "rel": "bookmark",
 
395
                          "href": flavor_bookmark,
 
396
                      },
 
397
                  ],
 
398
                },
 
399
                "addresses": {
 
400
                },
 
401
                "metadata": {
 
402
                    "seq": "1",
 
403
                },
 
404
                "config_drive": None,
 
405
                "links": [
 
406
                    {
 
407
                        "rel": "self",
 
408
                        "href": "http://localhost/v2/fake/servers/%s" % uuid,
 
409
                    },
 
410
                    {
 
411
                        "rel": "bookmark",
 
412
                        "href": "http://localhost/fake/servers/%s" % uuid,
 
413
                    },
 
414
                ],
 
415
            }
 
416
        }
 
417
 
 
418
        self.assertDictMatch(res_dict, expected_server)
 
419
 
 
420
    # NOTE(bcwaldon): lp830817
 
421
    def test_get_server_by_id_malformed_networks(self):
 
422
        def fake_instance_get(context, instance_uuid):
 
423
            instance = return_server_by_uuid(context, instance_uuid)
 
424
            instance['fixed_ips'] = [dict(network=None, address='1.2.3.4')]
 
425
            return instance
 
426
 
 
427
        self.stubs.Set(nova.db, 'instance_get_by_uuid', fake_instance_get)
 
428
 
 
429
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
 
430
        res_dict = self.controller.show(req, FAKE_UUID)
 
431
 
 
432
        self.assertEqual(res_dict['server']['id'], FAKE_UUID)
 
433
        self.assertEqual(res_dict['server']['name'], 'server1')
 
434
 
 
435
    def test_get_server_by_id_malformed_vif(self):
 
436
        def fake_instance_get(context, uuid):
 
437
            instance = return_server_by_uuid(context, uuid)
 
438
            instance['fixed_ips'] = [dict(network={'label': 'meow'},
 
439
                    address='1.2.3.4', virtual_interface=None)]
 
440
            return instance
 
441
 
 
442
        self.stubs.Set(nova.db, 'instance_get_by_uuid', fake_instance_get)
 
443
 
 
444
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
 
445
        res_dict = self.controller.show(req, FAKE_UUID)
 
446
 
 
447
        self.assertEqual(res_dict['server']['id'], FAKE_UUID)
 
448
        self.assertEqual(res_dict['server']['name'], 'server1')
 
449
 
 
450
    def test_get_server_by_id_with_addresses(self):
 
451
        self.flags(use_ipv6=True)
 
452
        privates = ['192.168.0.3', '192.168.0.4']
 
453
        publics = ['172.19.0.1', '172.19.0.2']
 
454
        public6s = ['b33f::fdee:ddff:fecc:bbaa']
 
455
 
 
456
        def nw_info(*args, **kwargs):
 
457
            return [(None, {'label': 'public',
 
458
                            'ips': [dict(ip=ip) for ip in publics],
 
459
                            'ip6s': [dict(ip=ip) for ip in public6s]}),
 
460
                    (None, {'label': 'private',
 
461
                            'ips': [dict(ip=ip) for ip in privates]})]
 
462
 
 
463
        def floaters(*args, **kwargs):
 
464
            return []
 
465
 
 
466
        new_return_server = return_server_with_attributes()
 
467
        fakes.stub_out_nw_api_get_instance_nw_info(self.stubs, nw_info)
 
468
        fakes.stub_out_nw_api_get_floating_ips_by_fixed_address(self.stubs,
 
469
                                                                floaters)
 
470
        self.stubs.Set(nova.db, 'instance_get', new_return_server)
 
471
 
 
472
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
 
473
        res_dict = self.controller.show(req, FAKE_UUID)
 
474
 
 
475
        self.assertEqual(res_dict['server']['id'], FAKE_UUID)
 
476
        self.assertEqual(res_dict['server']['name'], 'server1')
 
477
        addresses = res_dict['server']['addresses']
 
478
        expected = {
 
479
            'private': [
 
480
                {'addr': '192.168.0.3', 'version': 4},
 
481
                {'addr': '192.168.0.4', 'version': 4},
 
482
            ],
 
483
            'public': [
 
484
                {'addr': '172.19.0.1', 'version': 4},
 
485
                {'addr': '172.19.0.2', 'version': 4},
 
486
                {'addr': 'b33f::fdee:ddff:fecc:bbaa', 'version': 6},
 
487
            ],
 
488
        }
 
489
        self.assertDictMatch(addresses, expected)
 
490
 
 
491
    def test_get_server_addresses_from_nwinfo(self):
 
492
        self.flags(use_ipv6=True)
 
493
 
 
494
        privates = ['192.168.0.3', '192.168.0.4']
 
495
        publics = ['172.19.0.1', '1.2.3.4', '172.19.0.2']
 
496
 
 
497
        public6s = ['b33f::fdee:ddff:fecc:bbaa']
 
498
 
 
499
        def nw_info(*args, **kwargs):
 
500
            return [(None, {'label': 'public',
 
501
                            'ips': [dict(ip=ip) for ip in publics],
 
502
                            'ip6s': [dict(ip=ip) for ip in public6s]}),
 
503
                    (None, {'label': 'private',
 
504
                            'ips': [dict(ip=ip) for ip in privates]})]
 
505
 
 
506
        def floaters(*args, **kwargs):
 
507
            return []
 
508
 
 
509
        new_return_server = return_server_with_attributes_by_uuid()
 
510
        fakes.stub_out_nw_api_get_instance_nw_info(self.stubs, nw_info)
 
511
        fakes.stub_out_nw_api_get_floating_ips_by_fixed_address(self.stubs,
 
512
                                                                floaters)
 
513
        self.stubs.Set(nova.db, 'instance_get_by_uuid', new_return_server)
 
514
 
 
515
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s/ips' % FAKE_UUID)
 
516
        res_dict = self.ips_controller.index(req, FAKE_UUID)
 
517
 
 
518
        expected = {
 
519
            'addresses': {
 
520
                'private': [
 
521
                    {'version': 4, 'addr': '192.168.0.3'},
 
522
                    {'version': 4, 'addr': '192.168.0.4'},
 
523
                ],
 
524
                'public': [
 
525
                    {'version': 4, 'addr': '172.19.0.1'},
 
526
                    {'version': 4, 'addr': '1.2.3.4'},
 
527
                    {'version': 4, 'addr': '172.19.0.2'},
 
528
                    {'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
 
529
                ],
 
530
            },
 
531
        }
 
532
        self.assertDictMatch(res_dict, expected)
 
533
 
 
534
    def test_get_server_addresses_from_cache(self):
 
535
        pub0 = ('172.19.0.1', '172.19.0.2',)
 
536
        pub1 = ('1.2.3.4',)
 
537
        pub2 = ('b33f::fdee:ddff:fecc:bbaa',)
 
538
        priv0 = ('192.168.0.3', '192.168.0.4',)
 
539
 
 
540
        def _ip(ip):
 
541
            return {'address': ip, 'type': 'fixed'}
 
542
 
 
543
        nw_cache = [
 
544
            {'address': 'aa:aa:aa:aa:aa:aa',
 
545
             'id': 1,
 
546
             'network': {'bridge': 'br0',
 
547
                         'id': 1,
 
548
                         'label': 'public',
 
549
                         'subnets': [{'cidr': '172.19.0.0/24',
 
550
                                      'ips': [_ip(ip) for ip in pub0]},
 
551
                                      {'cidr': '1.2.3.0/16',
 
552
                                       'ips': [_ip(ip) for ip in pub1]},
 
553
                                      {'cidr': 'b33f::/64',
 
554
                                       'ips': [_ip(ip) for ip in pub2]}]}},
 
555
            {'address': 'bb:bb:bb:bb:bb:bb',
 
556
             'id': 2,
 
557
             'network': {'bridge': 'br1',
 
558
                         'id': 2,
 
559
                         'label': 'private',
 
560
                         'subnets': [{'cidr': '192.168.0.0/24',
 
561
                                      'ips': [_ip(ip) for ip in priv0]}]}}]
 
562
 
 
563
        kwargs = {'nw_cache': nw_cache}
 
564
        new_return_server = return_server_with_attributes_by_uuid(**kwargs)
 
565
        self.stubs.Set(nova.db, 'instance_get_by_uuid', new_return_server)
 
566
 
 
567
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s/ips' % FAKE_UUID)
 
568
        res_dict = self.ips_controller.index(req, FAKE_UUID)
 
569
 
 
570
        expected = {
 
571
            'addresses': {
 
572
                'private': [
 
573
                    {'version': 4, 'addr': '192.168.0.3'},
 
574
                    {'version': 4, 'addr': '192.168.0.4'},
 
575
                ],
 
576
                'public': [
 
577
                    {'version': 4, 'addr': '172.19.0.1'},
 
578
                    {'version': 4, 'addr': '172.19.0.2'},
 
579
                    {'version': 4, 'addr': '1.2.3.4'},
 
580
                    {'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
 
581
                ],
 
582
            },
 
583
        }
 
584
        self.assertDictMatch(res_dict, expected)
 
585
 
 
586
    def test_get_server_addresses_with_floating_from_nwinfo(self):
 
587
        ips = dict(privates=['192.168.0.3', '192.168.0.4'],
 
588
                   publics=['172.19.0.1', '1.2.3.4', '172.19.0.2'])
 
589
 
 
590
        def nw_info(*args, **kwargs):
 
591
            return [(None, {'label': 'private',
 
592
                            'ips': [dict(ip=ip)
 
593
                                    for ip in ips['privates']]})]
 
594
 
 
595
        def floaters(*args, **kwargs):
 
596
            # NOTE(jkoelker) floaters will get called multiple times
 
597
            #                this makes sure it will only return data
 
598
            #                once
 
599
            pubs = list(ips['publics'])
 
600
            ips['publics'] = []
 
601
            return pubs
 
602
 
 
603
        new_return_server = return_server_with_attributes_by_uuid()
 
604
        fakes.stub_out_nw_api_get_instance_nw_info(self.stubs, nw_info)
 
605
        fakes.stub_out_nw_api_get_floating_ips_by_fixed_address(self.stubs,
 
606
                                                                floaters)
 
607
        self.stubs.Set(nova.db, 'instance_get_by_uuid', new_return_server)
 
608
 
 
609
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s/ips' % FAKE_UUID)
 
610
        res_dict = self.ips_controller.index(req, FAKE_UUID)
 
611
 
 
612
        expected = {
 
613
            'addresses': {
 
614
                'private': [
 
615
                    {'version': 4, 'addr': '192.168.0.3'},
 
616
                    {'version': 4, 'addr': '192.168.0.4'},
 
617
                    {'version': 4, 'addr': '172.19.0.1'},
 
618
                    {'version': 4, 'addr': '1.2.3.4'},
 
619
                    {'version': 4, 'addr': '172.19.0.2'},
 
620
                ],
 
621
            },
 
622
        }
 
623
        self.assertDictMatch(res_dict, expected)
 
624
 
 
625
    def test_get_server_addresses_single_network_from_nwinfo(self):
 
626
        self.flags(use_ipv6=True)
 
627
        privates = ['192.168.0.3', '192.168.0.4']
 
628
        publics = ['172.19.0.1', '1.2.3.4', '172.19.0.2']
 
629
        public6s = ['b33f::fdee:ddff:fecc:bbaa']
 
630
 
 
631
        def nw_info(*args, **kwargs):
 
632
            return [(None, {'label': 'public',
 
633
                            'ips': [dict(ip=ip) for ip in publics],
 
634
                            'ip6s': [dict(ip=ip) for ip in public6s]}),
 
635
                    (None, {'label': 'private',
 
636
                            'ips': [dict(ip=ip) for ip in privates]})]
 
637
 
 
638
        def floaters(*args, **kwargs):
 
639
            return []
 
640
 
 
641
        new_return_server = return_server_with_attributes_by_uuid()
 
642
        fakes.stub_out_nw_api_get_instance_nw_info(self.stubs, nw_info)
 
643
        fakes.stub_out_nw_api_get_floating_ips_by_fixed_address(self.stubs,
 
644
                                                                floaters)
 
645
        self.stubs.Set(nova.db, 'instance_get_by_uuid', new_return_server)
 
646
 
 
647
        url = '/v2/fake/servers/%s/ips/public' % FAKE_UUID
 
648
        req = fakes.HTTPRequest.blank(url)
 
649
        res_dict = self.ips_controller.show(req, FAKE_UUID, 'public')
 
650
 
 
651
        expected = {
 
652
            'public': [
 
653
                {'version': 4, 'addr': '172.19.0.1'},
 
654
                {'version': 4, 'addr': '1.2.3.4'},
 
655
                {'version': 4, 'addr': '172.19.0.2'},
 
656
                {'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
 
657
            ],
 
658
        }
 
659
        self.assertDictMatch(res_dict, expected)
 
660
 
 
661
    def test_get_server_addresses_nonexistant_network(self):
 
662
        url = '/v2/fake/servers/%s/ips/network_0' % FAKE_UUID
 
663
        req = fakes.HTTPRequest.blank(url)
 
664
        self.assertRaises(webob.exc.HTTPNotFound, self.ips_controller.show,
 
665
                          req, FAKE_UUID, 'network_0')
 
666
 
 
667
    def test_get_server_addresses_nonexistant_server(self):
 
668
        def fake_instance_get(*args, **kwargs):
 
669
            raise nova.exception.InstanceNotFound()
 
670
 
 
671
        self.stubs.Set(nova.db, 'instance_get_by_uuid', fake_instance_get)
 
672
 
 
673
        server_id = str(utils.gen_uuid())
 
674
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s/ips' % server_id)
 
675
        self.assertRaises(webob.exc.HTTPNotFound,
 
676
                          self.ips_controller.index, req, server_id)
 
677
 
 
678
    def test_get_server_list_with_reservation_id(self):
 
679
        self.stubs.Set(nova.db, 'instance_get_all_by_reservation',
 
680
                       return_servers_by_reservation)
 
681
        self.stubs.Set(nova.scheduler.api, 'call_zone_method',
 
682
                       return_servers_from_child_zones)
 
683
 
 
684
        req = fakes.HTTPRequest.blank('/v2/fake/servers?reservation_id=foo')
 
685
        res_dict = self.controller.index(req)
 
686
 
 
687
        i = 0
 
688
        for s in res_dict['servers']:
 
689
            if '_is_precooked' in s:
 
690
                self.assertEqual(s.get('reservation_id'), 'child')
 
691
            else:
 
692
                print s
 
693
                self.assertEqual(s.get('name'), 'server%d' % i)
 
694
                i += 1
 
695
 
 
696
    def test_get_server_list_with_reservation_id_empty(self):
 
697
        self.stubs.Set(nova.db, 'instance_get_all_by_reservation',
 
698
                       return_servers_by_reservation_empty)
 
699
        self.stubs.Set(nova.scheduler.api, 'call_zone_method',
 
700
                       return_servers_from_child_zones_empty)
 
701
 
 
702
        req = fakes.HTTPRequest.blank('/v2/fake/servers/detail?'
 
703
                                      'reservation_id=foo')
 
704
        res_dict = self.controller.detail(req)
 
705
 
 
706
        i = 0
 
707
        for s in res_dict['servers']:
 
708
            if '_is_precooked' in s:
 
709
                self.assertEqual(s.get('reservation_id'), 'child')
 
710
            else:
 
711
                self.assertEqual(s.get('name'), 'server%d' % i)
 
712
                i += 1
 
713
 
 
714
    def test_get_server_list_with_reservation_id_details(self):
 
715
        self.stubs.Set(nova.db, 'instance_get_all_by_reservation',
 
716
                       return_servers_by_reservation)
 
717
        self.stubs.Set(nova.scheduler.api, 'call_zone_method',
 
718
                       return_servers_from_child_zones)
 
719
 
 
720
        req = fakes.HTTPRequest.blank('/v2/fake/servers/detail?'
 
721
                                      'reservation_id=foo')
 
722
        res_dict = self.controller.detail(req)
 
723
 
 
724
        i = 0
 
725
        for s in res_dict['servers']:
 
726
            if '_is_precooked' in s:
 
727
                self.assertEqual(s.get('reservation_id'), 'child')
 
728
            else:
 
729
                self.assertEqual(s.get('name'), 'server%d' % i)
 
730
                i += 1
 
731
 
 
732
    def test_get_server_list(self):
 
733
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
734
        res_dict = self.controller.index(req)
 
735
 
 
736
        self.assertEqual(len(res_dict['servers']), 5)
 
737
        for i, s in enumerate(res_dict['servers']):
 
738
            self.assertEqual(s['id'], get_fake_uuid(i))
 
739
            self.assertEqual(s['name'], 'server%d' % i)
 
740
            self.assertEqual(s.get('image', None), None)
 
741
 
 
742
            expected_links = [
 
743
                {
 
744
                    "rel": "self",
 
745
                    "href": "http://localhost/v2/fake/servers/%s" % s['id'],
 
746
                },
 
747
                {
 
748
                    "rel": "bookmark",
 
749
                    "href": "http://localhost/fake/servers/%s" % s['id'],
 
750
                },
 
751
            ]
 
752
 
 
753
            self.assertEqual(s['links'], expected_links)
 
754
 
 
755
    def test_get_servers_with_limit(self):
 
756
        req = fakes.HTTPRequest.blank('/v2/fake/servers?limit=3')
 
757
        res_dict = self.controller.index(req)
 
758
 
 
759
        servers = res_dict['servers']
 
760
        self.assertEqual([s['id'] for s in servers],
 
761
                         [get_fake_uuid(i) for i in xrange(len(servers))])
 
762
 
 
763
        servers_links = res_dict['servers_links']
 
764
        self.assertEqual(servers_links[0]['rel'], 'next')
 
765
        href_parts = urlparse.urlparse(servers_links[0]['href'])
 
766
        self.assertEqual('/v2/fake/servers', href_parts.path)
 
767
        params = urlparse.parse_qs(href_parts.query)
 
768
        expected_params = {'limit': ['3'], 'marker': [get_fake_uuid(2)]}
 
769
        self.assertDictMatch(expected_params, params)
 
770
 
 
771
    def test_get_servers_with_limit_bad_value(self):
 
772
        req = fakes.HTTPRequest.blank('/v2/fake/servers?limit=aaa')
 
773
        self.assertRaises(webob.exc.HTTPBadRequest,
 
774
                          self.controller.index, req)
 
775
 
 
776
    def test_get_server_details_with_limit(self):
 
777
        req = fakes.HTTPRequest.blank('/v2/fake/servers/detail?limit=3')
 
778
        res = self.controller.detail(req)
 
779
 
 
780
        servers = res['servers']
 
781
        self.assertEqual([s['id'] for s in servers],
 
782
                         [get_fake_uuid(i) for i in xrange(len(servers))])
 
783
 
 
784
        servers_links = res['servers_links']
 
785
        self.assertEqual(servers_links[0]['rel'], 'next')
 
786
 
 
787
        href_parts = urlparse.urlparse(servers_links[0]['href'])
 
788
        self.assertEqual('/v2/fake/servers', href_parts.path)
 
789
        params = urlparse.parse_qs(href_parts.query)
 
790
        expected = {'limit': ['3'], 'marker': [get_fake_uuid(2)]}
 
791
        self.assertDictMatch(expected, params)
 
792
 
 
793
    def test_get_server_details_with_limit_bad_value(self):
 
794
        req = fakes.HTTPRequest.blank('/v2/fake/servers/detail?limit=aaa')
 
795
        self.assertRaises(webob.exc.HTTPBadRequest,
 
796
                          self.controller.detail, req)
 
797
 
 
798
    def test_get_server_details_with_limit_and_other_params(self):
 
799
        req = fakes.HTTPRequest.blank('/v2/fake/servers/detail'
 
800
                                      '?limit=3&blah=2:t')
 
801
        res = self.controller.detail(req)
 
802
 
 
803
        servers = res['servers']
 
804
        self.assertEqual([s['id'] for s in servers],
 
805
                         [get_fake_uuid(i) for i in xrange(len(servers))])
 
806
 
 
807
        servers_links = res['servers_links']
 
808
        self.assertEqual(servers_links[0]['rel'], 'next')
 
809
 
 
810
        href_parts = urlparse.urlparse(servers_links[0]['href'])
 
811
        self.assertEqual('/v2/fake/servers', href_parts.path)
 
812
        params = urlparse.parse_qs(href_parts.query)
 
813
 
 
814
        self.assertDictMatch({'limit': ['3'], 'blah': ['2:t'],
 
815
                              'marker': [get_fake_uuid(2)]}, params)
 
816
 
 
817
    def test_get_servers_with_too_big_limit(self):
 
818
        req = fakes.HTTPRequest.blank('/v2/fake/servers?limit=30')
 
819
        res_dict = self.controller.index(req)
 
820
        self.assertTrue('servers_links' not in res_dict)
 
821
 
 
822
    def test_get_servers_with_bad_limit(self):
 
823
        req = fakes.HTTPRequest.blank('/v2/fake/servers?limit=asdf')
 
824
        self.assertRaises(webob.exc.HTTPBadRequest,
 
825
                          self.controller.index, req)
 
826
 
 
827
    def test_get_servers_with_marker(self):
 
828
        url = '/v2/fake/servers?marker=%s' % get_fake_uuid(2)
 
829
        req = fakes.HTTPRequest.blank(url)
 
830
        servers = self.controller.index(req)['servers']
 
831
        self.assertEqual([s['name'] for s in servers], ["server3", "server4"])
 
832
 
 
833
    def test_get_servers_with_limit_and_marker(self):
 
834
        url = '/v2/fake/servers?limit=2&marker=%s' % get_fake_uuid(1)
 
835
        req = fakes.HTTPRequest.blank(url)
 
836
        servers = self.controller.index(req)['servers']
 
837
        self.assertEqual([s['name'] for s in servers], ['server2', 'server3'])
 
838
 
 
839
    def test_get_servers_with_bad_marker(self):
 
840
        req = fakes.HTTPRequest.blank('/v2/fake/servers?limit=2&marker=asdf')
 
841
        self.assertRaises(webob.exc.HTTPBadRequest,
 
842
                          self.controller.index, req)
 
843
 
 
844
    def test_get_servers_with_bad_option(self):
 
845
        server_uuid = str(utils.gen_uuid())
 
846
 
 
847
        def fake_get_all(compute_self, context, search_opts=None):
 
848
            return [fakes.stub_instance(100, uuid=server_uuid)]
 
849
 
 
850
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
 
851
 
 
852
        req = fakes.HTTPRequest.blank('/v2/fake/servers?unknownoption=whee')
 
853
        servers = self.controller.index(req)['servers']
 
854
 
 
855
        self.assertEqual(len(servers), 1)
 
856
        self.assertEqual(servers[0]['id'], server_uuid)
 
857
 
 
858
    def test_get_servers_allows_image(self):
 
859
        server_uuid = str(utils.gen_uuid())
 
860
 
 
861
        def fake_get_all(compute_self, context, search_opts=None):
 
862
            self.assertNotEqual(search_opts, None)
 
863
            self.assertTrue('image' in search_opts)
 
864
            self.assertEqual(search_opts['image'], '12345')
 
865
            return [fakes.stub_instance(100, uuid=server_uuid)]
 
866
 
 
867
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
 
868
        self.flags(allow_admin_api=False)
 
869
 
 
870
        req = fakes.HTTPRequest.blank('/v2/fake/servers?image=12345')
 
871
        servers = self.controller.index(req)['servers']
 
872
 
 
873
        self.assertEqual(len(servers), 1)
 
874
        self.assertEqual(servers[0]['id'], server_uuid)
 
875
 
 
876
    def test_tenant_id_filter_converts_to_project_id_for_admin(self):
 
877
        def fake_get_all(context, filters=None, instances=None):
 
878
            self.assertNotEqual(filters, None)
 
879
            self.assertEqual(filters['project_id'], 'fake')
 
880
            self.assertFalse(filters.get('tenant_id'))
 
881
            return [fakes.stub_instance(100)]
 
882
 
 
883
        self.stubs.Set(nova.db, 'instance_get_all_by_filters',
 
884
                       fake_get_all)
 
885
        self.flags(allow_admin_api=True)
 
886
 
 
887
        req = fakes.HTTPRequest.blank('/v2/fake/servers?tenant_id=fake',
 
888
                                      use_admin_context=True)
 
889
        res = self.controller.index(req)
 
890
 
 
891
        self.assertTrue('servers' in res)
 
892
 
 
893
    def test_get_servers_allows_flavor(self):
 
894
        server_uuid = str(utils.gen_uuid())
 
895
 
 
896
        def fake_get_all(compute_self, context, search_opts=None):
 
897
            self.assertNotEqual(search_opts, None)
 
898
            self.assertTrue('flavor' in search_opts)
 
899
            # flavor is an integer ID
 
900
            self.assertEqual(search_opts['flavor'], '12345')
 
901
            return [fakes.stub_instance(100, uuid=server_uuid)]
 
902
 
 
903
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
 
904
        self.flags(allow_admin_api=False)
 
905
 
 
906
        req = fakes.HTTPRequest.blank('/v2/fake/servers?flavor=12345')
 
907
        servers = self.controller.index(req)['servers']
 
908
 
 
909
        self.assertEqual(len(servers), 1)
 
910
        self.assertEqual(servers[0]['id'], server_uuid)
 
911
 
 
912
    def test_get_servers_allows_status(self):
 
913
        server_uuid = str(utils.gen_uuid())
 
914
 
 
915
        def fake_get_all(compute_self, context, search_opts=None):
 
916
            self.assertNotEqual(search_opts, None)
 
917
            self.assertTrue('vm_state' in search_opts)
 
918
            self.assertEqual(search_opts['vm_state'], vm_states.ACTIVE)
 
919
            return [fakes.stub_instance(100, uuid=server_uuid)]
 
920
 
 
921
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
 
922
        self.flags(allow_admin_api=False)
 
923
 
 
924
        req = fakes.HTTPRequest.blank('/v2/fake/servers?status=active')
 
925
        servers = self.controller.index(req)['servers']
 
926
 
 
927
        self.assertEqual(len(servers), 1)
 
928
        self.assertEqual(servers[0]['id'], server_uuid)
 
929
 
 
930
    def test_get_servers_invalid_status(self):
 
931
        """Test getting servers by invalid status"""
 
932
        self.flags(allow_admin_api=False)
 
933
        req = fakes.HTTPRequest.blank('/v2/fake/servers?status=unknown')
 
934
        self.assertRaises(webob.exc.HTTPBadRequest, self.controller.index, req)
 
935
 
 
936
    def test_get_servers_allows_name(self):
 
937
        server_uuid = str(utils.gen_uuid())
 
938
 
 
939
        def fake_get_all(compute_self, context, search_opts=None):
 
940
            self.assertNotEqual(search_opts, None)
 
941
            self.assertTrue('name' in search_opts)
 
942
            self.assertEqual(search_opts['name'], 'whee.*')
 
943
            return [fakes.stub_instance(100, uuid=server_uuid)]
 
944
 
 
945
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
 
946
        self.flags(allow_admin_api=False)
 
947
 
 
948
        req = fakes.HTTPRequest.blank('/v2/fake/servers?name=whee.*')
 
949
        servers = self.controller.index(req)['servers']
 
950
 
 
951
        self.assertEqual(len(servers), 1)
 
952
        self.assertEqual(servers[0]['id'], server_uuid)
 
953
 
 
954
    def test_get_servers_allows_changes_since(self):
 
955
        server_uuid = str(utils.gen_uuid())
 
956
 
 
957
        def fake_get_all(compute_self, context, search_opts=None):
 
958
            self.assertNotEqual(search_opts, None)
 
959
            self.assertTrue('changes-since' in search_opts)
 
960
            changes_since = datetime.datetime(2011, 1, 24, 17, 8, 1)
 
961
            self.assertEqual(search_opts['changes-since'], changes_since)
 
962
            self.assertTrue('deleted' not in search_opts)
 
963
            return [fakes.stub_instance(100, uuid=server_uuid)]
 
964
 
 
965
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
 
966
 
 
967
        params = 'changes-since=2011-01-24T17:08:01Z'
 
968
        req = fakes.HTTPRequest.blank('/v2/fake/servers?%s' % params)
 
969
        servers = self.controller.index(req)['servers']
 
970
 
 
971
        self.assertEqual(len(servers), 1)
 
972
        self.assertEqual(servers[0]['id'], server_uuid)
 
973
 
 
974
    def test_get_servers_allows_changes_since_bad_value(self):
 
975
        params = 'changes-since=asdf'
 
976
        req = fakes.HTTPRequest.blank('/v2/fake/servers?%s' % params)
 
977
        self.assertRaises(webob.exc.HTTPBadRequest, self.controller.index, req)
 
978
 
 
979
    def test_get_servers_unknown_or_admin_options1(self):
 
980
        """Test getting servers by admin-only or unknown options.
 
981
        This tests when admin_api is off.  Make sure the admin and
 
982
        unknown options are stripped before they get to
 
983
        compute_api.get_all()
 
984
        """
 
985
 
 
986
        self.flags(allow_admin_api=False)
 
987
 
 
988
        server_uuid = str(utils.gen_uuid())
 
989
 
 
990
        def fake_get_all(compute_self, context, search_opts=None):
 
991
            self.assertNotEqual(search_opts, None)
 
992
            # Allowed by user
 
993
            self.assertTrue('name' in search_opts)
 
994
            self.assertTrue('status' in search_opts)
 
995
            # Allowed only by admins with admin API on
 
996
            self.assertFalse('ip' in search_opts)
 
997
            self.assertFalse('unknown_option' in search_opts)
 
998
            return [fakes.stub_instance(100, uuid=server_uuid)]
 
999
 
 
1000
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
 
1001
 
 
1002
        query_str = "name=foo&ip=10.*&status=active&unknown_option=meow"
 
1003
        req = fakes.HTTPRequest.blank('/v2/fake/servers?%s' % query_str,
 
1004
                                      use_admin_context=True)
 
1005
        res = self.controller.index(req)
 
1006
 
 
1007
        servers = res['servers']
 
1008
        self.assertEqual(len(servers), 1)
 
1009
        self.assertEqual(servers[0]['id'], server_uuid)
 
1010
 
 
1011
    def test_get_servers_unknown_or_admin_options2(self):
 
1012
        """Test getting servers by admin-only or unknown options.
 
1013
        This tests when admin_api is on, but context is a user.
 
1014
        Make sure the admin and unknown options are stripped before
 
1015
        they get to compute_api.get_all()
 
1016
        """
 
1017
 
 
1018
        self.flags(allow_admin_api=True)
 
1019
 
 
1020
        server_uuid = str(utils.gen_uuid())
 
1021
 
 
1022
        def fake_get_all(compute_self, context, search_opts=None):
 
1023
            self.assertNotEqual(search_opts, None)
 
1024
            # Allowed by user
 
1025
            self.assertTrue('name' in search_opts)
 
1026
            self.assertTrue('status' in search_opts)
 
1027
            # Allowed only by admins with admin API on
 
1028
            self.assertFalse('ip' in search_opts)
 
1029
            self.assertFalse('unknown_option' in search_opts)
 
1030
            return [fakes.stub_instance(100, uuid=server_uuid)]
 
1031
 
 
1032
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
 
1033
 
 
1034
        query_str = "name=foo&ip=10.*&status=active&unknown_option=meow"
 
1035
        req = fakes.HTTPRequest.blank('/v2/fake/servers?%s' % query_str)
 
1036
        res = self.controller.index(req)
 
1037
 
 
1038
        servers = res['servers']
 
1039
        self.assertEqual(len(servers), 1)
 
1040
        self.assertEqual(servers[0]['id'], server_uuid)
 
1041
 
 
1042
    def test_get_servers_unknown_or_admin_options3(self):
 
1043
        """Test getting servers by admin-only or unknown options.
 
1044
        This tests when admin_api is on and context is admin.
 
1045
        All options should be passed through to compute_api.get_all()
 
1046
        """
 
1047
 
 
1048
        self.flags(allow_admin_api=True)
 
1049
 
 
1050
        server_uuid = str(utils.gen_uuid())
 
1051
 
 
1052
        def fake_get_all(compute_self, context, search_opts=None):
 
1053
            self.assertNotEqual(search_opts, None)
 
1054
            # Allowed by user
 
1055
            self.assertTrue('name' in search_opts)
 
1056
            self.assertTrue('status' in search_opts)
 
1057
            # Allowed only by admins with admin API on
 
1058
            self.assertTrue('ip' in search_opts)
 
1059
            self.assertTrue('unknown_option' in search_opts)
 
1060
            return [fakes.stub_instance(100, uuid=server_uuid)]
 
1061
 
 
1062
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
 
1063
 
 
1064
        query_str = "name=foo&ip=10.*&status=active&unknown_option=meow"
 
1065
        req = fakes.HTTPRequest.blank('/v2/fake/servers?%s' % query_str,
 
1066
                                      use_admin_context=True)
 
1067
        servers = self.controller.index(req)['servers']
 
1068
 
 
1069
        self.assertEqual(len(servers), 1)
 
1070
        self.assertEqual(servers[0]['id'], server_uuid)
 
1071
 
 
1072
    def test_get_servers_admin_allows_ip(self):
 
1073
        """Test getting servers by ip with admin_api enabled and
 
1074
        admin context
 
1075
        """
 
1076
        self.flags(allow_admin_api=True)
 
1077
 
 
1078
        server_uuid = str(utils.gen_uuid())
 
1079
 
 
1080
        def fake_get_all(compute_self, context, search_opts=None):
 
1081
            self.assertNotEqual(search_opts, None)
 
1082
            self.assertTrue('ip' in search_opts)
 
1083
            self.assertEqual(search_opts['ip'], '10\..*')
 
1084
            return [fakes.stub_instance(100, uuid=server_uuid)]
 
1085
 
 
1086
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
 
1087
 
 
1088
        req = fakes.HTTPRequest.blank('/v2/fake/servers?ip=10\..*',
 
1089
                                      use_admin_context=True)
 
1090
        servers = self.controller.index(req)['servers']
 
1091
 
 
1092
        self.assertEqual(len(servers), 1)
 
1093
        self.assertEqual(servers[0]['id'], server_uuid)
 
1094
 
 
1095
    def test_get_servers_admin_allows_ip6(self):
 
1096
        """Test getting servers by ip6 with admin_api enabled and
 
1097
        admin context
 
1098
        """
 
1099
        self.flags(allow_admin_api=True)
 
1100
 
 
1101
        server_uuid = str(utils.gen_uuid())
 
1102
 
 
1103
        def fake_get_all(compute_self, context, search_opts=None):
 
1104
            self.assertNotEqual(search_opts, None)
 
1105
            self.assertTrue('ip6' in search_opts)
 
1106
            self.assertEqual(search_opts['ip6'], 'ffff.*')
 
1107
            return [fakes.stub_instance(100, uuid=server_uuid)]
 
1108
 
 
1109
        self.stubs.Set(nova.compute.API, 'get_all', fake_get_all)
 
1110
 
 
1111
        req = fakes.HTTPRequest.blank('/v2/fake/servers?ip6=ffff.*',
 
1112
                                      use_admin_context=True)
 
1113
        servers = self.controller.index(req)['servers']
 
1114
 
 
1115
        self.assertEqual(len(servers), 1)
 
1116
        self.assertEqual(servers[0]['id'], server_uuid)
 
1117
 
 
1118
    def test_update_server_no_body(self):
 
1119
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
 
1120
        req.method = 'PUT'
 
1121
 
 
1122
        self.assertRaises(webob.exc.HTTPUnprocessableEntity,
 
1123
                          self.controller.update, req, FAKE_UUID, None)
 
1124
 
 
1125
    def test_update_server_all_attributes(self):
 
1126
        self.stubs.Set(nova.db, 'instance_get',
 
1127
                return_server_with_attributes(name='server_test',
 
1128
                                              access_ipv4='0.0.0.0',
 
1129
                                              access_ipv6='beef::0123'))
 
1130
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
 
1131
        req.method = 'PUT'
 
1132
        req.content_type = 'application/json'
 
1133
        body = {'server': {
 
1134
                  'name': 'server_test',
 
1135
                  'accessIPv4': '0.0.0.0',
 
1136
                  'accessIPv6': 'beef::0123',
 
1137
               }}
 
1138
        req.body = json.dumps(body)
 
1139
        res_dict = self.controller.update(req, FAKE_UUID, body)
 
1140
 
 
1141
        self.assertEqual(res_dict['server']['id'], FAKE_UUID)
 
1142
        self.assertEqual(res_dict['server']['name'], 'server_test')
 
1143
        self.assertEqual(res_dict['server']['accessIPv4'], '0.0.0.0')
 
1144
        self.assertEqual(res_dict['server']['accessIPv6'], 'beef::0123')
 
1145
 
 
1146
    def test_update_server_name(self):
 
1147
        self.stubs.Set(nova.db, 'instance_get',
 
1148
                return_server_with_attributes(name='server_test'))
 
1149
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
 
1150
        req.method = 'PUT'
 
1151
        req.content_type = 'application/json'
 
1152
        body = {'server': {'name': 'server_test'}}
 
1153
        req.body = json.dumps(body)
 
1154
        res_dict = self.controller.update(req, FAKE_UUID, body)
 
1155
 
 
1156
        self.assertEqual(res_dict['server']['id'], FAKE_UUID)
 
1157
        self.assertEqual(res_dict['server']['name'], 'server_test')
 
1158
 
 
1159
    def test_update_server_access_ipv4(self):
 
1160
        self.stubs.Set(nova.db, 'instance_get',
 
1161
                return_server_with_attributes(access_ipv4='0.0.0.0'))
 
1162
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
 
1163
        req.method = 'PUT'
 
1164
        req.content_type = 'application/json'
 
1165
        body = {'server': {'accessIPv4': '0.0.0.0'}}
 
1166
        req.body = json.dumps(body)
 
1167
        res_dict = self.controller.update(req, FAKE_UUID, body)
 
1168
 
 
1169
        self.assertEqual(res_dict['server']['id'], FAKE_UUID)
 
1170
        self.assertEqual(res_dict['server']['accessIPv4'], '0.0.0.0')
 
1171
 
 
1172
    def test_update_server_access_ipv4_bad_format(self):
 
1173
        self.stubs.Set(nova.db, 'instance_get',
 
1174
                return_server_with_attributes(access_ipv4='0.0.0.0'))
 
1175
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
 
1176
        req.method = 'PUT'
 
1177
        req.content_type = 'application/json'
 
1178
        body = {'server': {'accessIPv4': 'bad_format'}}
 
1179
        req.body = json.dumps(body)
 
1180
        self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
 
1181
                            req, FAKE_UUID, body)
 
1182
 
 
1183
    def test_update_server_access_ipv6(self):
 
1184
        self.stubs.Set(nova.db, 'instance_get',
 
1185
                return_server_with_attributes(access_ipv6='beef::0123'))
 
1186
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
 
1187
        req.method = 'PUT'
 
1188
        req.content_type = 'application/json'
 
1189
        body = {'server': {'accessIPv6': 'beef::0123'}}
 
1190
        req.body = json.dumps(body)
 
1191
        res_dict = self.controller.update(req, FAKE_UUID, body)
 
1192
 
 
1193
        self.assertEqual(res_dict['server']['id'], FAKE_UUID)
 
1194
        self.assertEqual(res_dict['server']['accessIPv6'], 'beef::0123')
 
1195
 
 
1196
    def test_update_server_access_ipv6_bad_format(self):
 
1197
        self.stubs.Set(nova.db, 'instance_get',
 
1198
                return_server_with_attributes(access_ipv6='beef::0123'))
 
1199
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
 
1200
        req.method = 'PUT'
 
1201
        req.content_type = 'application/json'
 
1202
        body = {'server': {'accessIPv6': 'bad_format'}}
 
1203
        req.body = json.dumps(body)
 
1204
        self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
 
1205
                            req, FAKE_UUID, body)
 
1206
 
 
1207
    def test_update_server_adminPass_ignored(self):
 
1208
        inst_dict = dict(name='server_test', adminPass='bacon')
 
1209
        body = dict(server=inst_dict)
 
1210
 
 
1211
        def server_update(context, id, params):
 
1212
            filtered_dict = {
 
1213
                'display_name': 'server_test',
 
1214
            }
 
1215
            self.assertEqual(params, filtered_dict)
 
1216
            return filtered_dict
 
1217
 
 
1218
        self.stubs.Set(nova.db, 'instance_update', server_update)
 
1219
        self.stubs.Set(nova.db, 'instance_get',
 
1220
                return_server_with_attributes(name='server_test'))
 
1221
 
 
1222
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
 
1223
        req.method = 'PUT'
 
1224
        req.content_type = "application/json"
 
1225
        req.body = json.dumps(body)
 
1226
        res_dict = self.controller.update(req, FAKE_UUID, body)
 
1227
 
 
1228
        self.assertEqual(res_dict['server']['id'], FAKE_UUID)
 
1229
        self.assertEqual(res_dict['server']['name'], 'server_test')
 
1230
 
 
1231
    def test_rebuild_instance_with_access_ipv4_bad_format(self):
 
1232
 
 
1233
        def fake_get_instance(*args, **kwargs):
 
1234
            return fakes.stub_instance(1, vm_state=vm_states.ACTIVE)
 
1235
 
 
1236
        self.stubs.Set(nova.db, 'instance_get', fake_get_instance)
 
1237
        # proper local hrefs must start with 'http://localhost/v2/'
 
1238
        image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
1239
        image_href = 'http://localhost/v2/fake/images/%s' % image_uuid
 
1240
        access_ipv4 = 'bad_format'
 
1241
        access_ipv6 = 'fead::1234'
 
1242
        body = {
 
1243
            'rebuild': {
 
1244
                'name': 'new_name',
 
1245
                'imageRef': image_href,
 
1246
                'accessIPv4': access_ipv4,
 
1247
                'accessIPv6': access_ipv6,
 
1248
                'metadata': {
 
1249
                    'hello': 'world',
 
1250
                    'open': 'stack',
 
1251
                },
 
1252
                'personality': [
 
1253
                    {
 
1254
                        "path": "/etc/banner.txt",
 
1255
                        "contents": "MQ==",
 
1256
                    },
 
1257
                ],
 
1258
            },
 
1259
        }
 
1260
 
 
1261
        req = fakes.HTTPRequest.blank('/v2/fake/servers/a/action')
 
1262
        req.method = 'POST'
 
1263
        req.body = json.dumps(body)
 
1264
        req.headers["content-type"] = "application/json"
 
1265
        self.assertRaises(webob.exc.HTTPBadRequest,
 
1266
            self.controller._action_rebuild, req, 1, body)
 
1267
 
 
1268
    def test_rebuild_instance_with_access_ipv6_bad_format(self):
 
1269
 
 
1270
        def fake_get_instance(*args, **kwargs):
 
1271
            return fakes.stub_instance(1, vm_state=vm_states.ACTIVE)
 
1272
 
 
1273
        self.stubs.Set(nova.db, 'instance_get', fake_get_instance)
 
1274
        # proper local hrefs must start with 'http://localhost/v2/'
 
1275
        image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
1276
        image_href = 'http://localhost/v2/fake/images/%s' % image_uuid
 
1277
        access_ipv4 = '1.2.3.4'
 
1278
        access_ipv6 = 'bad_format'
 
1279
        body = {
 
1280
            'rebuild': {
 
1281
                'name': 'new_name',
 
1282
                'imageRef': image_href,
 
1283
                'accessIPv4': access_ipv4,
 
1284
                'accessIPv6': access_ipv6,
 
1285
                'metadata': {
 
1286
                    'hello': 'world',
 
1287
                    'open': 'stack',
 
1288
                },
 
1289
                'personality': [
 
1290
                    {
 
1291
                        "path": "/etc/banner.txt",
 
1292
                        "contents": "MQ==",
 
1293
                    },
 
1294
                ],
 
1295
            },
 
1296
        }
 
1297
 
 
1298
        req = fakes.HTTPRequest.blank('/v2/fake/servers/a/action')
 
1299
        req.method = 'POST'
 
1300
        req.body = json.dumps(body)
 
1301
        req.headers["content-type"] = "application/json"
 
1302
        self.assertRaises(webob.exc.HTTPBadRequest,
 
1303
            self.controller._action_rebuild, req, 1, body)
 
1304
 
 
1305
    def test_get_all_server_details(self):
 
1306
        expected_flavor = {
 
1307
            "id": "1",
 
1308
            "links": [
 
1309
                {
 
1310
                    "rel": "bookmark",
 
1311
                    "href": 'http://localhost/fake/flavors/1',
 
1312
                },
 
1313
            ],
 
1314
        }
 
1315
        expected_image = {
 
1316
            "id": "10",
 
1317
            "links": [
 
1318
                {
 
1319
                    "rel": "bookmark",
 
1320
                    "href": 'http://localhost/fake/images/10',
 
1321
                },
 
1322
            ],
 
1323
        }
 
1324
        req = fakes.HTTPRequest.blank('/v2/fake/servers/detail')
 
1325
        res_dict = self.controller.detail(req)
 
1326
 
 
1327
        for i, s in enumerate(res_dict['servers']):
 
1328
            self.assertEqual(s['id'], get_fake_uuid(i))
 
1329
            self.assertEqual(s['hostId'], '')
 
1330
            self.assertEqual(s['name'], 'server%d' % i)
 
1331
            self.assertEqual(s['image'], expected_image)
 
1332
            self.assertEqual(s['flavor'], expected_flavor)
 
1333
            self.assertEqual(s['status'], 'BUILD')
 
1334
            self.assertEqual(s['metadata']['seq'], str(i))
 
1335
 
 
1336
    def test_get_all_server_details_with_host(self):
 
1337
        '''
 
1338
        We want to make sure that if two instances are on the same host, then
 
1339
        they return the same hostId. If two instances are on different hosts,
 
1340
        they should return different hostId's. In this test, there are 5
 
1341
        instances - 2 on one host and 3 on another.
 
1342
        '''
 
1343
 
 
1344
        def return_servers_with_host(context, *args, **kwargs):
 
1345
            return [fakes.stub_instance(i, 'fake', 'fake', i % 2,
 
1346
                                  uuid=get_fake_uuid(i))
 
1347
                    for i in xrange(5)]
 
1348
 
 
1349
        self.stubs.Set(nova.db, 'instance_get_all_by_filters',
 
1350
            return_servers_with_host)
 
1351
 
 
1352
        req = fakes.HTTPRequest.blank('/v2/fake/servers/detail')
 
1353
        res_dict = self.controller.detail(req)
 
1354
 
 
1355
        server_list = res_dict['servers']
 
1356
        host_ids = [server_list[0]['hostId'], server_list[1]['hostId']]
 
1357
        self.assertTrue(host_ids[0] and host_ids[1])
 
1358
        self.assertNotEqual(host_ids[0], host_ids[1])
 
1359
 
 
1360
        for i, s in enumerate(server_list):
 
1361
            self.assertEqual(s['id'], get_fake_uuid(i))
 
1362
            self.assertEqual(s['hostId'], host_ids[i % 2])
 
1363
            self.assertEqual(s['name'], 'server%d' % i)
 
1364
 
 
1365
    def test_delete_server_instance(self):
 
1366
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
 
1367
        req.method = 'DELETE'
 
1368
 
 
1369
        self.server_delete_called = False
 
1370
 
 
1371
        new_return_server = return_server_with_attributes(
 
1372
            vm_state=vm_states.ACTIVE)
 
1373
        self.stubs.Set(nova.db, 'instance_get', new_return_server)
 
1374
 
 
1375
        def instance_destroy_mock(context, id):
 
1376
            self.server_delete_called = True
 
1377
        self.stubs.Set(nova.db, 'instance_destroy', instance_destroy_mock)
 
1378
 
 
1379
        self.controller.delete(req, FAKE_UUID)
 
1380
 
 
1381
        self.assertEqual(self.server_delete_called, True)
 
1382
 
 
1383
    def test_delete_server_instance_while_building(self):
 
1384
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
 
1385
        req.method = 'DELETE'
 
1386
 
 
1387
        self.server_delete_called = False
 
1388
 
 
1389
        new_return_server = return_server_with_attributes(
 
1390
            vm_state=vm_states.BUILDING)
 
1391
        self.stubs.Set(nova.db, 'instance_get', new_return_server)
 
1392
 
 
1393
        def instance_destroy_mock(context, id):
 
1394
            self.server_delete_called = True
 
1395
        self.stubs.Set(nova.db, 'instance_destroy', instance_destroy_mock)
 
1396
 
 
1397
        self.controller.delete(req, FAKE_UUID)
 
1398
 
 
1399
        self.assertEqual(self.server_delete_called, True)
 
1400
 
 
1401
    def test_delete_server_instance_while_resize(self):
 
1402
        req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
 
1403
        req.method = 'DELETE'
 
1404
 
 
1405
        self.server_delete_called = False
 
1406
 
 
1407
        new_return_server = return_server_with_attributes(
 
1408
            vm_state=vm_states.RESIZING)
 
1409
        self.stubs.Set(nova.db, 'instance_get', new_return_server)
 
1410
 
 
1411
        def instance_destroy_mock(context, id):
 
1412
            self.server_delete_called = True
 
1413
        self.stubs.Set(nova.db, 'instance_destroy', instance_destroy_mock)
 
1414
 
 
1415
        self.assertRaises(webob.exc.HTTPConflict,
 
1416
                          self.controller.delete,
 
1417
                          req,
 
1418
                          FAKE_UUID)
 
1419
 
 
1420
 
 
1421
class ServerStatusTest(test.TestCase):
 
1422
 
 
1423
    def setUp(self):
 
1424
        super(ServerStatusTest, self).setUp()
 
1425
        fakes.stub_out_nw_api(self.stubs)
 
1426
 
 
1427
        self.controller = servers.Controller()
 
1428
 
 
1429
    def _get_with_state(self, vm_state, task_state=None):
 
1430
        new_server = return_server_with_state(vm_state, task_state)
 
1431
        self.stubs.Set(nova.db, 'instance_get_by_uuid', new_server)
 
1432
        self.stubs.Set(nova.db, 'instance_get', new_server)
 
1433
 
 
1434
        request = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID)
 
1435
        return self.controller.show(request, FAKE_UUID)
 
1436
 
 
1437
    def test_active(self):
 
1438
        response = self._get_with_state(vm_states.ACTIVE)
 
1439
        self.assertEqual(response['server']['status'], 'ACTIVE')
 
1440
 
 
1441
    def test_reboot(self):
 
1442
        response = self._get_with_state(vm_states.ACTIVE,
 
1443
                                        task_states.REBOOTING)
 
1444
        self.assertEqual(response['server']['status'], 'REBOOT')
 
1445
 
 
1446
    def test_reboot_hard(self):
 
1447
        response = self._get_with_state(vm_states.ACTIVE,
 
1448
                                        task_states.REBOOTING_HARD)
 
1449
        self.assertEqual(response['server']['status'], 'HARD_REBOOT')
 
1450
 
 
1451
    def test_rebuild(self):
 
1452
        response = self._get_with_state(vm_states.REBUILDING)
 
1453
        self.assertEqual(response['server']['status'], 'REBUILD')
 
1454
 
 
1455
    def test_rebuild_error(self):
 
1456
        response = self._get_with_state(vm_states.ERROR)
 
1457
        self.assertEqual(response['server']['status'], 'ERROR')
 
1458
 
 
1459
    def test_resize(self):
 
1460
        response = self._get_with_state(vm_states.RESIZING)
 
1461
        self.assertEqual(response['server']['status'], 'RESIZE')
 
1462
 
 
1463
    def test_verify_resize(self):
 
1464
        response = self._get_with_state(vm_states.ACTIVE,
 
1465
                                        task_states.RESIZE_VERIFY)
 
1466
        self.assertEqual(response['server']['status'], 'VERIFY_RESIZE')
 
1467
 
 
1468
    def test_password_update(self):
 
1469
        response = self._get_with_state(vm_states.ACTIVE,
 
1470
                                        task_states.UPDATING_PASSWORD)
 
1471
        self.assertEqual(response['server']['status'], 'PASSWORD')
 
1472
 
 
1473
    def test_stopped(self):
 
1474
        response = self._get_with_state(vm_states.STOPPED)
 
1475
        self.assertEqual(response['server']['status'], 'STOPPED')
 
1476
 
 
1477
 
 
1478
class ServersControllerCreateTest(test.TestCase):
 
1479
 
 
1480
    def setUp(self):
 
1481
        """Shared implementation for tests below that create instance"""
 
1482
        super(ServersControllerCreateTest, self).setUp()
 
1483
 
 
1484
        self.maxDiff = None
 
1485
        self.flags(verbose=True)
 
1486
        self.config_drive = None
 
1487
        self.instance_cache_num = 0
 
1488
        self.instance_cache = {}
 
1489
 
 
1490
        self.controller = servers.Controller()
 
1491
 
 
1492
        def instance_create(context, inst):
 
1493
            inst_type = instance_types.get_instance_type_by_flavor_id(3)
 
1494
            image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
1495
            def_image_ref = 'http://localhost/images/%s' % image_uuid
 
1496
            self.instance_cache_num += 1
 
1497
            instance = {
 
1498
                'id': self.instance_cache_num,
 
1499
                'display_name': inst['display_name'] or 'test',
 
1500
                'uuid': FAKE_UUID,
 
1501
                'instance_type': dict(inst_type),
 
1502
                'access_ip_v4': '1.2.3.4',
 
1503
                'access_ip_v6': 'fead::1234',
 
1504
                'image_ref': inst.get('image_ref', def_image_ref),
 
1505
                'user_id': 'fake',
 
1506
                'project_id': 'fake',
 
1507
                'reservation_id': inst['reservation_id'],
 
1508
                "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0),
 
1509
                "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0),
 
1510
                "config_drive": self.config_drive,
 
1511
                "progress": 0,
 
1512
                "fixed_ips": []
 
1513
            }
 
1514
            self.instance_cache[instance['id']] = instance
 
1515
            return instance
 
1516
 
 
1517
        def instance_get(context, instance_id):
 
1518
            """Stub for compute/api create() pulling in instance after
 
1519
            scheduling
 
1520
            """
 
1521
            return self.instance_cache[instance_id]
 
1522
 
 
1523
        def rpc_call_wrapper(context, topic, msg):
 
1524
            """Stub out the scheduler creating the instance entry"""
 
1525
            if topic == FLAGS.scheduler_topic and \
 
1526
                    msg['method'] == 'run_instance':
 
1527
                request_spec = msg['args']['request_spec']
 
1528
                num_instances = request_spec.get('num_instances', 1)
 
1529
                instances = []
 
1530
                for x in xrange(num_instances):
 
1531
                    instances.append(instance_create(context,
 
1532
                        request_spec['instance_properties']))
 
1533
                return instances
 
1534
 
 
1535
        def server_update(context, instance_id, params):
 
1536
            inst = self.instance_cache[instance_id]
 
1537
            inst.update(params)
 
1538
            return inst
 
1539
 
 
1540
        def fake_method(*args, **kwargs):
 
1541
            pass
 
1542
 
 
1543
        def project_get_networks(context, user_id):
 
1544
            return dict(id='1', host='localhost')
 
1545
 
 
1546
        def queue_get_for(context, *args):
 
1547
            return 'network_topic'
 
1548
 
 
1549
        fakes.stub_out_networking(self.stubs)
 
1550
        fakes.stub_out_rate_limiting(self.stubs)
 
1551
        fakes.stub_out_key_pair_funcs(self.stubs)
 
1552
        fakes.stub_out_image_service(self.stubs)
 
1553
        fakes.stub_out_nw_api(self.stubs)
 
1554
        self.stubs.Set(utils, 'gen_uuid', fake_gen_uuid)
 
1555
        self.stubs.Set(nova.db, 'instance_add_security_group',
 
1556
                       return_security_group)
 
1557
        self.stubs.Set(nova.db, 'project_get_networks',
 
1558
                       project_get_networks)
 
1559
        self.stubs.Set(nova.db, 'instance_create', instance_create)
 
1560
        self.stubs.Set(nova.db, 'instance_get', instance_get)
 
1561
        self.stubs.Set(nova.rpc, 'cast', fake_method)
 
1562
        self.stubs.Set(nova.rpc, 'call', rpc_call_wrapper)
 
1563
        self.stubs.Set(nova.db, 'instance_update', server_update)
 
1564
        self.stubs.Set(nova.db, 'queue_get_for', queue_get_for)
 
1565
        self.stubs.Set(nova.network.manager.VlanManager, 'allocate_fixed_ip',
 
1566
                       fake_method)
 
1567
        self.stubs.Set(nova.compute.api.API, "_find_host", find_host)
 
1568
 
 
1569
    def _test_create_instance(self):
 
1570
        image_uuid = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'
 
1571
        body = dict(server=dict(
 
1572
            name='server_test', imageRef=image_uuid, flavorRef=2,
 
1573
            metadata={'hello': 'world', 'open': 'stack'},
 
1574
            personality={}))
 
1575
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
1576
        req.method = 'POST'
 
1577
        req.body = json.dumps(body)
 
1578
        req.headers["content-type"] = "application/json"
 
1579
        server = self.controller.create(req, body).obj['server']
 
1580
 
 
1581
        self.assertEqual(FLAGS.password_length, len(server['adminPass']))
 
1582
        self.assertEqual(FAKE_UUID, server['id'])
 
1583
 
 
1584
    def test_create_multiple_instances(self):
 
1585
        """Test creating multiple instances but not asking for
 
1586
        reservation_id
 
1587
        """
 
1588
        image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
1589
        flavor_ref = 'http://localhost/123/flavors/3'
 
1590
        body = {
 
1591
            'server': {
 
1592
                'min_count': 2,
 
1593
                'name': 'server_test',
 
1594
                'imageRef': image_href,
 
1595
                'flavorRef': flavor_ref,
 
1596
                'metadata': {'hello': 'world',
 
1597
                             'open': 'stack'},
 
1598
                'personality': []
 
1599
            }
 
1600
        }
 
1601
 
 
1602
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
1603
        req.method = 'POST'
 
1604
        req.body = json.dumps(body)
 
1605
        req.headers["content-type"] = "application/json"
 
1606
        res = self.controller.create(req, body).obj
 
1607
 
 
1608
        self.assertEqual(FAKE_UUID, res["server"]["id"])
 
1609
        self.assertEqual(12, len(res["server"]["adminPass"]))
 
1610
 
 
1611
    def test_create_multiple_instances_resv_id_return(self):
 
1612
        """Test creating multiple instances with asking for
 
1613
        reservation_id
 
1614
        """
 
1615
        image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
1616
        flavor_ref = 'http://localhost/123/flavors/3'
 
1617
        body = {
 
1618
            'server': {
 
1619
                'min_count': 2,
 
1620
                'name': 'server_test',
 
1621
                'imageRef': image_href,
 
1622
                'flavorRef': flavor_ref,
 
1623
                'metadata': {'hello': 'world',
 
1624
                             'open': 'stack'},
 
1625
                'personality': [],
 
1626
                'return_reservation_id': True
 
1627
            }
 
1628
        }
 
1629
 
 
1630
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
1631
        req.method = 'POST'
 
1632
        req.body = json.dumps(body)
 
1633
        req.headers["content-type"] = "application/json"
 
1634
        res = self.controller.create(req, body)
 
1635
 
 
1636
        reservation_id = res.get('reservation_id')
 
1637
        self.assertNotEqual(reservation_id, "")
 
1638
        self.assertNotEqual(reservation_id, None)
 
1639
        self.assertTrue(len(reservation_id) > 1)
 
1640
 
 
1641
    def test_create_instance_with_user_supplied_reservation_id(self):
 
1642
        """Non-admin supplied reservation_id should be ignored."""
 
1643
        image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
1644
        flavor_ref = 'http://localhost/123/flavors/3'
 
1645
        body = {
 
1646
            'server': {
 
1647
                'name': 'server_test',
 
1648
                'imageRef': image_href,
 
1649
                'flavorRef': flavor_ref,
 
1650
                'metadata': {'hello': 'world',
 
1651
                             'open': 'stack'},
 
1652
                'personality': [],
 
1653
                'reservation_id': 'myresid',
 
1654
                'return_reservation_id': True
 
1655
            }
 
1656
        }
 
1657
 
 
1658
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
1659
        req.method = 'POST'
 
1660
        req.body = json.dumps(body)
 
1661
        req.headers["content-type"] = "application/json"
 
1662
        res = self.controller.create(req, body)
 
1663
 
 
1664
        self.assertIn('reservation_id', res)
 
1665
        self.assertNotEqual(res['reservation_id'], 'myresid')
 
1666
 
 
1667
    def test_create_instance_with_admin_supplied_reservation_id(self):
 
1668
        """Admin supplied reservation_id should be honored."""
 
1669
        image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
1670
        flavor_ref = 'http://localhost/123/flavors/3'
 
1671
        body = {
 
1672
            'server': {
 
1673
                'name': 'server_test',
 
1674
                'imageRef': image_href,
 
1675
                'flavorRef': flavor_ref,
 
1676
                'metadata': {'hello': 'world',
 
1677
                             'open': 'stack'},
 
1678
                'personality': [],
 
1679
                'reservation_id': 'myresid',
 
1680
                'return_reservation_id': True
 
1681
            }
 
1682
        }
 
1683
 
 
1684
        req = fakes.HTTPRequest.blank('/v2/fake/servers',
 
1685
                                      use_admin_context=True)
 
1686
        req.method = 'POST'
 
1687
        req.body = json.dumps(body)
 
1688
        req.headers["content-type"] = "application/json"
 
1689
        res = self.controller.create(req, body)
 
1690
 
 
1691
        reservation_id = res['reservation_id']
 
1692
        self.assertEqual(reservation_id, "myresid")
 
1693
 
 
1694
    def test_create_instance_no_key_pair(self):
 
1695
        fakes.stub_out_key_pair_funcs(self.stubs, have_key_pair=False)
 
1696
        self._test_create_instance()
 
1697
 
 
1698
    def test_create_instance_with_access_ip(self):
 
1699
        # proper local hrefs must start with 'http://localhost/v2/'
 
1700
        image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
1701
        image_href = 'http://localhost/v2/fake/images/%s' % image_uuid
 
1702
        flavor_ref = 'http://localhost/fake/flavors/3'
 
1703
        access_ipv4 = '1.2.3.4'
 
1704
        access_ipv6 = 'fead::1234'
 
1705
        body = {
 
1706
            'server': {
 
1707
                'name': 'server_test',
 
1708
                'imageRef': image_href,
 
1709
                'flavorRef': flavor_ref,
 
1710
                'accessIPv4': access_ipv4,
 
1711
                'accessIPv6': access_ipv6,
 
1712
                'metadata': {
 
1713
                    'hello': 'world',
 
1714
                    'open': 'stack',
 
1715
                },
 
1716
                'personality': [
 
1717
                    {
 
1718
                        "path": "/etc/banner.txt",
 
1719
                        "contents": "MQ==",
 
1720
                    },
 
1721
                ],
 
1722
            },
 
1723
        }
 
1724
 
 
1725
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
1726
        req.method = 'POST'
 
1727
        req.body = json.dumps(body)
 
1728
        req.headers["content-type"] = "application/json"
 
1729
        res = self.controller.create(req, body).obj
 
1730
 
 
1731
        server = res['server']
 
1732
        self.assertEqual(FLAGS.password_length, len(server['adminPass']))
 
1733
        self.assertEqual(FAKE_UUID, server['id'])
 
1734
 
 
1735
    def test_create_instance_bad_format_access_ip_v4(self):
 
1736
        # proper local hrefs must start with 'http://localhost/v2/'
 
1737
        image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
1738
        image_href = 'http://localhost/v2/fake/images/%s' % image_uuid
 
1739
        flavor_ref = 'http://localhost/fake/flavors/3'
 
1740
        access_ipv4 = 'bad_format'
 
1741
        access_ipv6 = 'fead::1234'
 
1742
        body = {
 
1743
            'server': {
 
1744
                'name': 'server_test',
 
1745
                'imageRef': image_href,
 
1746
                'flavorRef': flavor_ref,
 
1747
                'accessIPv4': access_ipv4,
 
1748
                'accessIPv6': access_ipv6,
 
1749
                'metadata': {
 
1750
                    'hello': 'world',
 
1751
                    'open': 'stack',
 
1752
                },
 
1753
                'personality': [
 
1754
                    {
 
1755
                        "path": "/etc/banner.txt",
 
1756
                        "contents": "MQ==",
 
1757
                    },
 
1758
                ],
 
1759
            },
 
1760
        }
 
1761
 
 
1762
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
1763
        req.method = 'POST'
 
1764
        req.body = json.dumps(body)
 
1765
        req.headers["content-type"] = "application/json"
 
1766
        self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
 
1767
                            req, body)
 
1768
 
 
1769
    def test_create_instance_bad_format_access_ip_v6(self):
 
1770
        # proper local hrefs must start with 'http://localhost/v2/'
 
1771
        image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
1772
        image_href = 'http://localhost/v2/fake/images/%s' % image_uuid
 
1773
        flavor_ref = 'http://localhost/fake/flavors/3'
 
1774
        access_ipv4 = '1.2.3.4'
 
1775
        access_ipv6 = 'bad_format'
 
1776
        body = {
 
1777
            'server': {
 
1778
                'name': 'server_test',
 
1779
                'imageRef': image_href,
 
1780
                'flavorRef': flavor_ref,
 
1781
                'accessIPv4': access_ipv4,
 
1782
                'accessIPv6': access_ipv6,
 
1783
                'metadata': {
 
1784
                    'hello': 'world',
 
1785
                    'open': 'stack',
 
1786
                },
 
1787
                'personality': [
 
1788
                    {
 
1789
                        "path": "/etc/banner.txt",
 
1790
                        "contents": "MQ==",
 
1791
                    },
 
1792
                ],
 
1793
            },
 
1794
        }
 
1795
 
 
1796
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
1797
        req.method = 'POST'
 
1798
        req.body = json.dumps(body)
 
1799
        req.headers["content-type"] = "application/json"
 
1800
        self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
 
1801
                            req, body)
 
1802
 
 
1803
    def test_create_instance(self):
 
1804
        # proper local hrefs must start with 'http://localhost/v2/'
 
1805
        image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
1806
        image_href = 'http://localhost/v2/images/%s' % image_uuid
 
1807
        flavor_ref = 'http://localhost/123/flavors/3'
 
1808
        body = {
 
1809
            'server': {
 
1810
                'name': 'server_test',
 
1811
                'imageRef': image_href,
 
1812
                'flavorRef': flavor_ref,
 
1813
                'metadata': {
 
1814
                    'hello': 'world',
 
1815
                    'open': 'stack',
 
1816
                },
 
1817
                'personality': [
 
1818
                    {
 
1819
                        "path": "/etc/banner.txt",
 
1820
                        "contents": "MQ==",
 
1821
                    },
 
1822
                ],
 
1823
            },
 
1824
        }
 
1825
 
 
1826
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
1827
        req.method = 'POST'
 
1828
        req.body = json.dumps(body)
 
1829
        req.headers["content-type"] = "application/json"
 
1830
        res = self.controller.create(req, body).obj
 
1831
 
 
1832
        server = res['server']
 
1833
        self.assertEqual(FLAGS.password_length, len(server['adminPass']))
 
1834
        self.assertEqual(FAKE_UUID, server['id'])
 
1835
 
 
1836
    def test_create_instance_too_much_metadata(self):
 
1837
        self.flags(quota_metadata_items=1)
 
1838
        image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
1839
        image_href = 'http://localhost/v2/images/%s' % image_uuid
 
1840
        flavor_ref = 'http://localhost/123/flavors/3'
 
1841
        body = {
 
1842
            'server': {
 
1843
                'name': 'server_test',
 
1844
                'imageRef': image_href,
 
1845
                'flavorRef': flavor_ref,
 
1846
                'metadata': {
 
1847
                    'hello': 'world',
 
1848
                    'open': 'stack',
 
1849
                    'vote': 'fiddletown',
 
1850
                },
 
1851
            },
 
1852
        }
 
1853
 
 
1854
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
1855
        req.method = 'POST'
 
1856
        req.body = json.dumps(body)
 
1857
        req.headers["content-type"] = "application/json"
 
1858
 
 
1859
        self.assertRaises(webob.exc.HTTPRequestEntityTooLarge,
 
1860
                          self.controller.create, req, body)
 
1861
 
 
1862
    def test_create_instance_invalid_key_name(self):
 
1863
        image_href = 'http://localhost/v2/images/2'
 
1864
        flavor_ref = 'http://localhost/flavors/3'
 
1865
        body = dict(server=dict(
 
1866
            name='server_test', imageRef=image_href, flavorRef=flavor_ref,
 
1867
            key_name='nonexistentkey'))
 
1868
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
1869
        req.method = 'POST'
 
1870
        req.body = json.dumps(body)
 
1871
        req.headers["content-type"] = "application/json"
 
1872
 
 
1873
        self.assertRaises(webob.exc.HTTPBadRequest,
 
1874
                          self.controller.create, req, body)
 
1875
 
 
1876
    def test_create_instance_valid_key_name(self):
 
1877
        image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
1878
        flavor_ref = 'http://localhost/flavors/3'
 
1879
        body = dict(server=dict(
 
1880
            name='server_test', imageRef=image_href, flavorRef=flavor_ref,
 
1881
            key_name='key'))
 
1882
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
1883
        req.method = 'POST'
 
1884
        req.body = json.dumps(body)
 
1885
        req.headers["content-type"] = "application/json"
 
1886
        res = self.controller.create(req, body).obj
 
1887
 
 
1888
        self.assertEqual(FAKE_UUID, res["server"]["id"])
 
1889
        self.assertEqual(12, len(res["server"]["adminPass"]))
 
1890
 
 
1891
    def test_create_instance_invalid_flavor_href(self):
 
1892
        image_href = 'http://localhost/v2/images/2'
 
1893
        flavor_ref = 'http://localhost/v2/flavors/asdf'
 
1894
        body = dict(server=dict(
 
1895
            name='server_test', imageRef=image_href, flavorRef=flavor_ref,
 
1896
            metadata={'hello': 'world', 'open': 'stack'},
 
1897
            personality={}))
 
1898
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
1899
        req.method = 'POST'
 
1900
        req.body = json.dumps(body)
 
1901
        req.headers["content-type"] = "application/json"
 
1902
 
 
1903
        self.assertRaises(webob.exc.HTTPBadRequest,
 
1904
                          self.controller.create, req, body)
 
1905
 
 
1906
    def test_create_instance_invalid_flavor_id_int(self):
 
1907
        image_href = 'http://localhost/v2/fake/images/2'
 
1908
        flavor_ref = -1
 
1909
        body = dict(server=dict(
 
1910
            name='server_test', imageRef=image_href, flavorRef=flavor_ref,
 
1911
            metadata={'hello': 'world', 'open': 'stack'},
 
1912
            personality={}))
 
1913
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
1914
        req.method = 'POST'
 
1915
        req.body = json.dumps(body)
 
1916
        req.headers["content-type"] = "application/json"
 
1917
 
 
1918
        self.assertRaises(webob.exc.HTTPBadRequest,
 
1919
                          self.controller.create, req, body)
 
1920
 
 
1921
    def test_create_instance_bad_flavor_href(self):
 
1922
        image_href = 'http://localhost/v2/images/2'
 
1923
        flavor_ref = 'http://localhost/v2/flavors/17'
 
1924
        body = dict(server=dict(
 
1925
            name='server_test', imageRef=image_href, flavorRef=flavor_ref,
 
1926
            metadata={'hello': 'world', 'open': 'stack'},
 
1927
            personality={}))
 
1928
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
1929
        req.method = 'POST'
 
1930
        req.body = json.dumps(body)
 
1931
        req.headers["content-type"] = "application/json"
 
1932
 
 
1933
        self.assertRaises(webob.exc.HTTPBadRequest,
 
1934
                          self.controller.create, req, body)
 
1935
 
 
1936
    def test_create_instance_with_config_drive(self):
 
1937
        self.config_drive = True
 
1938
        image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
1939
        flavor_ref = 'http://localhost/v2/fake/flavors/3'
 
1940
        body = {
 
1941
            'server': {
 
1942
                'name': 'config_drive_test',
 
1943
                'imageRef': image_href,
 
1944
                'flavorRef': flavor_ref,
 
1945
                'metadata': {
 
1946
                    'hello': 'world',
 
1947
                    'open': 'stack',
 
1948
                },
 
1949
                'personality': {},
 
1950
                'config_drive': True,
 
1951
            },
 
1952
        }
 
1953
 
 
1954
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
1955
        req.method = 'POST'
 
1956
        req.body = json.dumps(body)
 
1957
        req.headers["content-type"] = "application/json"
 
1958
        res = self.controller.create(req, body).obj
 
1959
 
 
1960
        server = res['server']
 
1961
        self.assertEqual(FAKE_UUID, server['id'])
 
1962
 
 
1963
    def test_create_instance_with_config_drive_as_id(self):
 
1964
        self.config_drive = 2
 
1965
        image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
1966
        flavor_ref = 'http://localhost/v2/fake/flavors/3'
 
1967
        body = {
 
1968
            'server': {
 
1969
                'name': 'config_drive_test',
 
1970
                'imageRef': image_href,
 
1971
                'flavorRef': flavor_ref,
 
1972
                'metadata': {
 
1973
                    'hello': 'world',
 
1974
                    'open': 'stack',
 
1975
                },
 
1976
                'personality': {},
 
1977
                'config_drive': image_href,
 
1978
            },
 
1979
        }
 
1980
 
 
1981
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
1982
        req.method = 'POST'
 
1983
        req.body = json.dumps(body)
 
1984
        req.headers["content-type"] = "application/json"
 
1985
        res = self.controller.create(req, body).obj
 
1986
 
 
1987
        server = res['server']
 
1988
        self.assertEqual(FAKE_UUID, server['id'])
 
1989
 
 
1990
    def test_create_instance_with_bad_config_drive(self):
 
1991
        self.config_drive = "asdf"
 
1992
        image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
1993
        flavor_ref = 'http://localhost/v2/fake/flavors/3'
 
1994
        body = {
 
1995
            'server': {
 
1996
                'name': 'config_drive_test',
 
1997
                'imageRef': image_href,
 
1998
                'flavorRef': flavor_ref,
 
1999
                'metadata': {
 
2000
                    'hello': 'world',
 
2001
                    'open': 'stack',
 
2002
                },
 
2003
                'personality': {},
 
2004
                'config_drive': 'asdf',
 
2005
            },
 
2006
        }
 
2007
 
 
2008
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
2009
        req.method = 'POST'
 
2010
        req.body = json.dumps(body)
 
2011
        req.headers["content-type"] = "application/json"
 
2012
 
 
2013
        self.assertRaises(webob.exc.HTTPBadRequest,
 
2014
                          self.controller.create, req, body)
 
2015
 
 
2016
    def test_create_instance_without_config_drive(self):
 
2017
        image_href = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
2018
        flavor_ref = 'http://localhost/v2/fake/flavors/3'
 
2019
        body = {
 
2020
            'server': {
 
2021
                'name': 'config_drive_test',
 
2022
                'imageRef': image_href,
 
2023
                'flavorRef': flavor_ref,
 
2024
                'metadata': {
 
2025
                    'hello': 'world',
 
2026
                    'open': 'stack',
 
2027
                },
 
2028
                'personality': {},
 
2029
                'config_drive': True,
 
2030
            },
 
2031
        }
 
2032
 
 
2033
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
2034
        req.method = 'POST'
 
2035
        req.body = json.dumps(body)
 
2036
        req.headers["content-type"] = "application/json"
 
2037
        res = self.controller.create(req, body).obj
 
2038
 
 
2039
        server = res['server']
 
2040
        self.assertEqual(FAKE_UUID, server['id'])
 
2041
 
 
2042
    def test_create_instance_bad_href(self):
 
2043
        image_href = 'asdf'
 
2044
        flavor_ref = 'http://localhost/v2/flavors/3'
 
2045
        body = dict(server=dict(
 
2046
            name='server_test', imageRef=image_href, flavorRef=flavor_ref,
 
2047
            metadata={'hello': 'world', 'open': 'stack'},
 
2048
            personality={}))
 
2049
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
2050
        req.method = 'POST'
 
2051
        req.body = json.dumps(body)
 
2052
        req.headers["content-type"] = "application/json"
 
2053
 
 
2054
        self.assertRaises(webob.exc.HTTPBadRequest,
 
2055
                          self.controller.create, req, body)
 
2056
 
 
2057
    def test_create_instance_local_href(self):
 
2058
        image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
2059
        flavor_ref = 'http://localhost/v2/flavors/3'
 
2060
        body = {
 
2061
            'server': {
 
2062
                'name': 'server_test',
 
2063
                'imageRef': image_uuid,
 
2064
                'flavorRef': flavor_ref,
 
2065
            },
 
2066
        }
 
2067
 
 
2068
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
2069
        req.method = 'POST'
 
2070
        req.body = json.dumps(body)
 
2071
        req.headers["content-type"] = "application/json"
 
2072
        res = self.controller.create(req, body).obj
 
2073
 
 
2074
        server = res['server']
 
2075
        self.assertEqual(FAKE_UUID, server['id'])
 
2076
 
 
2077
    def test_create_instance_admin_pass(self):
 
2078
        image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
2079
        body = {
 
2080
            'server': {
 
2081
                'name': 'server_test',
 
2082
                'imageRef': image_uuid,
 
2083
                'flavorRef': 3,
 
2084
                'adminPass': 'testpass',
 
2085
            },
 
2086
        }
 
2087
 
 
2088
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
2089
        req.method = 'POST'
 
2090
        req.body = json.dumps(body)
 
2091
        req.headers['content-type'] = "application/json"
 
2092
        res = self.controller.create(req, body).obj
 
2093
 
 
2094
        server = res['server']
 
2095
        self.assertEqual(server['adminPass'], body['server']['adminPass'])
 
2096
 
 
2097
    def test_create_instance_admin_pass_empty(self):
 
2098
        body = {
 
2099
            'server': {
 
2100
                'name': 'server_test',
 
2101
                'imageRef': 3,
 
2102
                'flavorRef': 3,
 
2103
                'adminPass': '',
 
2104
            },
 
2105
        }
 
2106
 
 
2107
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
2108
        req.method = 'POST'
 
2109
        req.body = json.dumps(body)
 
2110
        req.headers['content-type'] = "application/json"
 
2111
 
 
2112
        self.assertRaises(webob.exc.HTTPBadRequest,
 
2113
                          self.controller.create, req, body)
 
2114
 
 
2115
    def test_create_instance_malformed_entity(self):
 
2116
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
2117
        req.method = 'POST'
 
2118
        body = {'server': 'string'}
 
2119
        req.body = json.dumps(body)
 
2120
        req.headers['content-type'] = "application/json"
 
2121
 
 
2122
        self.assertRaises(webob.exc.HTTPBadRequest,
 
2123
                          self.controller.create, req, body)
 
2124
 
 
2125
    def test_create_location(self):
 
2126
        selfhref = 'http://localhost/v2/fake/servers/%s' % FAKE_UUID
 
2127
        bookhref = 'http://localhost/fake/servers/%s' % FAKE_UUID
 
2128
        image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'
 
2129
        image_href = 'http://localhost/v2/images/%s' % image_uuid
 
2130
        flavor_ref = 'http://localhost/123/flavors/3'
 
2131
        body = {
 
2132
            'server': {
 
2133
                'name': 'server_test',
 
2134
                'imageRef': image_href,
 
2135
                'flavorRef': flavor_ref,
 
2136
                'metadata': {
 
2137
                    'hello': 'world',
 
2138
                    'open': 'stack',
 
2139
                },
 
2140
                'personality': [
 
2141
                    {
 
2142
                        "path": "/etc/banner.txt",
 
2143
                        "contents": "MQ==",
 
2144
                    },
 
2145
                ],
 
2146
            },
 
2147
        }
 
2148
 
 
2149
        req = fakes.HTTPRequest.blank('/v2/fake/servers')
 
2150
        req.method = 'POST'
 
2151
        req.body = json.dumps(body)
 
2152
        req.headers['content-type'] = 'application/json'
 
2153
        robj = self.controller.create(req, body)
 
2154
 
 
2155
        self.assertEqual(robj['Location'], selfhref)
 
2156
 
 
2157
 
 
2158
class TestServerCreateRequestXMLDeserializer(test.TestCase):
 
2159
 
 
2160
    def setUp(self):
 
2161
        super(TestServerCreateRequestXMLDeserializer, self).setUp()
 
2162
        self.deserializer = servers.CreateDeserializer()
 
2163
 
 
2164
    def test_minimal_request(self):
 
2165
        serial_request = """
 
2166
<server xmlns="http://docs.openstack.org/compute/api/v2"
 
2167
        name="new-server-test"
 
2168
        imageRef="1"
 
2169
        flavorRef="2"/>"""
 
2170
        request = self.deserializer.deserialize(serial_request)
 
2171
        expected = {
 
2172
            "server": {
 
2173
                "name": "new-server-test",
 
2174
                "imageRef": "1",
 
2175
                "flavorRef": "2",
 
2176
            },
 
2177
        }
 
2178
        self.assertEquals(request['body'], expected)
 
2179
 
 
2180
    def test_access_ipv4(self):
 
2181
        serial_request = """
 
2182
<server xmlns="http://docs.openstack.org/compute/api/v2"
 
2183
        name="new-server-test"
 
2184
        imageRef="1"
 
2185
        flavorRef="2"
 
2186
        accessIPv4="1.2.3.4"/>"""
 
2187
        request = self.deserializer.deserialize(serial_request)
 
2188
        expected = {
 
2189
            "server": {
 
2190
                "name": "new-server-test",
 
2191
                "imageRef": "1",
 
2192
                "flavorRef": "2",
 
2193
                "accessIPv4": "1.2.3.4",
 
2194
            },
 
2195
        }
 
2196
        self.assertEquals(request['body'], expected)
 
2197
 
 
2198
    def test_access_ipv6(self):
 
2199
        serial_request = """
 
2200
<server xmlns="http://docs.openstack.org/compute/api/v2"
 
2201
        name="new-server-test"
 
2202
        imageRef="1"
 
2203
        flavorRef="2"
 
2204
        accessIPv6="fead::1234"/>"""
 
2205
        request = self.deserializer.deserialize(serial_request)
 
2206
        expected = {
 
2207
            "server": {
 
2208
                "name": "new-server-test",
 
2209
                "imageRef": "1",
 
2210
                "flavorRef": "2",
 
2211
                "accessIPv6": "fead::1234",
 
2212
            },
 
2213
        }
 
2214
        self.assertEquals(request['body'], expected)
 
2215
 
 
2216
    def test_access_ip(self):
 
2217
        serial_request = """
 
2218
<server xmlns="http://docs.openstack.org/compute/api/v2"
 
2219
        name="new-server-test"
 
2220
        imageRef="1"
 
2221
        flavorRef="2"
 
2222
        accessIPv4="1.2.3.4"
 
2223
        accessIPv6="fead::1234"/>"""
 
2224
        request = self.deserializer.deserialize(serial_request)
 
2225
        expected = {
 
2226
            "server": {
 
2227
                "name": "new-server-test",
 
2228
                "imageRef": "1",
 
2229
                "flavorRef": "2",
 
2230
                "accessIPv4": "1.2.3.4",
 
2231
                "accessIPv6": "fead::1234",
 
2232
            },
 
2233
        }
 
2234
        self.assertEquals(request['body'], expected)
 
2235
 
 
2236
    def test_admin_pass(self):
 
2237
        serial_request = """
 
2238
<server xmlns="http://docs.openstack.org/compute/api/v2"
 
2239
        name="new-server-test"
 
2240
        imageRef="1"
 
2241
        flavorRef="2"
 
2242
        adminPass="1234"/>"""
 
2243
        request = self.deserializer.deserialize(serial_request)
 
2244
        expected = {
 
2245
            "server": {
 
2246
                "name": "new-server-test",
 
2247
                "imageRef": "1",
 
2248
                "flavorRef": "2",
 
2249
                "adminPass": "1234",
 
2250
            },
 
2251
        }
 
2252
        self.assertEquals(request['body'], expected)
 
2253
 
 
2254
    def test_image_link(self):
 
2255
        serial_request = """
 
2256
<server xmlns="http://docs.openstack.org/compute/api/v2"
 
2257
        name="new-server-test"
 
2258
        imageRef="http://localhost:8774/v2/images/2"
 
2259
        flavorRef="3"/>"""
 
2260
        request = self.deserializer.deserialize(serial_request)
 
2261
        expected = {
 
2262
            "server": {
 
2263
                "name": "new-server-test",
 
2264
                "imageRef": "http://localhost:8774/v2/images/2",
 
2265
                "flavorRef": "3",
 
2266
            },
 
2267
        }
 
2268
        self.assertEquals(request['body'], expected)
 
2269
 
 
2270
    def test_flavor_link(self):
 
2271
        serial_request = """
 
2272
<server xmlns="http://docs.openstack.org/compute/api/v2"
 
2273
        name="new-server-test"
 
2274
        imageRef="1"
 
2275
        flavorRef="http://localhost:8774/v2/flavors/3"/>"""
 
2276
        request = self.deserializer.deserialize(serial_request)
 
2277
        expected = {
 
2278
            "server": {
 
2279
                "name": "new-server-test",
 
2280
                "imageRef": "1",
 
2281
                "flavorRef": "http://localhost:8774/v2/flavors/3",
 
2282
            },
 
2283
        }
 
2284
        self.assertEquals(request['body'], expected)
 
2285
 
 
2286
    def test_empty_metadata_personality(self):
 
2287
        serial_request = """
 
2288
<server xmlns="http://docs.openstack.org/compute/api/v2"
 
2289
        name="new-server-test"
 
2290
        imageRef="1"
 
2291
        flavorRef="2">
 
2292
    <metadata/>
 
2293
    <personality/>
 
2294
</server>"""
 
2295
        request = self.deserializer.deserialize(serial_request)
 
2296
        expected = {
 
2297
            "server": {
 
2298
                "name": "new-server-test",
 
2299
                "imageRef": "1",
 
2300
                "flavorRef": "2",
 
2301
                "metadata": {},
 
2302
                "personality": [],
 
2303
            },
 
2304
        }
 
2305
        self.assertEquals(request['body'], expected)
 
2306
 
 
2307
    def test_multiple_metadata_items(self):
 
2308
        serial_request = """
 
2309
<server xmlns="http://docs.openstack.org/compute/api/v2"
 
2310
        name="new-server-test"
 
2311
        imageRef="1"
 
2312
        flavorRef="2">
 
2313
    <metadata>
 
2314
        <meta key="one">two</meta>
 
2315
        <meta key="open">snack</meta>
 
2316
    </metadata>
 
2317
</server>"""
 
2318
        request = self.deserializer.deserialize(serial_request)
 
2319
        expected = {
 
2320
            "server": {
 
2321
                "name": "new-server-test",
 
2322
                "imageRef": "1",
 
2323
                "flavorRef": "2",
 
2324
                "metadata": {"one": "two", "open": "snack"},
 
2325
            },
 
2326
        }
 
2327
        self.assertEquals(request['body'], expected)
 
2328
 
 
2329
    def test_multiple_personality_files(self):
 
2330
        serial_request = """
 
2331
<server xmlns="http://docs.openstack.org/compute/api/v2"
 
2332
        name="new-server-test"
 
2333
        imageRef="1"
 
2334
        flavorRef="2">
 
2335
    <personality>
 
2336
        <file path="/etc/banner.txt">MQ==</file>
 
2337
        <file path="/etc/hosts">Mg==</file>
 
2338
    </personality>
 
2339
</server>"""
 
2340
        request = self.deserializer.deserialize(serial_request)
 
2341
        expected = {
 
2342
            "server": {
 
2343
                "name": "new-server-test",
 
2344
                "imageRef": "1",
 
2345
                "flavorRef": "2",
 
2346
                "personality": [
 
2347
                    {"path": "/etc/banner.txt", "contents": "MQ=="},
 
2348
                    {"path": "/etc/hosts", "contents": "Mg=="},
 
2349
                ],
 
2350
            },
 
2351
        }
 
2352
        self.assertDictMatch(request['body'], expected)
 
2353
 
 
2354
    def test_spec_request(self):
 
2355
        image_bookmark_link = "http://servers.api.openstack.org/1234/" + \
 
2356
                              "images/52415800-8b69-11e0-9b19-734f6f006e54"
 
2357
        serial_request = """
 
2358
<server xmlns="http://docs.openstack.org/compute/api/v2"
 
2359
        imageRef="%s"
 
2360
        flavorRef="52415800-8b69-11e0-9b19-734f1195ff37"
 
2361
        name="new-server-test">
 
2362
  <metadata>
 
2363
    <meta key="My Server Name">Apache1</meta>
 
2364
  </metadata>
 
2365
  <personality>
 
2366
    <file path="/etc/banner.txt">Mg==</file>
 
2367
  </personality>
 
2368
</server>""" % (image_bookmark_link)
 
2369
        request = self.deserializer.deserialize(serial_request)
 
2370
        expected = {
 
2371
            "server": {
 
2372
                "name": "new-server-test",
 
2373
                "imageRef": "http://servers.api.openstack.org/1234/" + \
 
2374
                            "images/52415800-8b69-11e0-9b19-734f6f006e54",
 
2375
                "flavorRef": "52415800-8b69-11e0-9b19-734f1195ff37",
 
2376
                "metadata": {"My Server Name": "Apache1"},
 
2377
                "personality": [
 
2378
                    {
 
2379
                        "path": "/etc/banner.txt",
 
2380
                        "contents": "Mg==",
 
2381
                    },
 
2382
                ],
 
2383
            },
 
2384
        }
 
2385
        self.assertEquals(request['body'], expected)
 
2386
 
 
2387
    def test_request_with_empty_networks(self):
 
2388
        serial_request = """
 
2389
<server xmlns="http://docs.openstack.org/compute/api/v2"
 
2390
 name="new-server-test" imageRef="1" flavorRef="1">
 
2391
    <networks/>
 
2392
</server>"""
 
2393
        request = self.deserializer.deserialize(serial_request)
 
2394
        expected = {"server": {
 
2395
                "name": "new-server-test",
 
2396
                "imageRef": "1",
 
2397
                "flavorRef": "1",
 
2398
                "networks": [],
 
2399
                }}
 
2400
        self.assertEquals(request['body'], expected)
 
2401
 
 
2402
    def test_request_with_one_network(self):
 
2403
        serial_request = """
 
2404
<server xmlns="http://docs.openstack.org/compute/api/v2"
 
2405
 name="new-server-test" imageRef="1" flavorRef="1">
 
2406
    <networks>
 
2407
       <network uuid="1" fixed_ip="10.0.1.12"/>
 
2408
    </networks>
 
2409
</server>"""
 
2410
        request = self.deserializer.deserialize(serial_request)
 
2411
        expected = {"server": {
 
2412
                "name": "new-server-test",
 
2413
                "imageRef": "1",
 
2414
                "flavorRef": "1",
 
2415
                "networks": [{"uuid": "1", "fixed_ip": "10.0.1.12"}],
 
2416
                }}
 
2417
        self.assertEquals(request['body'], expected)
 
2418
 
 
2419
    def test_request_with_two_networks(self):
 
2420
        serial_request = """
 
2421
<server xmlns="http://docs.openstack.org/compute/api/v2"
 
2422
 name="new-server-test" imageRef="1" flavorRef="1">
 
2423
    <networks>
 
2424
       <network uuid="1" fixed_ip="10.0.1.12"/>
 
2425
       <network uuid="2" fixed_ip="10.0.2.12"/>
 
2426
    </networks>
 
2427
</server>"""
 
2428
        request = self.deserializer.deserialize(serial_request)
 
2429
        expected = {"server": {
 
2430
                "name": "new-server-test",
 
2431
                "imageRef": "1",
 
2432
                "flavorRef": "1",
 
2433
                "networks": [{"uuid": "1", "fixed_ip": "10.0.1.12"},
 
2434
                             {"uuid": "2", "fixed_ip": "10.0.2.12"}],
 
2435
                }}
 
2436
        self.assertEquals(request['body'], expected)
 
2437
 
 
2438
    def test_request_with_second_network_node_ignored(self):
 
2439
        serial_request = """
 
2440
<server xmlns="http://docs.openstack.org/compute/api/v2"
 
2441
 name="new-server-test" imageRef="1" flavorRef="1">
 
2442
    <networks>
 
2443
       <network uuid="1" fixed_ip="10.0.1.12"/>
 
2444
    </networks>
 
2445
    <networks>
 
2446
       <network uuid="2" fixed_ip="10.0.2.12"/>
 
2447
    </networks>
 
2448
</server>"""
 
2449
        request = self.deserializer.deserialize(serial_request)
 
2450
        expected = {"server": {
 
2451
                "name": "new-server-test",
 
2452
                "imageRef": "1",
 
2453
                "flavorRef": "1",
 
2454
                "networks": [{"uuid": "1", "fixed_ip": "10.0.1.12"}],
 
2455
                }}
 
2456
        self.assertEquals(request['body'], expected)
 
2457
 
 
2458
    def test_request_with_one_network_missing_id(self):
 
2459
        serial_request = """
 
2460
<server xmlns="http://docs.openstack.org/compute/api/v2"
 
2461
 name="new-server-test" imageRef="1" flavorRef="1">
 
2462
    <networks>
 
2463
       <network fixed_ip="10.0.1.12"/>
 
2464
    </networks>
 
2465
</server>"""
 
2466
        request = self.deserializer.deserialize(serial_request)
 
2467
        expected = {"server": {
 
2468
                "name": "new-server-test",
 
2469
                "imageRef": "1",
 
2470
                "flavorRef": "1",
 
2471
                "networks": [{"fixed_ip": "10.0.1.12"}],
 
2472
                }}
 
2473
        self.assertEquals(request['body'], expected)
 
2474
 
 
2475
    def test_request_with_one_network_missing_fixed_ip(self):
 
2476
        serial_request = """
 
2477
<server xmlns="http://docs.openstack.org/compute/api/v2"
 
2478
 name="new-server-test" imageRef="1" flavorRef="1">
 
2479
    <networks>
 
2480
       <network uuid="1"/>
 
2481
    </networks>
 
2482
</server>"""
 
2483
        request = self.deserializer.deserialize(serial_request)
 
2484
        expected = {"server": {
 
2485
                "name": "new-server-test",
 
2486
                "imageRef": "1",
 
2487
                "flavorRef": "1",
 
2488
                "networks": [{"uuid": "1"}],
 
2489
                }}
 
2490
        self.assertEquals(request['body'], expected)
 
2491
 
 
2492
    def test_request_with_one_network_empty_id(self):
 
2493
        serial_request = """
 
2494
    <server xmlns="http://docs.openstack.org/compute/api/v2"
 
2495
     name="new-server-test" imageRef="1" flavorRef="1">
 
2496
        <networks>
 
2497
           <network uuid="" fixed_ip="10.0.1.12"/>
 
2498
        </networks>
 
2499
    </server>"""
 
2500
        request = self.deserializer.deserialize(serial_request)
 
2501
        expected = {"server": {
 
2502
                "name": "new-server-test",
 
2503
                "imageRef": "1",
 
2504
                "flavorRef": "1",
 
2505
                "networks": [{"uuid": "", "fixed_ip": "10.0.1.12"}],
 
2506
                }}
 
2507
        self.assertEquals(request['body'], expected)
 
2508
 
 
2509
    def test_request_with_one_network_empty_fixed_ip(self):
 
2510
        serial_request = """
 
2511
    <server xmlns="http://docs.openstack.org/compute/api/v2"
 
2512
     name="new-server-test" imageRef="1" flavorRef="1">
 
2513
        <networks>
 
2514
           <network uuid="1" fixed_ip=""/>
 
2515
        </networks>
 
2516
    </server>"""
 
2517
        request = self.deserializer.deserialize(serial_request)
 
2518
        expected = {"server": {
 
2519
                "name": "new-server-test",
 
2520
                "imageRef": "1",
 
2521
                "flavorRef": "1",
 
2522
                "networks": [{"uuid": "1", "fixed_ip": ""}],
 
2523
                }}
 
2524
        self.assertEquals(request['body'], expected)
 
2525
 
 
2526
    def test_request_with_networks_duplicate_ids(self):
 
2527
        serial_request = """
 
2528
    <server xmlns="http://docs.openstack.org/compute/api/v2"
 
2529
     name="new-server-test" imageRef="1" flavorRef="1">
 
2530
        <networks>
 
2531
           <network uuid="1" fixed_ip="10.0.1.12"/>
 
2532
           <network uuid="1" fixed_ip="10.0.2.12"/>
 
2533
        </networks>
 
2534
    </server>"""
 
2535
        request = self.deserializer.deserialize(serial_request)
 
2536
        expected = {"server": {
 
2537
                "name": "new-server-test",
 
2538
                "imageRef": "1",
 
2539
                "flavorRef": "1",
 
2540
                "networks": [{"uuid": "1", "fixed_ip": "10.0.1.12"},
 
2541
                             {"uuid": "1", "fixed_ip": "10.0.2.12"}],
 
2542
                }}
 
2543
        self.assertEquals(request['body'], expected)
 
2544
 
 
2545
 
 
2546
class TestAddressesXMLSerialization(test.TestCase):
 
2547
 
 
2548
    index_serializer = nova.api.openstack.compute.ips.AddressesTemplate()
 
2549
    show_serializer = nova.api.openstack.compute.ips.NetworkTemplate()
 
2550
 
 
2551
    def test_xml_declaration(self):
 
2552
        fixture = {
 
2553
            'network_2': [
 
2554
                {'addr': '192.168.0.1', 'version': 4},
 
2555
                {'addr': 'fe80::beef', 'version': 6},
 
2556
            ],
 
2557
        }
 
2558
        output = self.show_serializer.serialize(fixture)
 
2559
        has_dec = output.startswith("<?xml version='1.0' encoding='UTF-8'?>")
 
2560
        self.assertTrue(has_dec)
 
2561
 
 
2562
    def test_show(self):
 
2563
        fixture = {
 
2564
            'network_2': [
 
2565
                {'addr': '192.168.0.1', 'version': 4},
 
2566
                {'addr': 'fe80::beef', 'version': 6},
 
2567
            ],
 
2568
        }
 
2569
        output = self.show_serializer.serialize(fixture)
 
2570
        root = etree.XML(output)
 
2571
        network = fixture['network_2']
 
2572
        self.assertEqual(str(root.get('id')), 'network_2')
 
2573
        ip_elems = root.findall('{0}ip'.format(NS))
 
2574
        for z, ip_elem in enumerate(ip_elems):
 
2575
            ip = network[z]
 
2576
            self.assertEqual(str(ip_elem.get('version')),
 
2577
                             str(ip['version']))
 
2578
            self.assertEqual(str(ip_elem.get('addr')),
 
2579
                             str(ip['addr']))
 
2580
 
 
2581
    def test_index(self):
 
2582
        fixture = {
 
2583
            'addresses': {
 
2584
                'network_1': [
 
2585
                    {'addr': '192.168.0.3', 'version': 4},
 
2586
                    {'addr': '192.168.0.5', 'version': 4},
 
2587
                ],
 
2588
                'network_2': [
 
2589
                    {'addr': '192.168.0.1', 'version': 4},
 
2590
                    {'addr': 'fe80::beef', 'version': 6},
 
2591
                ],
 
2592
            },
 
2593
        }
 
2594
        output = self.index_serializer.serialize(fixture)
 
2595
        root = etree.XML(output)
 
2596
        xmlutil.validate_schema(root, 'addresses')
 
2597
        addresses_dict = fixture['addresses']
 
2598
        network_elems = root.findall('{0}network'.format(NS))
 
2599
        self.assertEqual(len(network_elems), 2)
 
2600
        for i, network_elem in enumerate(network_elems):
 
2601
            network = addresses_dict.items()[i]
 
2602
            self.assertEqual(str(network_elem.get('id')), str(network[0]))
 
2603
            ip_elems = network_elem.findall('{0}ip'.format(NS))
 
2604
            for z, ip_elem in enumerate(ip_elems):
 
2605
                ip = network[1][z]
 
2606
                self.assertEqual(str(ip_elem.get('version')),
 
2607
                                 str(ip['version']))
 
2608
                self.assertEqual(str(ip_elem.get('addr')),
 
2609
                                 str(ip['addr']))
 
2610
 
 
2611
 
 
2612
class ServersViewBuilderTest(test.TestCase):
 
2613
 
 
2614
    def setUp(self):
 
2615
        super(ServersViewBuilderTest, self).setUp()
 
2616
        self.flags(use_ipv6=True)
 
2617
        self.instance = fakes.stub_instance(
 
2618
            id=1,
 
2619
            image_ref="5",
 
2620
            uuid="deadbeef-feed-edee-beef-d0ea7beefedd",
 
2621
            display_name="test_server",
 
2622
            include_fake_metadata=False)
 
2623
 
 
2624
        privates = ['172.19.0.1']
 
2625
        publics = ['192.168.0.3']
 
2626
        public6s = ['b33f::fdee:ddff:fecc:bbaa']
 
2627
 
 
2628
        def nw_info(*args, **kwargs):
 
2629
            return [(None, {'label': 'public',
 
2630
                            'ips': [dict(ip=ip) for ip in publics],
 
2631
                            'ip6s': [dict(ip=ip) for ip in public6s]}),
 
2632
                    (None, {'label': 'private',
 
2633
                            'ips': [dict(ip=ip) for ip in privates]})]
 
2634
 
 
2635
        def floaters(*args, **kwargs):
 
2636
            return []
 
2637
 
 
2638
        fakes.stub_out_nw_api_get_instance_nw_info(self.stubs, nw_info)
 
2639
        fakes.stub_out_nw_api_get_floating_ips_by_fixed_address(self.stubs,
 
2640
                                                                floaters)
 
2641
 
 
2642
        self.uuid = self.instance['uuid']
 
2643
        self.view_builder = views.servers.ViewBuilder()
 
2644
        self.request = fakes.HTTPRequest.blank("/v2")
 
2645
 
 
2646
    def test_build_server(self):
 
2647
        self_link = "http://localhost/v2/fake/servers/%s" % self.uuid
 
2648
        bookmark_link = "http://localhost/fake/servers/%s" % self.uuid
 
2649
        expected_server = {
 
2650
            "server": {
 
2651
                "id": self.uuid,
 
2652
                "name": "test_server",
 
2653
                "links": [
 
2654
                    {
 
2655
                        "rel": "self",
 
2656
                        "href": self_link,
 
2657
                    },
 
2658
                    {
 
2659
                        "rel": "bookmark",
 
2660
                        "href": bookmark_link,
 
2661
                    },
 
2662
                ],
 
2663
            }
 
2664
        }
 
2665
 
 
2666
        output = self.view_builder.basic(self.request, self.instance)
 
2667
        self.assertDictMatch(output, expected_server)
 
2668
 
 
2669
    def test_build_server_with_project_id(self):
 
2670
        expected_server = {
 
2671
            "server": {
 
2672
                "id": self.uuid,
 
2673
                "name": "test_server",
 
2674
                "links": [
 
2675
                    {
 
2676
                        "rel": "self",
 
2677
                        "href": "http://localhost/v2/fake/servers/%s" %
 
2678
                                self.uuid,
 
2679
                    },
 
2680
                    {
 
2681
                        "rel": "bookmark",
 
2682
                        "href": "http://localhost/fake/servers/%s" % self.uuid,
 
2683
                    },
 
2684
                ],
 
2685
            }
 
2686
        }
 
2687
 
 
2688
        output = self.view_builder.basic(self.request, self.instance)
 
2689
        self.assertDictMatch(output, expected_server)
 
2690
 
 
2691
    def test_build_server_detail(self):
 
2692
        image_bookmark = "http://localhost/fake/images/5"
 
2693
        flavor_bookmark = "http://localhost/fake/flavors/1"
 
2694
        self_link = "http://localhost/v2/fake/servers/%s" % self.uuid
 
2695
        bookmark_link = "http://localhost/fake/servers/%s" % self.uuid
 
2696
        expected_server = {
 
2697
            "server": {
 
2698
                "id": self.uuid,
 
2699
                "user_id": "fake",
 
2700
                "tenant_id": "fake",
 
2701
                "updated": "2010-11-11T11:00:00Z",
 
2702
                "created": "2010-10-10T12:00:00Z",
 
2703
                "progress": 0,
 
2704
                "name": "test_server",
 
2705
                "status": "BUILD",
 
2706
                "accessIPv4": "",
 
2707
                "accessIPv6": "",
 
2708
                "hostId": '',
 
2709
                "key_name": '',
 
2710
                "image": {
 
2711
                    "id": "5",
 
2712
                    "links": [
 
2713
                        {
 
2714
                            "rel": "bookmark",
 
2715
                            "href": image_bookmark,
 
2716
                        },
 
2717
                    ],
 
2718
                },
 
2719
                "flavor": {
 
2720
                    "id": "1",
 
2721
                  "links": [
 
2722
                                            {
 
2723
                          "rel": "bookmark",
 
2724
                          "href": flavor_bookmark,
 
2725
                      },
 
2726
                  ],
 
2727
                },
 
2728
                "addresses": {
 
2729
                    'private': [
 
2730
                        {'version': 4, 'addr': '172.19.0.1'}
 
2731
                    ],
 
2732
                    'public': [
 
2733
                        {'version': 4, 'addr': '192.168.0.3'},
 
2734
                        {'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
 
2735
                    ],
 
2736
                },
 
2737
                "metadata": {},
 
2738
                "config_drive": None,
 
2739
                "links": [
 
2740
                    {
 
2741
                        "rel": "self",
 
2742
                        "href": self_link,
 
2743
                    },
 
2744
                    {
 
2745
                        "rel": "bookmark",
 
2746
                        "href": bookmark_link,
 
2747
                    },
 
2748
                ],
 
2749
            }
 
2750
        }
 
2751
 
 
2752
        output = self.view_builder.show(self.request, self.instance)
 
2753
        self.assertDictMatch(output, expected_server)
 
2754
 
 
2755
    def test_build_server_detail_with_fault(self):
 
2756
        self.instance['vm_state'] = vm_states.ERROR
 
2757
        self.instance['fault'] = {
 
2758
            'code': 404,
 
2759
            'instance_uuid': self.uuid,
 
2760
            'message': "HTTPNotFound",
 
2761
            'details': "Stock details for test",
 
2762
            'created_at': datetime.datetime(2010, 10, 10, 12, 0, 0),
 
2763
        }
 
2764
 
 
2765
        image_bookmark = "http://localhost/fake/images/5"
 
2766
        flavor_bookmark = "http://localhost/fake/flavors/1"
 
2767
        self_link = "http://localhost/v2/fake/servers/%s" % self.uuid
 
2768
        bookmark_link = "http://localhost/fake/servers/%s" % self.uuid
 
2769
        expected_server = {
 
2770
            "server": {
 
2771
                "id": self.uuid,
 
2772
                "user_id": "fake",
 
2773
                "tenant_id": "fake",
 
2774
                "updated": "2010-11-11T11:00:00Z",
 
2775
                "created": "2010-10-10T12:00:00Z",
 
2776
                "name": "test_server",
 
2777
                "status": "ERROR",
 
2778
                "accessIPv4": "",
 
2779
                "accessIPv6": "",
 
2780
                "hostId": '',
 
2781
                "key_name": '',
 
2782
                "image": {
 
2783
                    "id": "5",
 
2784
                    "links": [
 
2785
                        {
 
2786
                            "rel": "bookmark",
 
2787
                            "href": image_bookmark,
 
2788
                        },
 
2789
                    ],
 
2790
                },
 
2791
                "flavor": {
 
2792
                    "id": "1",
 
2793
                  "links": [
 
2794
                                            {
 
2795
                          "rel": "bookmark",
 
2796
                          "href": flavor_bookmark,
 
2797
                      },
 
2798
                  ],
 
2799
                },
 
2800
                "addresses": {
 
2801
                    'private': [
 
2802
                        {'version': 4, 'addr': '172.19.0.1'}
 
2803
                    ],
 
2804
                    'public': [
 
2805
                        {'version': 4, 'addr': '192.168.0.3'},
 
2806
                        {'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
 
2807
                    ],
 
2808
                },
 
2809
                "metadata": {},
 
2810
                "config_drive": None,
 
2811
                "links": [
 
2812
                    {
 
2813
                        "rel": "self",
 
2814
                        "href": self_link,
 
2815
                    },
 
2816
                    {
 
2817
                        "rel": "bookmark",
 
2818
                        "href": bookmark_link,
 
2819
                    },
 
2820
                ],
 
2821
                "fault": {
 
2822
                    "code": 404,
 
2823
                    "created": "2010-10-10T12:00:00Z",
 
2824
                    "message": "HTTPNotFound",
 
2825
                    "details": "Stock details for test",
 
2826
                },
 
2827
            }
 
2828
        }
 
2829
 
 
2830
        output = self.view_builder.show(self.request, self.instance)
 
2831
        self.assertDictMatch(output, expected_server)
 
2832
 
 
2833
    def test_build_server_detail_with_fault_but_active(self):
 
2834
        self.instance['vm_state'] = vm_states.ACTIVE
 
2835
        self.instance['progress'] = 100
 
2836
        self.instance['fault'] = {
 
2837
            'code': 404,
 
2838
            'instance_uuid': self.uuid,
 
2839
            'message': "HTTPNotFound",
 
2840
            'details': "Stock details for test",
 
2841
            'created_at': datetime.datetime(2010, 10, 10, 12, 0, 0),
 
2842
        }
 
2843
 
 
2844
        image_bookmark = "http://localhost/fake/images/5"
 
2845
        flavor_bookmark = "http://localhost/fake/flavors/1"
 
2846
        self_link = "http://localhost/v2/fake/servers/%s" % self.uuid
 
2847
        bookmark_link = "http://localhost/fake/servers/%s" % self.uuid
 
2848
        expected_server = {
 
2849
            "server": {
 
2850
                "id": self.uuid,
 
2851
                "user_id": "fake",
 
2852
                "tenant_id": "fake",
 
2853
                "updated": "2010-11-11T11:00:00Z",
 
2854
                "created": "2010-10-10T12:00:00Z",
 
2855
                "progress": 100,
 
2856
                "name": "test_server",
 
2857
                "status": "ACTIVE",
 
2858
                "accessIPv4": "",
 
2859
                "accessIPv6": "",
 
2860
                "hostId": '',
 
2861
                "key_name": '',
 
2862
                "image": {
 
2863
                    "id": "5",
 
2864
                    "links": [
 
2865
                        {
 
2866
                            "rel": "bookmark",
 
2867
                            "href": image_bookmark,
 
2868
                        },
 
2869
                    ],
 
2870
                },
 
2871
                "flavor": {
 
2872
                    "id": "1",
 
2873
                  "links": [
 
2874
                                            {
 
2875
                          "rel": "bookmark",
 
2876
                          "href": flavor_bookmark,
 
2877
                      },
 
2878
                  ],
 
2879
                },
 
2880
                "addresses": {
 
2881
                    'private': [
 
2882
                        {'version': 4, 'addr': '172.19.0.1'}
 
2883
                    ],
 
2884
                    'public': [
 
2885
                        {'version': 4, 'addr': '192.168.0.3'},
 
2886
                        {'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
 
2887
                    ],
 
2888
                },
 
2889
                "metadata": {},
 
2890
                "config_drive": None,
 
2891
                "links": [
 
2892
                    {
 
2893
                        "rel": "self",
 
2894
                        "href": self_link,
 
2895
                    },
 
2896
                    {
 
2897
                        "rel": "bookmark",
 
2898
                        "href": bookmark_link,
 
2899
                    },
 
2900
                ],
 
2901
            }
 
2902
        }
 
2903
 
 
2904
        output = self.view_builder.show(self.request, self.instance)
 
2905
        self.assertDictMatch(output, expected_server)
 
2906
 
 
2907
    def test_build_server_detail_active_status(self):
 
2908
        #set the power state of the instance to running
 
2909
        self.instance['vm_state'] = vm_states.ACTIVE
 
2910
        self.instance['progress'] = 100
 
2911
        image_bookmark = "http://localhost/fake/images/5"
 
2912
        flavor_bookmark = "http://localhost/fake/flavors/1"
 
2913
        self_link = "http://localhost/v2/fake/servers/%s" % self.uuid
 
2914
        bookmark_link = "http://localhost/fake/servers/%s" % self.uuid
 
2915
        expected_server = {
 
2916
            "server": {
 
2917
                "id": self.uuid,
 
2918
                "user_id": "fake",
 
2919
                "tenant_id": "fake",
 
2920
                "updated": "2010-11-11T11:00:00Z",
 
2921
                "created": "2010-10-10T12:00:00Z",
 
2922
                "progress": 100,
 
2923
                "name": "test_server",
 
2924
                "status": "ACTIVE",
 
2925
                "accessIPv4": "",
 
2926
                "accessIPv6": "",
 
2927
                "hostId": '',
 
2928
                "key_name": '',
 
2929
                "image": {
 
2930
                    "id": "5",
 
2931
                    "links": [
 
2932
                        {
 
2933
                            "rel": "bookmark",
 
2934
                            "href": image_bookmark,
 
2935
                        },
 
2936
                    ],
 
2937
                },
 
2938
                "flavor": {
 
2939
                    "id": "1",
 
2940
                  "links": [
 
2941
                                            {
 
2942
                          "rel": "bookmark",
 
2943
                          "href": flavor_bookmark,
 
2944
                      },
 
2945
                  ],
 
2946
                },
 
2947
                "addresses": {
 
2948
                    'private': [
 
2949
                        {'version': 4, 'addr': '172.19.0.1'}
 
2950
                    ],
 
2951
                    'public': [
 
2952
                        {'version': 4, 'addr': '192.168.0.3'},
 
2953
                        {'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
 
2954
                    ],
 
2955
                },
 
2956
                "metadata": {},
 
2957
                "config_drive": None,
 
2958
                "links": [
 
2959
                    {
 
2960
                        "rel": "self",
 
2961
                        "href": self_link,
 
2962
                    },
 
2963
                    {
 
2964
                        "rel": "bookmark",
 
2965
                        "href": bookmark_link,
 
2966
                    },
 
2967
                ],
 
2968
            }
 
2969
        }
 
2970
 
 
2971
        output = self.view_builder.show(self.request, self.instance)
 
2972
        self.assertDictMatch(output, expected_server)
 
2973
 
 
2974
    def test_build_server_detail_with_accessipv4(self):
 
2975
 
 
2976
        self.instance['access_ip_v4'] = '1.2.3.4'
 
2977
 
 
2978
        image_bookmark = "http://localhost/fake/images/5"
 
2979
        flavor_bookmark = "http://localhost/fake/flavors/1"
 
2980
        self_link = "http://localhost/v2/fake/servers/%s" % self.uuid
 
2981
        bookmark_link = "http://localhost/fake/servers/%s" % self.uuid
 
2982
        expected_server = {
 
2983
            "server": {
 
2984
                "id": self.uuid,
 
2985
                "user_id": "fake",
 
2986
                "tenant_id": "fake",
 
2987
                "updated": "2010-11-11T11:00:00Z",
 
2988
                "created": "2010-10-10T12:00:00Z",
 
2989
                "progress": 0,
 
2990
                "name": "test_server",
 
2991
                "key_name": "",
 
2992
                "status": "BUILD",
 
2993
                "hostId": '',
 
2994
                "image": {
 
2995
                    "id": "5",
 
2996
                    "links": [
 
2997
                        {
 
2998
                            "rel": "bookmark",
 
2999
                            "href": image_bookmark,
 
3000
                        },
 
3001
                    ],
 
3002
                },
 
3003
                "flavor": {
 
3004
                    "id": "1",
 
3005
                    "links": [
 
3006
                                              {
 
3007
                            "rel": "bookmark",
 
3008
                            "href": flavor_bookmark,
 
3009
                        },
 
3010
                    ],
 
3011
                },
 
3012
                "addresses": {
 
3013
                    'private': [
 
3014
                        {'version': 4, 'addr': '172.19.0.1'}
 
3015
                    ],
 
3016
                    'public': [
 
3017
                        {'version': 4, 'addr': '192.168.0.3'},
 
3018
                        {'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
 
3019
                    ],
 
3020
                },
 
3021
                "metadata": {},
 
3022
                "config_drive": None,
 
3023
                "accessIPv4": "1.2.3.4",
 
3024
                "accessIPv6": "",
 
3025
                "links": [
 
3026
                    {
 
3027
                        "rel": "self",
 
3028
                        "href": self_link,
 
3029
                    },
 
3030
                    {
 
3031
                        "rel": "bookmark",
 
3032
                        "href": bookmark_link,
 
3033
                    },
 
3034
                ],
 
3035
            }
 
3036
        }
 
3037
 
 
3038
        output = self.view_builder.show(self.request, self.instance)
 
3039
        self.assertDictMatch(output, expected_server)
 
3040
 
 
3041
    def test_build_server_detail_with_accessipv6(self):
 
3042
 
 
3043
        self.instance['access_ip_v6'] = 'fead::1234'
 
3044
 
 
3045
        image_bookmark = "http://localhost/fake/images/5"
 
3046
        flavor_bookmark = "http://localhost/fake/flavors/1"
 
3047
        self_link = "http://localhost/v2/fake/servers/%s" % self.uuid
 
3048
        bookmark_link = "http://localhost/fake/servers/%s" % self.uuid
 
3049
        expected_server = {
 
3050
            "server": {
 
3051
                "id": self.uuid,
 
3052
                "user_id": "fake",
 
3053
                "tenant_id": "fake",
 
3054
                "updated": "2010-11-11T11:00:00Z",
 
3055
                "created": "2010-10-10T12:00:00Z",
 
3056
                "progress": 0,
 
3057
                "name": "test_server",
 
3058
                "key_name": "",
 
3059
                "status": "BUILD",
 
3060
                "hostId": '',
 
3061
                "image": {
 
3062
                    "id": "5",
 
3063
                    "links": [
 
3064
                        {
 
3065
                            "rel": "bookmark",
 
3066
                            "href": image_bookmark,
 
3067
                        },
 
3068
                    ],
 
3069
                },
 
3070
                "flavor": {
 
3071
                    "id": "1",
 
3072
                    "links": [
 
3073
                                              {
 
3074
                            "rel": "bookmark",
 
3075
                            "href": flavor_bookmark,
 
3076
                        },
 
3077
                    ],
 
3078
                },
 
3079
                "addresses": {
 
3080
                    'private': [
 
3081
                        {'version': 4, 'addr': '172.19.0.1'}
 
3082
                    ],
 
3083
                    'public': [
 
3084
                        {'version': 4, 'addr': '192.168.0.3'},
 
3085
                        {'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
 
3086
                    ]
 
3087
                },
 
3088
                "metadata": {},
 
3089
                "config_drive": None,
 
3090
                "accessIPv4": "",
 
3091
                "accessIPv6": "fead::1234",
 
3092
                "links": [
 
3093
                    {
 
3094
                        "rel": "self",
 
3095
                        "href": self_link,
 
3096
                    },
 
3097
                    {
 
3098
                        "rel": "bookmark",
 
3099
                        "href": bookmark_link,
 
3100
                    },
 
3101
                ],
 
3102
            }
 
3103
        }
 
3104
 
 
3105
        output = self.view_builder.show(self.request, self.instance)
 
3106
        self.assertDictMatch(output, expected_server)
 
3107
 
 
3108
    def test_build_server_detail_with_metadata(self):
 
3109
 
 
3110
        metadata = []
 
3111
        metadata.append(InstanceMetadata(key="Open", value="Stack"))
 
3112
        metadata.append(InstanceMetadata(key="Number", value=1))
 
3113
        self.instance['metadata'] = metadata
 
3114
 
 
3115
        image_bookmark = "http://localhost/fake/images/5"
 
3116
        flavor_bookmark = "http://localhost/fake/flavors/1"
 
3117
        self_link = "http://localhost/v2/fake/servers/%s" % self.uuid
 
3118
        bookmark_link = "http://localhost/fake/servers/%s" % self.uuid
 
3119
        expected_server = {
 
3120
            "server": {
 
3121
                "id": self.uuid,
 
3122
                "user_id": "fake",
 
3123
                "tenant_id": "fake",
 
3124
                "updated": "2010-11-11T11:00:00Z",
 
3125
                "created": "2010-10-10T12:00:00Z",
 
3126
                "progress": 0,
 
3127
                "name": "test_server",
 
3128
                "status": "BUILD",
 
3129
                "accessIPv4": "",
 
3130
                "accessIPv6": "",
 
3131
                "hostId": '',
 
3132
                "key_name": '',
 
3133
                "image": {
 
3134
                    "id": "5",
 
3135
                    "links": [
 
3136
                        {
 
3137
                            "rel": "bookmark",
 
3138
                            "href": image_bookmark,
 
3139
                        },
 
3140
                    ],
 
3141
                },
 
3142
                "flavor": {
 
3143
                    "id": "1",
 
3144
                    "links": [
 
3145
                                              {
 
3146
                            "rel": "bookmark",
 
3147
                            "href": flavor_bookmark,
 
3148
                        },
 
3149
                    ],
 
3150
                },
 
3151
                "addresses": {
 
3152
                    'private': [
 
3153
                        {'version': 4, 'addr': '172.19.0.1'}
 
3154
                    ],
 
3155
                    'public': [
 
3156
                        {'version': 4, 'addr': '192.168.0.3'},
 
3157
                        {'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'},
 
3158
                    ]
 
3159
                },
 
3160
                "metadata": {
 
3161
                    "Open": "Stack",
 
3162
                    "Number": "1",
 
3163
                },
 
3164
                "config_drive": None,
 
3165
                "links": [
 
3166
                    {
 
3167
                        "rel": "self",
 
3168
                        "href": self_link,
 
3169
                    },
 
3170
                    {
 
3171
                        "rel": "bookmark",
 
3172
                        "href": bookmark_link,
 
3173
                    },
 
3174
                ],
 
3175
            }
 
3176
        }
 
3177
 
 
3178
        output = self.view_builder.show(self.request, self.instance)
 
3179
        self.assertDictMatch(output, expected_server)
 
3180
 
 
3181
 
 
3182
class ServerXMLSerializationTest(test.TestCase):
 
3183
 
 
3184
    TIMESTAMP = "2010-10-11T10:30:22Z"
 
3185
    SERVER_HREF = 'http://localhost/v2/servers/%s' % FAKE_UUID
 
3186
    SERVER_NEXT = 'http://localhost/v2/servers?limit=%s&marker=%s'
 
3187
    SERVER_BOOKMARK = 'http://localhost/servers/%s' % FAKE_UUID
 
3188
    IMAGE_BOOKMARK = 'http://localhost/images/5'
 
3189
    FLAVOR_BOOKMARK = 'http://localhost/flavors/1'
 
3190
 
 
3191
    def setUp(self):
 
3192
        self.maxDiff = None
 
3193
        test.TestCase.setUp(self)
 
3194
 
 
3195
    def test_xml_declaration(self):
 
3196
        serializer = servers.ServerTemplate()
 
3197
 
 
3198
        fixture = {
 
3199
            "server": {
 
3200
                'id': FAKE_UUID,
 
3201
                'user_id': 'fake_user_id',
 
3202
                'tenant_id': 'fake_tenant_id',
 
3203
                'created': self.TIMESTAMP,
 
3204
                'updated': self.TIMESTAMP,
 
3205
                "progress": 0,
 
3206
                "name": "test_server",
 
3207
                "status": "BUILD",
 
3208
                "hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
 
3209
                "accessIPv4": "1.2.3.4",
 
3210
                "accessIPv6": "fead::1234",
 
3211
                "image": {
 
3212
                    "id": "5",
 
3213
                    "links": [
 
3214
                        {
 
3215
                            "rel": "bookmark",
 
3216
                            "href": self.IMAGE_BOOKMARK,
 
3217
                        },
 
3218
                    ],
 
3219
                },
 
3220
                "flavor": {
 
3221
                    "id": "1",
 
3222
                    "links": [
 
3223
                        {
 
3224
                            "rel": "bookmark",
 
3225
                            "href": self.FLAVOR_BOOKMARK,
 
3226
                        },
 
3227
                    ],
 
3228
                },
 
3229
                "addresses": {
 
3230
                    "network_one": [
 
3231
                        {
 
3232
                            "version": 4,
 
3233
                            "addr": "67.23.10.138",
 
3234
                        },
 
3235
                        {
 
3236
                            "version": 6,
 
3237
                            "addr": "::babe:67.23.10.138",
 
3238
                        },
 
3239
                    ],
 
3240
                    "network_two": [
 
3241
                        {
 
3242
                            "version": 4,
 
3243
                            "addr": "67.23.10.139",
 
3244
                        },
 
3245
                        {
 
3246
                            "version": 6,
 
3247
                            "addr": "::babe:67.23.10.139",
 
3248
                        },
 
3249
                    ],
 
3250
                },
 
3251
                "metadata": {
 
3252
                    "Open": "Stack",
 
3253
                    "Number": "1",
 
3254
                },
 
3255
                'links': [
 
3256
                    {
 
3257
                        'href': self.SERVER_HREF,
 
3258
                        'rel': 'self',
 
3259
                    },
 
3260
                    {
 
3261
                        'href': self.SERVER_BOOKMARK,
 
3262
                        'rel': 'bookmark',
 
3263
                    },
 
3264
                ],
 
3265
            }
 
3266
        }
 
3267
 
 
3268
        output = serializer.serialize(fixture)
 
3269
        print output
 
3270
        has_dec = output.startswith("<?xml version='1.0' encoding='UTF-8'?>")
 
3271
        self.assertTrue(has_dec)
 
3272
 
 
3273
    def test_show(self):
 
3274
        serializer = servers.ServerTemplate()
 
3275
 
 
3276
        fixture = {
 
3277
            "server": {
 
3278
                "id": FAKE_UUID,
 
3279
                "user_id": "fake",
 
3280
                "tenant_id": "fake",
 
3281
                'created': self.TIMESTAMP,
 
3282
                'updated': self.TIMESTAMP,
 
3283
                "progress": 0,
 
3284
                "name": "test_server",
 
3285
                "status": "BUILD",
 
3286
                "hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
 
3287
                "key_name": '',
 
3288
                "accessIPv4": "1.2.3.4",
 
3289
                "accessIPv6": "fead::1234",
 
3290
                "image": {
 
3291
                    "id": "5",
 
3292
                    "links": [
 
3293
                        {
 
3294
                            "rel": "bookmark",
 
3295
                            "href": self.IMAGE_BOOKMARK,
 
3296
                        },
 
3297
                    ],
 
3298
                },
 
3299
                "flavor": {
 
3300
                    "id": "1",
 
3301
                    "links": [
 
3302
                        {
 
3303
                            "rel": "bookmark",
 
3304
                            "href": self.FLAVOR_BOOKMARK,
 
3305
                        },
 
3306
                    ],
 
3307
                },
 
3308
                "addresses": {
 
3309
                    "network_one": [
 
3310
                        {
 
3311
                            "version": 4,
 
3312
                            "addr": "67.23.10.138",
 
3313
                        },
 
3314
                        {
 
3315
                            "version": 6,
 
3316
                            "addr": "::babe:67.23.10.138",
 
3317
                        },
 
3318
                    ],
 
3319
                    "network_two": [
 
3320
                        {
 
3321
                            "version": 4,
 
3322
                            "addr": "67.23.10.139",
 
3323
                        },
 
3324
                        {
 
3325
                            "version": 6,
 
3326
                            "addr": "::babe:67.23.10.139",
 
3327
                        },
 
3328
                    ],
 
3329
                },
 
3330
                "metadata": {
 
3331
                    "Open": "Stack",
 
3332
                    "Number": "1",
 
3333
                },
 
3334
                'links': [
 
3335
                    {
 
3336
                        'href': self.SERVER_HREF,
 
3337
                        'rel': 'self',
 
3338
                    },
 
3339
                    {
 
3340
                        'href': self.SERVER_BOOKMARK,
 
3341
                        'rel': 'bookmark',
 
3342
                    },
 
3343
                ],
 
3344
            }
 
3345
        }
 
3346
 
 
3347
        output = serializer.serialize(fixture)
 
3348
        print output
 
3349
        root = etree.XML(output)
 
3350
        xmlutil.validate_schema(root, 'server')
 
3351
 
 
3352
        server_dict = fixture['server']
 
3353
 
 
3354
        for key in ['name', 'id', 'created', 'accessIPv4',
 
3355
                    'updated', 'progress', 'status', 'hostId',
 
3356
                    'accessIPv6']:
 
3357
            self.assertEqual(root.get(key), str(server_dict[key]))
 
3358
 
 
3359
        link_nodes = root.findall('{0}link'.format(ATOMNS))
 
3360
        self.assertEqual(len(link_nodes), 2)
 
3361
        for i, link in enumerate(server_dict['links']):
 
3362
            for key, value in link.items():
 
3363
                self.assertEqual(link_nodes[i].get(key), value)
 
3364
 
 
3365
        metadata_root = root.find('{0}metadata'.format(NS))
 
3366
        metadata_elems = metadata_root.findall('{0}meta'.format(NS))
 
3367
        self.assertEqual(len(metadata_elems), 2)
 
3368
        for i, metadata_elem in enumerate(metadata_elems):
 
3369
            (meta_key, meta_value) = server_dict['metadata'].items()[i]
 
3370
            self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
 
3371
            self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
 
3372
 
 
3373
        image_root = root.find('{0}image'.format(NS))
 
3374
        self.assertEqual(image_root.get('id'), server_dict['image']['id'])
 
3375
        link_nodes = image_root.findall('{0}link'.format(ATOMNS))
 
3376
        self.assertEqual(len(link_nodes), 1)
 
3377
        for i, link in enumerate(server_dict['image']['links']):
 
3378
            for key, value in link.items():
 
3379
                self.assertEqual(link_nodes[i].get(key), value)
 
3380
 
 
3381
        flavor_root = root.find('{0}flavor'.format(NS))
 
3382
        self.assertEqual(flavor_root.get('id'), server_dict['flavor']['id'])
 
3383
        link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
 
3384
        self.assertEqual(len(link_nodes), 1)
 
3385
        for i, link in enumerate(server_dict['flavor']['links']):
 
3386
            for key, value in link.items():
 
3387
                self.assertEqual(link_nodes[i].get(key), value)
 
3388
 
 
3389
        addresses_root = root.find('{0}addresses'.format(NS))
 
3390
        addresses_dict = server_dict['addresses']
 
3391
        network_elems = addresses_root.findall('{0}network'.format(NS))
 
3392
        self.assertEqual(len(network_elems), 2)
 
3393
        for i, network_elem in enumerate(network_elems):
 
3394
            network = addresses_dict.items()[i]
 
3395
            self.assertEqual(str(network_elem.get('id')), str(network[0]))
 
3396
            ip_elems = network_elem.findall('{0}ip'.format(NS))
 
3397
            for z, ip_elem in enumerate(ip_elems):
 
3398
                ip = network[1][z]
 
3399
                self.assertEqual(str(ip_elem.get('version')),
 
3400
                                 str(ip['version']))
 
3401
                self.assertEqual(str(ip_elem.get('addr')),
 
3402
                                 str(ip['addr']))
 
3403
 
 
3404
    def test_create(self):
 
3405
        serializer = servers.FullServerTemplate()
 
3406
 
 
3407
        fixture = {
 
3408
            "server": {
 
3409
                "id": FAKE_UUID,
 
3410
                "user_id": "fake",
 
3411
                "tenant_id": "fake",
 
3412
                'created': self.TIMESTAMP,
 
3413
                'updated': self.TIMESTAMP,
 
3414
                "progress": 0,
 
3415
                "name": "test_server",
 
3416
                "status": "BUILD",
 
3417
                "accessIPv4": "1.2.3.4",
 
3418
                "accessIPv6": "fead::1234",
 
3419
                "hostId": "e4d909c290d0fb1ca068ffaddf22cbd0",
 
3420
                "adminPass": "test_password",
 
3421
                "image": {
 
3422
                    "id": "5",
 
3423
                    "links": [
 
3424
                        {
 
3425
                            "rel": "bookmark",
 
3426
                            "href": self.IMAGE_BOOKMARK,
 
3427
                        },
 
3428
                    ],
 
3429
                },
 
3430
                "flavor": {
 
3431
                    "id": "1",
 
3432
                    "links": [
 
3433
                        {
 
3434
                            "rel": "bookmark",
 
3435
                            "href": self.FLAVOR_BOOKMARK,
 
3436
                        },
 
3437
                    ],
 
3438
                },
 
3439
                "addresses": {
 
3440
                    "network_one": [
 
3441
                        {
 
3442
                            "version": 4,
 
3443
                            "addr": "67.23.10.138",
 
3444
                        },
 
3445
                        {
 
3446
                            "version": 6,
 
3447
                            "addr": "::babe:67.23.10.138",
 
3448
                        },
 
3449
                    ],
 
3450
                    "network_two": [
 
3451
                        {
 
3452
                            "version": 4,
 
3453
                            "addr": "67.23.10.139",
 
3454
                        },
 
3455
                        {
 
3456
                            "version": 6,
 
3457
                            "addr": "::babe:67.23.10.139",
 
3458
                        },
 
3459
                    ],
 
3460
                },
 
3461
                "metadata": {
 
3462
                    "Open": "Stack",
 
3463
                    "Number": "1",
 
3464
                },
 
3465
                'links': [
 
3466
                    {
 
3467
                        'href': self.SERVER_HREF,
 
3468
                        'rel': 'self',
 
3469
                    },
 
3470
                    {
 
3471
                        'href': self.SERVER_BOOKMARK,
 
3472
                        'rel': 'bookmark',
 
3473
                    },
 
3474
                ],
 
3475
            }
 
3476
        }
 
3477
 
 
3478
        output = serializer.serialize(fixture)
 
3479
        print output
 
3480
        root = etree.XML(output)
 
3481
        xmlutil.validate_schema(root, 'server')
 
3482
 
 
3483
        server_dict = fixture['server']
 
3484
 
 
3485
        for key in ['name', 'id', 'created', 'accessIPv4',
 
3486
                    'updated', 'progress', 'status', 'hostId',
 
3487
                    'accessIPv6', 'adminPass']:
 
3488
            self.assertEqual(root.get(key), str(server_dict[key]))
 
3489
 
 
3490
        link_nodes = root.findall('{0}link'.format(ATOMNS))
 
3491
        self.assertEqual(len(link_nodes), 2)
 
3492
        for i, link in enumerate(server_dict['links']):
 
3493
            for key, value in link.items():
 
3494
                self.assertEqual(link_nodes[i].get(key), value)
 
3495
 
 
3496
        metadata_root = root.find('{0}metadata'.format(NS))
 
3497
        metadata_elems = metadata_root.findall('{0}meta'.format(NS))
 
3498
        self.assertEqual(len(metadata_elems), 2)
 
3499
        for i, metadata_elem in enumerate(metadata_elems):
 
3500
            (meta_key, meta_value) = server_dict['metadata'].items()[i]
 
3501
            self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
 
3502
            self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
 
3503
 
 
3504
        image_root = root.find('{0}image'.format(NS))
 
3505
        self.assertEqual(image_root.get('id'), server_dict['image']['id'])
 
3506
        link_nodes = image_root.findall('{0}link'.format(ATOMNS))
 
3507
        self.assertEqual(len(link_nodes), 1)
 
3508
        for i, link in enumerate(server_dict['image']['links']):
 
3509
            for key, value in link.items():
 
3510
                self.assertEqual(link_nodes[i].get(key), value)
 
3511
 
 
3512
        flavor_root = root.find('{0}flavor'.format(NS))
 
3513
        self.assertEqual(flavor_root.get('id'), server_dict['flavor']['id'])
 
3514
        link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
 
3515
        self.assertEqual(len(link_nodes), 1)
 
3516
        for i, link in enumerate(server_dict['flavor']['links']):
 
3517
            for key, value in link.items():
 
3518
                self.assertEqual(link_nodes[i].get(key), value)
 
3519
 
 
3520
        addresses_root = root.find('{0}addresses'.format(NS))
 
3521
        addresses_dict = server_dict['addresses']
 
3522
        network_elems = addresses_root.findall('{0}network'.format(NS))
 
3523
        self.assertEqual(len(network_elems), 2)
 
3524
        for i, network_elem in enumerate(network_elems):
 
3525
            network = addresses_dict.items()[i]
 
3526
            self.assertEqual(str(network_elem.get('id')), str(network[0]))
 
3527
            ip_elems = network_elem.findall('{0}ip'.format(NS))
 
3528
            for z, ip_elem in enumerate(ip_elems):
 
3529
                ip = network[1][z]
 
3530
                self.assertEqual(str(ip_elem.get('version')),
 
3531
                                 str(ip['version']))
 
3532
                self.assertEqual(str(ip_elem.get('addr')),
 
3533
                                 str(ip['addr']))
 
3534
 
 
3535
    def test_index(self):
 
3536
        serializer = servers.MinimalServersTemplate()
 
3537
 
 
3538
        uuid1 = get_fake_uuid(1)
 
3539
        uuid2 = get_fake_uuid(2)
 
3540
        expected_server_href = 'http://localhost/v2/servers/%s' % uuid1
 
3541
        expected_server_bookmark = 'http://localhost/servers/%s' % uuid1
 
3542
        expected_server_href_2 = 'http://localhost/v2/servers/%s' % uuid2
 
3543
        expected_server_bookmark_2 = 'http://localhost/servers/%s' % uuid2
 
3544
        fixture = {"servers": [
 
3545
            {
 
3546
                "id": get_fake_uuid(1),
 
3547
                "name": "test_server",
 
3548
                'links': [
 
3549
                    {
 
3550
                        'href': expected_server_href,
 
3551
                        'rel': 'self',
 
3552
                    },
 
3553
                    {
 
3554
                        'href': expected_server_bookmark,
 
3555
                        'rel': 'bookmark',
 
3556
                    },
 
3557
                ],
 
3558
            },
 
3559
            {
 
3560
                "id": get_fake_uuid(2),
 
3561
                "name": "test_server_2",
 
3562
                'links': [
 
3563
                    {
 
3564
                        'href': expected_server_href_2,
 
3565
                        'rel': 'self',
 
3566
                    },
 
3567
                    {
 
3568
                        'href': expected_server_bookmark_2,
 
3569
                        'rel': 'bookmark',
 
3570
                    },
 
3571
                ],
 
3572
            },
 
3573
        ]}
 
3574
 
 
3575
        output = serializer.serialize(fixture)
 
3576
        print output
 
3577
        root = etree.XML(output)
 
3578
        xmlutil.validate_schema(root, 'servers_index')
 
3579
        server_elems = root.findall('{0}server'.format(NS))
 
3580
        self.assertEqual(len(server_elems), 2)
 
3581
        for i, server_elem in enumerate(server_elems):
 
3582
            server_dict = fixture['servers'][i]
 
3583
            for key in ['name', 'id']:
 
3584
                self.assertEqual(server_elem.get(key), str(server_dict[key]))
 
3585
 
 
3586
            link_nodes = server_elem.findall('{0}link'.format(ATOMNS))
 
3587
            self.assertEqual(len(link_nodes), 2)
 
3588
            for i, link in enumerate(server_dict['links']):
 
3589
                for key, value in link.items():
 
3590
                    self.assertEqual(link_nodes[i].get(key), value)
 
3591
 
 
3592
    def test_index_with_servers_links(self):
 
3593
        serializer = servers.MinimalServersTemplate()
 
3594
 
 
3595
        uuid1 = get_fake_uuid(1)
 
3596
        uuid2 = get_fake_uuid(2)
 
3597
        expected_server_href = 'http://localhost/v2/servers/%s' % uuid1
 
3598
        expected_server_next = self.SERVER_NEXT % (2, 2)
 
3599
        expected_server_bookmark = 'http://localhost/servers/%s' % uuid1
 
3600
        expected_server_href_2 = 'http://localhost/v2/servers/%s' % uuid2
 
3601
        expected_server_bookmark_2 = 'http://localhost/servers/%s' % uuid2
 
3602
        fixture = {"servers": [
 
3603
            {
 
3604
                "id": get_fake_uuid(1),
 
3605
                "name": "test_server",
 
3606
                'links': [
 
3607
                    {
 
3608
                        'href': expected_server_href,
 
3609
                        'rel': 'self',
 
3610
                    },
 
3611
                    {
 
3612
                        'href': expected_server_bookmark,
 
3613
                        'rel': 'bookmark',
 
3614
                    },
 
3615
                ],
 
3616
            },
 
3617
            {
 
3618
                "id": get_fake_uuid(2),
 
3619
                "name": "test_server_2",
 
3620
                'links': [
 
3621
                    {
 
3622
                        'href': expected_server_href_2,
 
3623
                        'rel': 'self',
 
3624
                    },
 
3625
                    {
 
3626
                        'href': expected_server_bookmark_2,
 
3627
                        'rel': 'bookmark',
 
3628
                    },
 
3629
                ],
 
3630
            },
 
3631
        ],
 
3632
        "servers_links": [
 
3633
            {
 
3634
                'rel': 'next',
 
3635
                'href': expected_server_next,
 
3636
            },
 
3637
        ]}
 
3638
 
 
3639
        output = serializer.serialize(fixture)
 
3640
        print output
 
3641
        root = etree.XML(output)
 
3642
        xmlutil.validate_schema(root, 'servers_index')
 
3643
        server_elems = root.findall('{0}server'.format(NS))
 
3644
        self.assertEqual(len(server_elems), 2)
 
3645
        for i, server_elem in enumerate(server_elems):
 
3646
            server_dict = fixture['servers'][i]
 
3647
            for key in ['name', 'id']:
 
3648
                self.assertEqual(server_elem.get(key), str(server_dict[key]))
 
3649
 
 
3650
            link_nodes = server_elem.findall('{0}link'.format(ATOMNS))
 
3651
            self.assertEqual(len(link_nodes), 2)
 
3652
            for i, link in enumerate(server_dict['links']):
 
3653
                for key, value in link.items():
 
3654
                    self.assertEqual(link_nodes[i].get(key), value)
 
3655
 
 
3656
        # Check servers_links
 
3657
        servers_links = root.findall('{0}link'.format(ATOMNS))
 
3658
        for i, link in enumerate(fixture['servers_links']):
 
3659
            for key, value in link.items():
 
3660
                self.assertEqual(servers_links[i].get(key), value)
 
3661
 
 
3662
    def test_detail(self):
 
3663
        serializer = servers.ServersTemplate()
 
3664
 
 
3665
        uuid1 = get_fake_uuid(1)
 
3666
        expected_server_href = 'http://localhost/v2/servers/%s' % uuid1
 
3667
        expected_server_bookmark = 'http://localhost/servers/%s' % uuid1
 
3668
        expected_image_bookmark = self.IMAGE_BOOKMARK
 
3669
        expected_flavor_bookmark = self.FLAVOR_BOOKMARK
 
3670
 
 
3671
        uuid2 = get_fake_uuid(2)
 
3672
        expected_server_href_2 = 'http://localhost/v2/servers/%s' % uuid2
 
3673
        expected_server_bookmark_2 = 'http://localhost/servers/%s' % uuid2
 
3674
        fixture = {"servers": [
 
3675
            {
 
3676
                "id": get_fake_uuid(1),
 
3677
                "user_id": "fake",
 
3678
                "tenant_id": "fake",
 
3679
                'created': self.TIMESTAMP,
 
3680
                'updated': self.TIMESTAMP,
 
3681
                "progress": 0,
 
3682
                "name": "test_server",
 
3683
                "status": "BUILD",
 
3684
                "accessIPv4": "1.2.3.4",
 
3685
                "accessIPv6": "fead::1234",
 
3686
                "hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
 
3687
                "image": {
 
3688
                    "id": "5",
 
3689
                    "links": [
 
3690
                        {
 
3691
                            "rel": "bookmark",
 
3692
                            "href": expected_image_bookmark,
 
3693
                        },
 
3694
                    ],
 
3695
                },
 
3696
                "flavor": {
 
3697
                    "id": "1",
 
3698
                    "links": [
 
3699
                        {
 
3700
                            "rel": "bookmark",
 
3701
                            "href": expected_flavor_bookmark,
 
3702
                        },
 
3703
                    ],
 
3704
                },
 
3705
                "addresses": {
 
3706
                    "network_one": [
 
3707
                        {
 
3708
                            "version": 4,
 
3709
                            "addr": "67.23.10.138",
 
3710
                        },
 
3711
                        {
 
3712
                            "version": 6,
 
3713
                            "addr": "::babe:67.23.10.138",
 
3714
                        },
 
3715
                    ],
 
3716
                },
 
3717
                "metadata": {
 
3718
                    "Number": "1",
 
3719
                },
 
3720
                "links": [
 
3721
                    {
 
3722
                        "href": expected_server_href,
 
3723
                        "rel": "self",
 
3724
                    },
 
3725
                    {
 
3726
                        "href": expected_server_bookmark,
 
3727
                        "rel": "bookmark",
 
3728
                    },
 
3729
                ],
 
3730
            },
 
3731
            {
 
3732
                "id": get_fake_uuid(2),
 
3733
                "user_id": 'fake',
 
3734
                "tenant_id": 'fake',
 
3735
                'created': self.TIMESTAMP,
 
3736
                'updated': self.TIMESTAMP,
 
3737
                "progress": 100,
 
3738
                "name": "test_server_2",
 
3739
                "status": "ACTIVE",
 
3740
                "accessIPv4": "1.2.3.4",
 
3741
                "accessIPv6": "fead::1234",
 
3742
                "hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
 
3743
                "image": {
 
3744
                    "id": "5",
 
3745
                    "links": [
 
3746
                        {
 
3747
                            "rel": "bookmark",
 
3748
                            "href": expected_image_bookmark,
 
3749
                        },
 
3750
                    ],
 
3751
                },
 
3752
                "flavor": {
 
3753
                    "id": "1",
 
3754
                    "links": [
 
3755
                        {
 
3756
                            "rel": "bookmark",
 
3757
                            "href": expected_flavor_bookmark,
 
3758
                        },
 
3759
                    ],
 
3760
                },
 
3761
                "addresses": {
 
3762
                    "network_one": [
 
3763
                        {
 
3764
                            "version": 4,
 
3765
                            "addr": "67.23.10.138",
 
3766
                        },
 
3767
                        {
 
3768
                            "version": 6,
 
3769
                            "addr": "::babe:67.23.10.138",
 
3770
                        },
 
3771
                    ],
 
3772
                },
 
3773
                "metadata": {
 
3774
                    "Number": "2",
 
3775
                },
 
3776
                "links": [
 
3777
                    {
 
3778
                        "href": expected_server_href_2,
 
3779
                        "rel": "self",
 
3780
                    },
 
3781
                    {
 
3782
                        "href": expected_server_bookmark_2,
 
3783
                        "rel": "bookmark",
 
3784
                    },
 
3785
                ],
 
3786
            },
 
3787
        ]}
 
3788
 
 
3789
        output = serializer.serialize(fixture)
 
3790
        root = etree.XML(output)
 
3791
        xmlutil.validate_schema(root, 'servers')
 
3792
        server_elems = root.findall('{0}server'.format(NS))
 
3793
        self.assertEqual(len(server_elems), 2)
 
3794
        for i, server_elem in enumerate(server_elems):
 
3795
            server_dict = fixture['servers'][i]
 
3796
 
 
3797
            for key in ['name', 'id', 'created', 'accessIPv4',
 
3798
                        'updated', 'progress', 'status', 'hostId',
 
3799
                        'accessIPv6']:
 
3800
                self.assertEqual(server_elem.get(key), str(server_dict[key]))
 
3801
 
 
3802
            link_nodes = server_elem.findall('{0}link'.format(ATOMNS))
 
3803
            self.assertEqual(len(link_nodes), 2)
 
3804
            for i, link in enumerate(server_dict['links']):
 
3805
                for key, value in link.items():
 
3806
                    self.assertEqual(link_nodes[i].get(key), value)
 
3807
 
 
3808
            metadata_root = server_elem.find('{0}metadata'.format(NS))
 
3809
            metadata_elems = metadata_root.findall('{0}meta'.format(NS))
 
3810
            for i, metadata_elem in enumerate(metadata_elems):
 
3811
                (meta_key, meta_value) = server_dict['metadata'].items()[i]
 
3812
                self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
 
3813
                self.assertEqual(str(metadata_elem.text).strip(),
 
3814
                                 str(meta_value))
 
3815
 
 
3816
            image_root = server_elem.find('{0}image'.format(NS))
 
3817
            self.assertEqual(image_root.get('id'), server_dict['image']['id'])
 
3818
            link_nodes = image_root.findall('{0}link'.format(ATOMNS))
 
3819
            self.assertEqual(len(link_nodes), 1)
 
3820
            for i, link in enumerate(server_dict['image']['links']):
 
3821
                for key, value in link.items():
 
3822
                    self.assertEqual(link_nodes[i].get(key), value)
 
3823
 
 
3824
            flavor_root = server_elem.find('{0}flavor'.format(NS))
 
3825
            self.assertEqual(flavor_root.get('id'),
 
3826
                             server_dict['flavor']['id'])
 
3827
            link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
 
3828
            self.assertEqual(len(link_nodes), 1)
 
3829
            for i, link in enumerate(server_dict['flavor']['links']):
 
3830
                for key, value in link.items():
 
3831
                    self.assertEqual(link_nodes[i].get(key), value)
 
3832
 
 
3833
            addresses_root = server_elem.find('{0}addresses'.format(NS))
 
3834
            addresses_dict = server_dict['addresses']
 
3835
            network_elems = addresses_root.findall('{0}network'.format(NS))
 
3836
            for i, network_elem in enumerate(network_elems):
 
3837
                network = addresses_dict.items()[i]
 
3838
                self.assertEqual(str(network_elem.get('id')), str(network[0]))
 
3839
                ip_elems = network_elem.findall('{0}ip'.format(NS))
 
3840
                for z, ip_elem in enumerate(ip_elems):
 
3841
                    ip = network[1][z]
 
3842
                    self.assertEqual(str(ip_elem.get('version')),
 
3843
                                     str(ip['version']))
 
3844
                    self.assertEqual(str(ip_elem.get('addr')),
 
3845
                                     str(ip['addr']))
 
3846
 
 
3847
    def test_update(self):
 
3848
        serializer = servers.ServerTemplate()
 
3849
 
 
3850
        fixture = {
 
3851
            "server": {
 
3852
                "id": FAKE_UUID,
 
3853
                "user_id": "fake",
 
3854
                "tenant_id": "fake",
 
3855
                'created': self.TIMESTAMP,
 
3856
                'updated': self.TIMESTAMP,
 
3857
                "progress": 0,
 
3858
                "name": "test_server",
 
3859
                "status": "BUILD",
 
3860
                "hostId": 'e4d909c290d0fb1ca068ffaddf22cbd0',
 
3861
                "accessIPv4": "1.2.3.4",
 
3862
                "accessIPv6": "fead::1234",
 
3863
                "image": {
 
3864
                    "id": "5",
 
3865
                    "links": [
 
3866
                        {
 
3867
                            "rel": "bookmark",
 
3868
                            "href": self.IMAGE_BOOKMARK,
 
3869
                        },
 
3870
                    ],
 
3871
                },
 
3872
                "flavor": {
 
3873
                    "id": "1",
 
3874
                    "links": [
 
3875
                        {
 
3876
                            "rel": "bookmark",
 
3877
                            "href": self.FLAVOR_BOOKMARK,
 
3878
                        },
 
3879
                    ],
 
3880
                },
 
3881
                "addresses": {
 
3882
                    "network_one": [
 
3883
                        {
 
3884
                            "version": 4,
 
3885
                            "addr": "67.23.10.138",
 
3886
                        },
 
3887
                        {
 
3888
                            "version": 6,
 
3889
                            "addr": "::babe:67.23.10.138",
 
3890
                        },
 
3891
                    ],
 
3892
                    "network_two": [
 
3893
                        {
 
3894
                            "version": 4,
 
3895
                            "addr": "67.23.10.139",
 
3896
                        },
 
3897
                        {
 
3898
                            "version": 6,
 
3899
                            "addr": "::babe:67.23.10.139",
 
3900
                        },
 
3901
                    ],
 
3902
                },
 
3903
                "metadata": {
 
3904
                    "Open": "Stack",
 
3905
                    "Number": "1",
 
3906
                },
 
3907
                'links': [
 
3908
                    {
 
3909
                        'href': self.SERVER_HREF,
 
3910
                        'rel': 'self',
 
3911
                    },
 
3912
                    {
 
3913
                        'href': self.SERVER_BOOKMARK,
 
3914
                        'rel': 'bookmark',
 
3915
                    },
 
3916
                ],
 
3917
                "fault": {
 
3918
                    "code": 500,
 
3919
                    "created": self.TIMESTAMP,
 
3920
                    "message": "Error Message",
 
3921
                    "details": "Fault details",
 
3922
                }
 
3923
            }
 
3924
        }
 
3925
 
 
3926
        output = serializer.serialize(fixture)
 
3927
        print output
 
3928
        root = etree.XML(output)
 
3929
        xmlutil.validate_schema(root, 'server')
 
3930
 
 
3931
        server_dict = fixture['server']
 
3932
 
 
3933
        for key in ['name', 'id', 'created', 'accessIPv4',
 
3934
                    'updated', 'progress', 'status', 'hostId',
 
3935
                    'accessIPv6']:
 
3936
            self.assertEqual(root.get(key), str(server_dict[key]))
 
3937
 
 
3938
        link_nodes = root.findall('{0}link'.format(ATOMNS))
 
3939
        self.assertEqual(len(link_nodes), 2)
 
3940
        for i, link in enumerate(server_dict['links']):
 
3941
            for key, value in link.items():
 
3942
                self.assertEqual(link_nodes[i].get(key), value)
 
3943
 
 
3944
        metadata_root = root.find('{0}metadata'.format(NS))
 
3945
        metadata_elems = metadata_root.findall('{0}meta'.format(NS))
 
3946
        self.assertEqual(len(metadata_elems), 2)
 
3947
        for i, metadata_elem in enumerate(metadata_elems):
 
3948
            (meta_key, meta_value) = server_dict['metadata'].items()[i]
 
3949
            self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
 
3950
            self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
 
3951
 
 
3952
        image_root = root.find('{0}image'.format(NS))
 
3953
        self.assertEqual(image_root.get('id'), server_dict['image']['id'])
 
3954
        link_nodes = image_root.findall('{0}link'.format(ATOMNS))
 
3955
        self.assertEqual(len(link_nodes), 1)
 
3956
        for i, link in enumerate(server_dict['image']['links']):
 
3957
            for key, value in link.items():
 
3958
                self.assertEqual(link_nodes[i].get(key), value)
 
3959
 
 
3960
        flavor_root = root.find('{0}flavor'.format(NS))
 
3961
        self.assertEqual(flavor_root.get('id'), server_dict['flavor']['id'])
 
3962
        link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
 
3963
        self.assertEqual(len(link_nodes), 1)
 
3964
        for i, link in enumerate(server_dict['flavor']['links']):
 
3965
            for key, value in link.items():
 
3966
                self.assertEqual(link_nodes[i].get(key), value)
 
3967
 
 
3968
        addresses_root = root.find('{0}addresses'.format(NS))
 
3969
        addresses_dict = server_dict['addresses']
 
3970
        network_elems = addresses_root.findall('{0}network'.format(NS))
 
3971
        self.assertEqual(len(network_elems), 2)
 
3972
        for i, network_elem in enumerate(network_elems):
 
3973
            network = addresses_dict.items()[i]
 
3974
            self.assertEqual(str(network_elem.get('id')), str(network[0]))
 
3975
            ip_elems = network_elem.findall('{0}ip'.format(NS))
 
3976
            for z, ip_elem in enumerate(ip_elems):
 
3977
                ip = network[1][z]
 
3978
                self.assertEqual(str(ip_elem.get('version')),
 
3979
                                 str(ip['version']))
 
3980
                self.assertEqual(str(ip_elem.get('addr')),
 
3981
                                 str(ip['addr']))
 
3982
 
 
3983
        fault_root = root.find('{0}fault'.format(NS))
 
3984
        fault_dict = server_dict['fault']
 
3985
        self.assertEqual(fault_root.get("code"), str(fault_dict["code"]))
 
3986
        self.assertEqual(fault_root.get("created"), fault_dict["created"])
 
3987
        msg_elem = fault_root.find('{0}message'.format(NS))
 
3988
        self.assertEqual(msg_elem.text, fault_dict["message"])
 
3989
        det_elem = fault_root.find('{0}details'.format(NS))
 
3990
        self.assertEqual(det_elem.text, fault_dict["details"])
 
3991
 
 
3992
    def test_action(self):
 
3993
        serializer = servers.FullServerTemplate()
 
3994
 
 
3995
        fixture = {
 
3996
            "server": {
 
3997
                "id": FAKE_UUID,
 
3998
                "user_id": "fake",
 
3999
                "tenant_id": "fake",
 
4000
                'created': self.TIMESTAMP,
 
4001
                'updated': self.TIMESTAMP,
 
4002
                "progress": 0,
 
4003
                "name": "test_server",
 
4004
                "status": "BUILD",
 
4005
                "accessIPv4": "1.2.3.4",
 
4006
                "accessIPv6": "fead::1234",
 
4007
                "hostId": "e4d909c290d0fb1ca068ffaddf22cbd0",
 
4008
                "adminPass": "test_password",
 
4009
                "image": {
 
4010
                    "id": "5",
 
4011
                    "links": [
 
4012
                        {
 
4013
                            "rel": "bookmark",
 
4014
                            "href": self.IMAGE_BOOKMARK,
 
4015
                        },
 
4016
                    ],
 
4017
                },
 
4018
                "flavor": {
 
4019
                    "id": "1",
 
4020
                    "links": [
 
4021
                        {
 
4022
                            "rel": "bookmark",
 
4023
                            "href": self.FLAVOR_BOOKMARK,
 
4024
                        },
 
4025
                    ],
 
4026
                },
 
4027
                "addresses": {
 
4028
                    "network_one": [
 
4029
                        {
 
4030
                            "version": 4,
 
4031
                            "addr": "67.23.10.138",
 
4032
                        },
 
4033
                        {
 
4034
                            "version": 6,
 
4035
                            "addr": "::babe:67.23.10.138",
 
4036
                        },
 
4037
                    ],
 
4038
                    "network_two": [
 
4039
                        {
 
4040
                            "version": 4,
 
4041
                            "addr": "67.23.10.139",
 
4042
                        },
 
4043
                        {
 
4044
                            "version": 6,
 
4045
                            "addr": "::babe:67.23.10.139",
 
4046
                        },
 
4047
                    ],
 
4048
                },
 
4049
                "metadata": {
 
4050
                    "Open": "Stack",
 
4051
                    "Number": "1",
 
4052
                },
 
4053
                'links': [
 
4054
                    {
 
4055
                        'href': self.SERVER_HREF,
 
4056
                        'rel': 'self',
 
4057
                    },
 
4058
                    {
 
4059
                        'href': self.SERVER_BOOKMARK,
 
4060
                        'rel': 'bookmark',
 
4061
                    },
 
4062
                ],
 
4063
            }
 
4064
        }
 
4065
 
 
4066
        output = serializer.serialize(fixture)
 
4067
        root = etree.XML(output)
 
4068
        xmlutil.validate_schema(root, 'server')
 
4069
 
 
4070
        server_dict = fixture['server']
 
4071
 
 
4072
        for key in ['name', 'id', 'created', 'accessIPv4',
 
4073
                    'updated', 'progress', 'status', 'hostId',
 
4074
                    'accessIPv6', 'adminPass']:
 
4075
            self.assertEqual(root.get(key), str(server_dict[key]))
 
4076
 
 
4077
        link_nodes = root.findall('{0}link'.format(ATOMNS))
 
4078
        self.assertEqual(len(link_nodes), 2)
 
4079
        for i, link in enumerate(server_dict['links']):
 
4080
            for key, value in link.items():
 
4081
                self.assertEqual(link_nodes[i].get(key), value)
 
4082
 
 
4083
        metadata_root = root.find('{0}metadata'.format(NS))
 
4084
        metadata_elems = metadata_root.findall('{0}meta'.format(NS))
 
4085
        self.assertEqual(len(metadata_elems), 2)
 
4086
        for i, metadata_elem in enumerate(metadata_elems):
 
4087
            (meta_key, meta_value) = server_dict['metadata'].items()[i]
 
4088
            self.assertEqual(str(metadata_elem.get('key')), str(meta_key))
 
4089
            self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
 
4090
 
 
4091
        image_root = root.find('{0}image'.format(NS))
 
4092
        self.assertEqual(image_root.get('id'), server_dict['image']['id'])
 
4093
        link_nodes = image_root.findall('{0}link'.format(ATOMNS))
 
4094
        self.assertEqual(len(link_nodes), 1)
 
4095
        for i, link in enumerate(server_dict['image']['links']):
 
4096
            for key, value in link.items():
 
4097
                self.assertEqual(link_nodes[i].get(key), value)
 
4098
 
 
4099
        flavor_root = root.find('{0}flavor'.format(NS))
 
4100
        self.assertEqual(flavor_root.get('id'), server_dict['flavor']['id'])
 
4101
        link_nodes = flavor_root.findall('{0}link'.format(ATOMNS))
 
4102
        self.assertEqual(len(link_nodes), 1)
 
4103
        for i, link in enumerate(server_dict['flavor']['links']):
 
4104
            for key, value in link.items():
 
4105
                self.assertEqual(link_nodes[i].get(key), value)
 
4106
 
 
4107
        addresses_root = root.find('{0}addresses'.format(NS))
 
4108
        addresses_dict = server_dict['addresses']
 
4109
        network_elems = addresses_root.findall('{0}network'.format(NS))
 
4110
        self.assertEqual(len(network_elems), 2)
 
4111
        for i, network_elem in enumerate(network_elems):
 
4112
            network = addresses_dict.items()[i]
 
4113
            self.assertEqual(str(network_elem.get('id')), str(network[0]))
 
4114
            ip_elems = network_elem.findall('{0}ip'.format(NS))
 
4115
            for z, ip_elem in enumerate(ip_elems):
 
4116
                ip = network[1][z]
 
4117
                self.assertEqual(str(ip_elem.get('version')),
 
4118
                                 str(ip['version']))
 
4119
                self.assertEqual(str(ip_elem.get('addr')),
 
4120
                                 str(ip['addr']))