Remove deprecated extension code.
The recent extensions refactoring (blueprint extension-refactor) deprecated ActionExtension and RequestExtension, replacing them with ControllerExtension. This patch completes the deprecation by removing those classes and all related support infrastructure, including ExtensionMiddleware and LazySerializationMiddleware. (The classes remain, as deprecated do-nothing stubs, for compatibility with existing api-paste.ini files.) Change-Id: I8272ac3cf432813d749db67b2e1ad1a72abbb784
This commit is contained in:
@@ -90,12 +90,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
|
||||
@@ -109,15 +109,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):
|
||||
@@ -189,10 +188,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.
|
||||
@@ -218,10 +215,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)
|
||||
@@ -235,18 +230,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
|
||||
|
||||
@@ -270,11 +262,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
|
||||
@@ -297,10 +287,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):
|
||||
@@ -308,10 +296,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)
|
||||
|
||||
@@ -320,10 +306,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)
|
||||
|
||||
@@ -332,11 +316,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)
|
||||
@@ -353,10 +335,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)
|
||||
@@ -393,10 +373,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)
|
||||
|
||||
@@ -404,8 +382,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)
|
||||
@@ -413,8 +390,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)
|
||||
@@ -422,8 +398,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)
|
||||
@@ -433,13 +408,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):
|
||||
@@ -494,35 +467,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
|
||||
@@ -611,7 +579,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',
|
||||
@@ -625,7 +593,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']
|
||||
@@ -644,7 +612,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",
|
||||
@@ -670,7 +638,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