Skip to content

Commit

Permalink
Use controller method in all admin actions tests
Browse files Browse the repository at this point in the history
In API unit testing, making call through WSGI is little bit overhead,
wherever applicable, unit tests can make direct call to controller
methods.

This patch makes above cleanup in all admin actions tests.

Partially implements blueprint v2-on-v3-api

Change-Id: I78339d96e8365e8c0d06426a6fa78a90d11d5e82
  • Loading branch information
gmannos committed Mar 9, 2015
1 parent 4103a86 commit c36d2b3
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 285 deletions.
103 changes: 55 additions & 48 deletions nova/tests/unit/api/openstack/compute/admin_only_action_common.py
Expand Up @@ -12,30 +12,23 @@
# License for the specific language governing permissions and limitations
# under the License.

from oslo_serialization import jsonutils
from oslo_utils import timeutils
from oslo_utils import uuidutils
import webob

from nova.compute import vm_states
import nova.context
from nova import exception
from nova import test
from nova.tests.unit.api.openstack import fakes
from nova.tests.unit import fake_instance


class CommonMixin(object):
def setUp(self):
super(CommonMixin, self).setUp()
self.compute_api = None
self.context = nova.context.RequestContext('fake', 'fake')

def _make_request(self, url, body):
req = webob.Request.blank('/v2/fake' + url)
req.method = 'POST'
req.body = jsonutils.dumps(body)
req.content_type = 'application/json'
return req.get_response(self.app)
self.req = fakes.HTTPRequest.blank('')
self.context = self.req.environ['nova.context']

def _stub_instance_get(self, uuid=None):
if uuid is None:
Expand All @@ -60,10 +53,10 @@ def _test_non_existing_instance(self, action, body_map=None):
exception.InstanceNotFound(instance_id=uuid), uuid=uuid)

self.mox.ReplayAll()

res = self._make_request('/servers/%s/action' % uuid,
{action: body_map.get(action)})
self.assertEqual(404, res.status_int)
controller_function = getattr(self.controller, action)
self.assertRaises(webob.exc.HTTPNotFound,
controller_function,
self.req, uuid, body=body_map)
# Do these here instead of tearDown because this method is called
# more than once for the same test case
self.mox.VerifyAll()
Expand All @@ -72,29 +65,32 @@ def _test_non_existing_instance(self, action, body_map=None):
def _test_action(self, action, body=None, method=None,
compute_api_args_map=None):
if method is None:
method = action

method = action.replace('_', '')
compute_api_args_map = compute_api_args_map or {}

instance = self._stub_instance_get()

args, kwargs = compute_api_args_map.get(action, ((), {}))
getattr(self.compute_api, method)(self.context, instance, *args,
**kwargs)

self.mox.ReplayAll()

res = self._make_request('/servers/%s/action' % instance.uuid,
{action: body})
self.assertEqual(202, res.status_int)
controller_function = getattr(self.controller, action)
res = controller_function(self.req, instance.uuid, body=body)
# NOTE: on v2.1, http status code is set as wsgi_code of API
# method instead of status_int in a response object.
if self._api_version == '2.1':
status_int = controller_function.wsgi_code
else:
status_int = res.status_int
self.assertEqual(202, status_int)
# Do these here instead of tearDown because this method is called
# more than once for the same test case
self.mox.VerifyAll()
self.mox.UnsetStubs()

def _test_not_implemented_state(self, action, method=None):
if method is None:
method = action
method = action.replace('_', '')

instance = self._stub_instance_get()
body = {}
Expand All @@ -105,19 +101,20 @@ def _test_not_implemented_state(self, action, method=None):
NotImplementedError())

self.mox.ReplayAll()

res = self._make_request('/servers/%s/action' % instance.uuid,
{action: body})
self.assertEqual(501, res.status_int)
controller_function = getattr(self.controller, action)
self.assertRaises(webob.exc.HTTPNotImplemented,
controller_function,
self.req, instance.uuid, body=body)
# Do these here instead of tearDown because this method is called
# more than once for the same test case
self.mox.VerifyAll()
self.mox.UnsetStubs()

def _test_invalid_state(self, action, method=None, body_map=None,
compute_api_args_map=None):
compute_api_args_map=None,
exception_arg=None):
if method is None:
method = action
method = action.replace('_', '')
if body_map is None:
body_map = {}
if compute_api_args_map is None:
Expand All @@ -134,12 +131,14 @@ def _test_invalid_state(self, action, method=None, body_map=None,
state='foo', method=method))

self.mox.ReplayAll()

res = self._make_request('/servers/%s/action' % instance.uuid,
{action: body_map.get(action)})
self.assertEqual(409, res.status_int)
controller_function = getattr(self.controller, action)
ex = self.assertRaises(webob.exc.HTTPConflict,
controller_function,
self.req, instance.uuid,
body=body_map)
self.assertIn("Cannot \'%(action)s\' instance %(id)s"
% {'action': action, 'id': instance.uuid}, res.body)
% {'action': exception_arg or method,
'id': instance.uuid}, ex.explanation)
# Do these here instead of tearDown because this method is called
# more than once for the same test case
self.mox.VerifyAll()
Expand All @@ -148,7 +147,7 @@ def _test_invalid_state(self, action, method=None, body_map=None,
def _test_locked_instance(self, action, method=None, body=None,
compute_api_args_map=None):
if method is None:
method = action
method = action.replace('_', '')

compute_api_args_map = compute_api_args_map or {}
instance = self._stub_instance_get()
Expand All @@ -160,9 +159,10 @@ def _test_locked_instance(self, action, method=None, body=None,

self.mox.ReplayAll()

res = self._make_request('/servers/%s/action' % instance.uuid,
{action: body})
self.assertEqual(409, res.status_int)
controller_function = getattr(self.controller, action)
self.assertRaises(webob.exc.HTTPConflict,
controller_function,
self.req, instance.uuid, body=body)
# Do these here instead of tearDown because this method is called
# more than once for the same test case
self.mox.VerifyAll()
Expand All @@ -171,8 +171,7 @@ def _test_locked_instance(self, action, method=None, body=None,
def _test_instance_not_found_in_compute_api(self, action,
method=None, body=None, compute_api_args_map=None):
if method is None:
method = action

method = action.replace('_', '')
compute_api_args_map = compute_api_args_map or {}

instance = self._stub_instance_get()
Expand All @@ -184,9 +183,10 @@ def _test_instance_not_found_in_compute_api(self, action,

self.mox.ReplayAll()

res = self._make_request('/servers/%s/action' % instance.uuid,
{action: body})
self.assertEqual(404, res.status_int)
controller_function = getattr(self.controller, action)
self.assertRaises(webob.exc.HTTPNotFound,
controller_function,
self.req, instance.uuid, body=body)
# Do these here instead of tearDown because this method is called
# more than once for the same test case
self.mox.VerifyAll()
Expand All @@ -202,7 +202,8 @@ def _test_actions(self, actions, method_translations=None, body_map=None,
for action in actions:
method = method_translations.get(action)
body = body_map.get(action)
self.mox.StubOutWithMock(self.compute_api, method or action)
self.mox.StubOutWithMock(self.compute_api,
method or action.replace('_', ''))
self._test_action(action, method=method, body=body,
compute_api_args_map=args_map)
# Re-mock this.
Expand All @@ -217,7 +218,8 @@ def _test_actions_instance_not_found_in_compute_api(self,
for action in actions:
method = method_translations.get(action)
body = body_map.get(action)
self.mox.StubOutWithMock(self.compute_api, method or action)
self.mox.StubOutWithMock(self.compute_api,
method or action.replace('_', ''))
self._test_instance_not_found_in_compute_api(
action, method=method, body=body,
compute_api_args_map=args_map)
Expand All @@ -234,16 +236,20 @@ def _test_actions_with_non_existed_instance(self, actions, body_map=None):

def _test_actions_raise_conflict_on_invalid_state(
self, actions, method_translations=None, body_map=None,
args_map=None):
args_map=None, exception_args=None):
method_translations = method_translations or {}
body_map = body_map or {}
args_map = args_map or {}
exception_args = exception_args or {}
for action in actions:
method = method_translations.get(action)
self.mox.StubOutWithMock(self.compute_api, method or action)
exception_arg = exception_args.get(action)
self.mox.StubOutWithMock(self.compute_api,
method or action.replace('_', ''))
self._test_invalid_state(action, method=method,
body_map=body_map,
compute_api_args_map=args_map)
compute_api_args_map=args_map,
exception_arg=exception_arg)
# Re-mock this.
self.mox.StubOutWithMock(self.compute_api, 'get')

Expand All @@ -256,7 +262,8 @@ def _test_actions_with_locked_instance(self, actions,
for action in actions:
method = method_translations.get(action)
body = body_map.get(action)
self.mox.StubOutWithMock(self.compute_api, method or action)
self.mox.StubOutWithMock(self.compute_api,
method or action.replace('_', ''))
self._test_locked_instance(action, method=method, body=body,
compute_api_args_map=args_map)
# Re-mock this.
Expand Down
Expand Up @@ -16,7 +16,6 @@
admin_actions_v2
from nova.api.openstack.compute.plugins.v3 import admin_actions as \
admin_actions_v21
import nova.context
from nova import exception
from nova import test
from nova.tests.unit.api.openstack.compute import admin_only_action_common
Expand All @@ -25,61 +24,44 @@

class AdminActionsTestV21(admin_only_action_common.CommonTests):
admin_actions = admin_actions_v21
fake_url = '/v2/fake'
_api_version = '2.1'

def setUp(self):
super(AdminActionsTestV21, self).setUp()
self.controller = self.admin_actions.AdminActionsController()
self.compute_api = self.controller.compute_api
self.context = nova.context.RequestContext('fake', 'fake')

def _fake_controller(*args, **kwargs):
return self.controller

self.stubs.Set(self.admin_actions, 'AdminActionsController',
_fake_controller)

self.app = self._get_app()
self.mox.StubOutWithMock(self.compute_api, 'get')

def _get_app(self):
return fakes.wsgi_app_v21(init_only=('servers',
'os-admin-actions'),
fake_auth_context=self.context)

def test_actions(self):
actions = ['resetNetwork', 'injectNetworkInfo']
method_translations = {'resetNetwork': 'reset_network',
'injectNetworkInfo': 'inject_network_info'}
actions = ['_reset_network', '_inject_network_info']
method_translations = {'_reset_network': 'reset_network',
'_inject_network_info': 'inject_network_info'}

self._test_actions(actions, method_translations)

def test_actions_with_non_existed_instance(self):
actions = ['resetNetwork', 'injectNetworkInfo']
actions = ['_reset_network', '_inject_network_info']
self._test_actions_with_non_existed_instance(actions)

def test_actions_with_locked_instance(self):
actions = ['resetNetwork', 'injectNetworkInfo']
method_translations = {'resetNetwork': 'reset_network',
'injectNetworkInfo': 'inject_network_info'}
actions = ['_reset_network', '_inject_network_info']
method_translations = {'_reset_network': 'reset_network',
'_inject_network_info': 'inject_network_info'}

self._test_actions_with_locked_instance(actions,
method_translations=method_translations)


class AdminActionsTestV2(AdminActionsTestV21):
admin_actions = admin_actions_v2

def setUp(self):
super(AdminActionsTestV2, self).setUp()
self.flags(
osapi_compute_extension=[
'nova.api.openstack.compute.contrib.select_extensions'],
osapi_compute_ext_list=['Admin_actions'])

def _get_app(self):
return fakes.wsgi_app(init_only=('servers',),
fake_auth_context=self.context)
_api_version = '2'


class AdminActionsPolicyEnforcementV21(test.NoDBTestCase):
Expand Down

0 comments on commit c36d2b3

Please sign in to comment.