Perform fault wrapping in the openstack WSGI controller. This allows

us to just raise webob Exceptions in OS API controllers with the
appropriate explanations set. This resolves some inconsistencies
with exception raising and returning that could cause HTML output
to occur when an exception was raised.
This commit is contained in:
Dan Prince
2011-07-21 10:02:16 -04:00
parent d86af556f4
commit 126714f297
15 changed files with 90 additions and 102 deletions

View File

@@ -47,10 +47,10 @@ class Controller(object):
raise exception.AdminRequired()
def index(self, req):
raise faults.Fault(webob.exc.HTTPNotImplemented())
raise webob.exc.HTTPNotImplemented()
def detail(self, req):
raise faults.Fault(webob.exc.HTTPNotImplemented())
raise webob.exc.HTTPNotImplemented()
def show(self, req, id):
"""Return data about the given account id"""
@@ -65,7 +65,7 @@ class Controller(object):
def create(self, req, body):
"""We use update with create-or-update semantics
because the id comes from an external source"""
raise faults.Fault(webob.exc.HTTPNotImplemented())
raise webob.exc.HTTPNotImplemented()
def update(self, req, id, body):
"""This is really create or update."""

View File

@@ -19,7 +19,6 @@ import time
from webob import exc
from nova.api.openstack import faults
from nova.api.openstack import wsgi
@@ -36,20 +35,20 @@ class Controller(object):
def index(self, req, server_id, **kwargs):
""" Returns the list of backup schedules for a given instance """
return faults.Fault(exc.HTTPNotImplemented())
raise exc.HTTPNotImplemented()
def show(self, req, server_id, id, **kwargs):
""" Returns a single backup schedule for a given instance """
return faults.Fault(exc.HTTPNotImplemented())
raise exc.HTTPNotImplemented()
def create(self, req, server_id, **kwargs):
""" No actual update method required, since the existing API allows
both create and update through a POST """
return faults.Fault(exc.HTTPNotImplemented())
raise exc.HTTPNotImplemented()
def delete(self, req, server_id, id, **kwargs):
""" Deletes an existing backup schedule """
return faults.Fault(exc.HTTPNotImplemented())
raise exc.HTTPNotImplemented()
def create_resource():

View File

@@ -53,10 +53,10 @@ def get_pagination_params(request):
params[param] = int(request.GET[param])
except ValueError:
msg = _('%s param must be an integer') % param
raise webob.exc.HTTPBadRequest(msg)
raise webob.exc.HTTPBadRequest(explanation=msg)
if params[param] < 0:
msg = _('%s param must be positive') % param
raise webob.exc.HTTPBadRequest(msg)
raise webob.exc.HTTPBadRequest(explanation=msg)
return params
@@ -77,18 +77,22 @@ def limited(items, request, max_limit=FLAGS.osapi_max_limit):
try:
offset = int(request.GET.get('offset', 0))
except ValueError:
raise webob.exc.HTTPBadRequest(_('offset param must be an integer'))
msg = _('offset param must be an integer')
raise webob.exc.HTTPBadRequest(explanation=msg)
try:
limit = int(request.GET.get('limit', max_limit))
except ValueError:
raise webob.exc.HTTPBadRequest(_('limit param must be an integer'))
msg = _('limit param must be an integer')
raise webob.exc.HTTPBadRequest(explanation=msg)
if limit < 0:
raise webob.exc.HTTPBadRequest(_('limit param must be positive'))
msg = _('limit param must be positive')
raise webob.exc.HTTPBadRequest(explanation=msg)
if offset < 0:
raise webob.exc.HTTPBadRequest(_('offset param must be positive'))
msg = _('offset param must be positive')
raise webob.exc.HTTPBadRequest(explanation=msg)
limit = min(max_limit, limit or max_limit)
range_end = offset + limit
@@ -111,7 +115,8 @@ def limited_by_marker(items, request, max_limit=FLAGS.osapi_max_limit):
start_index = i + 1
break
if start_index < 0:
raise webob.exc.HTTPBadRequest(_('marker [%s] not found' % marker))
msg = _('marker [%s] not found' % marker)
raise webob.exc.HTTPBadRequest(explanation=msg)
range_end = start_index + limit
return items[start_index:range_end]

View File

@@ -20,7 +20,6 @@ import webob
from nova import console
from nova import exception
from nova.api.openstack import faults
from nova.api.openstack import wsgi
@@ -72,12 +71,12 @@ class Controller(object):
int(server_id),
int(id))
except exception.NotFound:
return faults.Fault(exc.HTTPNotFound())
raise exc.HTTPNotFound()
return _translate_detail_keys(console)
def update(self, req, server_id, id):
"""You can't update a console"""
raise faults.Fault(exc.HTTPNotImplemented())
raise exc.HTTPNotImplemented()
def delete(self, req, server_id, id):
"""Deletes a console"""
@@ -86,7 +85,7 @@ class Controller(object):
int(server_id),
int(id))
except exception.NotFound:
return faults.Fault(exc.HTTPNotFound())
raise exc.HTTPNotFound()
return webob.Response(status_int=202)

View File

@@ -28,7 +28,6 @@ from nova import quota
from nova import utils
from nova.compute import instance_types
from nova.api.openstack import faults
from nova.api.openstack import wsgi
from nova.auth import manager as auth_manager
@@ -70,7 +69,7 @@ class CreateInstanceHelper(object):
return type from this method is left to the caller.
"""
if not body:
raise faults.Fault(exc.HTTPUnprocessableEntity())
raise exc.HTTPUnprocessableEntity()
context = req.environ['nova.context']
@@ -94,7 +93,7 @@ class CreateInstanceHelper(object):
except Exception, e:
msg = _("Cannot find requested image %(image_href)s: %(e)s" %
locals())
raise faults.Fault(exc.HTTPBadRequest(explanation=msg))
raise exc.HTTPBadRequest(explanation=msg)
personality = body['server'].get('personality')
@@ -153,7 +152,7 @@ class CreateInstanceHelper(object):
self._handle_quota_error(error)
except exception.ImageNotFound as error:
msg = _("Can not find requested image")
raise faults.Fault(exc.HTTPBadRequest(explanation=msg))
raise exc.HTTPBadRequest(explanation=msg)
# Let the caller deal with unhandled exceptions.

View File

@@ -22,7 +22,6 @@ from nova import flags
from nova import image
from nova import quota
from nova import utils
from nova.api.openstack import faults
from nova.api.openstack import wsgi
@@ -62,7 +61,7 @@ class Controller(object):
if id in metadata:
return {'meta': {id: metadata[id]}}
else:
return faults.Fault(exc.HTTPNotFound())
raise exc.HTTPNotFound()
def create(self, req, image_id, body):
context = req.environ['nova.context']
@@ -105,7 +104,7 @@ class Controller(object):
img = self.image_service.show(context, image_id)
metadata = self._get_metadata(context, image_id)
if not id in metadata:
return faults.Fault(exc.HTTPNotFound())
raise exc.HTTPNotFound()
metadata.pop(id)
img['properties'] = metadata
self.image_service.update(context, image_id, img, None)

View File

@@ -25,7 +25,6 @@ from nova import flags
import nova.image
from nova import log
from nova.api.openstack import common
from nova.api.openstack import faults
from nova.api.openstack import image_metadata
from nova.api.openstack import servers
from nova.api.openstack.views import images as images_view
@@ -78,7 +77,7 @@ class Controller(object):
image = self._image_service.show(context, id)
except (exception.NotFound, exception.InvalidImageRef):
explanation = _("Image not found.")
raise faults.Fault(webob.exc.HTTPNotFound(explanation=explanation))
raise webob.exc.HTTPNotFound(explanation=explanation)
return dict(image=self.get_builder(req).build(image, detail=True))

View File

@@ -20,7 +20,6 @@ import time
from webob import exc
import nova
from nova.api.openstack import faults
import nova.api.openstack.views.addresses
from nova.api.openstack import wsgi
from nova import db
@@ -37,14 +36,14 @@ class Controller(object):
instance = self.compute_api.get(
req.environ['nova.context'], server_id)
except nova.exception.NotFound:
return faults.Fault(exc.HTTPNotFound())
raise exc.HTTPNotFound()
return instance
def create(self, req, server_id, body):
return faults.Fault(exc.HTTPNotImplemented())
raise exc.HTTPNotImplemented()
def delete(self, req, server_id, id):
return faults.Fault(exc.HTTPNotImplemented())
raise exc.HTTPNotImplemented()
class ControllerV10(Controller):
@@ -63,7 +62,7 @@ class ControllerV10(Controller):
view = builder.build_public_parts(instance)
else:
msg = _("Only private and public networks available")
return faults.Fault(exc.HTTPNotFound(explanation=msg))
raise exc.HTTPNotFound(explanation=msg)
return {id: view}
@@ -86,7 +85,7 @@ class ControllerV11(Controller):
if network is None:
msg = _("Instance is not a member of specified network")
return faults.Fault(exc.HTTPNotFound(explanation=msg))
raise exc.HTTPNotFound(explanation=msg)
return network

View File

@@ -18,7 +18,6 @@
from webob import exc
from nova import compute
from nova.api.openstack import faults
from nova.api.openstack import wsgi
from nova import exception
from nova import quota

View File

@@ -27,7 +27,6 @@ from nova import log as logging
from nova import utils
from nova.api.openstack import common
from nova.api.openstack import create_instance_helper as helper
from nova.api.openstack import faults
import nova.api.openstack.views.addresses
import nova.api.openstack.views.flavors
import nova.api.openstack.views.images
@@ -102,17 +101,14 @@ class Controller(object):
req.environ['nova.context'], id)
return self._build_view(req, instance, is_detail=True)
except exception.NotFound:
return faults.Fault(exc.HTTPNotFound())
raise exc.HTTPNotFound()
def create(self, req, body):
""" Creates a new server for a given user """
extra_values = None
result = None
try:
extra_values, instances = self.helper.create_instance(
req, body, self.compute_api.create)
except faults.Fault, f:
return f
extra_values, instances = self.helper.create_instance(
req, body, self.compute_api.create)
# We can only return 1 instance via the API, if we happen to
# build more than one... instances is a list, so we'll just
@@ -132,7 +128,7 @@ class Controller(object):
raise exc.HTTPUnprocessableEntity()
if not body:
return faults.Fault(exc.HTTPUnprocessableEntity())
raise exc.HTTPUnprocessableEntity()
ctxt = req.environ['nova.context']
update_dict = {}
@@ -147,7 +143,7 @@ class Controller(object):
try:
self.compute_api.update(ctxt, id, **update_dict)
except exception.NotFound:
return faults.Fault(exc.HTTPNotFound())
raise exc.HTTPNotFound()
return exc.HTTPNoContent()
@@ -171,7 +167,7 @@ class Controller(object):
for key in actions.keys():
if key in body:
return actions[key](body, req, id)
return faults.Fault(exc.HTTPNotImplemented())
raise exc.HTTPNotImplemented()
def _action_change_password(self, input_dict, req, id):
return exc.HTTPNotImplemented()
@@ -181,7 +177,7 @@ class Controller(object):
self.compute_api.confirm_resize(req.environ['nova.context'], id)
except Exception, e:
LOG.exception(_("Error in confirm-resize %s"), e)
return faults.Fault(exc.HTTPBadRequest())
raise exc.HTTPBadRequest()
return exc.HTTPNoContent()
def _action_revert_resize(self, input_dict, req, id):
@@ -189,7 +185,7 @@ class Controller(object):
self.compute_api.revert_resize(req.environ['nova.context'], id)
except Exception, e:
LOG.exception(_("Error in revert-resize %s"), e)
return faults.Fault(exc.HTTPBadRequest())
raise exc.HTTPBadRequest()
return webob.Response(status_int=202)
def _action_resize(self, input_dict, req, id):
@@ -200,14 +196,14 @@ class Controller(object):
reboot_type = input_dict['reboot']['type']
else:
LOG.exception(_("Missing argument 'type' for reboot"))
return faults.Fault(exc.HTTPUnprocessableEntity())
raise exc.HTTPUnprocessableEntity()
try:
# TODO(gundlach): pass reboot_type, support soft reboot in
# virt driver
self.compute_api.reboot(req.environ['nova.context'], id)
except Exception, e:
LOG.exception(_("Error in reboot %s"), e)
return faults.Fault(exc.HTTPUnprocessableEntity())
raise exc.HTTPUnprocessableEntity()
return webob.Response(status_int=202)
def _action_migrate(self, input_dict, req, id):
@@ -215,7 +211,7 @@ class Controller(object):
self.compute_api.resize(req.environ['nova.context'], id)
except Exception, e:
LOG.exception(_("Error in migrate %s"), e)
return faults.Fault(exc.HTTPBadRequest())
raise exc.HTTPBadRequest()
return webob.Response(status_int=202)
@scheduler_api.redirect_handler
@@ -231,7 +227,7 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("Compute.api::lock %s"), readable)
return faults.Fault(exc.HTTPUnprocessableEntity())
raise exc.HTTPUnprocessableEntity()
return webob.Response(status_int=202)
@scheduler_api.redirect_handler
@@ -247,7 +243,7 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("Compute.api::unlock %s"), readable)
return faults.Fault(exc.HTTPUnprocessableEntity())
raise exc.HTTPUnprocessableEntity()
return webob.Response(status_int=202)
@scheduler_api.redirect_handler
@@ -262,7 +258,7 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("Compute.api::get_lock %s"), readable)
return faults.Fault(exc.HTTPUnprocessableEntity())
raise exc.HTTPUnprocessableEntity()
return webob.Response(status_int=202)
@scheduler_api.redirect_handler
@@ -277,7 +273,7 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("Compute.api::reset_network %s"), readable)
return faults.Fault(exc.HTTPUnprocessableEntity())
raise exc.HTTPUnprocessableEntity()
return webob.Response(status_int=202)
@scheduler_api.redirect_handler
@@ -292,7 +288,7 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("Compute.api::inject_network_info %s"), readable)
return faults.Fault(exc.HTTPUnprocessableEntity())
raise exc.HTTPUnprocessableEntity()
return webob.Response(status_int=202)
@scheduler_api.redirect_handler
@@ -304,7 +300,7 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("Compute.api::pause %s"), readable)
return faults.Fault(exc.HTTPUnprocessableEntity())
raise exc.HTTPUnprocessableEntity()
return webob.Response(status_int=202)
@scheduler_api.redirect_handler
@@ -316,7 +312,7 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("Compute.api::unpause %s"), readable)
return faults.Fault(exc.HTTPUnprocessableEntity())
raise exc.HTTPUnprocessableEntity()
return webob.Response(status_int=202)
@scheduler_api.redirect_handler
@@ -328,7 +324,7 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("compute.api::suspend %s"), readable)
return faults.Fault(exc.HTTPUnprocessableEntity())
raise exc.HTTPUnprocessableEntity()
return webob.Response(status_int=202)
@scheduler_api.redirect_handler
@@ -340,7 +336,7 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("compute.api::resume %s"), readable)
return faults.Fault(exc.HTTPUnprocessableEntity())
raise exc.HTTPUnprocessableEntity()
return webob.Response(status_int=202)
@scheduler_api.redirect_handler
@@ -352,7 +348,7 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("compute.api::rescue %s"), readable)
return faults.Fault(exc.HTTPUnprocessableEntity())
raise exc.HTTPUnprocessableEntity()
return webob.Response(status_int=202)
@scheduler_api.redirect_handler
@@ -364,7 +360,7 @@ class Controller(object):
except:
readable = traceback.format_exc()
LOG.exception(_("compute.api::unrescue %s"), readable)
return faults.Fault(exc.HTTPUnprocessableEntity())
raise exc.HTTPUnprocessableEntity()
return webob.Response(status_int=202)
@scheduler_api.redirect_handler
@@ -374,7 +370,7 @@ class Controller(object):
self.compute_api.get_ajax_console(req.environ['nova.context'],
int(id))
except exception.NotFound:
return faults.Fault(exc.HTTPNotFound())
raise exc.HTTPNotFound()
return webob.Response(status_int=202)
@scheduler_api.redirect_handler
@@ -384,7 +380,7 @@ class Controller(object):
self.compute_api.get_vnc_console(req.environ['nova.context'],
int(id))
except exception.NotFound:
return faults.Fault(exc.HTTPNotFound())
raise exc.HTTPNotFound()
return webob.Response(status_int=202)
@scheduler_api.redirect_handler
@@ -416,7 +412,7 @@ class ControllerV10(Controller):
try:
self.compute_api.delete(req.environ['nova.context'], id)
except exception.NotFound:
return faults.Fault(exc.HTTPNotFound())
raise exc.HTTPNotFound()
return webob.Response(status_int=202)
def _image_ref_from_req_data(self, data):
@@ -440,17 +436,13 @@ class ControllerV10(Controller):
def _action_resize(self, input_dict, req, id):
""" Resizes a given instance to the flavor size requested """
try:
if 'resize' in input_dict and 'flavorId' in input_dict['resize']:
flavor_id = input_dict['resize']['flavorId']
self.compute_api.resize(req.environ['nova.context'], id,
flavor_id)
else:
LOG.exception(_("Missing 'flavorId' argument for resize"))
return faults.Fault(exc.HTTPUnprocessableEntity())
except Exception, e:
LOG.exception(_("Error in resize %s"), e)
return faults.Fault(exc.HTTPBadRequest())
if 'resize' in input_dict and 'flavorId' in input_dict['resize']:
flavor_id = input_dict['resize']['flavorId']
self.compute_api.resize(req.environ['nova.context'], id,
flavor_id)
else:
LOG.exception(_("Missing 'flavorId' argument for resize"))
raise exc.HTTPUnprocessableEntity()
return webob.Response(status_int=202)
def _action_rebuild(self, info, request, instance_id):
@@ -462,14 +454,14 @@ class ControllerV10(Controller):
except (KeyError, TypeError):
msg = _("Could not parse imageId from request.")
LOG.debug(msg)
return faults.Fault(exc.HTTPBadRequest(explanation=msg))
raise exc.HTTPBadRequest(explanation=msg)
try:
self.compute_api.rebuild(context, instance_id, image_id)
except exception.BuildInProgress:
msg = _("Instance %d is currently being rebuilt.") % instance_id
LOG.debug(msg)
return faults.Fault(exc.HTTPConflict(explanation=msg))
raise exc.HTTPConflict(explanation=msg)
return webob.Response(status_int=202)
@@ -486,7 +478,7 @@ class ControllerV11(Controller):
try:
self.compute_api.delete(req.environ['nova.context'], id)
except exception.NotFound:
return faults.Fault(exc.HTTPNotFound())
raise exc.HTTPNotFound()
def _image_ref_from_req_data(self, data):
return data['server']['imageRef']
@@ -530,7 +522,7 @@ class ControllerV11(Controller):
except AttributeError as ex:
msg = _("Unable to parse metadata key/value pairs.")
LOG.debug(msg)
raise faults.Fault(exc.HTTPBadRequest(explanation=msg))
raise exc.HTTPBadRequest(explanation=msg)
def _decode_personalities(self, personalities):
"""Decode the Base64-encoded personalities."""
@@ -541,14 +533,14 @@ class ControllerV11(Controller):
except (KeyError, TypeError):
msg = _("Unable to parse personality path/contents.")
LOG.info(msg)
raise faults.Fault(exc.HTTPBadRequest(explanation=msg))
raise exc.HTTPBadRequest(explanation=msg)
try:
personality["contents"] = base64.b64decode(contents)
except TypeError:
msg = _("Personality content could not be Base64 decoded.")
LOG.info(msg)
raise faults.Fault(exc.HTTPBadRequest(explanation=msg))
raise exc.HTTPBadRequest(explanation=msg)
def _action_resize(self, input_dict, req, id):
""" Resizes a given instance to the flavor size requested """
@@ -560,10 +552,10 @@ class ControllerV11(Controller):
flavor_id)
else:
LOG.exception(_("Missing 'flavorRef' argument for resize"))
return faults.Fault(exc.HTTPUnprocessableEntity())
raise exc.HTTPUnprocessableEntity()
except Exception, e:
LOG.exception(_("Error in resize %s"), e)
return faults.Fault(exc.HTTPBadRequest())
raise exc.HTTPBadRequest()
return webob.Response(status_int=202)
def _action_rebuild(self, info, request, instance_id):
@@ -575,7 +567,7 @@ class ControllerV11(Controller):
except (KeyError, TypeError):
msg = _("Could not parse imageRef from request.")
LOG.debug(msg)
return faults.Fault(exc.HTTPBadRequest(explanation=msg))
raise exc.HTTPBadRequest(explanation=msg)
personalities = info["rebuild"].get("personality", [])
metadata = info["rebuild"].get("metadata")
@@ -591,7 +583,7 @@ class ControllerV11(Controller):
except exception.BuildInProgress:
msg = _("Instance %d is currently being rebuilt.") % instance_id
LOG.debug(msg)
return faults.Fault(exc.HTTPConflict(explanation=msg))
raise exc.HTTPConflict(explanation=msg)
return webob.Response(status_int=202)

View File

@@ -17,7 +17,6 @@
from webob import exc
from nova.api.openstack import faults
from nova.api.openstack import wsgi
@@ -26,27 +25,27 @@ class Controller(object):
def index(self, req, **kwargs):
""" Returns a list of Shared IP Groups for the user """
raise faults.Fault(exc.HTTPNotImplemented())
raise exc.HTTPNotImplemented()
def show(self, req, id, **kwargs):
""" Shows in-depth information on a specific Shared IP Group """
raise faults.Fault(exc.HTTPNotImplemented())
raise exc.HTTPNotImplemented()
def update(self, req, id, **kwargs):
""" You can't update a Shared IP Group """
raise faults.Fault(exc.HTTPNotImplemented())
raise exc.HTTPNotImplemented()
def delete(self, req, id, **kwargs):
""" Deletes a Shared IP Group """
raise faults.Fault(exc.HTTPNotImplemented())
raise exc.HTTPNotImplemented()
def detail(self, req, **kwargs):
""" Returns a complete list of Shared IP Groups """
raise faults.Fault(exc.HTTPNotImplemented())
raise exc.HTTPNotImplemented()
def create(self, req, **kwargs):
""" Creates a new Shared IP group """
raise faults.Fault(exc.HTTPNotImplemented())
raise exc.HTTPNotImplemented()
def create_resource():

View File

@@ -19,7 +19,6 @@ from nova import exception
from nova import flags
from nova import log as logging
from nova.api.openstack import common
from nova.api.openstack import faults
from nova.api.openstack import wsgi
from nova.auth import manager
@@ -69,7 +68,7 @@ class Controller(object):
user = None
if user is None:
raise faults.Fault(exc.HTTPNotFound())
raise exc.HTTPNotFound()
return dict(user=_translate_keys(user))

View File

@@ -441,7 +441,11 @@ class Resource(wsgi.Application):
msg = _("Malformed request body")
return faults.Fault(webob.exc.HTTPBadRequest(explanation=msg))
action_result = self.dispatch(request, action, args)
try:
action_result = self.dispatch(request, action, args)
except webob.exc.HTTPException as ex:
LOG.info(_("HTTP exception thrown: %s"), unicode(ex))
action_result = faults.Fault(ex)
#TODO(bcwaldon): find a more elegant way to pass through non-dict types
if type(action_result) is dict or action_result is None:

View File

@@ -27,7 +27,6 @@ from nova.scheduler import api
from nova.api.openstack import create_instance_helper as helper
from nova.api.openstack import common
from nova.api.openstack import faults
from nova.api.openstack import wsgi
@@ -127,11 +126,8 @@ class Controller(object):
Returns a reservation ID (a UUID).
"""
result = None
try:
extra_values, result = self.helper.create_instance(req, body,
self.compute_api.create_all_at_once)
except faults.Fault, f:
return f
extra_values, result = self.helper.create_instance(req, body,
self.compute_api.create_all_at_once)
reservation_id = result
return {'reservation_id': reservation_id}

View File

@@ -1707,7 +1707,7 @@ class ServersTest(test.TestCase):
self.stubs.Set(nova.compute.api.API, 'resize', resize_mock)
res = req.get_response(fakes.wsgi_app())
self.assertEqual(res.status_int, 400)
self.assertEqual(res.status_int, 500)
def test_resized_server_has_correct_status(self):
req = self.webreq('/1', 'GET')