Merge "Remove deprecated extension code."
This commit is contained in:
@@ -93,12 +93,12 @@ use = call:nova.api.openstack.urlmap:urlmap_factory
|
||||
/v1: openstack_volume_api_v1
|
||||
|
||||
[pipeline:openstack_compute_api_v2]
|
||||
pipeline = faultwrap noauth ratelimit serialize compute_extensions osapi_compute_app_v2
|
||||
pipeline = faultwrap noauth ratelimit osapi_compute_app_v2
|
||||
# NOTE(vish): use the following pipeline for deprecated auth
|
||||
# pipeline = faultwrap auth ratelimit serialize extensions osapi_compute_app_v2
|
||||
# pipeline = faultwrap auth ratelimit osapi_compute_app_v2
|
||||
|
||||
[pipeline:openstack_volume_api_v1]
|
||||
pipeline = faultwrap noauth ratelimit serialize volume_extensions osapi_volume_app_v1
|
||||
pipeline = faultwrap noauth ratelimit osapi_volume_app_v1
|
||||
|
||||
[filter:faultwrap]
|
||||
paste.filter_factory = nova.api.openstack:FaultWrapper.factory
|
||||
@@ -112,15 +112,6 @@ paste.filter_factory = nova.api.openstack.auth:NoAuthMiddleware.factory
|
||||
[filter:ratelimit]
|
||||
paste.filter_factory = nova.api.openstack.compute.limits:RateLimitingMiddleware.factory
|
||||
|
||||
[filter:serialize]
|
||||
paste.filter_factory = nova.api.openstack.wsgi:LazySerializationMiddleware.factory
|
||||
|
||||
[filter:compute_extensions]
|
||||
paste.filter_factory = nova.api.openstack.compute.extensions:ExtensionMiddleware.factory
|
||||
|
||||
[filter:volume_extensions]
|
||||
paste.filter_factory = nova.api.openstack.volume.extensions:ExtensionMiddleware.factory
|
||||
|
||||
[app:osapi_compute_app_v2]
|
||||
paste.app_factory = nova.api.openstack.compute:APIRouter.factory
|
||||
|
||||
|
||||
@@ -426,12 +426,6 @@ class MetadataXMLDeserializer(wsgi.XMLDeserializer):
|
||||
return {'body': {'meta': metadata_item}}
|
||||
|
||||
|
||||
class MetadataHeadersSerializer(wsgi.ResponseHeadersSerializer):
|
||||
|
||||
def delete(self, response, data):
|
||||
response.status_int = 204
|
||||
|
||||
|
||||
metadata_nsmap = {None: xmlutil.XMLNS_V11}
|
||||
|
||||
|
||||
@@ -459,26 +453,6 @@ class MetadataTemplate(xmlutil.TemplateBuilder):
|
||||
return xmlutil.MasterTemplate(root, 1, nsmap=metadata_nsmap)
|
||||
|
||||
|
||||
class MetadataXMLSerializer(xmlutil.XMLTemplateSerializer):
|
||||
def index(self):
|
||||
return MetadataTemplate()
|
||||
|
||||
def create(self):
|
||||
return MetadataTemplate()
|
||||
|
||||
def update_all(self):
|
||||
return MetadataTemplate()
|
||||
|
||||
def show(self):
|
||||
return MetaItemTemplate()
|
||||
|
||||
def update(self):
|
||||
return MetaItemTemplate()
|
||||
|
||||
def default(self):
|
||||
return xmlutil.MasterTemplate(None, 1)
|
||||
|
||||
|
||||
def check_snapshots_enabled(f):
|
||||
@functools.wraps(f)
|
||||
def inner(*args, **kwargs):
|
||||
|
||||
@@ -37,20 +37,6 @@ def _translate_floating_ip_pools_view(pools):
|
||||
}
|
||||
|
||||
|
||||
class FloatingIPPoolsController(object):
|
||||
"""The Floating IP Pool API controller for the OpenStack API."""
|
||||
|
||||
def __init__(self):
|
||||
self.network_api = network.API()
|
||||
super(FloatingIPPoolsController, self).__init__()
|
||||
|
||||
def index(self, req):
|
||||
"""Return a list of pools."""
|
||||
context = req.environ['nova.context']
|
||||
pools = self.network_api.get_floating_ip_pools(context)
|
||||
return _translate_floating_ip_pools_view(pools)
|
||||
|
||||
|
||||
def make_float_ip(elem):
|
||||
elem.set('name')
|
||||
|
||||
@@ -72,9 +58,19 @@ class FloatingIPPoolsTemplate(xmlutil.TemplateBuilder):
|
||||
return xmlutil.MasterTemplate(root, 1)
|
||||
|
||||
|
||||
class FloatingIPPoolsSerializer(xmlutil.XMLTemplateSerializer):
|
||||
def index(self):
|
||||
return FloatingIPPoolsTemplate()
|
||||
class FloatingIPPoolsController(object):
|
||||
"""The Floating IP Pool API controller for the OpenStack API."""
|
||||
|
||||
def __init__(self):
|
||||
self.network_api = network.API()
|
||||
super(FloatingIPPoolsController, self).__init__()
|
||||
|
||||
@wsgi.serializers(xml=FloatingIPPoolsTemplate)
|
||||
def index(self, req):
|
||||
"""Return a list of pools."""
|
||||
context = req.environ['nova.context']
|
||||
pools = self.network_api.get_floating_ip_pools(context)
|
||||
return _translate_floating_ip_pools_view(pools)
|
||||
|
||||
|
||||
class Floating_ip_pools(extensions.ExtensionDescriptor):
|
||||
@@ -89,15 +85,8 @@ class Floating_ip_pools(extensions.ExtensionDescriptor):
|
||||
def get_resources(self):
|
||||
resources = []
|
||||
|
||||
body_serializers = {
|
||||
'application/xml': FloatingIPPoolsSerializer(),
|
||||
}
|
||||
|
||||
serializer = wsgi.ResponseSerializer(body_serializers)
|
||||
|
||||
res = extensions.ResourceExtension('os-floating-ip-pools',
|
||||
FloatingIPPoolsController(),
|
||||
serializer=serializer,
|
||||
member_actions={})
|
||||
resources.append(res)
|
||||
|
||||
|
||||
@@ -130,14 +130,6 @@ class KeypairController(object):
|
||||
return {'keypairs': rval}
|
||||
|
||||
|
||||
class KeypairsSerializer(xmlutil.XMLTemplateSerializer):
|
||||
def index(self):
|
||||
return KeypairsTemplate()
|
||||
|
||||
def default(self):
|
||||
return KeypairTemplate()
|
||||
|
||||
|
||||
class Keypairs(extensions.ExtensionDescriptor):
|
||||
"""Keypair Support"""
|
||||
|
||||
|
||||
@@ -195,20 +195,6 @@ class Controller(object):
|
||||
return cooked
|
||||
|
||||
|
||||
class ZonesXMLSerializer(xmlutil.XMLTemplateSerializer):
|
||||
def index(self):
|
||||
return ZonesTemplate()
|
||||
|
||||
def detail(self):
|
||||
return ZonesTemplate()
|
||||
|
||||
def select(self):
|
||||
return WeightsTemplate()
|
||||
|
||||
def default(self):
|
||||
return ZoneTemplate()
|
||||
|
||||
|
||||
class Zones(extensions.ExtensionDescriptor):
|
||||
"""Enables zones-related functionality such as adding child zones,
|
||||
listing child zones, getting the capabilities of the local zone,
|
||||
|
||||
@@ -25,21 +25,20 @@ FLAGS = flags.FLAGS
|
||||
|
||||
|
||||
class ExtensionManager(base_extensions.ExtensionManager):
|
||||
def __new__(cls):
|
||||
if cls._ext_mgr is None:
|
||||
LOG.audit(_('Initializing extension manager.'))
|
||||
def __init__(self):
|
||||
LOG.audit(_('Initializing extension manager.'))
|
||||
|
||||
cls._ext_mgr = super(ExtensionManager, cls).__new__(cls)
|
||||
|
||||
cls.cls_list = FLAGS.osapi_compute_extension
|
||||
cls._ext_mgr.extensions = {}
|
||||
cls._ext_mgr._load_extensions()
|
||||
|
||||
return cls._ext_mgr
|
||||
self.cls_list = FLAGS.osapi_compute_extension
|
||||
self.extensions = {}
|
||||
self._load_extensions()
|
||||
|
||||
|
||||
class ExtensionMiddleware(base_extensions.ExtensionMiddleware):
|
||||
def __init__(self, application, ext_mgr=None):
|
||||
if not ext_mgr:
|
||||
ext_mgr = ExtensionManager()
|
||||
super(ExtensionMiddleware, self).__init__(application, ext_mgr)
|
||||
"""Extensions middleware for WSGI.
|
||||
|
||||
Provided only for backwards compatibility with existing
|
||||
api-paste.ini files. This middleware will be removed in future
|
||||
versions of nova.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
@@ -79,24 +79,6 @@ class ExtensionDescriptor(object):
|
||||
resources = []
|
||||
return resources
|
||||
|
||||
def get_actions(self):
|
||||
"""List of extensions.ActionExtension extension objects.
|
||||
|
||||
Actions are verbs callable from the API.
|
||||
|
||||
"""
|
||||
actions = []
|
||||
return actions
|
||||
|
||||
def get_request_extensions(self):
|
||||
"""List of extensions.RequestExtension extension objects.
|
||||
|
||||
Request extensions are used to handle custom request data.
|
||||
|
||||
"""
|
||||
request_exts = []
|
||||
return request_exts
|
||||
|
||||
def get_controller_extensions(self):
|
||||
"""List of extensions.ControllerExtension extension objects.
|
||||
|
||||
@@ -124,92 +106,6 @@ class ExtensionDescriptor(object):
|
||||
return '{%s}%s' % (cls.namespace, name)
|
||||
|
||||
|
||||
class ActionExtensionController(object):
|
||||
def __init__(self, application):
|
||||
self.application = application
|
||||
self.action_handlers = {}
|
||||
|
||||
def add_action(self, action_name, handler):
|
||||
self.action_handlers[action_name] = handler
|
||||
|
||||
def action(self, req, id, body):
|
||||
for action_name, handler in self.action_handlers.iteritems():
|
||||
if action_name in body:
|
||||
return handler(body, req, id)
|
||||
# no action handler found (bump to downstream application)
|
||||
res = self.application
|
||||
return res
|
||||
|
||||
|
||||
class ActionExtensionResource(wsgi.Resource):
|
||||
|
||||
def __init__(self, application):
|
||||
controller = ActionExtensionController(application)
|
||||
wsgi.Resource.__init__(self, controller,
|
||||
serializer=wsgi.ResponseSerializer(),
|
||||
deserializer=wsgi.RequestDeserializer())
|
||||
|
||||
def add_action(self, action_name, handler):
|
||||
self.controller.add_action(action_name, handler)
|
||||
|
||||
|
||||
class RequestExtensionController(object):
|
||||
|
||||
def __init__(self, application):
|
||||
self.application = application
|
||||
self.handlers = []
|
||||
self.pre_handlers = []
|
||||
|
||||
def add_handler(self, handler):
|
||||
self.handlers.append(handler)
|
||||
|
||||
def add_pre_handler(self, pre_handler):
|
||||
self.pre_handlers.append(pre_handler)
|
||||
|
||||
def process(self, req, *args, **kwargs):
|
||||
for pre_handler in self.pre_handlers:
|
||||
pre_handler(req)
|
||||
|
||||
res = req.get_response(self.application)
|
||||
res.environ = req.environ
|
||||
|
||||
# Don't call extensions if the main application returned an
|
||||
# unsuccessful status
|
||||
successful = 200 <= res.status_int < 400
|
||||
if not successful:
|
||||
return res
|
||||
|
||||
# Deserialize the response body, if any
|
||||
body = None
|
||||
if res.body:
|
||||
body = utils.loads(res.body)
|
||||
|
||||
# currently request handlers are un-ordered
|
||||
for handler in self.handlers:
|
||||
res = handler(req, res, body)
|
||||
|
||||
# Reserialize the response body
|
||||
if body is not None:
|
||||
res.body = utils.dumps(body)
|
||||
|
||||
return res
|
||||
|
||||
|
||||
class RequestExtensionResource(wsgi.Resource):
|
||||
|
||||
def __init__(self, application):
|
||||
controller = RequestExtensionController(application)
|
||||
wsgi.Resource.__init__(self, controller,
|
||||
serializer=wsgi.ResponseSerializer(),
|
||||
deserializer=wsgi.RequestDeserializer())
|
||||
|
||||
def add_handler(self, handler):
|
||||
self.controller.add_handler(handler)
|
||||
|
||||
def add_pre_handler(self, pre_handler):
|
||||
self.controller.add_pre_handler(pre_handler)
|
||||
|
||||
|
||||
def make_ext(elem):
|
||||
elem.set('name')
|
||||
elem.set('namespace')
|
||||
@@ -281,106 +177,16 @@ class ExtensionsResource(wsgi.Resource):
|
||||
raise webob.exc.HTTPNotFound()
|
||||
|
||||
|
||||
@utils.deprecated("The extension middleware is no longer necessary.")
|
||||
class ExtensionMiddleware(base_wsgi.Middleware):
|
||||
"""Extensions middleware for WSGI."""
|
||||
@classmethod
|
||||
def factory(cls, global_config, **local_config):
|
||||
"""Paste factory."""
|
||||
def _factory(app):
|
||||
return cls(app, **local_config)
|
||||
return _factory
|
||||
"""Extensions middleware for WSGI.
|
||||
|
||||
def _action_ext_resources(self, application, ext_mgr, mapper):
|
||||
"""Return a dict of ActionExtensionResource-s by collection."""
|
||||
action_resources = {}
|
||||
for action in ext_mgr.get_actions():
|
||||
if not action.collection in action_resources.keys():
|
||||
resource = ActionExtensionResource(application)
|
||||
mapper.connect("/:(project_id)/%s/:(id)/action.:(format)" %
|
||||
action.collection,
|
||||
action='action',
|
||||
controller=resource,
|
||||
conditions=dict(method=['POST']))
|
||||
mapper.connect("/:(project_id)/%s/:(id)/action" %
|
||||
action.collection,
|
||||
action='action',
|
||||
controller=resource,
|
||||
conditions=dict(method=['POST']))
|
||||
action_resources[action.collection] = resource
|
||||
Provided only for backwards compatibility with existing
|
||||
api-paste.ini files. This middleware will be removed in future
|
||||
versions of nova.
|
||||
"""
|
||||
|
||||
return action_resources
|
||||
|
||||
def _request_ext_resources(self, application, ext_mgr, mapper):
|
||||
"""Returns a dict of RequestExtensionResource-s by collection."""
|
||||
request_ext_resources = {}
|
||||
for req_ext in ext_mgr.get_request_extensions():
|
||||
if not req_ext.key in request_ext_resources.keys():
|
||||
resource = RequestExtensionResource(application)
|
||||
mapper.connect(req_ext.url_route + '.:(format)',
|
||||
action='process',
|
||||
controller=resource,
|
||||
conditions=req_ext.conditions)
|
||||
|
||||
mapper.connect(req_ext.url_route,
|
||||
action='process',
|
||||
controller=resource,
|
||||
conditions=req_ext.conditions)
|
||||
request_ext_resources[req_ext.key] = resource
|
||||
|
||||
return request_ext_resources
|
||||
|
||||
def __init__(self, application, ext_mgr=None):
|
||||
|
||||
if ext_mgr is None:
|
||||
ext_mgr = ExtensionManager()
|
||||
self.ext_mgr = ext_mgr
|
||||
|
||||
mapper = nova.api.openstack.ProjectMapper()
|
||||
|
||||
# extended actions
|
||||
action_resources = self._action_ext_resources(application, ext_mgr,
|
||||
mapper)
|
||||
for action in ext_mgr.get_actions():
|
||||
LOG.debug(_('Extended action: %s'), action.action_name)
|
||||
resource = action_resources[action.collection]
|
||||
resource.add_action(action.action_name, action.handler)
|
||||
|
||||
# extended requests
|
||||
req_controllers = self._request_ext_resources(application, ext_mgr,
|
||||
mapper)
|
||||
for request_ext in ext_mgr.get_request_extensions():
|
||||
LOG.debug(_('Extended request: %s'), request_ext.key)
|
||||
controller = req_controllers[request_ext.key]
|
||||
if request_ext.handler:
|
||||
controller.add_handler(request_ext.handler)
|
||||
if request_ext.pre_handler:
|
||||
controller.add_pre_handler(request_ext.pre_handler)
|
||||
|
||||
self._router = routes.middleware.RoutesMiddleware(self._dispatch,
|
||||
mapper)
|
||||
|
||||
super(ExtensionMiddleware, self).__init__(application)
|
||||
|
||||
@webob.dec.wsgify(RequestClass=wsgi.Request)
|
||||
def __call__(self, req):
|
||||
"""Route the incoming request with router."""
|
||||
req.environ['extended.app'] = self.application
|
||||
return self._router
|
||||
|
||||
@staticmethod
|
||||
@webob.dec.wsgify(RequestClass=wsgi.Request)
|
||||
def _dispatch(req):
|
||||
"""Dispatch the request.
|
||||
|
||||
Returns the routed WSGI app's response or defers to the extended
|
||||
application.
|
||||
|
||||
"""
|
||||
match = req.environ['wsgiorg.routing_args'][1]
|
||||
if not match:
|
||||
return req.environ['extended.app']
|
||||
app = match['controller']
|
||||
return app
|
||||
pass
|
||||
|
||||
|
||||
class ExtensionManager(object):
|
||||
@@ -391,12 +197,6 @@ class ExtensionManager(object):
|
||||
|
||||
"""
|
||||
|
||||
_ext_mgr = None
|
||||
|
||||
@classmethod
|
||||
def reset(cls):
|
||||
cls._ext_mgr = None
|
||||
|
||||
def register(self, ext):
|
||||
# Do nothing if the extension doesn't check out
|
||||
if not self._check_extension(ext):
|
||||
@@ -425,30 +225,6 @@ class ExtensionManager(object):
|
||||
pass
|
||||
return resources
|
||||
|
||||
def get_actions(self):
|
||||
"""Returns a list of ActionExtension objects."""
|
||||
actions = []
|
||||
for ext in self.extensions.values():
|
||||
try:
|
||||
actions.extend(ext.get_actions())
|
||||
except AttributeError:
|
||||
# NOTE(dprince): Extension aren't required to have action
|
||||
# extensions
|
||||
pass
|
||||
return actions
|
||||
|
||||
def get_request_extensions(self):
|
||||
"""Returns a list of RequestExtension objects."""
|
||||
request_exts = []
|
||||
for ext in self.extensions.values():
|
||||
try:
|
||||
request_exts.extend(ext.get_request_extensions())
|
||||
except AttributeError:
|
||||
# NOTE(dprince): Extension aren't required to have request
|
||||
# extensions
|
||||
pass
|
||||
return request_exts
|
||||
|
||||
def get_controller_extensions(self):
|
||||
"""Returns a list of ControllerExtension objects."""
|
||||
controller_exts = []
|
||||
@@ -525,32 +301,6 @@ class ControllerExtension(object):
|
||||
self.controller = controller
|
||||
|
||||
|
||||
@utils.deprecated("Superseded by ControllerExtension")
|
||||
class RequestExtension(object):
|
||||
"""Extend requests and responses of core nova OpenStack API resources.
|
||||
|
||||
Provide a way to add data to responses and handle custom request data
|
||||
that is sent to core nova OpenStack API controllers.
|
||||
|
||||
"""
|
||||
def __init__(self, method, url_route, handler=None, pre_handler=None):
|
||||
self.url_route = url_route
|
||||
self.handler = handler
|
||||
self.conditions = dict(method=[method])
|
||||
self.key = "%s-%s" % (method, url_route)
|
||||
self.pre_handler = pre_handler
|
||||
|
||||
|
||||
@utils.deprecated("Superseded by ControllerExtension")
|
||||
class ActionExtension(object):
|
||||
"""Add custom actions to core nova OpenStack API resources."""
|
||||
|
||||
def __init__(self, collection, action_name, handler):
|
||||
self.collection = collection
|
||||
self.action_name = action_name
|
||||
self.handler = handler
|
||||
|
||||
|
||||
class ResourceExtension(object):
|
||||
"""Add top level resources to the OpenStack API in nova."""
|
||||
|
||||
@@ -570,14 +320,6 @@ class ResourceExtension(object):
|
||||
self.serializer = serializer
|
||||
|
||||
|
||||
class ExtensionsXMLSerializer(xmlutil.XMLTemplateSerializer):
|
||||
def index(self):
|
||||
return ExtensionsTemplate()
|
||||
|
||||
def show(self):
|
||||
return ExtensionTemplate()
|
||||
|
||||
|
||||
def wrap_errors(fn):
|
||||
"""Ensure errors are not passed along."""
|
||||
def wrapped(*args, **kwargs):
|
||||
|
||||
@@ -62,8 +62,6 @@ class APIRouter(base_wsgi.Router):
|
||||
super(APIRouter, self).__init__(mapper)
|
||||
|
||||
def _setup_ext_routes(self, mapper, ext_mgr):
|
||||
serializer = wsgi.ResponseSerializer(
|
||||
{'application/xml': wsgi.XMLDictSerializer()})
|
||||
for resource in ext_mgr.get_resources():
|
||||
LOG.debug(_('Extended resource: %s'),
|
||||
resource.collection)
|
||||
|
||||
@@ -25,20 +25,20 @@ FLAGS = flags.FLAGS
|
||||
|
||||
|
||||
class ExtensionManager(base_extensions.ExtensionManager):
|
||||
def __new__(cls):
|
||||
if cls._ext_mgr is None:
|
||||
LOG.audit(_('Initializing extension manager.'))
|
||||
def __init__(self):
|
||||
LOG.audit(_('Initializing extension manager.'))
|
||||
|
||||
cls._ext_mgr = super(ExtensionManager, cls).__new__(cls)
|
||||
|
||||
cls.cls_list = FLAGS.osapi_volume_extension
|
||||
cls._ext_mgr.extensions = {}
|
||||
cls._ext_mgr._load_extensions()
|
||||
|
||||
return cls._ext_mgr
|
||||
self.cls_list = FLAGS.osapi_volume_extension
|
||||
self.extensions = {}
|
||||
self._load_extensions()
|
||||
|
||||
|
||||
class ExtensionMiddleware(base_extensions.ExtensionMiddleware):
|
||||
def __init__(self, application, ext_mgr=None):
|
||||
ext_mgr = ExtensionManager()
|
||||
super(ExtensionMiddleware, self).__init__(application, ext_mgr)
|
||||
"""Extensions middleware for WSGI.
|
||||
|
||||
Provided only for backwards compatibility with existing
|
||||
api-paste.ini files. This middleware will be removed in future
|
||||
versions of nova.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
@@ -57,6 +57,32 @@ def _translate_snapshot_summary_view(context, vol):
|
||||
return d
|
||||
|
||||
|
||||
def make_snapshot(elem):
|
||||
elem.set('id')
|
||||
elem.set('status')
|
||||
elem.set('size')
|
||||
elem.set('createdAt')
|
||||
elem.set('displayName')
|
||||
elem.set('displayDescription')
|
||||
elem.set('volumeId')
|
||||
|
||||
|
||||
class SnapshotTemplate(xmlutil.TemplateBuilder):
|
||||
def construct(self):
|
||||
root = xmlutil.TemplateElement('snapshot', selector='snapshot')
|
||||
make_snapshot(root)
|
||||
return xmlutil.MasterTemplate(root, 1)
|
||||
|
||||
|
||||
class SnapshotsTemplate(xmlutil.TemplateBuilder):
|
||||
def construct(self):
|
||||
root = xmlutil.TemplateElement('snapshots')
|
||||
elem = xmlutil.SubTemplateElement(root, 'snapshot',
|
||||
selector='snapshots')
|
||||
make_snapshot(elem)
|
||||
return xmlutil.MasterTemplate(root, 1)
|
||||
|
||||
|
||||
class SnapshotsController(object):
|
||||
"""The Volumes API controller for the OpenStack API."""
|
||||
|
||||
@@ -64,6 +90,7 @@ class SnapshotsController(object):
|
||||
self.volume_api = volume.API()
|
||||
super(SnapshotsController, self).__init__()
|
||||
|
||||
@wsgi.serializers(xml=SnapshotTemplate)
|
||||
def show(self, req, id):
|
||||
"""Return data about the given snapshot."""
|
||||
context = req.environ['nova.context']
|
||||
@@ -88,10 +115,12 @@ class SnapshotsController(object):
|
||||
return exc.HTTPNotFound()
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.serializers(xml=SnapshotsTemplate)
|
||||
def index(self, req):
|
||||
"""Returns a summary list of snapshots."""
|
||||
return self._items(req, entity_maker=_translate_snapshot_summary_view)
|
||||
|
||||
@wsgi.serializers(xml=SnapshotsTemplate)
|
||||
def detail(self, req):
|
||||
"""Returns a detailed list of snapshots."""
|
||||
return self._items(req, entity_maker=_translate_snapshot_detail_view)
|
||||
@@ -105,6 +134,7 @@ class SnapshotsController(object):
|
||||
res = [entity_maker(context, snapshot) for snapshot in limited_list]
|
||||
return {'snapshots': res}
|
||||
|
||||
@wsgi.serializers(xml=SnapshotTemplate)
|
||||
def create(self, req, body):
|
||||
"""Creates a new snapshot."""
|
||||
context = req.environ['nova.context']
|
||||
@@ -135,47 +165,5 @@ class SnapshotsController(object):
|
||||
return {'snapshot': retval}
|
||||
|
||||
|
||||
def make_snapshot(elem):
|
||||
elem.set('id')
|
||||
elem.set('status')
|
||||
elem.set('size')
|
||||
elem.set('createdAt')
|
||||
elem.set('displayName')
|
||||
elem.set('displayDescription')
|
||||
elem.set('volumeId')
|
||||
|
||||
|
||||
class SnapshotTemplate(xmlutil.TemplateBuilder):
|
||||
def construct(self):
|
||||
root = xmlutil.TemplateElement('snapshot', selector='snapshot')
|
||||
make_snapshot(root)
|
||||
return xmlutil.MasterTemplate(root, 1)
|
||||
|
||||
|
||||
class SnapshotsTemplate(xmlutil.TemplateBuilder):
|
||||
def construct(self):
|
||||
root = xmlutil.TemplateElement('snapshots')
|
||||
elem = xmlutil.SubTemplateElement(root, 'snapshot',
|
||||
selector='snapshots')
|
||||
make_snapshot(elem)
|
||||
return xmlutil.MasterTemplate(root, 1)
|
||||
|
||||
|
||||
class SnapshotSerializer(xmlutil.XMLTemplateSerializer):
|
||||
def default(self):
|
||||
return SnapshotTemplate()
|
||||
|
||||
def index(self):
|
||||
return SnapshotsTemplate()
|
||||
|
||||
def detail(self):
|
||||
return SnapshotsTemplate()
|
||||
|
||||
|
||||
def create_resource():
|
||||
body_serializers = {
|
||||
'application/xml': SnapshotSerializer(),
|
||||
}
|
||||
serializer = wsgi.ResponseSerializer(body_serializers)
|
||||
|
||||
return wsgi.Resource(SnapshotsController(), serializer=serializer)
|
||||
return wsgi.Resource(SnapshotsController())
|
||||
|
||||
@@ -25,26 +25,6 @@ from nova import exception
|
||||
from nova.volume import volume_types
|
||||
|
||||
|
||||
class VolumeTypesController(object):
|
||||
""" The volume types API controller for the Openstack API """
|
||||
|
||||
def index(self, req):
|
||||
""" Returns the list of volume types """
|
||||
context = req.environ['nova.context']
|
||||
return volume_types.get_all_types(context)
|
||||
|
||||
def show(self, req, id):
|
||||
""" Return a single volume type item """
|
||||
context = req.environ['nova.context']
|
||||
|
||||
try:
|
||||
vol_type = volume_types.get_volume_type(context, id)
|
||||
except exception.NotFound or exception.ApiError:
|
||||
raise exc.HTTPNotFound()
|
||||
|
||||
return {'volume_type': vol_type}
|
||||
|
||||
|
||||
def make_voltype(elem):
|
||||
elem.set('id')
|
||||
elem.set('name')
|
||||
@@ -68,20 +48,27 @@ class VolumeTypesTemplate(xmlutil.TemplateBuilder):
|
||||
return xmlutil.MasterTemplate(root, 1)
|
||||
|
||||
|
||||
class VolumeTypesSerializer(xmlutil.XMLTemplateSerializer):
|
||||
def index(self):
|
||||
return VolumeTypesTemplate()
|
||||
class VolumeTypesController(object):
|
||||
""" The volume types API controller for the Openstack API """
|
||||
|
||||
def default(self):
|
||||
return VolumeTypeTemplate()
|
||||
@wsgi.serializers(xml=VolumeTypesTemplate)
|
||||
def index(self, req):
|
||||
""" Returns the list of volume types """
|
||||
context = req.environ['nova.context']
|
||||
return volume_types.get_all_types(context)
|
||||
|
||||
@wsgi.serializers(xml=VolumeTypeTemplate)
|
||||
def show(self, req, id):
|
||||
""" Return a single volume type item """
|
||||
context = req.environ['nova.context']
|
||||
|
||||
try:
|
||||
vol_type = volume_types.get_volume_type(context, id)
|
||||
except exception.NotFound or exception.ApiError:
|
||||
raise exc.HTTPNotFound()
|
||||
|
||||
return {'volume_type': vol_type}
|
||||
|
||||
|
||||
def create_resource():
|
||||
body_serializers = {
|
||||
'application/xml': VolumeTypesSerializer(),
|
||||
}
|
||||
serializer = wsgi.ResponseSerializer(body_serializers)
|
||||
|
||||
deserializer = wsgi.RequestDeserializer()
|
||||
|
||||
return wsgi.Resource(VolumeTypesController(), serializer=serializer)
|
||||
return wsgi.Resource(VolumeTypesController())
|
||||
|
||||
@@ -109,6 +109,48 @@ def _translate_volume_summary_view(context, vol):
|
||||
return d
|
||||
|
||||
|
||||
def make_attachment(elem):
|
||||
elem.set('id')
|
||||
elem.set('serverId')
|
||||
elem.set('volumeId')
|
||||
elem.set('device')
|
||||
|
||||
|
||||
def make_volume(elem):
|
||||
elem.set('id')
|
||||
elem.set('status')
|
||||
elem.set('size')
|
||||
elem.set('availabilityZone')
|
||||
elem.set('createdAt')
|
||||
elem.set('displayName')
|
||||
elem.set('displayDescription')
|
||||
elem.set('volumeType')
|
||||
elem.set('snapshotId')
|
||||
|
||||
attachments = xmlutil.SubTemplateElement(elem, 'attachments')
|
||||
attachment = xmlutil.SubTemplateElement(attachments, 'attachment',
|
||||
selector='attachments')
|
||||
make_attachment(attachment)
|
||||
|
||||
metadata = xmlutil.make_flat_dict('metadata')
|
||||
elem.append(metadata)
|
||||
|
||||
|
||||
class VolumeTemplate(xmlutil.TemplateBuilder):
|
||||
def construct(self):
|
||||
root = xmlutil.TemplateElement('volume', selector='volume')
|
||||
make_volume(root)
|
||||
return xmlutil.MasterTemplate(root, 1)
|
||||
|
||||
|
||||
class VolumesTemplate(xmlutil.TemplateBuilder):
|
||||
def construct(self):
|
||||
root = xmlutil.TemplateElement('volumes')
|
||||
elem = xmlutil.SubTemplateElement(root, 'volume', selector='volumes')
|
||||
make_volume(elem)
|
||||
return xmlutil.MasterTemplate(root, 1)
|
||||
|
||||
|
||||
class VolumeController(object):
|
||||
"""The Volumes API controller for the OpenStack API."""
|
||||
|
||||
@@ -116,6 +158,7 @@ class VolumeController(object):
|
||||
self.volume_api = volume.API()
|
||||
super(VolumeController, self).__init__()
|
||||
|
||||
@wsgi.serializers(xml=VolumeTemplate)
|
||||
def show(self, req, id):
|
||||
"""Return data about the given volume."""
|
||||
context = req.environ['nova.context']
|
||||
@@ -140,10 +183,12 @@ class VolumeController(object):
|
||||
raise exc.HTTPNotFound()
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.serializers(xml=VolumesTemplate)
|
||||
def index(self, req):
|
||||
"""Returns a summary list of volumes."""
|
||||
return self._items(req, entity_maker=_translate_volume_summary_view)
|
||||
|
||||
@wsgi.serializers(xml=VolumesTemplate)
|
||||
def detail(self, req):
|
||||
"""Returns a detailed list of volumes."""
|
||||
return self._items(req, entity_maker=_translate_volume_detail_view)
|
||||
@@ -157,6 +202,7 @@ class VolumeController(object):
|
||||
res = [entity_maker(context, vol) for vol in limited_list]
|
||||
return {'volumes': res}
|
||||
|
||||
@wsgi.serializers(xml=VolumeTemplate)
|
||||
def create(self, req, body):
|
||||
"""Creates a new volume."""
|
||||
context = req.environ['nova.context']
|
||||
@@ -201,90 +247,5 @@ class VolumeController(object):
|
||||
return {'volume': retval}
|
||||
|
||||
|
||||
class VolumeAttachmentTemplate(xmlutil.TemplateBuilder):
|
||||
def construct(self):
|
||||
root = xmlutil.TemplateElement('volumeAttachment',
|
||||
selector='volumeAttachment')
|
||||
make_attachment(root)
|
||||
return xmlutil.MasterTemplate(root, 1)
|
||||
|
||||
|
||||
class VolumeAttachmentsTemplate(xmlutil.TemplateBuilder):
|
||||
def construct(self):
|
||||
root = xmlutil.TemplateElement('volumeAttachments')
|
||||
elem = xmlutil.SubTemplateElement(root, 'volumeAttachment',
|
||||
selector='volumeAttachments')
|
||||
make_attachment(elem)
|
||||
return xmlutil.MasterTemplate(root, 1)
|
||||
|
||||
|
||||
class VolumeAttachmentSerializer(xmlutil.XMLTemplateSerializer):
|
||||
def default(self):
|
||||
return VolumeAttachmentTemplate()
|
||||
|
||||
def index(self):
|
||||
return VolumeAttachmentsTemplate()
|
||||
|
||||
|
||||
def make_attachment(elem):
|
||||
elem.set('id')
|
||||
elem.set('serverId')
|
||||
elem.set('volumeId')
|
||||
elem.set('device')
|
||||
|
||||
|
||||
def make_volume(elem):
|
||||
elem.set('id')
|
||||
elem.set('status')
|
||||
elem.set('size')
|
||||
elem.set('availabilityZone')
|
||||
elem.set('createdAt')
|
||||
elem.set('displayName')
|
||||
elem.set('displayDescription')
|
||||
elem.set('volumeType')
|
||||
elem.set('snapshotId')
|
||||
|
||||
attachments = xmlutil.SubTemplateElement(elem, 'attachments')
|
||||
attachment = xmlutil.SubTemplateElement(attachments, 'attachment',
|
||||
selector='attachments')
|
||||
make_attachment(attachment)
|
||||
|
||||
metadata = xmlutil.make_flat_dict('metadata')
|
||||
elem.append(metadata)
|
||||
|
||||
|
||||
class VolumeTemplate(xmlutil.TemplateBuilder):
|
||||
def construct(self):
|
||||
root = xmlutil.TemplateElement('volume', selector='volume')
|
||||
make_volume(root)
|
||||
return xmlutil.MasterTemplate(root, 1)
|
||||
|
||||
|
||||
class VolumesTemplate(xmlutil.TemplateBuilder):
|
||||
def construct(self):
|
||||
root = xmlutil.TemplateElement('volumes')
|
||||
elem = xmlutil.SubTemplateElement(root, 'volume', selector='volumes')
|
||||
make_volume(elem)
|
||||
return xmlutil.MasterTemplate(root, 1)
|
||||
|
||||
|
||||
class VolumeSerializer(xmlutil.XMLTemplateSerializer):
|
||||
def default(self):
|
||||
return VolumeTemplate()
|
||||
|
||||
def index(self):
|
||||
return VolumesTemplate()
|
||||
|
||||
def detail(self):
|
||||
return VolumesTemplate()
|
||||
|
||||
|
||||
def create_resource():
|
||||
body_serializers = {
|
||||
'application/xml': VolumeSerializer(),
|
||||
}
|
||||
serializer = wsgi.ResponseSerializer(body_serializers)
|
||||
|
||||
deserializer = wsgi.RequestDeserializer()
|
||||
|
||||
return wsgi.Resource(VolumeController(), serializer=serializer)
|
||||
return wsgi.Resource(VolumeController())
|
||||
|
||||
@@ -216,104 +216,6 @@ class MetadataXMLDeserializer(XMLDeserializer):
|
||||
return metadata
|
||||
|
||||
|
||||
class RequestHeadersDeserializer(ActionDispatcher):
|
||||
"""Default request headers deserializer"""
|
||||
|
||||
def deserialize(self, request, action):
|
||||
return self.dispatch(request, action=action)
|
||||
|
||||
def default(self, request):
|
||||
return {}
|
||||
|
||||
|
||||
class RequestDeserializer(object):
|
||||
"""Break up a Request object into more useful pieces."""
|
||||
|
||||
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.headers_deserializer = headers_deserializer or \
|
||||
RequestHeadersDeserializer()
|
||||
|
||||
def deserialize(self, request):
|
||||
"""Extract necessary pieces of the request.
|
||||
|
||||
:param request: Request object
|
||||
:returns tuple of expected controller action name, dictionary of
|
||||
keyword arguments to pass to the controller, the expected
|
||||
content type of the response
|
||||
|
||||
"""
|
||||
action_args = self.get_action_args(request.environ)
|
||||
action = action_args.pop('action', 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 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()
|
||||
except exception.InvalidContentType:
|
||||
LOG.debug(_("Unrecognized Content-Type provided in request"))
|
||||
return {}
|
||||
|
||||
if content_type is None:
|
||||
LOG.debug(_("No Content-Type provided in request"))
|
||||
return {}
|
||||
|
||||
if not len(request.body) > 0:
|
||||
LOG.debug(_("Empty body provided in request"))
|
||||
return {}
|
||||
|
||||
try:
|
||||
deserializer = self.get_body_deserializer(content_type)
|
||||
except exception.InvalidContentType:
|
||||
LOG.debug(_("Unable to deserialize body as provided Content-Type"))
|
||||
raise
|
||||
|
||||
return deserializer.deserialize(request.body, action)
|
||||
|
||||
def get_body_deserializer(self, content_type):
|
||||
try:
|
||||
ctype = _CONTENT_TYPE_MAP.get(content_type, content_type)
|
||||
return self.body_deserializers[ctype]
|
||||
except (KeyError, TypeError):
|
||||
raise exception.InvalidContentType(content_type=content_type)
|
||||
|
||||
def get_expected_content_type(self, request):
|
||||
return request.best_match_content_type()
|
||||
|
||||
def get_action_args(self, request_environment):
|
||||
"""Parse dictionary created by routes library."""
|
||||
try:
|
||||
args = request_environment['wsgiorg.routing_args'][1].copy()
|
||||
except Exception:
|
||||
return {}
|
||||
|
||||
try:
|
||||
del args['controller']
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
del args['format']
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
return args
|
||||
|
||||
|
||||
class DictSerializer(ActionDispatcher):
|
||||
"""Default request body serialization"""
|
||||
|
||||
@@ -435,104 +337,16 @@ class XMLDictSerializer(DictSerializer):
|
||||
return etree.tostring(root, encoding='UTF-8', xml_declaration=True)
|
||||
|
||||
|
||||
class ResponseHeadersSerializer(ActionDispatcher):
|
||||
"""Default response headers serialization"""
|
||||
|
||||
def serialize(self, response, data, action):
|
||||
self.dispatch(response, data, action=action)
|
||||
context = response.request.environ.get('nova.context')
|
||||
if context:
|
||||
response.headers['X-Compute-Request-Id'] = context.request_id
|
||||
|
||||
def default(self, response, data):
|
||||
response.status_int = 200
|
||||
|
||||
|
||||
class ResponseSerializer(object):
|
||||
"""Encode the necessary pieces into a response object"""
|
||||
|
||||
def __init__(self, body_serializers=None, headers_serializer=None):
|
||||
self.body_serializers = {
|
||||
'application/xml': XMLDictSerializer(),
|
||||
'application/json': JSONDictSerializer(),
|
||||
}
|
||||
self.body_serializers.update(body_serializers or {})
|
||||
|
||||
self.headers_serializer = headers_serializer or \
|
||||
ResponseHeadersSerializer()
|
||||
|
||||
def serialize(self, request, response_data, content_type,
|
||||
action='default'):
|
||||
"""Serialize a dict into a string and wrap in a wsgi.Request object.
|
||||
|
||||
:param response_data: dict produced by the Controller
|
||||
:param content_type: expected mimetype of serialized response body
|
||||
|
||||
"""
|
||||
response = webob.Response(request=request)
|
||||
self.serialize_headers(response, response_data, action)
|
||||
self.serialize_body(request, response, response_data, content_type,
|
||||
action)
|
||||
return response
|
||||
|
||||
def serialize_headers(self, response, data, action):
|
||||
self.headers_serializer.serialize(response, data, action)
|
||||
|
||||
def serialize_body(self, request, response, data, content_type, action):
|
||||
response.headers['Content-Type'] = content_type
|
||||
if data is not None:
|
||||
serializer = self.get_body_serializer(content_type)
|
||||
lazy_serialize = request.environ.get('nova.lazy_serialize', False)
|
||||
if lazy_serialize:
|
||||
response.body = utils.dumps(data)
|
||||
request.environ['nova.serializer'] = serializer
|
||||
request.environ['nova.action'] = action
|
||||
if (hasattr(serializer, 'get_template') and
|
||||
'nova.template' not in request.environ):
|
||||
|
||||
template = serializer.get_template(action)
|
||||
request.environ['nova.template'] = template
|
||||
else:
|
||||
response.body = serializer.serialize(data, action)
|
||||
|
||||
def get_body_serializer(self, content_type):
|
||||
try:
|
||||
ctype = _CONTENT_TYPE_MAP.get(content_type, content_type)
|
||||
return self.body_serializers[ctype]
|
||||
except (KeyError, TypeError):
|
||||
raise exception.InvalidContentType(content_type=content_type)
|
||||
|
||||
|
||||
@utils.deprecated("The lazy serialization middleware is no longer necessary.")
|
||||
class LazySerializationMiddleware(wsgi.Middleware):
|
||||
"""Lazy serialization middleware."""
|
||||
@webob.dec.wsgify(RequestClass=Request)
|
||||
def __call__(self, req):
|
||||
# Request lazy serialization
|
||||
req.environ['nova.lazy_serialize'] = True
|
||||
"""Lazy serialization middleware.
|
||||
|
||||
response = req.get_response(self.application)
|
||||
Provided only for backwards compatibility with existing
|
||||
api-paste.ini files. This middleware will be removed in future
|
||||
versions of nova.
|
||||
"""
|
||||
|
||||
# See if we're using the simple serialization driver
|
||||
simple_serial = req.environ.get('nova.simple_serial')
|
||||
if simple_serial is not None:
|
||||
body_obj = utils.loads(response.body)
|
||||
response.body = simple_serial.serialize(body_obj)
|
||||
return response
|
||||
|
||||
# See if there's a serializer...
|
||||
serializer = req.environ.get('nova.serializer')
|
||||
if serializer is None:
|
||||
return response
|
||||
|
||||
# OK, build up the arguments for the serialize() method
|
||||
kwargs = dict(action=req.environ['nova.action'])
|
||||
if 'nova.template' in req.environ:
|
||||
kwargs['template'] = req.environ['nova.template']
|
||||
|
||||
# Re-serialize the body
|
||||
response.body = serializer.serialize(utils.loads(response.body),
|
||||
**kwargs)
|
||||
return response
|
||||
pass
|
||||
|
||||
|
||||
def serializers(**serializers):
|
||||
@@ -698,20 +512,7 @@ class ResponseObject(object):
|
||||
response.headers[hdr] = value
|
||||
response.headers['Content-Type'] = content_type
|
||||
if self.obj is not None:
|
||||
# TODO(Vek): When lazy serialization is retired, so can
|
||||
# this inner 'if'...
|
||||
lazy_serialize = request.environ.get('nova.lazy_serialize', False)
|
||||
if lazy_serialize:
|
||||
response.body = utils.dumps(self.obj)
|
||||
request.environ['nova.simple_serial'] = serializer
|
||||
# NOTE(Vek): Temporary ugly hack to support xml
|
||||
# templates in extensions, until we can
|
||||
# fold extensions into Resource and do away
|
||||
# with lazy serialization...
|
||||
if _MEDIA_TYPE_MAP.get(content_type) == 'xml':
|
||||
request.environ['nova.template'] = serializer
|
||||
else:
|
||||
response.body = serializer.serialize(self.obj)
|
||||
response.body = serializer.serialize(self.obj)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
@@ -858,48 +858,6 @@ class TemplateBuilder(object):
|
||||
raise NotImplementedError(_("subclasses must implement construct()!"))
|
||||
|
||||
|
||||
class XMLTemplateSerializer(wsgi.ActionDispatcher):
|
||||
"""Template-based XML serializer.
|
||||
|
||||
Data serializer that uses templates to perform its serialization.
|
||||
"""
|
||||
|
||||
def get_template(self, action='default'):
|
||||
"""Retrieve the template to use for serialization."""
|
||||
|
||||
return self.dispatch(action=action)
|
||||
|
||||
def serialize(self, data, action='default', template=None):
|
||||
"""Serialize data.
|
||||
|
||||
:param data: The data to serialize.
|
||||
:param action: The action, for identifying the template to
|
||||
use. If no template is provided,
|
||||
get_template() will be called with this action
|
||||
to retrieve the template.
|
||||
:param template: The template to use in serialization.
|
||||
"""
|
||||
|
||||
# No template provided, look one up
|
||||
if template is None:
|
||||
template = self.get_template(action)
|
||||
|
||||
# Still couldn't find a template; try the base
|
||||
# XMLDictSerializer
|
||||
if template is None:
|
||||
serial = wsgi.XMLDictSerializer()
|
||||
return serial.serialize(data, action=action)
|
||||
|
||||
# Serialize the template
|
||||
return template.serialize(data, encoding='UTF-8',
|
||||
xml_declaration=True)
|
||||
|
||||
def default(self):
|
||||
"""Retrieve the default template to use."""
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def make_links(parent, selector=None):
|
||||
"""
|
||||
Attach an Atom <links> element to the parent.
|
||||
|
||||
@@ -123,9 +123,7 @@ class CreateBackupTests(test.TestCase):
|
||||
self.backup_stubs = fakes.stub_out_compute_api_backup(self.stubs)
|
||||
|
||||
self.flags(allow_admin_api=True)
|
||||
router = compute_api.APIRouter()
|
||||
ext_middleware = extensions.ExtensionMiddleware(router)
|
||||
self.app = wsgi.LazySerializationMiddleware(ext_middleware)
|
||||
self.app = compute_api.APIRouter()
|
||||
|
||||
self.uuid = utils.gen_uuid()
|
||||
|
||||
|
||||
@@ -120,10 +120,7 @@ class DiskConfigTestCase(test.TestCase):
|
||||
|
||||
self.stubs.Set(nova.db, 'instance_create', fake_instance_create)
|
||||
|
||||
app = compute.APIRouter()
|
||||
app = extensions.ExtensionMiddleware(app)
|
||||
app = wsgi.LazySerializationMiddleware(app)
|
||||
self.app = app
|
||||
self.app = compute.APIRouter()
|
||||
|
||||
def assertDiskConfig(self, dict_, value):
|
||||
self.assert_(API_DISK_CONFIG in dict_)
|
||||
|
||||
@@ -56,12 +56,12 @@ class FloatingIpPoolTest(test.TestCase):
|
||||
|
||||
class FloatingIpPoolSerializerTest(test.TestCase):
|
||||
def test_index_serializer(self):
|
||||
serializer = floating_ip_pools.FloatingIPPoolsSerializer()
|
||||
serializer = floating_ip_pools.FloatingIPPoolsTemplate()
|
||||
text = serializer.serialize(dict(
|
||||
floating_ip_pools=[
|
||||
dict(name='nova'),
|
||||
dict(name='other')
|
||||
]), 'index')
|
||||
]))
|
||||
|
||||
tree = etree.fromstring(text)
|
||||
|
||||
|
||||
@@ -54,13 +54,11 @@ class ServerActionsTest(test.TestCase):
|
||||
self.compute_api = nova.compute.API()
|
||||
|
||||
self.router = compute.APIRouter()
|
||||
ext_middleware = extensions.ExtensionMiddleware(self.router)
|
||||
self.app = wsgi.LazySerializationMiddleware(ext_middleware)
|
||||
|
||||
def test_get_actions(self):
|
||||
uuid = nova.utils.gen_uuid()
|
||||
req = fakes.HTTPRequest.blank('/fake/servers/%s/actions' % uuid)
|
||||
res = req.get_response(self.app)
|
||||
res = req.get_response(self.router)
|
||||
output = json.loads(res.body)
|
||||
expected = {'actions': [
|
||||
{'action': 'rebuild', 'error': None, 'created_at': str(dt)},
|
||||
|
||||
@@ -48,13 +48,11 @@ class ServerDiagnosticsTest(test.TestCase):
|
||||
self.compute_api = nova.compute.API()
|
||||
|
||||
self.router = compute.APIRouter()
|
||||
ext_middleware = extensions.ExtensionMiddleware(self.router)
|
||||
self.app = wsgi.LazySerializationMiddleware(ext_middleware)
|
||||
|
||||
def test_get_diagnostics(self):
|
||||
uuid = nova.utils.gen_uuid()
|
||||
req = fakes.HTTPRequest.blank('/fake/servers/%s/diagnostics' % uuid)
|
||||
res = req.get_response(self.app)
|
||||
res = req.get_response(self.router)
|
||||
output = json.loads(res.body)
|
||||
self.assertEqual(output, {'data': 'Some diagnostic info'})
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
import webob.exc
|
||||
|
||||
from nova.api.openstack import extensions
|
||||
from nova.api.openstack import wsgi
|
||||
|
||||
|
||||
class FoxInSocksController(object):
|
||||
@@ -26,6 +27,39 @@ class FoxInSocksController(object):
|
||||
return "Try to say this Mr. Knox, sir..."
|
||||
|
||||
|
||||
class FoxInSocksServerControllerExtension(wsgi.Controller):
|
||||
@wsgi.action('add_tweedle')
|
||||
def _add_tweedle(self, req, id, body):
|
||||
|
||||
return "Tweedle Beetle Added."
|
||||
|
||||
@wsgi.action('delete_tweedle')
|
||||
def _delete_tweedle(self, req, id, body):
|
||||
|
||||
return "Tweedle Beetle Deleted."
|
||||
|
||||
@wsgi.action('fail')
|
||||
def _fail(self, req, id, body):
|
||||
|
||||
raise webob.exc.HTTPBadRequest(explanation='Tweedle fail')
|
||||
|
||||
|
||||
class FoxInSocksFlavorGooseControllerExtension(wsgi.Controller):
|
||||
@wsgi.extends
|
||||
def show(self, req, resp_obj, id):
|
||||
#NOTE: This only handles JSON responses.
|
||||
# You can use content type header to test for XML.
|
||||
resp_obj.obj['flavor']['googoose'] = req.GET.get('chewing')
|
||||
|
||||
|
||||
class FoxInSocksFlavorBandsControllerExtension(wsgi.Controller):
|
||||
@wsgi.extends
|
||||
def show(self, req, resp_obj, id):
|
||||
#NOTE: This only handles JSON responses.
|
||||
# You can use content type header to test for XML.
|
||||
resp_obj.obj['big_bands'] = 'Pig Bands!'
|
||||
|
||||
|
||||
class Foxinsocks(extensions.ExtensionDescriptor):
|
||||
"""The Fox In Socks Extension"""
|
||||
|
||||
@@ -44,50 +78,17 @@ class Foxinsocks(extensions.ExtensionDescriptor):
|
||||
resources.append(resource)
|
||||
return resources
|
||||
|
||||
def get_actions(self):
|
||||
actions = []
|
||||
actions.append(extensions.ActionExtension('servers', 'add_tweedle',
|
||||
self._add_tweedle))
|
||||
actions.append(extensions.ActionExtension('servers', 'delete_tweedle',
|
||||
self._delete_tweedle))
|
||||
actions.append(extensions.ActionExtension('servers', 'fail',
|
||||
self._fail))
|
||||
return actions
|
||||
def get_controller_extensions(self):
|
||||
extension_list = []
|
||||
|
||||
def get_request_extensions(self):
|
||||
request_exts = []
|
||||
extension_set = [
|
||||
(FoxInSocksServerControllerExtension, 'servers'),
|
||||
(FoxInSocksFlavorGooseControllerExtension, 'flavors'),
|
||||
(FoxInSocksFlavorBandsControllerExtension, 'flavors'),
|
||||
]
|
||||
for klass, collection in extension_set:
|
||||
controller = klass()
|
||||
ext = extensions.ControllerExtension(self, collection, controller)
|
||||
extension_list.append(ext)
|
||||
|
||||
def _goose_handler(req, res, body):
|
||||
#NOTE: This only handles JSON responses.
|
||||
# You can use content type header to test for XML.
|
||||
body['flavor']['googoose'] = req.GET.get('chewing')
|
||||
return res
|
||||
|
||||
req_ext1 = extensions.RequestExtension('GET',
|
||||
'/v2/:(project_id)/flavors/:(id)',
|
||||
_goose_handler)
|
||||
request_exts.append(req_ext1)
|
||||
|
||||
def _bands_handler(req, res, body):
|
||||
#NOTE: This only handles JSON responses.
|
||||
# You can use content type header to test for XML.
|
||||
body['big_bands'] = 'Pig Bands!'
|
||||
return res
|
||||
|
||||
req_ext2 = extensions.RequestExtension('GET',
|
||||
'/v2/:(project_id)/flavors/:(id)',
|
||||
_bands_handler)
|
||||
request_exts.append(req_ext2)
|
||||
return request_exts
|
||||
|
||||
def _add_tweedle(self, input_dict, req, id):
|
||||
|
||||
return "Tweedle Beetle Added."
|
||||
|
||||
def _delete_tweedle(self, input_dict, req, id):
|
||||
|
||||
return "Tweedle Beetle Deleted."
|
||||
|
||||
def _fail(self, input_dict, req, id):
|
||||
|
||||
raise webob.exc.HTTPBadRequest(explanation='Tweedle fail')
|
||||
return extension_list
|
||||
|
||||
@@ -144,7 +144,6 @@ class ExtensionTestCase(test.TestCase):
|
||||
if fox not in ext_list:
|
||||
ext_list.append(fox)
|
||||
self.flags(osapi_compute_extension=ext_list)
|
||||
compute_extensions.ExtensionManager.reset()
|
||||
|
||||
|
||||
class ExtensionControllerTest(ExtensionTestCase):
|
||||
@@ -190,10 +189,8 @@ class ExtensionControllerTest(ExtensionTestCase):
|
||||
|
||||
def test_list_extensions_json(self):
|
||||
app = compute.APIRouter()
|
||||
ext_midware = compute_extensions.ExtensionMiddleware(app)
|
||||
ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
|
||||
request = webob.Request.blank("/fake/extensions")
|
||||
response = request.get_response(ser_midware)
|
||||
response = request.get_response(app)
|
||||
self.assertEqual(200, response.status_int)
|
||||
|
||||
# Make sure we have all the extensions.
|
||||
@@ -219,10 +216,8 @@ class ExtensionControllerTest(ExtensionTestCase):
|
||||
|
||||
def test_get_extension_json(self):
|
||||
app = compute.APIRouter()
|
||||
ext_midware = compute_extensions.ExtensionMiddleware(app)
|
||||
ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
|
||||
request = webob.Request.blank("/fake/extensions/FOXNSOX")
|
||||
response = request.get_response(ser_midware)
|
||||
response = request.get_response(app)
|
||||
self.assertEqual(200, response.status_int)
|
||||
|
||||
data = json.loads(response.body)
|
||||
@@ -236,18 +231,15 @@ class ExtensionControllerTest(ExtensionTestCase):
|
||||
|
||||
def test_get_non_existing_extension_json(self):
|
||||
app = compute.APIRouter()
|
||||
ext_midware = compute_extensions.ExtensionMiddleware(app)
|
||||
request = webob.Request.blank("/fake/extensions/4")
|
||||
response = request.get_response(ext_midware)
|
||||
response = request.get_response(app)
|
||||
self.assertEqual(404, response.status_int)
|
||||
|
||||
def test_list_extensions_xml(self):
|
||||
app = compute.APIRouter()
|
||||
ext_midware = compute_extensions.ExtensionMiddleware(app)
|
||||
ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
|
||||
request = webob.Request.blank("/fake/extensions")
|
||||
request.accept = "application/xml"
|
||||
response = request.get_response(ser_midware)
|
||||
response = request.get_response(app)
|
||||
self.assertEqual(200, response.status_int)
|
||||
print response.body
|
||||
|
||||
@@ -271,11 +263,9 @@ class ExtensionControllerTest(ExtensionTestCase):
|
||||
|
||||
def test_get_extension_xml(self):
|
||||
app = compute.APIRouter()
|
||||
ext_midware = compute_extensions.ExtensionMiddleware(app)
|
||||
ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
|
||||
request = webob.Request.blank("/fake/extensions/FOXNSOX")
|
||||
request.accept = "application/xml"
|
||||
response = request.get_response(ser_midware)
|
||||
response = request.get_response(app)
|
||||
self.assertEqual(200, response.status_int)
|
||||
xml = response.body
|
||||
print xml
|
||||
@@ -298,10 +288,8 @@ class ResourceExtensionTest(ExtensionTestCase):
|
||||
def test_no_extension_present(self):
|
||||
manager = StubExtensionManager(None)
|
||||
app = compute.APIRouter(manager)
|
||||
ext_midware = compute_extensions.ExtensionMiddleware(app, manager)
|
||||
ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
|
||||
request = webob.Request.blank("/blah")
|
||||
response = request.get_response(ser_midware)
|
||||
response = request.get_response(app)
|
||||
self.assertEqual(404, response.status_int)
|
||||
|
||||
def test_get_resources(self):
|
||||
@@ -309,10 +297,8 @@ class ResourceExtensionTest(ExtensionTestCase):
|
||||
StubController(response_body))
|
||||
manager = StubExtensionManager(res_ext)
|
||||
app = compute.APIRouter(manager)
|
||||
ext_midware = compute_extensions.ExtensionMiddleware(app, manager)
|
||||
ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
|
||||
request = webob.Request.blank("/fake/tweedles")
|
||||
response = request.get_response(ser_midware)
|
||||
response = request.get_response(app)
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual(response_body, response.body)
|
||||
|
||||
@@ -321,10 +307,8 @@ class ResourceExtensionTest(ExtensionTestCase):
|
||||
StubController(response_body))
|
||||
manager = StubExtensionManager(res_ext)
|
||||
app = compute.APIRouter(manager)
|
||||
ext_midware = compute_extensions.ExtensionMiddleware(app, manager)
|
||||
ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
|
||||
request = webob.Request.blank("/fake/tweedles")
|
||||
response = request.get_response(ser_midware)
|
||||
response = request.get_response(app)
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual(response_body, response.body)
|
||||
|
||||
@@ -333,11 +317,9 @@ class ResourceExtensionTest(ExtensionTestCase):
|
||||
StubController(response_body))
|
||||
manager = StubExtensionManager(res_ext)
|
||||
app = compute.APIRouter(manager)
|
||||
ext_midware = compute_extensions.ExtensionMiddleware(app, manager)
|
||||
ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
|
||||
request = webob.Request.blank("/fake/tweedles")
|
||||
request.method = "POST"
|
||||
response = request.get_response(ser_midware)
|
||||
response = request.get_response(app)
|
||||
self.assertEqual(400, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
body = json.loads(response.body)
|
||||
@@ -354,10 +336,8 @@ class ResourceExtensionTest(ExtensionTestCase):
|
||||
StubController(response_body))
|
||||
manager = StubExtensionManager(res_ext)
|
||||
app = compute.APIRouter(manager)
|
||||
ext_midware = compute_extensions.ExtensionMiddleware(app, manager)
|
||||
ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
|
||||
request = webob.Request.blank("/fake/tweedles/1")
|
||||
response = request.get_response(ser_midware)
|
||||
response = request.get_response(app)
|
||||
self.assertEqual(404, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
body = json.loads(response.body)
|
||||
@@ -394,10 +374,8 @@ class ExtensionManagerTest(ExtensionTestCase):
|
||||
|
||||
def test_get_resources(self):
|
||||
app = compute.APIRouter()
|
||||
ext_midware = compute_extensions.ExtensionMiddleware(app)
|
||||
ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
|
||||
request = webob.Request.blank("/fake/foxnsocks")
|
||||
response = request.get_response(ser_midware)
|
||||
response = request.get_response(app)
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual(response_body, response.body)
|
||||
|
||||
@@ -405,8 +383,7 @@ class ExtensionManagerTest(ExtensionTestCase):
|
||||
# Don't need the serialization middleware here because we're
|
||||
# not testing any serialization
|
||||
app = compute.APIRouter()
|
||||
ext_midware = compute_extensions.ExtensionMiddleware(app)
|
||||
ext_mgr = ext_midware.ext_mgr
|
||||
ext_mgr = compute_extensions.ExtensionManager()
|
||||
ext_mgr.register(InvalidExtension())
|
||||
self.assertTrue('FOXNSOX' in ext_mgr.extensions)
|
||||
self.assertTrue('THIRD' not in ext_mgr.extensions)
|
||||
@@ -414,8 +391,7 @@ class ExtensionManagerTest(ExtensionTestCase):
|
||||
def test_admin_extensions(self):
|
||||
self.flags(allow_admin_api=True)
|
||||
app = compute.APIRouter()
|
||||
ext_midware = compute_extensions.ExtensionMiddleware(app)
|
||||
ext_mgr = ext_midware.ext_mgr
|
||||
ext_mgr = compute_extensions.ExtensionManager()
|
||||
ext_mgr.register(AdminExtension())
|
||||
self.assertTrue('FOXNSOX' in ext_mgr.extensions)
|
||||
self.assertTrue('ADMIN' in ext_mgr.extensions)
|
||||
@@ -423,8 +399,7 @@ class ExtensionManagerTest(ExtensionTestCase):
|
||||
def test_admin_extensions_no_admin_api(self):
|
||||
self.flags(allow_admin_api=False)
|
||||
app = compute.APIRouter()
|
||||
ext_midware = compute_extensions.ExtensionMiddleware(app)
|
||||
ext_mgr = ext_midware.ext_mgr
|
||||
ext_mgr = compute_extensions.ExtensionManager()
|
||||
ext_mgr.register(AdminExtension())
|
||||
self.assertTrue('FOXNSOX' in ext_mgr.extensions)
|
||||
self.assertTrue('ADMIN' not in ext_mgr.extensions)
|
||||
@@ -434,13 +409,11 @@ class ActionExtensionTest(ExtensionTestCase):
|
||||
|
||||
def _send_server_action_request(self, url, body):
|
||||
app = compute.APIRouter()
|
||||
ext_midware = compute_extensions.ExtensionMiddleware(app)
|
||||
ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
|
||||
request = webob.Request.blank(url)
|
||||
request.method = 'POST'
|
||||
request.content_type = 'application/json'
|
||||
request.body = json.dumps(body)
|
||||
response = request.get_response(ser_midware)
|
||||
response = request.get_response(app)
|
||||
return response
|
||||
|
||||
def test_extended_action(self):
|
||||
@@ -495,35 +468,30 @@ class ActionExtensionTest(ExtensionTestCase):
|
||||
class RequestExtensionTest(ExtensionTestCase):
|
||||
|
||||
def test_get_resources_with_stub_mgr(self):
|
||||
class GooGoose(wsgi.Controller):
|
||||
@wsgi.extends
|
||||
def show(self, req, resp_obj, id):
|
||||
# only handle JSON responses
|
||||
resp_obj.obj['flavor']['googoose'] = req.GET.get('chewing')
|
||||
|
||||
def _req_handler(req, res, body):
|
||||
# only handle JSON responses
|
||||
body['flavor']['googoose'] = req.GET.get('chewing')
|
||||
return res
|
||||
req_ext = base_extensions.ControllerExtension(
|
||||
StubControllerExtension(), 'flavors', GooGoose())
|
||||
|
||||
req_ext = base_extensions.RequestExtension('GET',
|
||||
'/v2/fake/flavors/:(id)',
|
||||
_req_handler)
|
||||
|
||||
manager = StubExtensionManager(None, None, req_ext)
|
||||
app = fakes.wsgi_app(serialization=base_wsgi.Middleware)
|
||||
ext_midware = compute_extensions.ExtensionMiddleware(app, manager)
|
||||
ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
|
||||
manager = StubExtensionManager(None, None, None, req_ext)
|
||||
app = fakes.wsgi_app(ext_mgr=manager)
|
||||
request = webob.Request.blank("/v2/fake/flavors/1?chewing=bluegoo")
|
||||
request.environ['api.version'] = '2'
|
||||
response = request.get_response(ser_midware)
|
||||
response = request.get_response(app)
|
||||
self.assertEqual(200, response.status_int)
|
||||
response_data = json.loads(response.body)
|
||||
self.assertEqual('bluegoo', response_data['flavor']['googoose'])
|
||||
|
||||
def test_get_resources_with_mgr(self):
|
||||
|
||||
app = fakes.wsgi_app(serialization=base_wsgi.Middleware)
|
||||
ext_midware = compute_extensions.ExtensionMiddleware(app)
|
||||
ser_midware = wsgi.LazySerializationMiddleware(ext_midware)
|
||||
app = fakes.wsgi_app()
|
||||
request = webob.Request.blank("/v2/fake/flavors/1?chewing=newblue")
|
||||
request.environ['api.version'] = '2'
|
||||
response = request.get_response(ser_midware)
|
||||
response = request.get_response(app)
|
||||
self.assertEqual(200, response.status_int)
|
||||
response_data = json.loads(response.body)
|
||||
print response_data
|
||||
@@ -612,7 +580,7 @@ class ControllerExtensionTest(ExtensionTestCase):
|
||||
class ExtensionsXMLSerializerTest(test.TestCase):
|
||||
|
||||
def test_serialize_extension(self):
|
||||
serializer = base_extensions.ExtensionsXMLSerializer()
|
||||
serializer = base_extensions.ExtensionTemplate()
|
||||
data = {'extension': {
|
||||
'name': 'ext1',
|
||||
'namespace': 'http://docs.rack.com/servers/api/ext/pie/v1.0',
|
||||
@@ -626,7 +594,7 @@ class ExtensionsXMLSerializerTest(test.TestCase):
|
||||
'type': 'application/vnd.sun.wadl+xml',
|
||||
'href': 'http://docs.rack.com/servers/api/ext/cs.wadl'}]}}
|
||||
|
||||
xml = serializer.serialize(data, 'show')
|
||||
xml = serializer.serialize(data)
|
||||
print xml
|
||||
root = etree.XML(xml)
|
||||
ext_dict = data['extension']
|
||||
@@ -645,7 +613,7 @@ class ExtensionsXMLSerializerTest(test.TestCase):
|
||||
xmlutil.validate_schema(root, 'extension')
|
||||
|
||||
def test_serialize_extensions(self):
|
||||
serializer = base_extensions.ExtensionsXMLSerializer()
|
||||
serializer = base_extensions.ExtensionsTemplate()
|
||||
data = {"extensions": [{
|
||||
"name": "Public Image Extension",
|
||||
"namespace": "http://foo.com/api/ext/pie/v1.0",
|
||||
@@ -671,7 +639,7 @@ class ExtensionsXMLSerializerTest(test.TestCase):
|
||||
"type": "application/vnd.sun.wadl+xml",
|
||||
"href": "http://foo.com/api/ext/cs-cbs.wadl"}]}]}
|
||||
|
||||
xml = serializer.serialize(data, 'index')
|
||||
xml = serializer.serialize(data)
|
||||
print xml
|
||||
root = etree.XML(xml)
|
||||
ext_elems = root.findall('{0}extension'.format(NS))
|
||||
|
||||
@@ -81,8 +81,7 @@ class LimitsControllerTest(BaseLimitTestSuite):
|
||||
def setUp(self):
|
||||
"""Run before each test."""
|
||||
BaseLimitTestSuite.setUp(self)
|
||||
self.controller = wsgi.LazySerializationMiddleware(
|
||||
limits.create_resource())
|
||||
self.controller = limits.create_resource()
|
||||
self.maxDiff = None
|
||||
|
||||
def _get_index_request(self, accept_header="application/json"):
|
||||
|
||||
@@ -50,7 +50,7 @@ class Context(object):
|
||||
|
||||
|
||||
class FakeRouter(wsgi.Router):
|
||||
def __init__(self):
|
||||
def __init__(self, ext_mgr=None):
|
||||
pass
|
||||
|
||||
@webob.dec.wsgify
|
||||
@@ -74,10 +74,9 @@ def fake_wsgi(self, req):
|
||||
|
||||
|
||||
def wsgi_app(inner_app_v2=None, fake_auth=True, fake_auth_context=None,
|
||||
serialization=os_wsgi.LazySerializationMiddleware,
|
||||
use_no_auth=False):
|
||||
use_no_auth=False, ext_mgr=None):
|
||||
if not inner_app_v2:
|
||||
inner_app_v2 = compute.APIRouter()
|
||||
inner_app_v2 = compute.APIRouter(ext_mgr)
|
||||
|
||||
if fake_auth:
|
||||
if fake_auth_context is not None:
|
||||
@@ -85,19 +84,13 @@ def wsgi_app(inner_app_v2=None, fake_auth=True, fake_auth_context=None,
|
||||
else:
|
||||
ctxt = context.RequestContext('fake', 'fake', auth_token=True)
|
||||
api_v2 = openstack_api.FaultWrapper(api_auth.InjectContext(ctxt,
|
||||
limits.RateLimitingMiddleware(
|
||||
serialization(
|
||||
extensions.ExtensionMiddleware(inner_app_v2)))))
|
||||
limits.RateLimitingMiddleware(inner_app_v2)))
|
||||
elif use_no_auth:
|
||||
api_v2 = openstack_api.FaultWrapper(auth.NoAuthMiddleware(
|
||||
limits.RateLimitingMiddleware(
|
||||
serialization(
|
||||
extensions.ExtensionMiddleware(inner_app_v2)))))
|
||||
limits.RateLimitingMiddleware(inner_app_v2)))
|
||||
else:
|
||||
api_v2 = openstack_api.FaultWrapper(auth.AuthMiddleware(
|
||||
limits.RateLimitingMiddleware(
|
||||
serialization(
|
||||
extensions.ExtensionMiddleware(inner_app_v2)))))
|
||||
limits.RateLimitingMiddleware(inner_app_v2)))
|
||||
|
||||
mapper = urlmap.URLMap()
|
||||
mapper['/v2'] = api_v2
|
||||
|
||||
@@ -372,7 +372,7 @@ class MetadataXMLDeserializationTest(test.TestCase):
|
||||
class MetadataXMLSerializationTest(test.TestCase):
|
||||
|
||||
def test_xml_declaration(self):
|
||||
serializer = common.MetadataXMLSerializer()
|
||||
serializer = common.MetadataTemplate()
|
||||
fixture = {
|
||||
'metadata': {
|
||||
'one': 'two',
|
||||
@@ -380,20 +380,20 @@ class MetadataXMLSerializationTest(test.TestCase):
|
||||
},
|
||||
}
|
||||
|
||||
output = serializer.serialize(fixture, 'index')
|
||||
output = serializer.serialize(fixture)
|
||||
print output
|
||||
has_dec = output.startswith("<?xml version='1.0' encoding='UTF-8'?>")
|
||||
self.assertTrue(has_dec)
|
||||
|
||||
def test_index(self):
|
||||
serializer = common.MetadataXMLSerializer()
|
||||
serializer = common.MetadataTemplate()
|
||||
fixture = {
|
||||
'metadata': {
|
||||
'one': 'two',
|
||||
'three': 'four',
|
||||
},
|
||||
}
|
||||
output = serializer.serialize(fixture, 'index')
|
||||
output = serializer.serialize(fixture)
|
||||
print output
|
||||
root = etree.XML(output)
|
||||
xmlutil.validate_schema(root, 'metadata')
|
||||
@@ -406,13 +406,13 @@ class MetadataXMLSerializationTest(test.TestCase):
|
||||
self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
|
||||
|
||||
def test_index_null(self):
|
||||
serializer = common.MetadataXMLSerializer()
|
||||
serializer = common.MetadataTemplate()
|
||||
fixture = {
|
||||
'metadata': {
|
||||
None: None,
|
||||
},
|
||||
}
|
||||
output = serializer.serialize(fixture, 'index')
|
||||
output = serializer.serialize(fixture)
|
||||
print output
|
||||
root = etree.XML(output)
|
||||
xmlutil.validate_schema(root, 'metadata')
|
||||
@@ -425,13 +425,13 @@ class MetadataXMLSerializationTest(test.TestCase):
|
||||
self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
|
||||
|
||||
def test_index_unicode(self):
|
||||
serializer = common.MetadataXMLSerializer()
|
||||
serializer = common.MetadataTemplate()
|
||||
fixture = {
|
||||
'metadata': {
|
||||
u'three': u'Jos\xe9',
|
||||
},
|
||||
}
|
||||
output = serializer.serialize(fixture, 'index')
|
||||
output = serializer.serialize(fixture)
|
||||
print output
|
||||
root = etree.XML(output)
|
||||
xmlutil.validate_schema(root, 'metadata')
|
||||
@@ -444,13 +444,13 @@ class MetadataXMLSerializationTest(test.TestCase):
|
||||
self.assertEqual(metadata_elem.text.strip(), meta_value)
|
||||
|
||||
def test_show(self):
|
||||
serializer = common.MetadataXMLSerializer()
|
||||
serializer = common.MetaItemTemplate()
|
||||
fixture = {
|
||||
'meta': {
|
||||
'one': 'two',
|
||||
},
|
||||
}
|
||||
output = serializer.serialize(fixture, 'show')
|
||||
output = serializer.serialize(fixture)
|
||||
print output
|
||||
root = etree.XML(output)
|
||||
meta_dict = fixture['meta']
|
||||
@@ -459,14 +459,14 @@ class MetadataXMLSerializationTest(test.TestCase):
|
||||
self.assertEqual(root.text.strip(), meta_value)
|
||||
|
||||
def test_update_all(self):
|
||||
serializer = common.MetadataXMLSerializer()
|
||||
serializer = common.MetadataTemplate()
|
||||
fixture = {
|
||||
'metadata': {
|
||||
'key6': 'value6',
|
||||
'key4': 'value4',
|
||||
},
|
||||
}
|
||||
output = serializer.serialize(fixture, 'update_all')
|
||||
output = serializer.serialize(fixture)
|
||||
print output
|
||||
root = etree.XML(output)
|
||||
xmlutil.validate_schema(root, 'metadata')
|
||||
@@ -479,13 +479,13 @@ class MetadataXMLSerializationTest(test.TestCase):
|
||||
self.assertEqual(str(metadata_elem.text).strip(), str(meta_value))
|
||||
|
||||
def test_update_item(self):
|
||||
serializer = common.MetadataXMLSerializer()
|
||||
serializer = common.MetaItemTemplate()
|
||||
fixture = {
|
||||
'meta': {
|
||||
'one': 'two',
|
||||
},
|
||||
}
|
||||
output = serializer.serialize(fixture, 'update')
|
||||
output = serializer.serialize(fixture)
|
||||
print output
|
||||
root = etree.XML(output)
|
||||
meta_dict = fixture['meta']
|
||||
@@ -494,7 +494,7 @@ class MetadataXMLSerializationTest(test.TestCase):
|
||||
self.assertEqual(root.text.strip(), meta_value)
|
||||
|
||||
def test_create(self):
|
||||
serializer = common.MetadataXMLSerializer()
|
||||
serializer = common.MetadataTemplate()
|
||||
fixture = {
|
||||
'metadata': {
|
||||
'key9': 'value9',
|
||||
@@ -502,7 +502,7 @@ class MetadataXMLSerializationTest(test.TestCase):
|
||||
'key1': 'value1',
|
||||
},
|
||||
}
|
||||
output = serializer.serialize(fixture, 'create')
|
||||
output = serializer.serialize(fixture)
|
||||
print output
|
||||
root = etree.XML(output)
|
||||
xmlutil.validate_schema(root, 'metadata')
|
||||
@@ -524,8 +524,3 @@ class MetadataXMLSerializationTest(test.TestCase):
|
||||
""".replace(" ", "").replace("\n", ""))
|
||||
|
||||
self.assertEqual(expected.toxml(), actual.toxml())
|
||||
|
||||
def test_delete(self):
|
||||
serializer = common.MetadataXMLSerializer()
|
||||
output = serializer.serialize(None, 'delete')
|
||||
self.assertEqual(output, '')
|
||||
|
||||
@@ -98,29 +98,6 @@ class ActionDispatcherTest(test.TestCase):
|
||||
self.assertEqual(serializer.dispatch({}, action='update'), 'trousers')
|
||||
|
||||
|
||||
class ResponseHeadersSerializerTest(test.TestCase):
|
||||
def test_default(self):
|
||||
serializer = wsgi.ResponseHeadersSerializer()
|
||||
context = nova.context.get_admin_context()
|
||||
req = webob.Request.blank('/', environ={'nova.context': context})
|
||||
response = webob.Response(request=req)
|
||||
serializer.serialize(response, {'v': '123'}, 'asdf')
|
||||
self.assertEqual(response.status_int, 200)
|
||||
|
||||
def test_custom(self):
|
||||
class Serializer(wsgi.ResponseHeadersSerializer):
|
||||
def update(self, response, data):
|
||||
response.status_int = 404
|
||||
response.headers['X-Custom-Header'] = data['v']
|
||||
serializer = Serializer()
|
||||
context = nova.context.get_admin_context()
|
||||
req = webob.Request.blank('/', environ={'nova.context': context})
|
||||
response = webob.Response(request=req)
|
||||
serializer.serialize(response, {'v': '123'}, 'update')
|
||||
self.assertEqual(response.status_int, 404)
|
||||
self.assertEqual(response.headers['X-Custom-Header'], '123')
|
||||
|
||||
|
||||
class DictSerializerTest(test.TestCase):
|
||||
def test_dispatch_default(self):
|
||||
serializer = wsgi.DictSerializer()
|
||||
@@ -207,226 +184,6 @@ class XMLDeserializerTest(test.TestCase):
|
||||
self.assertEqual(deserializer.deserialize(xml), as_dict)
|
||||
|
||||
|
||||
class RequestHeadersDeserializerTest(test.TestCase):
|
||||
def test_default(self):
|
||||
deserializer = wsgi.RequestHeadersDeserializer()
|
||||
req = wsgi.Request.blank('/')
|
||||
self.assertEqual(deserializer.deserialize(req, 'asdf'), {})
|
||||
|
||||
def test_custom(self):
|
||||
class Deserializer(wsgi.RequestHeadersDeserializer):
|
||||
def update(self, request):
|
||||
return {'a': request.headers['X-Custom-Header']}
|
||||
deserializer = Deserializer()
|
||||
req = wsgi.Request.blank('/')
|
||||
req.headers['X-Custom-Header'] = 'b'
|
||||
self.assertEqual(deserializer.deserialize(req, 'update'), {'a': 'b'})
|
||||
|
||||
|
||||
class ResponseHeadersSerializerTest(test.TestCase):
|
||||
def test_request_id(self):
|
||||
serializer = wsgi.ResponseHeadersSerializer()
|
||||
|
||||
context = nova.context.get_admin_context()
|
||||
req = webob.Request.blank('/', environ={'nova.context': context})
|
||||
res = webob.Response(request=req)
|
||||
serializer.serialize(res, {}, 'foo')
|
||||
h1 = res.headers.get('X-Compute-Request-Id')
|
||||
self.assertTrue(h1)
|
||||
|
||||
context = nova.context.get_admin_context()
|
||||
req = webob.Request.blank('/', environ={'nova.context': context})
|
||||
res = webob.Response(request=req)
|
||||
serializer.serialize(res, {}, 'foo')
|
||||
h2 = res.headers.get('X-Compute-Request-Id')
|
||||
self.assertTrue(h2)
|
||||
|
||||
self.assertNotEqual(h1, h2)
|
||||
|
||||
|
||||
class JSONSerializer(object):
|
||||
def serialize(self, data, action='default'):
|
||||
return 'pew_json'
|
||||
|
||||
|
||||
class XMLSerializer(object):
|
||||
def serialize(self, data, action='default'):
|
||||
return 'pew_xml'
|
||||
|
||||
|
||||
class HeadersSerializer(object):
|
||||
def serialize(self, response, data, action):
|
||||
response.status_int = 404
|
||||
|
||||
|
||||
class ResponseSerializerTest(test.TestCase):
|
||||
def setUp(self):
|
||||
self.body_serializers = {
|
||||
'application/json': JSONSerializer(),
|
||||
'application/xml': XMLSerializer(),
|
||||
}
|
||||
|
||||
self.serializer = wsgi.ResponseSerializer(self.body_serializers,
|
||||
HeadersSerializer())
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_get_serializer(self):
|
||||
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_body_serializer,
|
||||
'application/unknown')
|
||||
|
||||
def test_serialize_response_json(self):
|
||||
for content_type in ('application/json',
|
||||
'application/vnd.openstack.compute+json'):
|
||||
request = wsgi.Request.blank('/')
|
||||
response = self.serializer.serialize(request, {}, content_type)
|
||||
self.assertEqual(response.headers['Content-Type'], content_type)
|
||||
self.assertEqual(response.body, 'pew_json')
|
||||
self.assertEqual(response.status_int, 404)
|
||||
|
||||
def test_serialize_response_xml(self):
|
||||
for content_type in ('application/xml',
|
||||
'application/vnd.openstack.compute+xml'):
|
||||
request = wsgi.Request.blank('/')
|
||||
response = self.serializer.serialize(request, {}, content_type)
|
||||
self.assertEqual(response.headers['Content-Type'], content_type)
|
||||
self.assertEqual(response.body, 'pew_xml')
|
||||
self.assertEqual(response.status_int, 404)
|
||||
|
||||
def test_serialize_response_None(self):
|
||||
request = wsgi.Request.blank('/')
|
||||
response = self.serializer.serialize(request, None, 'application/json')
|
||||
self.assertEqual(response.headers['Content-Type'], 'application/json')
|
||||
self.assertEqual(response.body, '')
|
||||
self.assertEqual(response.status_int, 404)
|
||||
|
||||
def test_serialize_response_dict_to_unknown_content_type(self):
|
||||
request = wsgi.Request.blank('/')
|
||||
self.assertRaises(exception.InvalidContentType,
|
||||
self.serializer.serialize,
|
||||
request, {}, 'application/unknown')
|
||||
|
||||
|
||||
class LazySerializationTest(test.TestCase):
|
||||
def setUp(self):
|
||||
self.body_serializers = {
|
||||
'application/json': JSONSerializer(),
|
||||
'application/xml': XMLSerializer(),
|
||||
}
|
||||
|
||||
self.serializer = wsgi.ResponseSerializer(self.body_serializers,
|
||||
HeadersSerializer())
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_serialize_response_json(self):
|
||||
for content_type in ('application/json',
|
||||
'application/vnd.openstack.compute+json'):
|
||||
request = wsgi.Request.blank('/')
|
||||
request.environ['nova.lazy_serialize'] = True
|
||||
response = self.serializer.serialize(request, {}, content_type)
|
||||
self.assertEqual(response.headers['Content-Type'], content_type)
|
||||
self.assertEqual(response.status_int, 404)
|
||||
body = json.loads(response.body)
|
||||
self.assertEqual(body, {})
|
||||
serializer = request.environ['nova.serializer']
|
||||
self.assertEqual(serializer.serialize(body), 'pew_json')
|
||||
|
||||
def test_serialize_response_xml(self):
|
||||
for content_type in ('application/xml',
|
||||
'application/vnd.openstack.compute+xml'):
|
||||
request = wsgi.Request.blank('/')
|
||||
request.environ['nova.lazy_serialize'] = True
|
||||
response = self.serializer.serialize(request, {}, content_type)
|
||||
self.assertEqual(response.headers['Content-Type'], content_type)
|
||||
self.assertEqual(response.status_int, 404)
|
||||
body = json.loads(response.body)
|
||||
self.assertEqual(body, {})
|
||||
serializer = request.environ['nova.serializer']
|
||||
self.assertEqual(serializer.serialize(body), 'pew_xml')
|
||||
|
||||
def test_serialize_response_None(self):
|
||||
request = wsgi.Request.blank('/')
|
||||
request.environ['nova.lazy_serialize'] = True
|
||||
response = self.serializer.serialize(request, None, 'application/json')
|
||||
self.assertEqual(response.headers['Content-Type'], 'application/json')
|
||||
self.assertEqual(response.status_int, 404)
|
||||
self.assertEqual(response.body, '')
|
||||
|
||||
|
||||
class RequestDeserializerTest(test.TestCase):
|
||||
def setUp(self):
|
||||
class JSONDeserializer(object):
|
||||
def deserialize(self, data, action='default'):
|
||||
return 'pew_json'
|
||||
|
||||
class XMLDeserializer(object):
|
||||
def deserialize(self, data, action='default'):
|
||||
return 'pew_xml'
|
||||
|
||||
self.body_deserializers = {
|
||||
'application/json': JSONDeserializer(),
|
||||
'application/xml': XMLDeserializer(),
|
||||
}
|
||||
|
||||
self.deserializer = wsgi.RequestDeserializer(self.body_deserializers)
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_get_deserializer(self):
|
||||
ctype = 'application/json'
|
||||
expected = self.deserializer.get_body_deserializer(ctype)
|
||||
self.assertEqual(expected, self.body_deserializers[ctype])
|
||||
|
||||
def test_get_deserializer_unknown_content_type(self):
|
||||
self.assertRaises(exception.InvalidContentType,
|
||||
self.deserializer.get_body_deserializer,
|
||||
'application/unknown')
|
||||
|
||||
def test_get_expected_content_type(self):
|
||||
ctype = 'application/json'
|
||||
request = wsgi.Request.blank('/')
|
||||
request.headers['Accept'] = ctype
|
||||
self.assertEqual(self.deserializer.get_expected_content_type(request),
|
||||
ctype)
|
||||
|
||||
def test_get_action_args(self):
|
||||
env = {
|
||||
'wsgiorg.routing_args': [None, {
|
||||
'controller': None,
|
||||
'format': None,
|
||||
'action': 'update',
|
||||
'id': 12,
|
||||
}],
|
||||
}
|
||||
|
||||
expected = {'action': 'update', 'id': 12}
|
||||
|
||||
self.assertEqual(self.deserializer.get_action_args(env), expected)
|
||||
|
||||
def test_deserialize(self):
|
||||
def fake_get_routing_args(request):
|
||||
return {'action': 'create'}
|
||||
self.deserializer.get_action_args = fake_get_routing_args
|
||||
|
||||
request = wsgi.Request.blank('/')
|
||||
request.headers['Accept'] = 'application/xml'
|
||||
|
||||
deserialized = self.deserializer.deserialize(request)
|
||||
expected = ('create', {}, 'application/xml')
|
||||
|
||||
self.assertEqual(expected, deserialized)
|
||||
|
||||
|
||||
class ResourceTest(test.TestCase):
|
||||
def test_resource_call(self):
|
||||
class Controller(object):
|
||||
|
||||
@@ -712,78 +712,6 @@ class TemplateBuilderTest(test.TestCase):
|
||||
self.assertEqual(tmpl1, tmpl2)
|
||||
|
||||
|
||||
class SerializerTest(xmlutil.XMLTemplateSerializer):
|
||||
def test(self):
|
||||
root = xmlutil.TemplateElement('servers')
|
||||
a = xmlutil.SubTemplateElement(root, 'a', selector='servers')
|
||||
a.text = xmlutil.Selector('a')
|
||||
return xmlutil.MasterTemplate(root, 1, nsmap={None: "asdf"})
|
||||
|
||||
|
||||
class XMLTemplateSerializerTest(test.TestCase):
|
||||
def setUp(self):
|
||||
self.tmpl_serializer = SerializerTest()
|
||||
self.data = dict(servers=dict(a=(2, 3)))
|
||||
self.data_multi = dict(servers=[dict(a=(2, 3)), dict(a=(3, 4))])
|
||||
super(XMLTemplateSerializerTest, self).setUp()
|
||||
|
||||
def test_get_template(self):
|
||||
# First, check what happens when we fall back on the default
|
||||
# option
|
||||
self.assertEqual(self.tmpl_serializer.get_template(), None)
|
||||
self.assertEqual(self.tmpl_serializer.get_template('nosuch'), None)
|
||||
|
||||
# Now, check that we get back a template
|
||||
tmpl = self.tmpl_serializer.get_template('test')
|
||||
self.assertNotEqual(tmpl, None)
|
||||
self.assertEqual(tmpl.root.tag, 'servers')
|
||||
|
||||
def test_serialize_default(self):
|
||||
expected_xml = '<servers><a>(2,3)</a></servers>'
|
||||
result = self.tmpl_serializer.serialize(self.data)
|
||||
result = result.replace('\n', '').replace(' ', '')
|
||||
self.assertEqual(result, expected_xml)
|
||||
|
||||
def test_serialize_multi_default(self):
|
||||
expected_xml = ('<servers><server><a>(2,3)</a></server>'
|
||||
'<server><a>(3,4)</a></server></servers>')
|
||||
result = self.tmpl_serializer.serialize(self.data_multi)
|
||||
result = result.replace('\n', '').replace(' ', '')
|
||||
self.assertEqual(result, expected_xml)
|
||||
|
||||
def test_serialize_explicit(self):
|
||||
expected_xml = ("<?xmlversion='1.0'encoding='UTF-8'?>"
|
||||
'<serversxmlns="asdf"><a>(2,3)</a></servers>')
|
||||
tmpl = self.tmpl_serializer.get_template('test')
|
||||
result = self.tmpl_serializer.serialize(self.data, template=tmpl)
|
||||
result = result.replace('\n', '').replace(' ', '')
|
||||
self.assertEqual(result, expected_xml)
|
||||
|
||||
def test_serialize_multi_explicit(self):
|
||||
expected_xml = ("<?xmlversion='1.0'encoding='UTF-8'?>"
|
||||
'<serversxmlns="asdf"><a>(2,3)</a>'
|
||||
'<a>(3,4)</a></servers>')
|
||||
tmpl = self.tmpl_serializer.get_template('test')
|
||||
result = self.tmpl_serializer.serialize(self.data_multi, template=tmpl)
|
||||
result = result.replace('\n', '').replace(' ', '')
|
||||
self.assertEqual(result, expected_xml)
|
||||
|
||||
def test_serialize(self):
|
||||
expected_xml = ("<?xmlversion='1.0'encoding='UTF-8'?>"
|
||||
'<serversxmlns="asdf"><a>(2,3)</a></servers>')
|
||||
result = self.tmpl_serializer.serialize(self.data, 'test')
|
||||
result = result.replace('\n', '').replace(' ', '')
|
||||
self.assertEqual(result, expected_xml)
|
||||
|
||||
def test_serialize_multi(self):
|
||||
expected_xml = ("<?xmlversion='1.0'encoding='UTF-8'?>"
|
||||
'<serversxmlns="asdf"><a>(2,3)</a>'
|
||||
'<a>(3,4)</a></servers>')
|
||||
result = self.tmpl_serializer.serialize(self.data_multi, 'test')
|
||||
result = result.replace('\n', '').replace(' ', '')
|
||||
self.assertEqual(result, expected_xml)
|
||||
|
||||
|
||||
class MiscellaneousXMLUtilTests(test.TestCase):
|
||||
def test_make_flat_dict(self):
|
||||
expected_xml = ("<?xml version='1.0' encoding='UTF-8'?>\n"
|
||||
|
||||
@@ -251,7 +251,7 @@ class SnapshotSerializerTest(test.TestCase):
|
||||
self.assertEqual(str(snap[attr]), tree.get(attr))
|
||||
|
||||
def test_snapshot_show_create_serializer(self):
|
||||
serializer = snapshots.SnapshotSerializer()
|
||||
serializer = snapshots.SnapshotTemplate()
|
||||
raw_snapshot = dict(
|
||||
id='snap_id',
|
||||
status='snap_status',
|
||||
@@ -261,7 +261,7 @@ class SnapshotSerializerTest(test.TestCase):
|
||||
displayDescription='snap_desc',
|
||||
volumeId='vol_id',
|
||||
)
|
||||
text = serializer.serialize(dict(snapshot=raw_snapshot), 'show')
|
||||
text = serializer.serialize(dict(snapshot=raw_snapshot))
|
||||
|
||||
print text
|
||||
tree = etree.fromstring(text)
|
||||
@@ -269,7 +269,7 @@ class SnapshotSerializerTest(test.TestCase):
|
||||
self._verify_snapshot(raw_snapshot, tree)
|
||||
|
||||
def test_snapshot_index_detail_serializer(self):
|
||||
serializer = snapshots.SnapshotSerializer()
|
||||
serializer = snapshots.SnapshotsTemplate()
|
||||
raw_snapshots = [dict(
|
||||
id='snap1_id',
|
||||
status='snap1_status',
|
||||
@@ -288,7 +288,7 @@ class SnapshotSerializerTest(test.TestCase):
|
||||
displayDescription='snap2_desc',
|
||||
volumeId='vol2_id',
|
||||
)]
|
||||
text = serializer.serialize(dict(snapshots=raw_snapshots), 'index')
|
||||
text = serializer.serialize(dict(snapshots=raw_snapshots))
|
||||
|
||||
print text
|
||||
tree = etree.fromstring(text)
|
||||
|
||||
@@ -123,10 +123,6 @@ class VolumeTypesApiTest(test.TestCase):
|
||||
|
||||
|
||||
class VolumeTypesSerializerTest(test.TestCase):
|
||||
def setUp(self):
|
||||
super(VolumeTypesSerializerTest, self).setUp()
|
||||
self.serializer = types.VolumeTypesSerializer()
|
||||
|
||||
def _verify_volume_type(self, vtype, tree):
|
||||
self.assertEqual('volume_type', tree.tag)
|
||||
self.assertEqual(vtype['name'], tree.get('name'))
|
||||
@@ -142,9 +138,11 @@ class VolumeTypesSerializerTest(test.TestCase):
|
||||
self.assertEqual(len(seen), 0)
|
||||
|
||||
def test_index_serializer(self):
|
||||
serializer = types.VolumeTypesTemplate()
|
||||
|
||||
# Just getting some input data
|
||||
vtypes = return_volume_types_get_all_types(None)
|
||||
text = self.serializer.serialize(vtypes, 'index')
|
||||
text = serializer.serialize(vtypes)
|
||||
|
||||
print text
|
||||
tree = etree.fromstring(text)
|
||||
@@ -157,8 +155,10 @@ class VolumeTypesSerializerTest(test.TestCase):
|
||||
self._verify_volume_type(vtypes[name], child)
|
||||
|
||||
def test_voltype_serializer(self):
|
||||
serializer = types.VolumeTypeTemplate()
|
||||
|
||||
vtype = stub_volume_type(1)
|
||||
text = self.serializer.serialize(dict(volume_type=vtype))
|
||||
text = serializer.serialize(dict(volume_type=vtype))
|
||||
|
||||
print text
|
||||
tree = etree.fromstring(text)
|
||||
|
||||
@@ -134,47 +134,8 @@ class VolumeSerializerTest(test.TestCase):
|
||||
not_seen.remove(gr_child.tag)
|
||||
self.assertEqual(0, len(not_seen))
|
||||
|
||||
def test_attach_show_create_serializer(self):
|
||||
serializer = volumes.VolumeAttachmentSerializer()
|
||||
raw_attach = dict(
|
||||
id='vol_id',
|
||||
volumeId='vol_id',
|
||||
serverId='instance_uuid',
|
||||
device='/foo')
|
||||
text = serializer.serialize(dict(volumeAttachment=raw_attach), 'show')
|
||||
|
||||
print text
|
||||
tree = etree.fromstring(text)
|
||||
|
||||
self.assertEqual('volumeAttachment', tree.tag)
|
||||
self._verify_volume_attachment(raw_attach, tree)
|
||||
|
||||
def test_attach_index_serializer(self):
|
||||
serializer = volumes.VolumeAttachmentSerializer()
|
||||
raw_attaches = [dict(
|
||||
id='vol_id1',
|
||||
volumeId='vol_id1',
|
||||
serverId='instance1_uuid',
|
||||
device='/foo1'),
|
||||
dict(
|
||||
id='vol_id2',
|
||||
volumeId='vol_id2',
|
||||
serverId='instance2_uuid',
|
||||
device='/foo2')]
|
||||
text = serializer.serialize(dict(volumeAttachments=raw_attaches),
|
||||
'index')
|
||||
|
||||
print text
|
||||
tree = etree.fromstring(text)
|
||||
|
||||
self.assertEqual('volumeAttachments', tree.tag)
|
||||
self.assertEqual(len(raw_attaches), len(tree))
|
||||
for idx, child in enumerate(tree):
|
||||
self.assertEqual('volumeAttachment', child.tag)
|
||||
self._verify_volume_attachment(raw_attaches[idx], child)
|
||||
|
||||
def test_volume_show_create_serializer(self):
|
||||
serializer = volumes.VolumeSerializer()
|
||||
serializer = volumes.VolumeTemplate()
|
||||
raw_volume = dict(
|
||||
id='vol_id',
|
||||
status='vol_status',
|
||||
@@ -195,7 +156,7 @@ class VolumeSerializerTest(test.TestCase):
|
||||
baz='quux',
|
||||
),
|
||||
)
|
||||
text = serializer.serialize(dict(volume=raw_volume), 'show')
|
||||
text = serializer.serialize(dict(volume=raw_volume))
|
||||
|
||||
print text
|
||||
tree = etree.fromstring(text)
|
||||
@@ -203,7 +164,7 @@ class VolumeSerializerTest(test.TestCase):
|
||||
self._verify_volume(raw_volume, tree)
|
||||
|
||||
def test_volume_index_detail_serializer(self):
|
||||
serializer = volumes.VolumeSerializer()
|
||||
serializer = volumes.VolumesTemplate()
|
||||
raw_volumes = [dict(
|
||||
id='vol1_id',
|
||||
status='vol1_status',
|
||||
@@ -244,7 +205,7 @@ class VolumeSerializerTest(test.TestCase):
|
||||
bar='vol2_bar',
|
||||
),
|
||||
)]
|
||||
text = serializer.serialize(dict(volumes=raw_volumes), 'index')
|
||||
text = serializer.serialize(dict(volumes=raw_volumes))
|
||||
|
||||
print text
|
||||
tree = etree.fromstring(text)
|
||||
|
||||
@@ -27,8 +27,6 @@ LOG = logging.getLogger('nova.tests.integrated')
|
||||
|
||||
class ExtensionsTest(integrated_helpers._IntegratedTestBase):
|
||||
def _get_flags(self):
|
||||
extensions.ExtensionManager.reset()
|
||||
|
||||
f = super(ExtensionsTest, self)._get_flags()
|
||||
f['osapi_compute_extension'] = FLAGS.osapi_compute_extension[:]
|
||||
f['osapi_compute_extension'].append(
|
||||
|
||||
Reference in New Issue
Block a user