Merge lp:~rackspace-titan/nova/servers-response-formatting into lp:~hudson-openstack/nova/trunk

Proposed by Alex Meade
Status: Merged
Approved by: Brian Waldon
Approved revision: 1297
Merged at revision: 1323
Proposed branch: lp:~rackspace-titan/nova/servers-response-formatting
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 918 lines (+658/-63)
2 files modified
nova/api/openstack/views/servers.py (+38/-7)
nova/tests/api/openstack/test_servers.py (+620/-56)
To merge this branch: bzr merge lp:~rackspace-titan/nova/servers-response-formatting
Reviewer Review Type Date Requested Status
Brian Waldon (community) Approve
Vish Ishaya (community) Approve
Review via email: mp+68119@code.launchpad.net

Description of the change

Updates /servers requests to follow the v1.1 spec. Except for implementation of uuids replacing ids and access ips both of which are not yet implemented. Also, does not include serialized xml responses.

To post a comment you must log in.
Revision history for this message
Brian Waldon (bcwaldon) wrote :

Looks good, guys. I love the view builder tests. Looking forward to the xml serialization in the next branch.

review: Approve
Revision history for this message
Vish Ishaya (vishvananda) wrote :

Nice work,

Really appreciate all of the tests going in with these branches.

review: Approve
Revision history for this message
OpenStack Infra (hudson-openstack) wrote :
Download full text (186.1 KiB)

The attempt to merge lp:~rackspace-titan/nova/servers-response-formatting into lp:nova failed. Below is the output from the failed tests.

FloatingIpTest
    test_floating_ip_allocate OK 0.31
    test_floating_ip_associate OK 0.11
    test_floating_ip_disassociate OK 0.11
    test_floating_ip_release OK 0.11
    test_floating_ip_show OK 0.13
    test_floating_ips_list OK 0.10
    test_translate_floating_ip_view OK 0.05
FixedIpTest
    test_add_fixed_ip OK 0.08
    test_add_fixed_ip_no_network OK 0.09
    test_remove_fixed_ip OK 0.29
    test_remove_fixed_ip_no_address OK 0.07
FlavorsExtraSpecsTest
    test_create OK 0.05
    test_create_empty_body OK 0.05
    test_delete OK 0.05
    test_index OK 0.05
    test_index_no_data OK 0.05
    test_show OK 0.05
    test_show_spec_not_found OK 0.05
    test_update_item OK 0.05
    test_update_item_body_uri_mismatch OK 0.05
    test_update_item_empty_body OK 0.05
    test_update_item_too_many_keys OK 0.05
AccountsTest
    test_account_create OK 0.41
    test_account_delete OK 0.18
    test_account_update OK 0.18
    test_get_account OK 0.18
AdminAPITest
    test_admin_disabled OK 0.13
    test_admin_enabled OK 0.43
APITest
    test_exceptions_are_converted_to_faults OK 0.01
    test_malformed_json OK 0.06
    test_malformed_xml OK 0.06
Test
    test_authorize_project OK 0.10
    test_authorize_token OK 0.11
    test_authorize_user OK 0.06
    test_bad_project OK 0.36
    test_bad_token OK 0.07
    test_bad_user_bad_key OK 0.06
    test_bad_user_good_key OK 0.06
    test_no_user OK 0.06
    test_not_existing_project OK 0.10
    test_token_expiry ...

Revision history for this message
Brian Waldon (bcwaldon) wrote :

Trying again.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'nova/api/openstack/views/servers.py'
--- nova/api/openstack/views/servers.py 2011-07-21 18:21:27 +0000
+++ nova/api/openstack/views/servers.py 2011-07-26 13:49:41 +0000
@@ -50,7 +50,7 @@
50 else:50 else:
51 server = self._build_simple(inst)51 server = self._build_simple(inst)
5252
53 self._build_extra(server, inst)53 self._build_extra(server['server'], inst)
5454
55 return server55 return server
5656
@@ -99,7 +99,6 @@
99 self._build_flavor(inst_dict, inst)99 self._build_flavor(inst_dict, inst)
100 self._build_addresses(inst_dict, inst)100 self._build_addresses(inst_dict, inst)
101101
102 inst_dict['uuid'] = inst['uuid']
103 return dict(server=inst_dict)102 return dict(server=inst_dict)
104103
105 def _build_addresses(self, response, inst):104 def _build_addresses(self, response, inst):
@@ -121,6 +120,9 @@
121class ViewBuilderV10(ViewBuilder):120class ViewBuilderV10(ViewBuilder):
122 """Model an Openstack API V1.0 server response."""121 """Model an Openstack API V1.0 server response."""
123122
123 def _build_extra(self, response, inst):
124 response['uuid'] = inst['uuid']
125
124 def _build_image(self, response, inst):126 def _build_image(self, response, inst):
125 if 'image_ref' in dict(inst):127 if 'image_ref' in dict(inst):
126 image_ref = inst['image_ref']128 image_ref = inst['image_ref']
@@ -145,18 +147,46 @@
145 self.image_builder = image_builder147 self.image_builder = image_builder
146 self.base_url = base_url148 self.base_url = base_url
147149
150 def _build_detail(self, inst):
151 response = super(ViewBuilderV11, self)._build_detail(inst)
152 response['server']['created'] = inst['created_at']
153 response['server']['updated'] = inst['updated_at']
154 if 'status' in response['server']:
155 if response['server']['status'] == "ACTIVE":
156 response['server']['progress'] = 100
157 elif response['server']['status'] == "BUILD":
158 response['server']['progress'] = 0
159 return response
160
148 def _build_image(self, response, inst):161 def _build_image(self, response, inst):
149 if 'image_ref' in dict(inst):162 if 'image_ref' in dict(inst):
150 image_href = inst['image_ref']163 image_href = inst['image_ref']
151 if str(image_href).isdigit():164 image_id = str(common.get_id_from_href(image_href))
152 image_href = int(image_href)165 _bookmark = self.image_builder.generate_bookmark(image_id)
153 response['imageRef'] = image_href166 response['image'] = {
167 "id": image_id,
168 "links": [
169 {
170 "rel": "bookmark",
171 "href": _bookmark,
172 },
173 ]
174 }
154175
155 def _build_flavor(self, response, inst):176 def _build_flavor(self, response, inst):
156 if "instance_type" in dict(inst):177 if "instance_type" in dict(inst):
157 flavor_id = inst["instance_type"]['flavorid']178 flavor_id = inst["instance_type"]['flavorid']
158 flavor_ref = self.flavor_builder.generate_href(flavor_id)179 flavor_ref = self.flavor_builder.generate_href(flavor_id)
159 response["flavorRef"] = flavor_ref180 flavor_bookmark = self.flavor_builder.generate_bookmark(flavor_id)
181 response["flavor"] = {
182 "id": str(common.get_id_from_href(flavor_ref)),
183 "links": [
184 {
185 "rel": "bookmark",
186 "href": flavor_bookmark,
187 },
188 ]
189 }
160190
161 def _build_addresses(self, response, inst):191 def _build_addresses(self, response, inst):
162 interfaces = inst.get('virtual_interfaces', [])192 interfaces = inst.get('virtual_interfaces', [])
@@ -164,6 +194,7 @@
164194
165 def _build_extra(self, response, inst):195 def _build_extra(self, response, inst):
166 self._build_links(response, inst)196 self._build_links(response, inst)
197 response['uuid'] = inst['uuid']
167198
168 def _build_links(self, response, inst):199 def _build_links(self, response, inst):
169 href = self.generate_href(inst["id"])200 href = self.generate_href(inst["id"])
@@ -180,7 +211,7 @@
180 },211 },
181 ]212 ]
182213
183 response["server"]["links"] = links214 response["links"] = links
184215
185 def generate_href(self, server_id):216 def generate_href(self, server_id):
186 """Create an url that refers to a specific server id."""217 """Create an url that refers to a specific server id."""
187218
=== modified file 'nova/tests/api/openstack/test_servers.py'
--- nova/tests/api/openstack/test_servers.py 2011-07-25 23:38:07 +0000
+++ nova/tests/api/openstack/test_servers.py 2011-07-26 13:49:41 +0000
@@ -78,6 +78,12 @@
78 return _return_virtual_interface_by_instance78 return _return_virtual_interface_by_instance
7979
8080
81def return_server_with_attributes(**kwargs):
82 def _return_server(context, id):
83 return stub_instance(id, **kwargs)
84 return _return_server
85
86
81def return_server_with_addresses(private, public):87def return_server_with_addresses(private, public):
82 def _return_server(context, id):88 def _return_server(context, id):
83 return stub_instance(id, private_address=private,89 return stub_instance(id, private_address=private,
@@ -85,12 +91,6 @@
85 return _return_server91 return _return_server
8692
8793
88def return_server_with_interfaces(interfaces):
89 def _return_server(context, id):
90 return stub_instance(id, interfaces=interfaces)
91 return _return_server
92
93
94def return_server_with_power_state(power_state):94def return_server_with_power_state(power_state):
95 def _return_server(context, id):95 def _return_server(context, id):
96 return stub_instance(id, power_state=power_state)96 return stub_instance(id, power_state=power_state)
@@ -143,14 +143,15 @@
143143
144def stub_instance(id, user_id=1, private_address=None, public_addresses=None,144def stub_instance(id, user_id=1, private_address=None, public_addresses=None,
145 host=None, power_state=0, reservation_id="",145 host=None, power_state=0, reservation_id="",
146 uuid=FAKE_UUID, interfaces=None):146 uuid=FAKE_UUID, image_ref="10", flavor_id="1",
147 interfaces=None):
147 metadata = []148 metadata = []
148 metadata.append(InstanceMetadata(key='seq', value=id))149 metadata.append(InstanceMetadata(key='seq', value=id))
149150
150 if interfaces is None:151 if interfaces is None:
151 interfaces = []152 interfaces = []
152153
153 inst_type = instance_types.get_instance_type_by_flavor_id(1)154 inst_type = instance_types.get_instance_type_by_flavor_id(int(flavor_id))
154155
155 if public_addresses is None:156 if public_addresses is None:
156 public_addresses = list()157 public_addresses = list()
@@ -165,10 +166,12 @@
165166
166 instance = {167 instance = {
167 "id": int(id),168 "id": int(id),
169 "created_at": "2010-10-10T12:00:00Z",
170 "updated_at": "2010-11-11T11:00:00Z",
168 "admin_pass": "",171 "admin_pass": "",
169 "user_id": user_id,172 "user_id": user_id,
170 "project_id": "",173 "project_id": "",
171 "image_ref": "10",174 "image_ref": image_ref,
172 "kernel_id": "",175 "kernel_id": "",
173 "ramdisk_id": "",176 "ramdisk_id": "",
174 "launch_index": 0,177 "launch_index": 0,
@@ -224,6 +227,7 @@
224class ServersTest(test.TestCase):227class ServersTest(test.TestCase):
225228
226 def setUp(self):229 def setUp(self):
230 self.maxDiff = None
227 super(ServersTest, self).setUp()231 super(ServersTest, self).setUp()
228 self.stubs = stubout.StubOutForTesting()232 self.stubs = stubout.StubOutForTesting()
229 fakes.FakeAuthManager.reset_fake_data()233 fakes.FakeAuthManager.reset_fake_data()
@@ -300,24 +304,274 @@
300 self.assertEqual(res_dict['server']['name'], 'server1')304 self.assertEqual(res_dict['server']['name'], 'server1')
301305
302 def test_get_server_by_id_v1_1(self):306 def test_get_server_by_id_v1_1(self):
303 req = webob.Request.blank('/v1.1/servers/1')307 image_bookmark = "http://localhost/images/10"
304 res = req.get_response(fakes.wsgi_app())308 flavor_ref = "http://localhost/v1.1/flavors/1"
305 res_dict = json.loads(res.body)309 flavor_id = "1"
306 self.assertEqual(res_dict['server']['id'], 1)310 flavor_bookmark = "http://localhost/flavors/1"
307 self.assertEqual(res_dict['server']['name'], 'server1')311
308312 public_ip = '192.168.0.3'
309 expected_links = [313 private_ip = '172.19.0.1'
310 {314 interfaces = [
311 "rel": "self",315 {
312 "href": "http://localhost/v1.1/servers/1",316 'network': {'label': 'public'},
313 },317 'fixed_ips': [
314 {318 {'address': public_ip},
315 "rel": "bookmark",319 ],
316 "href": "http://localhost/servers/1",320 },
317 },321 {
318 ]322 'network': {'label': 'private'},
319323 'fixed_ips': [
320 self.assertEqual(res_dict['server']['links'], expected_links)324 {'address': private_ip},
325 ],
326 },
327 ]
328 new_return_server = return_server_with_attributes(
329 interfaces=interfaces)
330 self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
331
332 req = webob.Request.blank('/v1.1/servers/1')
333 res = req.get_response(fakes.wsgi_app())
334 res_dict = json.loads(res.body)
335 expected_server = {
336 "server": {
337 "id": 1,
338 "uuid": FAKE_UUID,
339 "updated": "2010-11-11T11:00:00Z",
340 "created": "2010-10-10T12:00:00Z",
341 "progress": 0,
342 "name": "server1",
343 "status": "BUILD",
344 "hostId": '',
345 "image": {
346 "id": "10",
347 "links": [
348 {
349 "rel": "bookmark",
350 "href": image_bookmark,
351 },
352 ],
353 },
354 "flavor": {
355 "id": "1",
356 "links": [
357 {
358 "rel": "bookmark",
359 "href": flavor_bookmark,
360 },
361 ],
362 },
363 "addresses": {
364 "public": [
365 {
366 "version": 4,
367 "addr": public_ip,
368 },
369 ],
370 "private": [
371 {
372 "version": 4,
373 "addr": private_ip,
374 },
375 ],
376 },
377 "metadata": {
378 "seq": "1",
379 },
380 "links": [
381 {
382 "rel": "self",
383 #FIXME(wwolf) Do we want the links to be id or uuid?
384 "href": "http://localhost/v1.1/servers/1",
385 },
386 {
387 "rel": "bookmark",
388 "href": "http://localhost/servers/1",
389 },
390 ],
391 }
392 }
393
394 self.assertDictMatch(res_dict, expected_server)
395
396 def test_get_server_with_active_status_by_id_v1_1(self):
397 image_bookmark = "http://localhost/images/10"
398 flavor_ref = "http://localhost/v1.1/flavors/1"
399 flavor_id = "1"
400 flavor_bookmark = "http://localhost/flavors/1"
401 private_ip = "192.168.0.3"
402 public_ip = "1.2.3.4"
403
404 interfaces = [
405 {
406 'network': {'label': 'public'},
407 'fixed_ips': [
408 {'address': public_ip},
409 ],
410 },
411 {
412 'network': {'label': 'private'},
413 'fixed_ips': [
414 {'address': private_ip},
415 ],
416 },
417 ]
418 new_return_server = return_server_with_attributes(
419 interfaces=interfaces, power_state=1)
420 self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
421
422 req = webob.Request.blank('/v1.1/servers/1')
423 res = req.get_response(fakes.wsgi_app())
424 res_dict = json.loads(res.body)
425 expected_server = {
426 "server": {
427 "id": 1,
428 "uuid": FAKE_UUID,
429 "updated": "2010-11-11T11:00:00Z",
430 "created": "2010-10-10T12:00:00Z",
431 "progress": 100,
432 "name": "server1",
433 "status": "ACTIVE",
434 "hostId": '',
435 "image": {
436 "id": "10",
437 "links": [
438 {
439 "rel": "bookmark",
440 "href": image_bookmark,
441 },
442 ],
443 },
444 "flavor": {
445 "id": "1",
446 "links": [
447 {
448 "rel": "bookmark",
449 "href": flavor_bookmark,
450 },
451 ],
452 },
453 "addresses": {
454 "public": [
455 {
456 "version": 4,
457 "addr": public_ip,
458 },
459 ],
460 "private": [
461 {
462 "version": 4,
463 "addr": private_ip,
464 },
465 ],
466 },
467 "metadata": {
468 "seq": "1",
469 },
470 "links": [
471 {
472 "rel": "self",
473 "href": "http://localhost/v1.1/servers/1",
474 },
475 {
476 "rel": "bookmark",
477 "href": "http://localhost/servers/1",
478 },
479 ],
480 }
481 }
482
483 self.assertDictMatch(res_dict, expected_server)
484
485 def test_get_server_with_id_image_ref_by_id_v1_1(self):
486 image_ref = "10"
487 image_bookmark = "http://localhost/images/10"
488 flavor_ref = "http://localhost/v1.1/flavors/1"
489 flavor_id = "1"
490 flavor_bookmark = "http://localhost/flavors/1"
491 private_ip = "192.168.0.3"
492 public_ip = "1.2.3.4"
493
494 interfaces = [
495 {
496 'network': {'label': 'public'},
497 'fixed_ips': [
498 {'address': public_ip},
499 ],
500 },
501 {
502 'network': {'label': 'private'},
503 'fixed_ips': [
504 {'address': private_ip},
505 ],
506 },
507 ]
508 new_return_server = return_server_with_attributes(
509 interfaces=interfaces, power_state=1, image_ref=image_ref,
510 flavor_id=flavor_id)
511 self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
512
513 req = webob.Request.blank('/v1.1/servers/1')
514 res = req.get_response(fakes.wsgi_app())
515 res_dict = json.loads(res.body)
516 expected_server = {
517 "server": {
518 "id": 1,
519 "uuid": FAKE_UUID,
520 "updated": "2010-11-11T11:00:00Z",
521 "created": "2010-10-10T12:00:00Z",
522 "progress": 100,
523 "name": "server1",
524 "status": "ACTIVE",
525 "hostId": '',
526 "image": {
527 "id": "10",
528 "links": [
529 {
530 "rel": "bookmark",
531 "href": image_bookmark,
532 },
533 ],
534 },
535 "flavor": {
536 "id": "1",
537 "links": [
538 {
539 "rel": "bookmark",
540 "href": flavor_bookmark,
541 },
542 ],
543 },
544 "addresses": {
545 "public": [
546 {
547 "version": 4,
548 "addr": public_ip,
549 },
550 ],
551 "private": [
552 {
553 "version": 4,
554 "addr": private_ip,
555 },
556 ],
557 },
558 "metadata": {
559 "seq": "1",
560 },
561 "links": [
562 {
563 "rel": "self",
564 "href": "http://localhost/v1.1/servers/1",
565 },
566 {
567 "rel": "bookmark",
568 "href": "http://localhost/servers/1",
569 },
570 ],
571 }
572 }
573
574 self.assertDictMatch(res_dict, expected_server)
321575
322 def test_get_server_by_id_with_addresses_xml(self):576 def test_get_server_by_id_with_addresses_xml(self):
323 private = "192.168.0.3"577 private = "192.168.0.3"
@@ -452,7 +706,8 @@
452 'fixed_ipv6': '2001:4860::12',706 'fixed_ipv6': '2001:4860::12',
453 },707 },
454 ]708 ]
455 new_return_server = return_server_with_interfaces(interfaces)709 new_return_server = return_server_with_attributes(
710 interfaces=interfaces)
456 self.stubs.Set(nova.db.api, 'instance_get', new_return_server)711 self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
457712
458 req = webob.Request.blank('/v1.1/servers/1')713 req = webob.Request.blank('/v1.1/servers/1')
@@ -495,7 +750,8 @@
495 'fixed_ipv6': '2001:4860::12',750 'fixed_ipv6': '2001:4860::12',
496 },751 },
497 ]752 ]
498 new_return_server = return_server_with_interfaces(interfaces)753 new_return_server = return_server_with_attributes(
754 interfaces=interfaces)
499 self.stubs.Set(nova.db.api, 'instance_get', new_return_server)755 self.stubs.Set(nova.db.api, 'instance_get', new_return_server)
500756
501 req = webob.Request.blank('/v1.1/servers/1')757 req = webob.Request.blank('/v1.1/servers/1')
@@ -703,20 +959,20 @@
703 for i, s in enumerate(res_dict['servers']):959 for i, s in enumerate(res_dict['servers']):
704 self.assertEqual(s['id'], i)960 self.assertEqual(s['id'], i)
705 self.assertEqual(s['name'], 'server%d' % i)961 self.assertEqual(s['name'], 'server%d' % i)
706 self.assertEqual(s.get('imageId', None), None)962 self.assertEqual(s.get('image', None), None)
707963
708 expected_links = [964 expected_links = [
709 {965 {
710 "rel": "self",966 "rel": "self",
711 "href": "http://localhost/v1.1/servers/%d" % (i,),967 "href": "http://localhost/v1.1/servers/%s" % s['id'],
712 },968 },
713 {969 {
714 "rel": "bookmark",970 "rel": "bookmark",
715 "href": "http://localhost/servers/%d" % (i,),971 "href": "http://localhost/servers/%s" % s['id'],
716 },972 },
717 ]973 ]
718974
719 self.assertEqual(s['links'], expected_links)975 self.assertEqual(s['links'], expected_links)
720976
721 def test_get_servers_with_limit(self):977 def test_get_servers_with_limit(self):
722 req = webob.Request.blank('/v1.0/servers?limit=3')978 req = webob.Request.blank('/v1.0/servers?limit=3')
@@ -762,13 +1018,13 @@
762 req = webob.Request.blank('/v1.1/servers?marker=2')1018 req = webob.Request.blank('/v1.1/servers?marker=2')
763 res = req.get_response(fakes.wsgi_app())1019 res = req.get_response(fakes.wsgi_app())
764 servers = json.loads(res.body)['servers']1020 servers = json.loads(res.body)['servers']
765 self.assertEqual([s['id'] for s in servers], [3, 4])1021 self.assertEqual([s['name'] for s in servers], ["server3", "server4"])
7661022
767 def test_get_servers_with_limit_and_marker(self):1023 def test_get_servers_with_limit_and_marker(self):
768 req = webob.Request.blank('/v1.1/servers?limit=2&marker=1')1024 req = webob.Request.blank('/v1.1/servers?limit=2&marker=1')
769 res = req.get_response(fakes.wsgi_app())1025 res = req.get_response(fakes.wsgi_app())
770 servers = json.loads(res.body)['servers']1026 servers = json.loads(res.body)['servers']
771 self.assertEqual([s['id'] for s in servers], [2, 3])1027 self.assertEqual([s['name'] for s in servers], ['server2', 'server3'])
7721028
773 def test_get_servers_with_bad_marker(self):1029 def test_get_servers_with_bad_marker(self):
774 req = webob.Request.blank('/v1.1/servers?limit=2&marker=asdf')1030 req = webob.Request.blank('/v1.1/servers?limit=2&marker=asdf')
@@ -779,8 +1035,16 @@
779 def _setup_for_create_instance(self):1035 def _setup_for_create_instance(self):
780 """Shared implementation for tests below that create instance"""1036 """Shared implementation for tests below that create instance"""
781 def instance_create(context, inst):1037 def instance_create(context, inst):
782 return {'id': 1, 'display_name': 'server_test',1038 inst_type = instance_types.get_instance_type_by_flavor_id(3)
783 'uuid': FAKE_UUID}1039 image_ref = 'http://localhost/images/2'
1040 return {'id': 1,
1041 'display_name': 'server_test',
1042 'uuid': FAKE_UUID,
1043 'instance_type': dict(inst_type),
1044 'image_ref': image_ref,
1045 'created_at': '2010-10-10T12:00:00Z',
1046 'updated_at': '2010-11-11T11:00:00Z',
1047 }
7841048
785 def server_update(context, id, params):1049 def server_update(context, id, params):
786 return instance_create(context, id)1050 return instance_create(context, id)
@@ -980,8 +1244,26 @@
980 def test_create_instance_v1_1(self):1244 def test_create_instance_v1_1(self):
981 self._setup_for_create_instance()1245 self._setup_for_create_instance()
9821246
983 image_href = 'http://localhost/v1.1/images/2'1247 image_href = 'http://localhost/images/2'
984 flavor_ref = 'http://localhost/v1.1/flavors/3'1248 flavor_ref = 'http://localhost/flavors/3'
1249 expected_flavor = {
1250 "id": "3",
1251 "links": [
1252 {
1253 "rel": "bookmark",
1254 "href": 'http://localhost/flavors/3',
1255 },
1256 ],
1257 }
1258 expected_image = {
1259 "id": "2",
1260 "links": [
1261 {
1262 "rel": "bookmark",
1263 "href": 'http://localhost/images/2',
1264 },
1265 ],
1266 }
985 body = {1267 body = {
986 'server': {1268 'server': {
987 'name': 'server_test',1269 'name': 'server_test',
@@ -1006,9 +1288,10 @@
1006 server = json.loads(res.body)['server']1288 server = json.loads(res.body)['server']
1007 self.assertEqual(16, len(server['adminPass']))1289 self.assertEqual(16, len(server['adminPass']))
1008 self.assertEqual('server_test', server['name'])1290 self.assertEqual('server_test', server['name'])
1009 self.assertEqual(1, server['id'])1291 self.assertEqual(expected_flavor, server['flavor'])
1010 self.assertEqual(flavor_ref, server['flavorRef'])1292 self.assertEqual(expected_image, server['image'])
1011 self.assertEqual(image_href, server['imageRef'])1293 self.assertEqual(res.status_int, 200)
1294 #self.assertEqual(1, server['id'])
10121295
1013 def test_create_instance_v1_1_invalid_flavor_href(self):1296 def test_create_instance_v1_1_invalid_flavor_href(self):
1014 self._setup_for_create_instance()1297 self._setup_for_create_instance()
@@ -1061,8 +1344,26 @@
1061 def test_create_instance_v1_1_local_href(self):1344 def test_create_instance_v1_1_local_href(self):
1062 self._setup_for_create_instance()1345 self._setup_for_create_instance()
10631346
1064 image_id = 21347 image_id = "2"
1065 flavor_ref = 'http://localhost/v1.1/flavors/3'1348 flavor_ref = 'http://localhost/flavors/3'
1349 expected_flavor = {
1350 "id": "3",
1351 "links": [
1352 {
1353 "rel": "bookmark",
1354 "href": 'http://localhost/flavors/3',
1355 },
1356 ],
1357 }
1358 expected_image = {
1359 "id": "2",
1360 "links": [
1361 {
1362 "rel": "bookmark",
1363 "href": 'http://localhost/images/2',
1364 },
1365 ],
1366 }
1066 body = {1367 body = {
1067 'server': {1368 'server': {
1068 'name': 'server_test',1369 'name': 'server_test',
@@ -1079,9 +1380,8 @@
1079 res = req.get_response(fakes.wsgi_app())1380 res = req.get_response(fakes.wsgi_app())
10801381
1081 server = json.loads(res.body)['server']1382 server = json.loads(res.body)['server']
1082 self.assertEqual(1, server['id'])1383 self.assertEqual(expected_flavor, server['flavor'])
1083 self.assertEqual(flavor_ref, server['flavorRef'])1384 self.assertEqual(expected_image, server['image'])
1084 self.assertEqual(image_id, server['imageRef'])
1085 self.assertEqual(res.status_int, 200)1385 self.assertEqual(res.status_int, 200)
10861386
1087 def test_create_instance_with_admin_pass_v1_0(self):1387 def test_create_instance_with_admin_pass_v1_0(self):
@@ -1306,6 +1606,24 @@
1306 self.assertEqual(s['metadata']['seq'], str(i))1606 self.assertEqual(s['metadata']['seq'], str(i))
13071607
1308 def test_get_all_server_details_v1_1(self):1608 def test_get_all_server_details_v1_1(self):
1609 expected_flavor = {
1610 "id": "1",
1611 "links": [
1612 {
1613 "rel": "bookmark",
1614 "href": 'http://localhost/flavors/1',
1615 },
1616 ],
1617 }
1618 expected_image = {
1619 "id": "10",
1620 "links": [
1621 {
1622 "rel": "bookmark",
1623 "href": 'http://localhost/images/10',
1624 },
1625 ],
1626 }
1309 req = webob.Request.blank('/v1.1/servers/detail')1627 req = webob.Request.blank('/v1.1/servers/detail')
1310 res = req.get_response(fakes.wsgi_app())1628 res = req.get_response(fakes.wsgi_app())
1311 res_dict = json.loads(res.body)1629 res_dict = json.loads(res.body)
@@ -1314,8 +1632,8 @@
1314 self.assertEqual(s['id'], i)1632 self.assertEqual(s['id'], i)
1315 self.assertEqual(s['hostId'], '')1633 self.assertEqual(s['hostId'], '')
1316 self.assertEqual(s['name'], 'server%d' % i)1634 self.assertEqual(s['name'], 'server%d' % i)
1317 self.assertEqual(s['imageRef'], 10)1635 self.assertEqual(s['image'], expected_image)
1318 self.assertEqual(s['flavorRef'], 'http://localhost/v1.1/flavors/1')1636 self.assertEqual(s['flavor'], expected_flavor)
1319 self.assertEqual(s['status'], 'BUILD')1637 self.assertEqual(s['status'], 'BUILD')
1320 self.assertEqual(s['metadata']['seq'], str(i))1638 self.assertEqual(s['metadata']['seq'], str(i))
13211639
@@ -2559,3 +2877,249 @@
2559 kernel_id, ramdisk_id = create_instance_helper.CreateInstanceHelper. \2877 kernel_id, ramdisk_id = create_instance_helper.CreateInstanceHelper. \
2560 _do_get_kernel_ramdisk_from_image(image_meta)2878 _do_get_kernel_ramdisk_from_image(image_meta)
2561 return kernel_id, ramdisk_id2879 return kernel_id, ramdisk_id
2880
2881
2882class ServersViewBuilderV11Test(test.TestCase):
2883
2884 def setUp(self):
2885 self.instance = self._get_instance()
2886 self.view_builder = self._get_view_builder()
2887
2888 def tearDown(self):
2889 pass
2890
2891 def _get_instance(self):
2892 instance = {
2893 "id": 1,
2894 "created_at": "2010-10-10T12:00:00Z",
2895 "updated_at": "2010-11-11T11:00:00Z",
2896 "admin_pass": "",
2897 "user_id": "",
2898 "project_id": "",
2899 "image_ref": "5",
2900 "kernel_id": "",
2901 "ramdisk_id": "",
2902 "launch_index": 0,
2903 "key_name": "",
2904 "key_data": "",
2905 "state": 0,
2906 "state_description": "",
2907 "memory_mb": 0,
2908 "vcpus": 0,
2909 "local_gb": 0,
2910 "hostname": "",
2911 "host": "",
2912 "instance_type": {
2913 "flavorid": 1,
2914 },
2915 "user_data": "",
2916 "reservation_id": "",
2917 "mac_address": "",
2918 "scheduled_at": utils.utcnow(),
2919 "launched_at": utils.utcnow(),
2920 "terminated_at": utils.utcnow(),
2921 "availability_zone": "",
2922 "display_name": "test_server",
2923 "display_description": "",
2924 "locked": False,
2925 "metadata": [],
2926 #"address": ,
2927 #"floating_ips": [{"address":ip} for ip in public_addresses]}
2928 "uuid": "deadbeef-feed-edee-beef-d0ea7beefedd"}
2929
2930 return instance
2931
2932 def _get_view_builder(self):
2933 base_url = "http://localhost/v1.1"
2934 views = nova.api.openstack.views
2935 address_builder = views.addresses.ViewBuilderV11()
2936 flavor_builder = views.flavors.ViewBuilderV11(base_url)
2937 image_builder = views.images.ViewBuilderV11(base_url)
2938
2939 view_builder = nova.api.openstack.views.servers.ViewBuilderV11(
2940 address_builder,
2941 flavor_builder,
2942 image_builder,
2943 base_url
2944 )
2945 return view_builder
2946
2947 def test_build_server(self):
2948 expected_server = {
2949 "server": {
2950 "id": 1,
2951 "uuid": self.instance['uuid'],
2952 "name": "test_server",
2953 "links": [
2954 {
2955 "rel": "self",
2956 "href": "http://localhost/v1.1/servers/1",
2957 },
2958 {
2959 "rel": "bookmark",
2960 "href": "http://localhost/servers/1",
2961 },
2962 ],
2963 }
2964 }
2965
2966 output = self.view_builder.build(self.instance, False)
2967 self.assertDictMatch(output, expected_server)
2968
2969 def test_build_server_detail(self):
2970 image_bookmark = "http://localhost/images/5"
2971 flavor_bookmark = "http://localhost/flavors/1"
2972 expected_server = {
2973 "server": {
2974 "id": 1,
2975 "uuid": self.instance['uuid'],
2976 "updated": "2010-11-11T11:00:00Z",
2977 "created": "2010-10-10T12:00:00Z",
2978 "progress": 0,
2979 "name": "test_server",
2980 "status": "BUILD",
2981 "hostId": '',
2982 "image": {
2983 "id": "5",
2984 "links": [
2985 {
2986 "rel": "bookmark",
2987 "href": image_bookmark,
2988 },
2989 ],
2990 },
2991 "flavor": {
2992 "id": "1",
2993 "links": [
2994 {
2995 "rel": "bookmark",
2996 "href": flavor_bookmark,
2997 },
2998 ],
2999 },
3000 "addresses": {},
3001 "metadata": {},
3002 "links": [
3003 {
3004 "rel": "self",
3005 "href": "http://localhost/v1.1/servers/1",
3006 },
3007 {
3008 "rel": "bookmark",
3009 "href": "http://localhost/servers/1",
3010 },
3011 ],
3012 }
3013 }
3014
3015 output = self.view_builder.build(self.instance, True)
3016 self.assertDictMatch(output, expected_server)
3017
3018 def test_build_server_detail_active_status(self):
3019 #set the power state of the instance to running
3020 self.instance['state'] = 1
3021 image_bookmark = "http://localhost/images/5"
3022 flavor_bookmark = "http://localhost/flavors/1"
3023 expected_server = {
3024 "server": {
3025 "id": 1,
3026 "uuid": self.instance['uuid'],
3027 "updated": "2010-11-11T11:00:00Z",
3028 "created": "2010-10-10T12:00:00Z",
3029 "progress": 100,
3030 "name": "test_server",
3031 "status": "ACTIVE",
3032 "hostId": '',
3033 "image": {
3034 "id": "5",
3035 "links": [
3036 {
3037 "rel": "bookmark",
3038 "href": image_bookmark,
3039 },
3040 ],
3041 },
3042 "flavor": {
3043 "id": "1",
3044 "links": [
3045 {
3046 "rel": "bookmark",
3047 "href": flavor_bookmark,
3048 },
3049 ],
3050 },
3051 "addresses": {},
3052 "metadata": {},
3053 "links": [
3054 {
3055 "rel": "self",
3056 "href": "http://localhost/v1.1/servers/1",
3057 },
3058 {
3059 "rel": "bookmark",
3060 "href": "http://localhost/servers/1",
3061 },
3062 ],
3063 }
3064 }
3065
3066 output = self.view_builder.build(self.instance, True)
3067 self.assertDictMatch(output, expected_server)
3068
3069 def test_build_server_detail_with_metadata(self):
3070
3071 metadata = []
3072 metadata.append(InstanceMetadata(key="Open", value="Stack"))
3073 metadata.append(InstanceMetadata(key="Number", value=1))
3074 self.instance['metadata'] = metadata
3075
3076 image_bookmark = "http://localhost/images/5"
3077 flavor_bookmark = "http://localhost/flavors/1"
3078 expected_server = {
3079 "server": {
3080 "id": 1,
3081 "uuid": self.instance['uuid'],
3082 "updated": "2010-11-11T11:00:00Z",
3083 "created": "2010-10-10T12:00:00Z",
3084 "progress": 0,
3085 "name": "test_server",
3086 "status": "BUILD",
3087 "hostId": '',
3088 "image": {
3089 "id": "5",
3090 "links": [
3091 {
3092 "rel": "bookmark",
3093 "href": image_bookmark,
3094 },
3095 ],
3096 },
3097 "flavor": {
3098 "id": "1",
3099 "links": [
3100 {
3101 "rel": "bookmark",
3102 "href": flavor_bookmark,
3103 },
3104 ],
3105 },
3106 "addresses": {},
3107 "metadata": {
3108 "Open": "Stack",
3109 "Number": "1",
3110 },
3111 "links": [
3112 {
3113 "rel": "self",
3114 "href": "http://localhost/v1.1/servers/1",
3115 },
3116 {
3117 "rel": "bookmark",
3118 "href": "http://localhost/servers/1",
3119 },
3120 ],
3121 }
3122 }
3123
3124 output = self.view_builder.build(self.instance, True)
3125 self.assertDictMatch(output, expected_server)