make heat-api return a parsable error

add a wsgi middleware (faultwrap) that catches exceptions
and transform those exceptions into a parsable format
according to 'Content-Type' of the request.

Fixes bug 1158598
Implements blueprint exception-formatting

Change-Id: Iacdb8cc119b250ff1e39c99b7a7f66fd4c35e7d9
changes/78/36678/12
Jianing YANG 9 years ago committed by Steve Baker
parent fe1557d60d
commit c5ab33614b
  1. 10
      etc/heat/api-paste.ini
  2. 108
      heat/api/middleware/fault.py
  3. 5
      heat/api/openstack/__init__.py
  4. 31
      heat/api/openstack/v1/util.py
  5. 8
      heat/common/config.py
  6. 370
      heat/tests/test_api_openstack_v1.py

@ -1,7 +1,7 @@
# heat-api pipeline
[pipeline:heat-api]
pipeline = versionnegotiation authtoken context apiv1app
pipeline = faultwrap versionnegotiation authtoken context apiv1app
# heat-api pipeline for standalone heat
# ie. uses alternative auth backend that authenticates users against keystone
@ -12,7 +12,7 @@ pipeline = versionnegotiation authtoken context apiv1app
# flavor = standalone
#
[pipeline:heat-api-standalone]
pipeline = versionnegotiation authpassword context apiv1app
pipeline = faultwrap versionnegotiation authpassword context apiv1app
# heat-api pipeline for custom cloud backends
# i.e. in heat-api.conf:
@ -20,7 +20,7 @@ pipeline = versionnegotiation authpassword context apiv1app
# flavor = custombackend
#
[pipeline:heat-api-custombackend]
pipeline = versionnegotiation context custombackendauth apiv1app
pipeline = faultwrap versionnegotiation context custombackendauth apiv1app
# heat-api-cfn pipeline
[pipeline:heat-api-cfn]
@ -56,6 +56,10 @@ heat.app_factory = heat.api.cloudwatch:API
paste.filter_factory = heat.common.wsgi:filter_factory
heat.filter_factory = heat.api.openstack:version_negotiation_filter
[filter:faultwrap]
paste.filter_factory = heat.common.wsgi:filter_factory
heat.filter_factory = heat.api.openstack:faultwrap_filter
[filter:cfnversionnegotiation]
paste.filter_factory = heat.common.wsgi:filter_factory
heat.filter_factory = heat.api.cfn:version_negotiation_filter

@ -0,0 +1,108 @@
# -*- encoding: utf-8 -*-
#
# Copyright © 2013 Unitedstack Inc.
#
# Author: Jianing YANG (jianingy@unitedstack.com)
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""A middleware that turns exceptions into parsable string. Inspired by
Cinder's faultwrapper
"""
import traceback
import webob
from heat.openstack.common import log as logging
import heat.openstack.common.rpc.common as rpc_common
from heat.common import wsgi
logger = logging.getLogger(__name__)
class Fault(object):
def __init__(self, error):
self.error = error
@webob.dec.wsgify(RequestClass=wsgi.Request)
def __call__(self, req):
if req.content_type == 'application/xml':
serializer = wsgi.XMLResponseSerializer()
else:
serializer = wsgi.JSONResponseSerializer()
resp = webob.Response(request=req)
default_webob_exc = webob.exc.HTTPInternalServerError()
resp.status_code = self.error.get('code', default_webob_exc.code)
serializer.default(resp, self.error)
return resp
class FaultWrapper(wsgi.Middleware):
"""Replace error body with something the client can parse."""
error_map = {
'AttributeError': webob.exc.HTTPBadRequest,
'ValueError': webob.exc.HTTPBadRequest,
'StackNotFound': webob.exc.HTTPNotFound,
'ResourceNotFound': webob.exc.HTTPNotFound,
'ResourceNotAvailable': webob.exc.HTTPNotFound,
'PhysicalResourceNotFound': webob.exc.HTTPNotFound,
'InvalidTenant': webob.exc.HTTPForbidden,
'StackExists': webob.exc.HTTPConflict,
'StackValidationFailed': webob.exc.HTTPBadRequest,
'InvalidTemplateReference': webob.exc.HTTPBadRequest,
'UnknownUserParameter': webob.exc.HTTPBadRequest,
'RevertFailed': webob.exc.HTTPInternalServerError,
'ServerBuildFailed': webob.exc.HTTPInternalServerError,
'NotSupported': webob.exc.HTTPBadRequest,
'MissingCredentialError': webob.exc.HTTPBadRequest,
'UserParameterMissing': webob.exc.HTTPBadRequest,
}
def _error(self, ex):
ex_type = ex.__class__.__name__
if ex_type.endswith(rpc_common._REMOTE_POSTFIX):
ex_type = ex_type[:-len(rpc_common._REMOTE_POSTFIX)]
message = str(ex)
if message.find('\n') > -1:
message, trace = message.split('\n', 1)
else:
message = str(ex)
trace = traceback.format_exc()
webob_exc = self.error_map.get(ex_type,
webob.exc.HTTPInternalServerError)
error = {
'code': webob_exc.code,
'title': webob_exc.title,
'explanation': webob_exc.explanation,
'error': {
'message': message,
'type': ex_type,
'traceback': trace,
}
}
return error
def process_request(self, req):
try:
return req.get_response(self.application)
except Exception as exc:
return req.get_response(Fault(self._error(exc)))

@ -14,9 +14,14 @@
# under the License.
from heat.api.middleware.version_negotiation import VersionNegotiationFilter
from heat.api.middleware.fault import FaultWrapper
from heat.api.openstack import versions
def version_negotiation_filter(app, conf, **local_conf):
return VersionNegotiationFilter(versions.Controller, app,
conf, **local_conf)
def faultwrap_filter(app, conf, **local_conf):
return FaultWrapper(app)

@ -67,31 +67,10 @@ def make_link(req, identity, relationship='self'):
def remote_error(ex):
"""
Map rpc_common.RemoteError exceptions returned by the engine
to webob exceptions which can be used to return
properly formatted error responses.
"""The RemoteError mapping work has been moved to heat.api.middleware.fault
which handles error formating now. This function will be deprecated
in the future, so please raise exceptions directly.
"""
error_map = {
'AttributeError': exc.HTTPBadRequest,
'ValueError': exc.HTTPBadRequest,
'StackNotFound': exc.HTTPNotFound,
'ResourceNotFound': exc.HTTPNotFound,
'ResourceNotAvailable': exc.HTTPNotFound,
'PhysicalResourceNotFound': exc.HTTPNotFound,
'InvalidTenant': exc.HTTPForbidden,
'StackExists': exc.HTTPConflict,
'StackValidationFailed': exc.HTTPBadRequest,
'InvalidTemplateReference': exc.HTTPBadRequest,
'UnknownUserParameter': exc.HTTPBadRequest,
'RevertFailed': exc.HTTPInternalServerError,
'ServerBuildFailed': exc.HTTPInternalServerError,
'NotSupported': exc.HTTPBadRequest,
'MissingCredentialError': exc.HTTPBadRequest,
'UserParameterMissing': exc.HTTPBadRequest,
}
Exc = error_map.get(ex.exc_type, exc.HTTPInternalServerError)
raise Exc(str(ex))
# TODO(jianingy): add a deprecated warning here to inform others.
raise ex

@ -116,6 +116,14 @@ cfg.CONF.register_opts(rpc_opts)
cfg.CONF.register_group(paste_deploy_group)
cfg.CONF.register_opts(paste_deploy_opts, group=paste_deploy_group)
# TODO(jianingy): I'll set allowed_rpc_exception_modules here for now.
# after figure out why rpc_set_default was not called,
# I'll move these settings into rpc_set_default()
allowed_rpc_exception_modules = cfg.CONF.allowed_rpc_exception_modules
allowed_rpc_exception_modules.append('heat.common.exception')
cfg.CONF.set_default(name='allowed_rpc_exception_modules',
default=allowed_rpc_exception_modules)
def rpc_set_default():
rpc.set_defaults(control_exchange='heat')

@ -19,9 +19,11 @@ import webob.exc
from heat.common import identifier
from heat.openstack.common import rpc
import heat.openstack.common.rpc.common as rpc_common
from heat.common import exception as heat_exc
from heat.common.wsgi import Request
from heat.common import urlfetch
from heat.openstack.common.rpc import common as rpc_common
from heat.rpc import api as rpc_api
from heat.tests.common import HeatTestCase
@ -32,6 +34,33 @@ import heat.api.openstack.v1.events as events
import heat.api.openstack.v1.actions as actions
from heat.tests.utils import dummy_context
import heat.api.middleware.fault as fault
def request_with_middleware(middleware, func, req, *args, **kwargs):
@webob.dec.wsgify
def _app(req):
return func(req, *args, **kwargs)
resp = middleware(_app).process_request(req)
return resp
def remote_error(ex_type, message=''):
"""convert rpc original exception to the one with _Remote suffix."""
# NOTE(jianingy): this function helps simulate the real world exceptions
module = ex_type().__class__.__module__
str_override = lambda self: "%s\n<Traceback>" % message
new_ex_type = type(ex_type.__name__ + rpc_common._REMOTE_POSTFIX,
(ex_type,),
{'__str__': str_override, '__unicode__': str_override})
new_ex_type.__module__ = '%s%s' % (module, rpc_common._REMOTE_POSTFIX)
return new_ex_type()
class InstantiationDataTest(HeatTestCase):
@ -369,12 +398,15 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'method': 'list_stacks',
'args': {},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("AttributeError"))
None).AndRaise(remote_error(AttributeError))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPBadRequest,
self.controller.index,
req, tenant_id=self.tenant)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.index,
req, tenant_id=self.tenant)
self.assertEqual(resp.json['code'], 400)
self.assertEqual(resp.json['error']['type'], 'AttributeError')
self.m.VerifyAll()
def test_index_rmt_interr(self):
@ -386,12 +418,15 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'method': 'list_stacks',
'args': {},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("Exception"))
None).AndRaise(remote_error(Exception))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPInternalServerError,
self.controller.index,
req, tenant_id=self.tenant)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.index,
req, tenant_id=self.tenant)
self.assertEqual(resp.json['code'], 500)
self.assertEqual(resp.json['error']['type'], 'Exception')
self.m.VerifyAll()
def test_create(self):
@ -488,7 +523,7 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'files': {},
'args': {'timeout_mins': 30}},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("AttributeError"))
None).AndRaise(remote_error(AttributeError))
rpc.call(req.context, self.topic,
{'namespace': None,
'method': 'create_stack',
@ -498,7 +533,7 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'files': {},
'args': {'timeout_mins': 30}},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("UnknownUserParameter"))
None).AndRaise(remote_error(heat_exc.UnknownUserParameter))
rpc.call(req.context, self.topic,
{'namespace': None,
'method': 'create_stack',
@ -508,20 +543,28 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'files': {},
'args': {'timeout_mins': 30}},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("UserParameterMissing"))
None).AndRaise(remote_error(heat_exc.UserParameterMissing))
self.m.ReplayAll()
resp = request_with_middleware(fault.FaultWrapper,
self.controller.create,
req, tenant_id=self.tenant, body=body)
self.assertRaises(webob.exc.HTTPBadRequest,
self.controller.create,
req, tenant_id=self.tenant, body=body)
self.assertRaises(webob.exc.HTTPBadRequest,
self.controller.create,
req, tenant_id=self.tenant, body=body)
self.assertRaises(webob.exc.HTTPBadRequest,
self.controller.create,
req, tenant_id=self.tenant, body=body)
self.assertEqual(resp.json['code'], 400)
self.assertEqual(resp.json['error']['type'], 'AttributeError')
resp = request_with_middleware(fault.FaultWrapper,
self.controller.create,
req, tenant_id=self.tenant, body=body)
self.assertEqual(resp.json['code'], 400)
self.assertEqual(resp.json['error']['type'], 'UnknownUserParameter')
resp = request_with_middleware(fault.FaultWrapper,
self.controller.create,
req, tenant_id=self.tenant, body=body)
self.assertEqual(resp.json['code'], 400)
self.assertEqual(resp.json['error']['type'], 'UserParameterMissing')
self.m.VerifyAll()
def test_create_err_existing(self):
@ -546,12 +589,15 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'files': {},
'args': {'timeout_mins': 30}},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("StackExists"))
None).AndRaise(remote_error(heat_exc.StackExists))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPConflict,
self.controller.create,
req, tenant_id=self.tenant, body=body)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.create,
req, tenant_id=self.tenant, body=body)
self.assertEqual(resp.json['code'], 409)
self.assertEqual(resp.json['error']['type'], 'StackExists')
self.m.VerifyAll()
def test_create_err_engine(self):
@ -576,14 +622,15 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'files': {},
'args': {'timeout_mins': 30}},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError(
'StackValidationFailed',
'Something went wrong'))
None).AndRaise(remote_error(heat_exc.StackValidationFailed))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPBadRequest,
self.controller.create,
req, tenant_id=self.tenant, body=body)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.create,
req, tenant_id=self.tenant, body=body)
self.assertEqual(resp.json['code'], 400)
self.assertEqual(resp.json['error']['type'], 'StackValidationFailed')
self.m.VerifyAll()
def test_lookup(self):
@ -637,11 +684,16 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'method': 'identify_stack',
'args': {'stack_name': stack_name},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("StackNotFound"))
None).AndRaise(remote_error(heat_exc.StackNotFound))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPNotFound, self.controller.lookup,
req, tenant_id=self.tenant, stack_name=stack_name)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.lookup,
req, tenant_id=self.tenant,
stack_name=stack_name)
self.assertEqual(resp.json['code'], 404)
self.assertEqual(resp.json['error']['type'], 'StackNotFound')
self.m.VerifyAll()
def test_lookup_resource(self):
@ -681,12 +733,17 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'method': 'identify_stack',
'args': {'stack_name': stack_name},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("StackNotFound"))
None).AndRaise(remote_error(heat_exc.StackNotFound))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPNotFound, self.controller.lookup,
req, tenant_id=self.tenant, stack_name=stack_name,
path='resources')
resp = request_with_middleware(fault.FaultWrapper,
self.controller.lookup,
req, tenant_id=self.tenant,
stack_name=stack_name,
path='resources')
self.assertEqual(resp.json['code'], 404)
self.assertEqual(resp.json['error']['type'], 'StackNotFound')
self.m.VerifyAll()
def test_show(self):
@ -769,14 +826,17 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'method': 'show_stack',
'args': {'stack_identity': dict(identity)},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("StackNotFound"))
None).AndRaise(remote_error(heat_exc.StackNotFound))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPNotFound,
self.controller.show,
req, tenant_id=identity.tenant,
stack_name=identity.stack_name,
stack_id=identity.stack_id)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.show,
req, tenant_id=identity.tenant,
stack_name=identity.stack_name,
stack_id=identity.stack_id)
self.assertEqual(resp.json['code'], 404)
self.assertEqual(resp.json['error']['type'], 'StackNotFound')
self.m.VerifyAll()
def test_show_invalidtenant(self):
@ -790,14 +850,17 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'method': 'show_stack',
'args': {'stack_identity': dict(identity)},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("InvalidTenant"))
None).AndRaise(remote_error(heat_exc.InvalidTenant))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPForbidden,
self.controller.show,
req, tenant_id=identity.tenant,
stack_name=identity.stack_name,
stack_id=identity.stack_id)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.show,
req, tenant_id=identity.tenant,
stack_name=identity.stack_name,
stack_id=identity.stack_id)
self.assertEqual(resp.json['code'], 403)
self.assertEqual(resp.json['error']['type'], 'InvalidTenant')
self.m.VerifyAll()
def test_get_template(self):
@ -832,15 +895,18 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'method': 'get_template',
'args': {'stack_identity': dict(identity)},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("StackNotFound"))
None).AndRaise(remote_error(heat_exc.StackNotFound))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPNotFound,
self.controller.template,
req, tenant_id=identity.tenant,
stack_name=identity.stack_name,
stack_id=identity.stack_id)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.template,
req, tenant_id=identity.tenant,
stack_name=identity.stack_name,
stack_id=identity.stack_id)
self.assertEqual(resp.json['code'], 404)
self.assertEqual(resp.json['error']['type'], 'StackNotFound')
self.m.VerifyAll()
def test_update(self):
@ -902,15 +968,18 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'files': {},
'args': {'timeout_mins': 30}},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("StackNotFound"))
None).AndRaise(remote_error(heat_exc.StackNotFound))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPNotFound,
self.controller.update,
req, tenant_id=identity.tenant,
stack_name=identity.stack_name,
stack_id=identity.stack_id,
body=body)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.update,
req, tenant_id=identity.tenant,
stack_name=identity.stack_name,
stack_id=identity.stack_id,
body=body)
self.assertEqual(resp.json['code'], 404)
self.assertEqual(resp.json['error']['type'], 'StackNotFound')
self.m.VerifyAll()
def test_delete(self):
@ -959,14 +1028,17 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'method': 'delete_stack',
'args': {'stack_identity': dict(identity)},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("StackNotFound"))
None).AndRaise(remote_error(heat_exc.StackNotFound))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPNotFound,
self.controller.delete,
req, tenant_id=identity.tenant,
stack_name=identity.stack_name,
stack_id=identity.stack_id)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.delete,
req, tenant_id=identity.tenant,
stack_name=identity.stack_name,
stack_id=identity.stack_id)
self.assertEqual(resp.json['code'], 404)
self.assertEqual(resp.json['error']['type'], 'StackNotFound')
self.m.VerifyAll()
def test_validate_template(self):
@ -1056,12 +1128,14 @@ class StackControllerTest(ControllerTest, HeatTestCase):
'method': 'list_resource_types',
'args': {},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("ValueError"))
None).AndRaise(remote_error(heat_exc.ServerError))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPInternalServerError,
self.controller.list_resource_types,
req, tenant_id=self.tenant)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.list_resource_types,
req, tenant_id=self.tenant)
self.assertEqual(resp.json['code'], 500)
self.assertEqual(resp.json['error']['type'], 'ServerError')
self.m.VerifyAll()
@ -1163,14 +1237,17 @@ class ResourceControllerTest(ControllerTest, HeatTestCase):
'method': 'list_stack_resources',
'args': {'stack_identity': stack_identity},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("StackNotFound"))
None).AndRaise(remote_error(heat_exc.StackNotFound))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPNotFound,
self.controller.index,
req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.index,
req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id)
self.assertEqual(resp.json['code'], 404)
self.assertEqual(resp.json['error']['type'], 'StackNotFound')
self.m.VerifyAll()
def test_show(self):
@ -1248,15 +1325,18 @@ class ResourceControllerTest(ControllerTest, HeatTestCase):
'args': {'stack_identity': stack_identity,
'resource_name': res_name},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("StackNotFound"))
None).AndRaise(remote_error(heat_exc.StackNotFound))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPNotFound,
self.controller.show,
req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id,
resource_name=res_name)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.show,
req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id,
resource_name=res_name)
self.assertEqual(resp.json['code'], 404)
self.assertEqual(resp.json['error']['type'], 'StackNotFound')
self.m.VerifyAll()
def test_show_nonexist_resource(self):
@ -1275,15 +1355,18 @@ class ResourceControllerTest(ControllerTest, HeatTestCase):
'args': {'stack_identity': stack_identity,
'resource_name': res_name},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("ResourceNotFound"))
None).AndRaise(remote_error(heat_exc.ResourceNotFound))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPNotFound,
self.controller.show,
req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id,
resource_name=res_name)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.show,
req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id,
resource_name=res_name)
self.assertEqual(resp.json['code'], 404)
self.assertEqual(resp.json['error']['type'], 'ResourceNotFound')
self.m.VerifyAll()
def test_show_uncreated_resource(self):
@ -1302,15 +1385,18 @@ class ResourceControllerTest(ControllerTest, HeatTestCase):
'args': {'stack_identity': stack_identity,
'resource_name': res_name},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("ResourceNotAvailable"))
None).AndRaise(remote_error(heat_exc.ResourceNotAvailable))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPNotFound,
self.controller.show,
req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id,
resource_name=res_name)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.show,
req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id,
resource_name=res_name)
self.assertEqual(resp.json['code'], 404)
self.assertEqual(resp.json['error']['type'], 'ResourceNotAvailable')
self.m.VerifyAll()
def test_metadata_show(self):
@ -1373,15 +1459,18 @@ class ResourceControllerTest(ControllerTest, HeatTestCase):
'args': {'stack_identity': stack_identity,
'resource_name': res_name},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("StackNotFound"))
None).AndRaise(remote_error(heat_exc.StackNotFound))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPNotFound,
self.controller.metadata,
req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id,
resource_name=res_name)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.metadata,
req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id,
resource_name=res_name)
self.assertEqual(resp.json['code'], 404)
self.assertEqual(resp.json['error']['type'], 'StackNotFound')
self.m.VerifyAll()
def test_metadata_show_nonexist_resource(self):
@ -1400,15 +1489,18 @@ class ResourceControllerTest(ControllerTest, HeatTestCase):
'args': {'stack_identity': stack_identity,
'resource_name': res_name},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("ResourceNotFound"))
None).AndRaise(remote_error(heat_exc.ResourceNotFound))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPNotFound,
self.controller.metadata,
req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id,
resource_name=res_name)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.metadata,
req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id,
resource_name=res_name)
self.assertEqual(resp.json['code'], 404)
self.assertEqual(resp.json['error']['type'], 'ResourceNotFound')
self.m.VerifyAll()
@ -1577,14 +1669,17 @@ class EventControllerTest(ControllerTest, HeatTestCase):
'method': 'list_events',
'args': {'stack_identity': stack_identity},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("StackNotFound"))
None).AndRaise(remote_error(heat_exc.StackNotFound))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPNotFound,
self.controller.index,
req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.index,
req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id)
self.assertEqual(resp.json['code'], 404)
self.assertEqual(resp.json['error']['type'], 'StackNotFound')
self.m.VerifyAll()
def test_index_resource_nonexist(self):
@ -1818,15 +1913,19 @@ class EventControllerTest(ControllerTest, HeatTestCase):
'method': 'list_events',
'args': {'stack_identity': stack_identity},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("StackNotFound"))
None).AndRaise(remote_error(heat_exc.StackNotFound))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPNotFound,
self.controller.show,
req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id,
resource_name=res_name, event_id=event_id)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.show,
req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id,
resource_name=res_name,
event_id=event_id)
self.assertEqual(resp.json['code'], 404)
self.assertEqual(resp.json['error']['type'], 'StackNotFound')
self.m.VerifyAll()
@ -2233,15 +2332,18 @@ class ActionControllerTest(ControllerTest, HeatTestCase):
'method': 'stack_suspend',
'args': {'stack_identity': stack_identity},
'version': self.api_version},
None).AndRaise(rpc_common.RemoteError("AttributeError"))
None).AndRaise(remote_error(AttributeError))
self.m.ReplayAll()
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.action,
req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id,
body=body)
resp = request_with_middleware(fault.FaultWrapper,
self.controller.action,
req, tenant_id=self.tenant,
stack_name=stack_identity.stack_name,
stack_id=stack_identity.stack_id,
body=body)
self.assertEqual(resp.json['code'], 400)
self.assertEqual(resp.json['error']['type'], 'AttributeError')
self.m.VerifyAll()
def test_action_badaction_ise(self):

Loading…
Cancel
Save