From bb09e0e1bc1c587e7677eb5db68a8fbd293ecd5b Mon Sep 17 00:00:00 2001
From: Brian Waldon
Date: Wed, 6 Jul 2011 16:28:10 -0400
Subject: first round
---
nova/api/openstack/accounts.py | 6 +-
nova/api/openstack/backup_schedules.py | 13 +-
nova/api/openstack/consoles.py | 12 +-
nova/api/openstack/contrib/floating_ips.py | 4 +-
nova/api/openstack/create_instance_helper.py | 2 +-
nova/api/openstack/flavors.py | 6 +-
nova/api/openstack/image_metadata.py | 5 +-
nova/api/openstack/images.py | 6 +-
nova/api/openstack/ips.py | 5 +-
nova/api/openstack/limits.py | 6 +-
nova/api/openstack/server_metadata.py | 6 +-
nova/api/openstack/servers.py | 10 +-
nova/api/openstack/shared_ip_groups.py | 12 +-
nova/api/openstack/users.py | 6 +-
nova/api/openstack/versions.py | 5 +-
nova/api/openstack/wsgi.py | 144 +++++++++++++--------
nova/api/openstack/zones.py | 9 +-
.../api/openstack/contrib/test_floating_ips.py | 3 +
nova/tests/api/openstack/test_servers.py | 46 +++----
nova/tests/api/openstack/test_wsgi.py | 61 +++++----
nova/tests/integrated/api/client.py | 7 +-
21 files changed, 217 insertions(+), 157 deletions(-)
diff --git a/nova/api/openstack/accounts.py b/nova/api/openstack/accounts.py
index 0dcd37217..e3201b14f 100644
--- a/nova/api/openstack/accounts.py
+++ b/nova/api/openstack/accounts.py
@@ -87,8 +87,8 @@ def create_resource():
},
}
- serializers = {
+ body_serializers = {
'application/xml': wsgi.XMLDictSerializer(metadata=metadata),
}
-
- return wsgi.Resource(Controller(), serializers=serializers)
+ serializer = wsgi.ResponseSerializer(body_serializers)
+ return wsgi.Resource(Controller(), serializer=serializer)
diff --git a/nova/api/openstack/backup_schedules.py b/nova/api/openstack/backup_schedules.py
index 71a14d4ce..3e95aedf3 100644
--- a/nova/api/openstack/backup_schedules.py
+++ b/nova/api/openstack/backup_schedules.py
@@ -34,20 +34,20 @@ class Controller(object):
def __init__(self):
pass
- def index(self, req, server_id):
+ def index(self, req, server_id, **kwargs):
""" Returns the list of backup schedules for a given instance """
return faults.Fault(exc.HTTPNotImplemented())
- def show(self, req, server_id, id):
+ def show(self, req, server_id, id, **kwargs):
""" Returns a single backup schedule for a given instance """
return faults.Fault(exc.HTTPNotImplemented())
- def create(self, req, server_id, body):
+ def create(self, req, server_id, **kwargs):
""" No actual update method required, since the existing API allows
both create and update through a POST """
return faults.Fault(exc.HTTPNotImplemented())
- def delete(self, req, server_id, id):
+ def delete(self, req, server_id, id, **kwargs):
""" Deletes an existing backup schedule """
return faults.Fault(exc.HTTPNotImplemented())
@@ -59,9 +59,10 @@ def create_resource():
},
}
- serializers = {
+ body_serializers = {
'application/xml': wsgi.XMLDictSerializer(xmlns=wsgi.XMLNS_V10,
metadata=metadata),
}
- return wsgi.Resource(Controller(), serializers=serializers)
+ serializer = wsgi.ResponseSerializer(body_serializers)
+ return wsgi.Resource(Controller(), serializer=serializer)
diff --git a/nova/api/openstack/consoles.py b/nova/api/openstack/consoles.py
index bccf04d8f..7a43fba96 100644
--- a/nova/api/openstack/consoles.py
+++ b/nova/api/openstack/consoles.py
@@ -90,14 +90,4 @@ class Controller(object):
def create_resource():
- metadata = {
- 'attributes': {
- 'console': [],
- },
- }
-
- serializers = {
- 'application/xml': wsgi.XMLDictSerializer(metadata=metadata),
- }
-
- return wsgi.Resource(Controller(), serializers=serializers)
+ return wsgi.Resource(Controller())
diff --git a/nova/api/openstack/contrib/floating_ips.py b/nova/api/openstack/contrib/floating_ips.py
index b27336574..b4a211857 100644
--- a/nova/api/openstack/contrib/floating_ips.py
+++ b/nova/api/openstack/contrib/floating_ips.py
@@ -78,7 +78,7 @@ class FloatingIPController(object):
return _translate_floating_ips_view(floating_ips)
- def create(self, req, body):
+ def create(self, req):
context = req.environ['nova.context']
try:
@@ -124,7 +124,7 @@ class FloatingIPController(object):
"floating_ip": floating_ip,
"fixed_ip": fixed_ip}}
- def disassociate(self, req, id, body):
+ def disassociate(self, req, id):
""" POST /floating_ips/{id}/disassociate """
context = req.environ['nova.context']
floating_ip = self.network_api.get_floating_ip(context, id)
diff --git a/nova/api/openstack/create_instance_helper.py b/nova/api/openstack/create_instance_helper.py
index 1066713a3..2654e3c40 100644
--- a/nova/api/openstack/create_instance_helper.py
+++ b/nova/api/openstack/create_instance_helper.py
@@ -289,7 +289,7 @@ class ServerXMLDeserializer(wsgi.XMLDeserializer):
"""Deserialize an xml-formatted server create request"""
dom = minidom.parseString(string)
server = self._extract_server(dom)
- return {'server': server}
+ return {'body': {'server': server}}
def _extract_server(self, node):
"""Marshal the server attribute of a parsed request"""
diff --git a/nova/api/openstack/flavors.py b/nova/api/openstack/flavors.py
index a21ff6cb2..6fab13147 100644
--- a/nova/api/openstack/flavors.py
+++ b/nova/api/openstack/flavors.py
@@ -85,8 +85,10 @@ def create_resource(version='1.0'):
'1.1': wsgi.XMLNS_V11,
}[version]
- serializers = {
+ body_serializers = {
'application/xml': wsgi.XMLDictSerializer(xmlns=xmlns),
}
- return wsgi.Resource(controller, serializers=serializers)
+ serializer = wsgi.ResponseSerializer(body_serializers)
+
+ return wsgi.Resource(controller, serializer=serializer)
diff --git a/nova/api/openstack/image_metadata.py b/nova/api/openstack/image_metadata.py
index 638b1ec15..4f33844fa 100644
--- a/nova/api/openstack/image_metadata.py
+++ b/nova/api/openstack/image_metadata.py
@@ -160,8 +160,9 @@ class ImageMetadataXMLSerializer(wsgi.XMLDictSerializer):
def create_resource():
- serializers = {
+ body_serializers = {
'application/xml': ImageMetadataXMLSerializer(),
}
+ serializer = wsgi.ResponseSerializer(body_serializers)
- return wsgi.Resource(Controller(), serializers=serializers)
+ return wsgi.Resource(Controller(), serializer=serializer)
diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py
index bde9507c8..178374721 100644
--- a/nova/api/openstack/images.py
+++ b/nova/api/openstack/images.py
@@ -338,8 +338,10 @@ def create_resource(version='1.0'):
'1.1': ImageXMLSerializer(),
}[version]
- serializers = {
+ body_serializers = {
'application/xml': xml_serializer,
}
- return wsgi.Resource(controller, serializers=serializers)
+ serializer = wsgi.ResponseSerializer(body_serializers)
+
+ return wsgi.Resource(controller, serializer=serializer)
diff --git a/nova/api/openstack/ips.py b/nova/api/openstack/ips.py
index 71646b6d3..23e5432d6 100644
--- a/nova/api/openstack/ips.py
+++ b/nova/api/openstack/ips.py
@@ -70,9 +70,10 @@ def create_resource():
},
}
- serializers = {
+ body_serializers = {
'application/xml': wsgi.XMLDictSerializer(metadata=metadata,
xmlns=wsgi.XMLNS_V10),
}
+ serializer = wsgi.ResponseSerializer(body_serializers)
- return wsgi.Resource(Controller(), serializers=serializers)
+ return wsgi.Resource(Controller(), serializer=serializer)
diff --git a/nova/api/openstack/limits.py b/nova/api/openstack/limits.py
index fede96e33..d08287f6b 100644
--- a/nova/api/openstack/limits.py
+++ b/nova/api/openstack/limits.py
@@ -97,12 +97,14 @@ def create_resource(version='1.0'):
},
}
- serializers = {
+ body_serializers = {
'application/xml': wsgi.XMLDictSerializer(xmlns=xmlns,
metadata=metadata),
}
- return wsgi.Resource(controller, serializers=serializers)
+ serializer = wsgi.ResponseSerializer(body_serializers)
+
+ return wsgi.Resource(controller, serializer=serializer)
class Limit(object):
diff --git a/nova/api/openstack/server_metadata.py b/nova/api/openstack/server_metadata.py
index 8a314de22..3b9169f81 100644
--- a/nova/api/openstack/server_metadata.py
+++ b/nova/api/openstack/server_metadata.py
@@ -123,8 +123,10 @@ class Controller(object):
def create_resource():
- serializers = {
+ body_serializers = {
'application/xml': wsgi.XMLDictSerializer(xmlns=wsgi.XMLNS_V11),
}
- return wsgi.Resource(Controller(), serializers=serializers)
+ serializer = wsgi.ResponseSerializer(body_serializers)
+
+ return wsgi.Resource(Controller(), serializer=serializer)
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py
index fc1ab8d46..9953a8fb7 100644
--- a/nova/api/openstack/servers.py
+++ b/nova/api/openstack/servers.py
@@ -616,14 +616,16 @@ def create_resource(version='1.0'):
'1.1': wsgi.XMLNS_V11,
}[version]
- serializers = {
+ body_serializers = {
'application/xml': wsgi.XMLDictSerializer(metadata=metadata,
xmlns=xmlns),
}
- deserializers = {
+ body_deserializers = {
'application/xml': helper.ServerXMLDeserializer(),
}
- return wsgi.Resource(controller, serializers=serializers,
- deserializers=deserializers)
+ serializer = wsgi.ResponseSerializer(body_serializers)
+ deserializer = wsgi.RequestDeserializer(body_deserializers)
+
+ return wsgi.Resource(controller, deserializer, serializer)
diff --git a/nova/api/openstack/shared_ip_groups.py b/nova/api/openstack/shared_ip_groups.py
index 4f11f8dfb..cf2ddbabb 100644
--- a/nova/api/openstack/shared_ip_groups.py
+++ b/nova/api/openstack/shared_ip_groups.py
@@ -24,27 +24,27 @@ from nova.api.openstack import wsgi
class Controller(object):
""" The Shared IP Groups Controller for the Openstack API """
- def index(self, req):
+ def index(self, req, **kwargs):
""" Returns a list of Shared IP Groups for the user """
raise faults.Fault(exc.HTTPNotImplemented())
- def show(self, req, id):
+ def show(self, req, id, **kwargs):
""" Shows in-depth information on a specific Shared IP Group """
raise faults.Fault(exc.HTTPNotImplemented())
- def update(self, req, id, body):
+ def update(self, req, id, **kwargs):
""" You can't update a Shared IP Group """
raise faults.Fault(exc.HTTPNotImplemented())
- def delete(self, req, id):
+ def delete(self, req, id, **kwargs):
""" Deletes a Shared IP Group """
raise faults.Fault(exc.HTTPNotImplemented())
- def detail(self, req):
+ def detail(self, req, **kwargs):
""" Returns a complete list of Shared IP Groups """
raise faults.Fault(exc.HTTPNotImplemented())
- def create(self, req, body):
+ def create(self, req, **kwargs):
""" Creates a new Shared IP group """
raise faults.Fault(exc.HTTPNotImplemented())
diff --git a/nova/api/openstack/users.py b/nova/api/openstack/users.py
index 50975fc1f..6ae1eaf2a 100644
--- a/nova/api/openstack/users.py
+++ b/nova/api/openstack/users.py
@@ -105,8 +105,10 @@ def create_resource():
},
}
- serializers = {
+ body_serializers = {
'application/xml': wsgi.XMLDictSerializer(metadata=metadata),
}
- return wsgi.Resource(Controller(), serializers=serializers)
+ serializer = wsgi.ResponseSerializer(body_serializers)
+
+ return wsgi.Resource(Controller(), serializer=serializer)
diff --git a/nova/api/openstack/versions.py b/nova/api/openstack/versions.py
index 4c682302f..a634c3267 100644
--- a/nova/api/openstack/versions.py
+++ b/nova/api/openstack/versions.py
@@ -31,11 +31,12 @@ class Versions(wsgi.Resource):
}
}
- serializers = {
+ body_serializers = {
'application/xml': wsgi.XMLDictSerializer(metadata=metadata),
}
+ serializer = wsgi.ResponseSerializer(body_serializers)
- wsgi.Resource.__init__(self, None, serializers=serializers)
+ wsgi.Resource.__init__(self, None, serializer=serializer)
def dispatch(self, request, *args):
"""Respond to a request for all OpenStack API versions."""
diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py
index 5b6e3cb1d..6726531be 100644
--- a/nova/api/openstack/wsgi.py
+++ b/nova/api/openstack/wsgi.py
@@ -46,7 +46,7 @@ class Request(webob.Request):
"""
if not "Content-Type" in self.headers:
- raise exception.InvalidContentType(content_type=None)
+ return None
allowed_types = ("application/xml", "application/json")
content_type = self.content_type
@@ -67,17 +67,20 @@ class TextDeserializer(object):
def default(self, datastring):
"""Default deserialization code should live here"""
- raise NotImplementedError()
+ return {}
class JSONDeserializer(TextDeserializer):
- def default(self, datastring):
+ def _from_json(self, datastring):
try:
return utils.loads(datastring)
except ValueError:
- raise exception.MalformedRequestBody(
- reason=_("malformed JSON in request body"))
+ msg = _("cannot understand JSON")
+ raise exception.MalformedRequestBody(reason=msg)
+
+ def default(self, datastring):
+ return {'body': self._from_json(datastring)}
class XMLDeserializer(TextDeserializer):
@@ -90,15 +93,15 @@ class XMLDeserializer(TextDeserializer):
super(XMLDeserializer, self).__init__()
self.metadata = metadata or {}
- def default(self, datastring):
+ def _from_xml(self, datastring):
plurals = set(self.metadata.get('plurals', {}))
try:
node = minidom.parseString(datastring).childNodes[0]
return {node.nodeName: self._from_xml_node(node, plurals)}
except expat.ExpatError:
- raise exception.MalformedRequestBody(
- reason=_("malformed XML in request body"))
+ msg = _("cannot understand XML")
+ raise exception.MalformedRequestBody(reason=msg)
def _from_xml_node(self, node, listnames):
"""Convert a minidom node to a simple Python type.
@@ -121,21 +124,27 @@ class XMLDeserializer(TextDeserializer):
listnames)
return result
+ def default(self, datastring):
+ return {'body': self._from_xml(datastring)}
+
+
+class RequestHeadersDeserializer(object):
+ def deserialize(self, request, action):
+ return {}
+
class RequestDeserializer(object):
"""Break up a Request object into more useful pieces."""
- def __init__(self, deserializers=None):
- """
- :param deserializers: dictionary of content-type-specific deserializers
-
- """
- self.deserializers = {
+ def __init__(self, body_deserializers=None, headers_deserializer=None):
+ self.body_deserializers = {
'application/xml': XMLDeserializer(),
'application/json': JSONDeserializer(),
}
+ self.body_deserializers.update(body_deserializers or {})
- self.deserializers.update(deserializers or {})
+ self.headers_deserializer = headers_deserializer or \
+ RequestHeadersDeserializer()
def deserialize(self, request):
"""Extract necessary pieces of the request.
@@ -149,26 +158,45 @@ class RequestDeserializer(object):
action_args = self.get_action_args(request.environ)
action = action_args.pop('action', None)
- if request.method.lower() in ('post', 'put'):
- if len(request.body) == 0:
- action_args['body'] = None
- else:
- content_type = request.get_content_type()
- deserializer = self.get_deserializer(content_type)
-
- try:
- body = deserializer.deserialize(request.body, action)
- action_args['body'] = body
- except exception.InvalidContentType:
- action_args['body'] = None
+ action_args.update(self.deserialize_headers(request, action))
+ action_args.update(self.deserialize_body(request, action))
accept = self.get_expected_content_type(request)
return (action, action_args, accept)
- def get_deserializer(self, content_type):
+ def deserialize_headers(self, request, action):
+ return self.headers_deserializer.deserialize(request, action)
+
+ def deserialize_body(self, request, action):
+ try:
+ content_type = request.get_content_type()
+
+ if content_type is None:
+ LOG.debug(_("No Content-Type provided in request"))
+ return {}
+
+ if 'Content-Length' not in request.headers:
+ msg = _("No Content-Length provided in request")
+ LOG.debug(msg)
+ return {}
+
+ if not request.content_length > 0:
+ msg = _("Request has Content-Length of zero")
+ LOG.debug(msg)
+ return {}
+
+ deserializer = self.get_body_deserializer(content_type)
+
+ except exception.InvalidContentType:
+ LOG.debug(_("Unable to read body as provided Content-Type"))
+ raise
+
+ return deserializer.deserialize(request.body, action)
+
+ def get_body_deserializer(self, content_type):
try:
- return self.deserializers[content_type]
+ return self.body_deserializers[content_type]
except (KeyError, TypeError):
raise exception.InvalidContentType(content_type=content_type)
@@ -295,19 +323,23 @@ class XMLDictSerializer(DictSerializer):
return result
+class ResponseHeadersSerializer(object):
+ def serialize(self, response, data, action):
+ response.status_int = 200
+
+
class ResponseSerializer(object):
"""Encode the necessary pieces into a response object"""
- def __init__(self, serializers=None):
- """
- :param serializers: dictionary of content-type-specific serializers
-
- """
- self.serializers = {
+ def __init__(self, body_serializers=None, headers_serializer=None):
+ self.body_serializers = {
'application/xml': XMLDictSerializer(),
'application/json': JSONDictSerializer(),
}
- self.serializers.update(serializers or {})
+ self.body_serializers.update(body_serializers or {})
+
+ self.headers_serializer = headers_serializer or \
+ ResponseHeadersSerializer()
def serialize(self, response_data, content_type, action='default'):
"""Serialize a dict into a string and wrap in a wsgi.Request object.
@@ -317,16 +349,21 @@ class ResponseSerializer(object):
"""
response = webob.Response()
- response.headers['Content-Type'] = content_type
+ self.serialize_headers(response, response_data, action)
+ self.serialize_body(response, response_data, content_type, action)
+ return response
- serializer = self.get_serializer(content_type)
- response.body = serializer.serialize(response_data, action)
+ def serialize_headers(self, response, data, action):
+ self.headers_serializer.serialize(response, data, action)
- return response
+ def serialize_body(self, response, data, content_type, action):
+ response.headers['Content-Type'] = content_type
+ serializer = self.get_body_serializer(content_type)
+ response.body = serializer.serialize(data, action)
- def get_serializer(self, content_type):
+ def get_body_serializer(self, content_type):
try:
- return self.serializers[content_type]
+ return self.body_serializers[content_type]
except (KeyError, TypeError):
raise exception.InvalidContentType(content_type=content_type)
@@ -343,16 +380,18 @@ class Resource(wsgi.Application):
serialized by requested content type.
"""
- def __init__(self, controller, serializers=None, deserializers=None):
+ def __init__(self, controller, deserializer=None, serializer=None):
"""
:param controller: object that implement methods created by routes lib
- :param serializers: dict of content-type specific text serializers
- :param deserializers: dict of content-type specific text deserializers
+ :param deserializer: object that can serialize the output of a
+ controller into a webob response
+ :param serializer: object that can deserialize a webob request
+ into necessary pieces
"""
self.controller = controller
- self.serializer = ResponseSerializer(serializers)
- self.deserializer = RequestDeserializer(deserializers)
+ self.deserializer = deserializer or RequestDeserializer()
+ self.serializer = serializer or ResponseSerializer()
@webob.dec.wsgify(RequestClass=Request)
def __call__(self, request):
@@ -362,8 +401,7 @@ class Resource(wsgi.Application):
"url": request.url})
try:
- action, action_args, accept = self.deserializer.deserialize(
- request)
+ action, args, accept = self.deserializer.deserialize(request)
except exception.InvalidContentType:
msg = _("Unsupported Content-Type")
return webob.exc.HTTPBadRequest(explanation=msg)
@@ -371,7 +409,7 @@ class Resource(wsgi.Application):
msg = _("Malformed request body")
return faults.Fault(webob.exc.HTTPBadRequest(explanation=msg))
- action_result = self.dispatch(request, action, action_args)
+ action_result = self.dispatch(request, action, args)
#TODO(bcwaldon): find a more elegant way to pass through non-dict types
if type(action_result) is dict:
@@ -394,4 +432,8 @@ class Resource(wsgi.Application):
"""Find action-spefic method on controller and call it."""
controller_method = getattr(self.controller, action)
- return controller_method(req=request, **action_args)
+ try:
+ return controller_method(req=request, **action_args)
+ except TypeError, exc:
+ LOG.debug(str(exc))
+ return webob.exc.HTTPBadRequest()
diff --git a/nova/api/openstack/zones.py b/nova/api/openstack/zones.py
index 8864f825b..2e02ec380 100644
--- a/nova/api/openstack/zones.py
+++ b/nova/api/openstack/zones.py
@@ -196,14 +196,15 @@ def create_resource(version):
},
}
- serializers = {
+ body_serializers = {
'application/xml': wsgi.XMLDictSerializer(xmlns=wsgi.XMLNS_V10,
metadata=metadata),
}
+ serializer = wsgi.ResponseSerializer(body_serializers)
- deserializers = {
+ body_deserializers = {
'application/xml': helper.ServerXMLDeserializer(),
}
+ deserializer = wsgi.RequestDeserializer(body_deserializers)
- return wsgi.Resource(controller, serializers=serializers,
- deserializers=deserializers)
+ return wsgi.Resource(controller, deserializer, serializer)
diff --git a/nova/tests/api/openstack/contrib/test_floating_ips.py b/nova/tests/api/openstack/contrib/test_floating_ips.py
index de1eb2f53..de006d088 100644
--- a/nova/tests/api/openstack/contrib/test_floating_ips.py
+++ b/nova/tests/api/openstack/contrib/test_floating_ips.py
@@ -139,7 +139,9 @@ class FloatingIpTest(test.TestCase):
def test_floating_ip_allocate(self):
req = webob.Request.blank('/v1.1/os-floating-ips')
req.method = 'POST'
+ req.headers['Content-Type'] = 'application/json'
res = req.get_response(fakes.wsgi_app())
+ print res
self.assertEqual(res.status_int, 200)
ip = json.loads(res.body)['allocated']
expected = {
@@ -177,6 +179,7 @@ class FloatingIpTest(test.TestCase):
def test_floating_ip_disassociate(self):
req = webob.Request.blank('/v1.1/os-floating-ips/1/disassociate')
req.method = 'POST'
+ req.headers['Content-Type'] = 'application/json'
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 200)
ip = json.loads(res.body)['disassociated']
diff --git a/nova/tests/api/openstack/test_servers.py b/nova/tests/api/openstack/test_servers.py
index c3ca1431b..5004fbce1 100644
--- a/nova/tests/api/openstack/test_servers.py
+++ b/nova/tests/api/openstack/test_servers.py
@@ -917,7 +917,7 @@ class ServersTest(test.TestCase):
req = webob.Request.blank('/v1.0/servers/1')
req.method = 'PUT'
res = req.get_response(fakes.wsgi_app())
- self.assertEqual(res.status_int, 422)
+ self.assertEqual(res.status_int, 400)
def test_update_nonstring_name(self):
""" Confirm that update is filtering params """
@@ -1603,7 +1603,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"imageId": "1",
"flavorId": "1",
}}
- self.assertEquals(request, expected)
+ self.assertEquals(request['body'], expected)
def test_request_with_empty_metadata(self):
serial_request = """
@@ -1618,7 +1618,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"flavorId": "1",
"metadata": {},
}}
- self.assertEquals(request, expected)
+ self.assertEquals(request['body'], expected)
def test_request_with_empty_personality(self):
serial_request = """
@@ -1633,7 +1633,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"flavorId": "1",
"personality": [],
}}
- self.assertEquals(request, expected)
+ self.assertEquals(request['body'], expected)
def test_request_with_empty_metadata_and_personality(self):
serial_request = """
@@ -1650,7 +1650,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"metadata": {},
"personality": [],
}}
- self.assertEquals(request, expected)
+ self.assertEquals(request['body'], expected)
def test_request_with_empty_metadata_and_personality_reversed(self):
serial_request = """
@@ -1667,7 +1667,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"metadata": {},
"personality": [],
}}
- self.assertEquals(request, expected)
+ self.assertEquals(request['body'], expected)
def test_request_with_one_personality(self):
serial_request = """
@@ -1679,7 +1679,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"""
request = self.deserializer.deserialize(serial_request, 'create')
expected = [{"path": "/etc/conf", "contents": "aabbccdd"}]
- self.assertEquals(request["server"]["personality"], expected)
+ self.assertEquals(request['body']["server"]["personality"], expected)
def test_request_with_two_personalities(self):
serial_request = """
@@ -1690,7 +1690,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
request = self.deserializer.deserialize(serial_request, 'create')
expected = [{"path": "/etc/conf", "contents": "aabbccdd"},
{"path": "/etc/sudoers", "contents": "abcd"}]
- self.assertEquals(request["server"]["personality"], expected)
+ self.assertEquals(request['body']["server"]["personality"], expected)
def test_request_second_personality_node_ignored(self):
serial_request = """
@@ -1705,7 +1705,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"""
request = self.deserializer.deserialize(serial_request, 'create')
expected = [{"path": "/etc/conf", "contents": "aabbccdd"}]
- self.assertEquals(request["server"]["personality"], expected)
+ self.assertEquals(request['body']["server"]["personality"], expected)
def test_request_with_one_personality_missing_path(self):
serial_request = """
@@ -1714,7 +1714,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
aabbccdd"""
request = self.deserializer.deserialize(serial_request, 'create')
expected = [{"contents": "aabbccdd"}]
- self.assertEquals(request["server"]["personality"], expected)
+ self.assertEquals(request['body']["server"]["personality"], expected)
def test_request_with_one_personality_empty_contents(self):
serial_request = """
@@ -1723,7 +1723,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"""
request = self.deserializer.deserialize(serial_request, 'create')
expected = [{"path": "/etc/conf", "contents": ""}]
- self.assertEquals(request["server"]["personality"], expected)
+ self.assertEquals(request['body']["server"]["personality"], expected)
def test_request_with_one_personality_empty_contents_variation(self):
serial_request = """
@@ -1732,7 +1732,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"""
request = self.deserializer.deserialize(serial_request, 'create')
expected = [{"path": "/etc/conf", "contents": ""}]
- self.assertEquals(request["server"]["personality"], expected)
+ self.assertEquals(request['body']["server"]["personality"], expected)
def test_request_with_one_metadata(self):
serial_request = """
@@ -1744,7 +1744,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"""
request = self.deserializer.deserialize(serial_request, 'create')
expected = {"alpha": "beta"}
- self.assertEquals(request["server"]["metadata"], expected)
+ self.assertEquals(request['body']["server"]["metadata"], expected)
def test_request_with_two_metadata(self):
serial_request = """
@@ -1757,7 +1757,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"""
request = self.deserializer.deserialize(serial_request, 'create')
expected = {"alpha": "beta", "foo": "bar"}
- self.assertEquals(request["server"]["metadata"], expected)
+ self.assertEquals(request['body']["server"]["metadata"], expected)
def test_request_with_metadata_missing_value(self):
serial_request = """
@@ -1769,7 +1769,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"""
request = self.deserializer.deserialize(serial_request, 'create')
expected = {"alpha": ""}
- self.assertEquals(request["server"]["metadata"], expected)
+ self.assertEquals(request['body']["server"]["metadata"], expected)
def test_request_with_two_metadata_missing_value(self):
serial_request = """
@@ -1782,7 +1782,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"""
request = self.deserializer.deserialize(serial_request, 'create')
expected = {"alpha": "", "delta": ""}
- self.assertEquals(request["server"]["metadata"], expected)
+ self.assertEquals(request['body']["server"]["metadata"], expected)
def test_request_with_metadata_missing_key(self):
serial_request = """
@@ -1794,7 +1794,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"""
request = self.deserializer.deserialize(serial_request, 'create')
expected = {"": "beta"}
- self.assertEquals(request["server"]["metadata"], expected)
+ self.assertEquals(request['body']["server"]["metadata"], expected)
def test_request_with_two_metadata_missing_key(self):
serial_request = """
@@ -1807,7 +1807,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"""
request = self.deserializer.deserialize(serial_request, 'create')
expected = {"": "gamma"}
- self.assertEquals(request["server"]["metadata"], expected)
+ self.assertEquals(request['body']["server"]["metadata"], expected)
def test_request_with_metadata_duplicate_key(self):
serial_request = """
@@ -1820,7 +1820,7 @@ class TestServerCreateRequestXMLDeserializer(unittest.TestCase):
"""
request = self.deserializer.deserialize(serial_request, 'create')
expected = {"foo": "baz"}
- self.assertEquals(request["server"]["metadata"], expected)
+ self.assertEquals(request['body']["server"]["metadata"], expected)
def test_canonical_request_from_docs(self):
serial_request = """
@@ -1866,7 +1866,7 @@ b25zLiINCg0KLVJpY2hhcmQgQmFjaA==""",
],
}}
request = self.deserializer.deserialize(serial_request, 'create')
- self.assertEqual(request, expected)
+ self.assertEqual(request['body'], expected)
def test_request_xmlser_with_flavor_image_href(self):
serial_request = """
@@ -1876,9 +1876,9 @@ b25zLiINCg0KLVJpY2hhcmQgQmFjaA==""",
flavorRef="http://localhost:8774/v1.1/flavors/1">
"""
request = self.deserializer.deserialize(serial_request, 'create')
- self.assertEquals(request["server"]["flavorRef"],
+ self.assertEquals(request['body']["server"]["flavorRef"],
"http://localhost:8774/v1.1/flavors/1")
- self.assertEquals(request["server"]["imageRef"],
+ self.assertEquals(request['body']["server"]["imageRef"],
"http://localhost:8774/v1.1/images/1")
@@ -1943,7 +1943,7 @@ class TestServerInstanceCreation(test.TestCase):
def _get_create_request_json(self, body_dict):
req = webob.Request.blank('/v1.0/servers')
- req.content_type = 'application/json'
+ req.headers['Content-Type'] = 'application/json'
req.method = 'POST'
req.body = json.dumps(body_dict)
return req
diff --git a/nova/tests/api/openstack/test_wsgi.py b/nova/tests/api/openstack/test_wsgi.py
index 73a26a087..938637207 100644
--- a/nova/tests/api/openstack/test_wsgi.py
+++ b/nova/tests/api/openstack/test_wsgi.py
@@ -12,8 +12,7 @@ class RequestTest(test.TestCase):
def test_content_type_missing(self):
request = wsgi.Request.blank('/tests/123', method='POST')
request.body = ""
- self.assertRaises(exception.InvalidContentType,
- request.get_content_type)
+ self.assertEqual(None, request.get_content_type())
def test_content_type_unsupported(self):
request = wsgi.Request.blank('/tests/123', method='POST')
@@ -144,12 +143,17 @@ class JSONDeserializerTest(test.TestCase):
"bs": ["1", "2", "3", {"c": {"c1": "1"}}],
"d": {"e": "1"},
"f": "1"}}"""
- as_dict = dict(a={
- 'a1': '1',
- 'a2': '2',
- 'bs': ['1', '2', '3', {'c': dict(c1='1')}],
- 'd': {'e': '1'},
- 'f': '1'})
+ as_dict = {
+ 'body': {
+ 'a': {
+ 'a1': '1',
+ 'a2': '2',
+ 'bs': ['1', '2', '3', {'c': {'c1': '1'}}],
+ 'd': {'e': '1'},
+ 'f': '1',
+ },
+ },
+ }
deserializer = wsgi.JSONDeserializer()
self.assertEqual(deserializer.deserialize(data), as_dict)
@@ -163,19 +167,24 @@ class XMLDeserializerTest(test.TestCase):
1
""".strip()
- as_dict = dict(a={
- 'a1': '1',
- 'a2': '2',
- 'bs': ['1', '2', '3', {'c': dict(c1='1')}],
- 'd': {'e': '1'},
- 'f': '1'})
+ as_dict = {
+ 'body': {
+ 'a': {
+ 'a1': '1',
+ 'a2': '2',
+ 'bs': ['1', '2', '3', {'c': {'c1': '1'}}],
+ 'd': {'e': '1'},
+ 'f': '1',
+ },
+ },
+ }
metadata = {'plurals': {'bs': 'b', 'ts': 't'}}
deserializer = wsgi.XMLDeserializer(metadata=metadata)
self.assertEqual(deserializer.deserialize(xml), as_dict)
def test_xml_empty(self):
xml = """"""
- as_dict = {"a": {}}
+ as_dict = {"body": {"a": {}}}
deserializer = wsgi.XMLDeserializer()
self.assertEqual(deserializer.deserialize(xml), as_dict)
@@ -190,23 +199,24 @@ class ResponseSerializerTest(test.TestCase):
def serialize(self, data, action='default'):
return 'pew_xml'
- self.serializers = {
+ self.body_serializers = {
'application/json': JSONSerializer(),
'application/XML': XMLSerializer(),
}
- self.serializer = wsgi.ResponseSerializer(serializers=self.serializers)
+ self.serializer = wsgi.ResponseSerializer(self.body_serializers)
def tearDown(self):
pass
def test_get_serializer(self):
- self.assertEqual(self.serializer.get_serializer('application/json'),
- self.serializers['application/json'])
+ ctype = 'application/json'
+ self.assertEqual(self.serializer.get_body_serializer(ctype),
+ self.body_serializers[ctype])
def test_get_serializer_unknown_content_type(self):
self.assertRaises(exception.InvalidContentType,
- self.serializer.get_serializer,
+ self.serializer.get_body_serializer,
'application/unknown')
def test_serialize_response(self):
@@ -230,24 +240,23 @@ class RequestDeserializerTest(test.TestCase):
def deserialize(self, data, action='default'):
return 'pew_xml'
- self.deserializers = {
+ self.body_deserializers = {
'application/json': JSONDeserializer(),
'application/XML': XMLDeserializer(),
}
- self.deserializer = wsgi.RequestDeserializer(
- deserializers=self.deserializers)
+ self.deserializer = wsgi.RequestDeserializer(self.body_deserializers)
def tearDown(self):
pass
def test_get_deserializer(self):
- expected = self.deserializer.get_deserializer('application/json')
- self.assertEqual(expected, self.deserializers['application/json'])
+ expected = self.deserializer.get_body_deserializer('application/json')
+ self.assertEqual(expected, self.body_deserializers['application/json'])
def test_get_deserializer_unknown_content_type(self):
self.assertRaises(exception.InvalidContentType,
- self.deserializer.get_deserializer,
+ self.deserializer.get_body_deserializer,
'application/unknown')
def test_get_expected_content_type(self):
diff --git a/nova/tests/integrated/api/client.py b/nova/tests/integrated/api/client.py
index 76c03c5fa..3d255b40c 100644
--- a/nova/tests/integrated/api/client.py
+++ b/nova/tests/integrated/api/client.py
@@ -71,8 +71,8 @@ class TestOpenStackClient(object):
self.auth_uri = auth_uri
def request(self, url, method='GET', body=None, headers=None):
- if headers is None:
- headers = {}
+ _headers = {'Content-Type': 'application/json'}
+ _headers.update(headers or {})
parsed_url = urlparse.urlparse(url)
port = parsed_url.port
@@ -94,9 +94,8 @@ class TestOpenStackClient(object):
LOG.info(_("Doing %(method)s on %(relative_url)s") % locals())
if body:
LOG.info(_("Body: %s") % body)
- headers.setdefault('Content-Type', 'application/json')
- conn.request(method, relative_url, body, headers)
+ conn.request(method, relative_url, body, _headers)
response = conn.getresponse()
return response
--
cgit