summaryrefslogtreecommitdiffstats
path: root/nova/tests
diff options
context:
space:
mode:
authorKevin L. Mitchell <kevin.mitchell@rackspace.com>2012-01-13 14:13:59 -0600
committerKevin L. Mitchell <kevin.mitchell@rackspace.com>2012-01-13 14:13:59 -0600
commit1d4e35be694884a0ea8e586ffb2d06ecd6c48685 (patch)
tree66e310d4ade4e53a66195d1e4c11cf1ab3168935 /nova/tests
parent6c898e6abf44caa176790e9cd4505aeed145397c (diff)
Refactor request and action extensions.
The goal of this refactoring is to eventually eliminate ExtensionMiddleware and LazySerializationMiddleware completely, by executing extensions directly within the processing done by Resource.__call__(). This patch implements the infrastructure required to perform this extension processing. Implements blueprint extension-refactor. Change-Id: I23398fc906a9a105de354a8133337ecfc69a3ad3
Diffstat (limited to 'nova/tests')
-rw-r--r--nova/tests/api/openstack/compute/test_extensions.py135
-rw-r--r--nova/tests/api/openstack/compute/test_server_actions.py115
-rw-r--r--nova/tests/api/openstack/test_wsgi.py347
3 files changed, 540 insertions, 57 deletions
diff --git a/nova/tests/api/openstack/compute/test_extensions.py b/nova/tests/api/openstack/compute/test_extensions.py
index a4585781b..4e41caa69 100644
--- a/nova/tests/api/openstack/compute/test_extensions.py
+++ b/nova/tests/api/openstack/compute/test_extensions.py
@@ -21,7 +21,7 @@ import json
import webob
from lxml import etree
-from nova.api.openstack import compute
+from nova.api.openstack import compute
from nova.api.openstack import extensions as base_extensions
from nova.api.openstack.compute import extensions as compute_extensions
from nova.api.openstack import wsgi
@@ -36,6 +36,7 @@ FLAGS = flags.FLAGS
NS = "{http://docs.openstack.org/compute/api/v1.1}"
ATOMNS = "{http://www.w3.org/2005/Atom}"
response_body = "Try to say this Mr. Knox, sir..."
+extension_body = "I am not a fox!"
class StubController(object):
@@ -54,16 +55,60 @@ class StubController(object):
raise webob.exc.HTTPNotFound()
+class StubActionController(wsgi.Controller):
+ def __init__(self, body):
+ self.body = body
+
+ @wsgi.action('fooAction')
+ def _action_foo(self, req, id, body):
+ return self.body
+
+
+class StubControllerExtension(base_extensions.ExtensionDescriptor):
+ name = 'twaadle'
+
+ def __init__(self):
+ pass
+
+
+class StubEarlyExtensionController(wsgi.Controller):
+ def __init__(self, body):
+ self.body = body
+
+ @wsgi.extends
+ def index(self, req):
+ yield self.body
+
+ @wsgi.extends(action='fooAction')
+ def _action_foo(self, req, id, body):
+ yield self.body
+
+
+class StubLateExtensionController(wsgi.Controller):
+ def __init__(self, body):
+ self.body = body
+
+ @wsgi.extends
+ def index(self, req, resp_obj):
+ return self.body
+
+ @wsgi.extends(action='fooAction')
+ def _action_foo(self, req, resp_obj, id, body):
+ return self.body
+
+
class StubExtensionManager(object):
"""Provides access to Tweedle Beetles"""
name = "Tweedle Beetle Extension"
alias = "TWDLBETL"
- def __init__(self, resource_ext=None, action_ext=None, request_ext=None):
+ def __init__(self, resource_ext=None, action_ext=None, request_ext=None,
+ controller_ext=None):
self.resource_ext = resource_ext
self.action_ext = action_ext
self.request_ext = request_ext
+ self.controller_ext = controller_ext
def get_resources(self):
resource_exts = []
@@ -83,6 +128,12 @@ class StubExtensionManager(object):
request_extensions.append(self.request_ext)
return request_extensions
+ def get_controller_extensions(self):
+ controller_extensions = []
+ if self.controller_ext:
+ controller_extensions.append(self.controller_ext)
+ return controller_extensions
+
class ExtensionTestCase(test.TestCase):
def setUp(self):
@@ -411,7 +462,7 @@ class ActionExtensionTest(ExtensionTestCase):
body = json.loads(response.body)
expected = {
"badRequest": {
- "message": "There is no such server action: blah",
+ "message": "There is no such action: blah",
"code": 400
}
}
@@ -478,6 +529,84 @@ class RequestExtensionTest(ExtensionTestCase):
self.assertEqual("Pig Bands!", response_data['big_bands'])
+class ControllerExtensionTest(ExtensionTestCase):
+ def test_controller_extension_early(self):
+ controller = StubController(response_body)
+ res_ext = base_extensions.ResourceExtension('tweedles', controller)
+ ext_controller = StubEarlyExtensionController(extension_body)
+ extension = StubControllerExtension()
+ cont_ext = base_extensions.ControllerExtension(extension, 'tweedles',
+ ext_controller)
+ manager = StubExtensionManager(resource_ext=res_ext,
+ controller_ext=cont_ext)
+ app = compute.APIRouter(manager)
+ request = webob.Request.blank("/fake/tweedles")
+ response = request.get_response(app)
+ self.assertEqual(200, response.status_int)
+ self.assertEqual(extension_body, response.body)
+
+ def test_controller_extension_late(self):
+ # Need a dict for the body to convert to a ResponseObject
+ controller = StubController(dict(foo=response_body))
+ res_ext = base_extensions.ResourceExtension('tweedles', controller)
+
+ ext_controller = StubLateExtensionController(extension_body)
+ extension = StubControllerExtension()
+ cont_ext = base_extensions.ControllerExtension(extension, 'tweedles',
+ ext_controller)
+
+ manager = StubExtensionManager(resource_ext=res_ext,
+ controller_ext=cont_ext)
+ app = compute.APIRouter(manager)
+ request = webob.Request.blank("/fake/tweedles")
+ response = request.get_response(app)
+ self.assertEqual(200, response.status_int)
+ self.assertEqual(extension_body, response.body)
+
+ def test_controller_action_extension_early(self):
+ controller = StubActionController(response_body)
+ actions = dict(action='POST')
+ res_ext = base_extensions.ResourceExtension('tweedles', controller,
+ member_actions=actions)
+ ext_controller = StubEarlyExtensionController(extension_body)
+ extension = StubControllerExtension()
+ cont_ext = base_extensions.ControllerExtension(extension, 'tweedles',
+ ext_controller)
+ manager = StubExtensionManager(resource_ext=res_ext,
+ controller_ext=cont_ext)
+ app = compute.APIRouter(manager)
+ request = webob.Request.blank("/fake/tweedles/foo/action")
+ request.method = 'POST'
+ request.headers['Content-Type'] = 'application/json'
+ request.body = json.dumps(dict(fooAction=True))
+ response = request.get_response(app)
+ self.assertEqual(200, response.status_int)
+ self.assertEqual(extension_body, response.body)
+
+ def test_controller_action_extension_late(self):
+ # Need a dict for the body to convert to a ResponseObject
+ controller = StubActionController(dict(foo=response_body))
+ actions = dict(action='POST')
+ res_ext = base_extensions.ResourceExtension('tweedles', controller,
+ member_actions=actions)
+
+ ext_controller = StubLateExtensionController(extension_body)
+ extension = StubControllerExtension()
+ cont_ext = base_extensions.ControllerExtension(extension, 'tweedles',
+ ext_controller)
+
+ manager = StubExtensionManager(resource_ext=res_ext,
+ controller_ext=cont_ext)
+ app = compute.APIRouter(manager)
+ request = webob.Request.blank("/fake/tweedles/foo/action")
+ request.method = 'POST'
+ request.headers['Content-Type'] = 'application/json'
+ request.body = json.dumps(dict(fooAction=True))
+ response = request.get_response(app)
+ self.assertEqual(200, response.status_int)
+ self.assertEqual(extension_body, response.body)
+
+
class ExtensionsXMLSerializerTest(test.TestCase):
def test_serialize_extension(self):
diff --git a/nova/tests/api/openstack/compute/test_server_actions.py b/nova/tests/api/openstack/compute/test_server_actions.py
index 2f3976375..e92816172 100644
--- a/nova/tests/api/openstack/compute/test_server_actions.py
+++ b/nova/tests/api/openstack/compute/test_server_actions.py
@@ -174,27 +174,13 @@ class ServerActionsControllerTest(test.TestCase):
self.stubs.UnsetAll()
super(ServerActionsControllerTest, self).tearDown()
- def test_server_bad_body(self):
- body = {}
-
- req = fakes.HTTPRequest.blank(self.url)
- self.assertRaises(webob.exc.HTTPBadRequest,
- self.controller.action, req, FAKE_UUID, body)
-
- def test_server_unknown_action(self):
- body = {'sockTheFox': {'fakekey': '1234'}}
-
- req = fakes.HTTPRequest.blank(self.url)
- self.assertRaises(webob.exc.HTTPBadRequest,
- self.controller.action, req, FAKE_UUID, body)
-
def test_server_change_password(self):
mock_method = MockSetAdminPassword()
self.stubs.Set(nova.compute.api.API, 'set_admin_password', mock_method)
body = {'changePassword': {'adminPass': '1234pass'}}
req = fakes.HTTPRequest.blank(self.url)
- self.controller.action(req, FAKE_UUID, body)
+ self.controller._action_change_password(req, FAKE_UUID, body)
self.assertEqual(mock_method.instance_id, self.uuid)
self.assertEqual(mock_method.password, '1234pass')
@@ -203,47 +189,53 @@ class ServerActionsControllerTest(test.TestCase):
body = {'changePassword': {'adminPass': 1234}}
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPBadRequest,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_change_password,
+ req, FAKE_UUID, body)
def test_server_change_password_bad_request(self):
body = {'changePassword': {'pass': '12345'}}
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPBadRequest,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_change_password,
+ req, FAKE_UUID, body)
def test_server_change_password_empty_string(self):
body = {'changePassword': {'adminPass': ''}}
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPBadRequest,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_change_password,
+ req, FAKE_UUID, body)
def test_server_change_password_none(self):
body = {'changePassword': {'adminPass': None}}
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPBadRequest,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_change_password,
+ req, FAKE_UUID, body)
def test_reboot_hard(self):
body = dict(reboot=dict(type="HARD"))
req = fakes.HTTPRequest.blank(self.url)
- self.controller.action(req, FAKE_UUID, body)
+ self.controller._action_reboot(req, FAKE_UUID, body)
def test_reboot_soft(self):
body = dict(reboot=dict(type="SOFT"))
req = fakes.HTTPRequest.blank(self.url)
- self.controller.action(req, FAKE_UUID, body)
+ self.controller._action_reboot(req, FAKE_UUID, body)
def test_reboot_incorrect_type(self):
body = dict(reboot=dict(type="NOT_A_TYPE"))
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPBadRequest,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_reboot,
+ req, FAKE_UUID, body)
def test_reboot_missing_type(self):
body = dict(reboot=dict())
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPBadRequest,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_reboot,
+ req, FAKE_UUID, body)
def test_reboot_not_found(self):
self.stubs.Set(nova.db, 'instance_get_by_uuid',
@@ -251,7 +243,8 @@ class ServerActionsControllerTest(test.TestCase):
body = dict(reboot=dict(type="HARD"))
req = fakes.HTTPRequest.blank(self.url)
- self.assertRaises(webob.exc.HTTPNotFound, self.controller.action,
+ self.assertRaises(webob.exc.HTTPNotFound,
+ self.controller._action_reboot,
req, str(utils.gen_uuid()), body)
def test_reboot_raises_conflict_on_invalid_state(self):
@@ -263,7 +256,8 @@ class ServerActionsControllerTest(test.TestCase):
self.stubs.Set(nova.compute.api.API, 'reboot', fake_reboot)
req = fakes.HTTPRequest.blank(self.url)
- self.assertRaises(webob.exc.HTTPConflict, self.controller.action,
+ self.assertRaises(webob.exc.HTTPConflict,
+ self.controller._action_reboot,
req, FAKE_UUID, body)
def test_rebuild_accepted_minimum(self):
@@ -278,7 +272,7 @@ class ServerActionsControllerTest(test.TestCase):
}
req = fakes.HTTPRequest.blank(self.url)
- robj = self.controller.action(req, FAKE_UUID, body)
+ robj = self.controller._action_rebuild(req, FAKE_UUID, body)
body = robj.obj
self.assertEqual(body['server']['image']['id'], '2')
@@ -300,7 +294,8 @@ class ServerActionsControllerTest(test.TestCase):
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPConflict,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_rebuild,
+ req, FAKE_UUID, body)
def test_rebuild_accepted_with_metadata(self):
metadata = {'new': 'metadata'}
@@ -316,7 +311,7 @@ class ServerActionsControllerTest(test.TestCase):
}
req = fakes.HTTPRequest.blank(self.url)
- body = self.controller.action(req, FAKE_UUID, body).obj
+ body = self.controller._action_rebuild(req, FAKE_UUID, body).obj
self.assertEqual(body['server']['metadata'], metadata)
@@ -330,7 +325,8 @@ class ServerActionsControllerTest(test.TestCase):
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPBadRequest,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_rebuild,
+ req, FAKE_UUID, body)
def test_rebuild_bad_entity(self):
body = {
@@ -341,7 +337,8 @@ class ServerActionsControllerTest(test.TestCase):
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPBadRequest,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_rebuild,
+ req, FAKE_UUID, body)
def test_rebuild_bad_personality(self):
body = {
@@ -356,7 +353,8 @@ class ServerActionsControllerTest(test.TestCase):
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPBadRequest,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_rebuild,
+ req, FAKE_UUID, body)
def test_rebuild_personality(self):
body = {
@@ -370,7 +368,7 @@ class ServerActionsControllerTest(test.TestCase):
}
req = fakes.HTTPRequest.blank(self.url)
- body = self.controller.action(req, FAKE_UUID, body).obj
+ body = self.controller._action_rebuild(req, FAKE_UUID, body).obj
self.assertTrue('personality' not in body['server'])
@@ -386,7 +384,7 @@ class ServerActionsControllerTest(test.TestCase):
}
req = fakes.HTTPRequest.blank(self.url)
- body = self.controller.action(req, FAKE_UUID, body).obj
+ body = self.controller._action_rebuild(req, FAKE_UUID, body).obj
self.assertEqual(body['server']['image']['id'], '2')
self.assertEqual(body['server']['adminPass'], 'asdf')
@@ -404,7 +402,8 @@ class ServerActionsControllerTest(test.TestCase):
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPNotFound,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_rebuild,
+ req, FAKE_UUID, body)
def test_rebuild_accessIP(self):
attributes = {
@@ -430,7 +429,7 @@ class ServerActionsControllerTest(test.TestCase):
task_state=None, progress=0, **attributes).AndReturn(None)
self.mox.ReplayAll()
- self.controller.action(req, FAKE_UUID, body)
+ self.controller._action_rebuild(req, FAKE_UUID, body)
self.mox.VerifyAll()
def test_resize_server(self):
@@ -445,7 +444,7 @@ class ServerActionsControllerTest(test.TestCase):
self.stubs.Set(nova.compute.api.API, 'resize', resize_mock)
req = fakes.HTTPRequest.blank(self.url)
- body = self.controller.action(req, FAKE_UUID, body)
+ body = self.controller._action_resize(req, FAKE_UUID, body)
self.assertEqual(self.resize_called, True)
@@ -454,14 +453,16 @@ class ServerActionsControllerTest(test.TestCase):
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPBadRequest,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_resize,
+ req, FAKE_UUID, body)
def test_resize_server_no_flavor_ref(self):
body = dict(resize=dict(flavorRef=None))
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPBadRequest,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_resize,
+ req, FAKE_UUID, body)
def test_resize_raises_conflict_on_invalid_state(self):
body = dict(resize=dict(flavorRef="http://localhost/3"))
@@ -472,7 +473,8 @@ class ServerActionsControllerTest(test.TestCase):
self.stubs.Set(nova.compute.api.API, 'resize', fake_resize)
req = fakes.HTTPRequest.blank(self.url)
- self.assertRaises(webob.exc.HTTPConflict, self.controller.action,
+ self.assertRaises(webob.exc.HTTPConflict,
+ self.controller._action_resize,
req, FAKE_UUID, body)
def test_confirm_resize_server(self):
@@ -486,7 +488,7 @@ class ServerActionsControllerTest(test.TestCase):
self.stubs.Set(nova.compute.api.API, 'confirm_resize', cr_mock)
req = fakes.HTTPRequest.blank(self.url)
- body = self.controller.action(req, FAKE_UUID, body)
+ body = self.controller._action_confirm_resize(req, FAKE_UUID, body)
self.assertEqual(self.confirm_resize_called, True)
@@ -503,7 +505,8 @@ class ServerActionsControllerTest(test.TestCase):
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPBadRequest,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_confirm_resize,
+ req, FAKE_UUID, body)
def test_confirm_resize_raises_conflict_on_invalid_state(self):
body = dict(confirmResize=None)
@@ -515,7 +518,8 @@ class ServerActionsControllerTest(test.TestCase):
fake_confirm_resize)
req = fakes.HTTPRequest.blank(self.url)
- self.assertRaises(webob.exc.HTTPConflict, self.controller.action,
+ self.assertRaises(webob.exc.HTTPConflict,
+ self.controller._action_confirm_resize,
req, FAKE_UUID, body)
def test_revert_resize_migration_not_found(self):
@@ -531,7 +535,8 @@ class ServerActionsControllerTest(test.TestCase):
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPBadRequest,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_revert_resize,
+ req, FAKE_UUID, body)
def test_revert_resize_server(self):
body = dict(revertResize=None)
@@ -544,7 +549,7 @@ class ServerActionsControllerTest(test.TestCase):
self.stubs.Set(nova.compute.api.API, 'revert_resize', revert_mock)
req = fakes.HTTPRequest.blank(self.url)
- body = self.controller.action(req, FAKE_UUID, body)
+ body = self.controller._action_revert_resize(req, FAKE_UUID, body)
self.assertEqual(self.revert_resize_called, True)
@@ -558,7 +563,8 @@ class ServerActionsControllerTest(test.TestCase):
fake_revert_resize)
req = fakes.HTTPRequest.blank(self.url)
- self.assertRaises(webob.exc.HTTPConflict, self.controller.action,
+ self.assertRaises(webob.exc.HTTPConflict,
+ self.controller._action_revert_resize,
req, FAKE_UUID, body)
def test_create_image(self):
@@ -569,7 +575,7 @@ class ServerActionsControllerTest(test.TestCase):
}
req = fakes.HTTPRequest.blank(self.url)
- response = self.controller.action(req, FAKE_UUID, body)
+ response = self.controller._action_create_image(req, FAKE_UUID, body)
location = response.headers['Location']
self.assertEqual('http://localhost/v2/fake/images/123', location)
@@ -589,7 +595,8 @@ class ServerActionsControllerTest(test.TestCase):
}
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPBadRequest,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_create_image,
+ req, FAKE_UUID, body)
def test_create_image_with_metadata(self):
body = {
@@ -600,7 +607,7 @@ class ServerActionsControllerTest(test.TestCase):
}
req = fakes.HTTPRequest.blank(self.url)
- response = self.controller.action(req, FAKE_UUID, body)
+ response = self.controller._action_create_image(req, FAKE_UUID, body)
location = response.headers['Location']
self.assertEqual('http://localhost/v2/fake/images/123', location)
@@ -617,7 +624,8 @@ class ServerActionsControllerTest(test.TestCase):
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPRequestEntityTooLarge,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_create_image,
+ req, FAKE_UUID, body)
def test_create_image_no_name(self):
body = {
@@ -625,7 +633,8 @@ class ServerActionsControllerTest(test.TestCase):
}
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPBadRequest,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_create_image,
+ req, FAKE_UUID, body)
def test_create_image_bad_metadata(self):
body = {
@@ -636,7 +645,8 @@ class ServerActionsControllerTest(test.TestCase):
}
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPBadRequest,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_create_image,
+ req, FAKE_UUID, body)
def test_create_image_raises_conflict_on_invalid_state(self):
def snapshot(*args, **kwargs):
@@ -651,7 +661,8 @@ class ServerActionsControllerTest(test.TestCase):
req = fakes.HTTPRequest.blank(self.url)
self.assertRaises(webob.exc.HTTPConflict,
- self.controller.action, req, FAKE_UUID, body)
+ self.controller._action_create_image,
+ req, FAKE_UUID, body)
class TestServerActionXMLDeserializer(test.TestCase):
diff --git a/nova/tests/api/openstack/test_wsgi.py b/nova/tests/api/openstack/test_wsgi.py
index 2d5f33eee..534ae7e2c 100644
--- a/nova/tests/api/openstack/test_wsgi.py
+++ b/nova/tests/api/openstack/test_wsgi.py
@@ -1,5 +1,6 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
+import inspect
import json
import webob
@@ -445,7 +446,7 @@ class ResourceTest(test.TestCase):
controller = Controller()
resource = wsgi.Resource(controller)
- method = resource.get_method(None, 'index')
+ method, extensions = resource.get_method(None, 'index', None, '')
actual = resource.dispatch(method, None, {'pants': 'off'})
expected = 'off'
self.assertEqual(actual, expected)
@@ -458,7 +459,68 @@ class ResourceTest(test.TestCase):
controller = Controller()
resource = wsgi.Resource(controller)
self.assertRaises(AttributeError, resource.get_method,
- None, 'create')
+ None, 'create', None, '')
+
+ def test_get_method_action_json(self):
+ class Controller(wsgi.Controller):
+ @wsgi.action('fooAction')
+ def _action_foo(self, req, id, body):
+ return body
+
+ controller = Controller()
+ resource = wsgi.Resource(controller)
+ method, extensions = resource.get_method(None, 'action',
+ 'application/json',
+ '{"fooAction": true}')
+ self.assertEqual(controller._action_foo, method)
+
+ def test_get_method_action_xml(self):
+ class Controller(wsgi.Controller):
+ @wsgi.action('fooAction')
+ def _action_foo(self, req, id, body):
+ return body
+
+ controller = Controller()
+ resource = wsgi.Resource(controller)
+ method, extensions = resource.get_method(None, 'action',
+ 'application/xml',
+ '<fooAction>true</fooAction>')
+ self.assertEqual(controller._action_foo, method)
+
+ def test_get_method_action_bad_body(self):
+ class Controller(wsgi.Controller):
+ @wsgi.action('fooAction')
+ def _action_foo(self, req, id, body):
+ return body
+
+ controller = Controller()
+ resource = wsgi.Resource(controller)
+ self.assertRaises(exception.MalformedRequestBody, resource.get_method,
+ None, 'action', 'application/json', '{}')
+
+ def test_get_method_unknown_controller_action(self):
+ class Controller(wsgi.Controller):
+ @wsgi.action('fooAction')
+ def _action_foo(self, req, id, body):
+ return body
+
+ controller = Controller()
+ resource = wsgi.Resource(controller)
+ self.assertRaises(KeyError, resource.get_method,
+ None, 'action', 'application/json',
+ '{"barAction": true}')
+
+ def test_get_method_action_method(self):
+ class Controller():
+ def action(self, req, pants=None):
+ return pants
+
+ controller = Controller()
+ resource = wsgi.Resource(controller)
+ method, extensions = resource.get_method(None, 'action',
+ 'application/xml',
+ '<fooAction>true</fooAction')
+ self.assertEqual(controller.action, method)
def test_get_action_args(self):
class Controller(object):
@@ -595,6 +657,287 @@ class ResourceTest(test.TestCase):
obj = resource.deserialize(controller.index, 'application/xml', 'foo')
self.assertEqual(obj, 'xml')
+ def test_register_actions(self):
+ class Controller(object):
+ def index(self, req, pants=None):
+ return pants
+
+ class ControllerExtended(wsgi.Controller):
+ @wsgi.action('fooAction')
+ def _action_foo(self, req, id, body):
+ return body
+
+ @wsgi.action('barAction')
+ def _action_bar(self, req, id, body):
+ return body
+
+ controller = Controller()
+ resource = wsgi.Resource(controller)
+ self.assertEqual({}, resource.wsgi_actions)
+
+ extended = ControllerExtended()
+ resource.register_actions(extended)
+ self.assertEqual({
+ 'fooAction': extended._action_foo,
+ 'barAction': extended._action_bar,
+ }, resource.wsgi_actions)
+
+ def test_register_extensions(self):
+ class Controller(object):
+ def index(self, req, pants=None):
+ return pants
+
+ class ControllerExtended(wsgi.Controller):
+ @wsgi.extends
+ def index(self, req, resp_obj, pants=None):
+ return None
+
+ @wsgi.extends(action='fooAction')
+ def _action_foo(self, req, resp, id, body):
+ return None
+
+ controller = Controller()
+ resource = wsgi.Resource(controller)
+ self.assertEqual({}, resource.wsgi_extensions)
+ self.assertEqual({}, resource.wsgi_action_extensions)
+
+ extended = ControllerExtended()
+ resource.register_extensions(extended)
+ self.assertEqual({'index': [extended.index]}, resource.wsgi_extensions)
+ self.assertEqual({'fooAction': [extended._action_foo]},
+ resource.wsgi_action_extensions)
+
+ def test_get_method_extensions(self):
+ class Controller(object):
+ def index(self, req, pants=None):
+ return pants
+
+ class ControllerExtended(wsgi.Controller):
+ @wsgi.extends
+ def index(self, req, resp_obj, pants=None):
+ return None
+
+ controller = Controller()
+ extended = ControllerExtended()
+ resource = wsgi.Resource(controller)
+ resource.register_extensions(extended)
+ method, extensions = resource.get_method(None, 'index', None, '')
+ self.assertEqual(method, controller.index)
+ self.assertEqual(extensions, [extended.index])
+
+ def test_get_method_action_extensions(self):
+ class Controller(wsgi.Controller):
+ def index(self, req, pants=None):
+ return pants
+
+ @wsgi.action('fooAction')
+ def _action_foo(self, req, id, body):
+ return body
+
+ class ControllerExtended(wsgi.Controller):
+ @wsgi.extends(action='fooAction')
+ def _action_foo(self, req, resp_obj, id, body):
+ return None
+
+ controller = Controller()
+ extended = ControllerExtended()
+ resource = wsgi.Resource(controller)
+ resource.register_extensions(extended)
+ method, extensions = resource.get_method(None, 'action',
+ 'application/json',
+ '{"fooAction": true}')
+ self.assertEqual(method, controller._action_foo)
+ self.assertEqual(extensions, [extended._action_foo])
+
+ def test_pre_process_extensions_regular(self):
+ class Controller(object):
+ def index(self, req, pants=None):
+ return pants
+
+ controller = Controller()
+ resource = wsgi.Resource(controller)
+
+ called = []
+
+ def extension1(req, resp_obj):
+ called.append(1)
+ return None
+
+ def extension2(req, resp_obj):
+ called.append(2)
+ return None
+
+ extensions = [extension1, extension2]
+ response, post = resource.pre_process_extensions(extensions, None, {})
+ self.assertEqual(called, [])
+ self.assertEqual(response, None)
+ self.assertEqual(list(post), [extension2, extension1])
+
+ def test_pre_process_extensions_generator(self):
+ class Controller(object):
+ def index(self, req, pants=None):
+ return pants
+
+ controller = Controller()
+ resource = wsgi.Resource(controller)
+
+ called = []
+
+ def extension1(req):
+ called.append('pre1')
+ resp_obj = yield
+ called.append('post1')
+
+ def extension2(req):
+ called.append('pre2')
+ resp_obj = yield
+ called.append('post2')
+
+ extensions = [extension1, extension2]
+ response, post = resource.pre_process_extensions(extensions, None, {})
+ post = list(post)
+ self.assertEqual(called, ['pre1', 'pre2'])
+ self.assertEqual(response, None)
+ self.assertEqual(len(post), 2)
+ self.assertTrue(inspect.isgenerator(post[0]))
+ self.assertTrue(inspect.isgenerator(post[1]))
+
+ for gen in post:
+ try:
+ gen.send(None)
+ except StopIteration:
+ continue
+
+ self.assertEqual(called, ['pre1', 'pre2', 'post2', 'post1'])
+
+ def test_pre_process_extensions_generator_response(self):
+ class Controller(object):
+ def index(self, req, pants=None):
+ return pants
+
+ controller = Controller()
+ resource = wsgi.Resource(controller)
+
+ called = []
+
+ def extension1(req):
+ called.append('pre1')
+ yield 'foo'
+
+ def extension2(req):
+ called.append('pre2')
+
+ extensions = [extension1, extension2]
+ response, post = resource.pre_process_extensions(extensions, None, {})
+ self.assertEqual(called, ['pre1'])
+ self.assertEqual(response, 'foo')
+ self.assertEqual(post, [])
+
+ def test_post_process_extensions_regular(self):
+ class Controller(object):
+ def index(self, req, pants=None):
+ return pants
+
+ controller = Controller()
+ resource = wsgi.Resource(controller)
+
+ called = []
+
+ def extension1(req, resp_obj):
+ called.append(1)
+ return None
+
+ def extension2(req, resp_obj):
+ called.append(2)
+ return None
+
+ response = resource.post_process_extensions([extension2, extension1],
+ None, None, {})
+ self.assertEqual(called, [2, 1])
+ self.assertEqual(response, None)
+
+ def test_post_process_extensions_regular_response(self):
+ class Controller(object):
+ def index(self, req, pants=None):
+ return pants
+
+ controller = Controller()
+ resource = wsgi.Resource(controller)
+
+ called = []
+
+ def extension1(req, resp_obj):
+ called.append(1)
+ return None
+
+ def extension2(req, resp_obj):
+ called.append(2)
+ return 'foo'
+
+ response = resource.post_process_extensions([extension2, extension1],
+ None, None, {})
+ self.assertEqual(called, [2])
+ self.assertEqual(response, 'foo')
+
+ def test_post_process_extensions_generator(self):
+ class Controller(object):
+ def index(self, req, pants=None):
+ return pants
+
+ controller = Controller()
+ resource = wsgi.Resource(controller)
+
+ called = []
+
+ def extension1(req):
+ resp_obj = yield
+ called.append(1)
+
+ def extension2(req):
+ resp_obj = yield
+ called.append(2)
+
+ ext1 = extension1(None)
+ ext1.next()
+ ext2 = extension2(None)
+ ext2.next()
+
+ response = resource.post_process_extensions([ext2, ext1],
+ None, None, {})
+
+ self.assertEqual(called, [2, 1])
+ self.assertEqual(response, None)
+
+ def test_post_process_extensions_generator_response(self):
+ class Controller(object):
+ def index(self, req, pants=None):
+ return pants
+
+ controller = Controller()
+ resource = wsgi.Resource(controller)
+
+ called = []
+
+ def extension1(req):
+ resp_obj = yield
+ called.append(1)
+
+ def extension2(req):
+ resp_obj = yield
+ called.append(2)
+ yield 'foo'
+
+ ext1 = extension1(None)
+ ext1.next()
+ ext2 = extension2(None)
+ ext2.next()
+
+ response = resource.post_process_extensions([ext2, ext1],
+ None, None, {})
+
+ self.assertEqual(called, [2])
+ self.assertEqual(response, 'foo')
+
class ResponseObjectTest(test.TestCase):
def test_default_code(self):