Merge "Tune receiver unit tests in service engine"

This commit is contained in:
Jenkins 2016-02-16 12:26:08 +00:00 committed by Gerrit Code Review
commit 1efac4cb6b
2 changed files with 116 additions and 99 deletions

View File

@ -1838,7 +1838,16 @@ class EngineService(service.Service):
LOG.info(_LI("Action '%s' is deleted."), identity)
def receiver_find(self, context, identity, project_safe=True):
"""Find a receiver with the given identity (could be name or ID)."""
"""Find a receiver with the given identity.
:param context: An instance of the request context.
:param identity: The UUID, name or short-id of a receiver.
:param project_safe: A boolean indicating whether receiver from other
projects other than the requesting one can be
returned.
:return: A DB object of receiver or an exception `ReceiverNotFound`
if no matching reciever is found.
"""
if uuidutils.is_uuid_like(identity):
receiver = db_api.receiver_get(context, identity,
project_safe=project_safe)
@ -1860,10 +1869,23 @@ class EngineService(service.Service):
@request_context
def receiver_list(self, context, limit=None, marker=None, sort=None,
filters=None, project_safe=True):
if limit is not None:
limit = utils.parse_int_param('limit', limit)
if project_safe is not None:
project_safe = utils.parse_bool_param('project_safe', project_safe)
"""List receivers matching the specified criteria.
:param context: An instance of the request context.
:param limit: An integer specifying the maximum number of objects to
return in a response.
:param marker: An UUID specifying the receiver after which the result
list starts.
:param sort: A list of sorting keys (each optionally attached with a
sorting direction) separated by commas.
:param filters: A dictionary of key-value pairs for filtering out the
result list.
:param project_safe: A boolean indicating whether receivers from all
projects will be returned.
:return: A list of `Receiver` object representations.
"""
limit = utils.parse_int_param('limit', limit)
project_safe = utils.parse_bool_param('project_safe', project_safe)
receivers = receiver_mod.Receiver.load_all(context, limit=limit,
marker=marker,
@ -1876,15 +1898,17 @@ class EngineService(service.Service):
actor=None, params=None):
"""Create a receiver.
:param context: RPC context.
:param context: An instance of the request context.
:param name: Name of the receiver.
:param type_name: Name of the receiver type, subject to validation.
:param cluster_id: Name or ID of a cluster.
:param cluster_id: UUID, name or short-id of a cluster.
:param action: Name or ID of an action, currently only builtin action
names are supported.
:param actor: Future extension.
:param params: A dictionary containing key-value pairs as inputs to
the action.
:return: A dictionary containing the details about the receiver
created.
"""
if cfg.CONF.name_unique:
if db_api.receiver_get_by_name(context, name):
@ -1933,13 +1957,22 @@ class EngineService(service.Service):
receiver = receiver_mod.Receiver.create(context, rtype, cluster,
action, **kwargs)
LOG.info(_LI("Webhook (%(n)s) is created: %(i)s."),
LOG.info(_LI("Receiver (%(n)s) is created: %(i)s."),
{'n': name, 'i': receiver.id})
return receiver.to_dict()
@request_context
def receiver_get(self, context, identity, project_safe=True):
"""Get the details about a receiver.
:param context: An instance of the request context.
:param identity: The UUID, name or short-id of a receiver.
:param project_safe: Whether matching object from other projects can
be returned.
:return: A dictionary containing the details about a receiver or
an exception `ReceiverNotFound` if no matching object found.
"""
db_receiver = self.receiver_find(context, identity,
project_safe=project_safe)
receiver = receiver_mod.Receiver.load(context,
@ -1949,6 +1982,13 @@ class EngineService(service.Service):
@request_context
def receiver_delete(self, context, identity):
"""Delete the specified receiver.
:param context: An instance of the request context.
:param identity: The UUID, name or short-id of a receiver.
:return: None if successfully deleted the receiver or an exception of
`ReceiverNotFound` if the object could not be found.
"""
db_receiver = self.receiver_find(context, identity)
LOG.info(_LI("Deleting receiver %s."), identity)
db_api.receiver_delete(context, db_receiver.id)

View File

@ -16,8 +16,7 @@ from oslo_messaging.rpc import dispatcher as rpc
from oslo_utils import uuidutils
import six
from senlin.common import exception
from senlin.common.i18n import _
from senlin.common import exception as exc
from senlin.db.sqlalchemy import api as db_api
from senlin.engine import receiver
from senlin.engine import service
@ -31,107 +30,82 @@ class ReceiverTest(base.SenlinTestCase):
super(ReceiverTest, self).setUp()
self.ctx = utils.dummy_context(project='receiver_test_project')
self.eng = service.EngineService('host-a', 'topic-a')
self.eng.init_tgm()
@mock.patch.object(db_api, 'receiver_get')
@mock.patch.object(db_api, 'receiver_get_by_name')
def test_receiver_find_by_id(self, mock_get_name, mock_get):
def test_receiver_find_by_uuid(self, mock_get):
fake_obj = mock.Mock()
mock_get.return_value = fake_obj
fake_id = uuidutils.generate_uuid()
# Found: project_safe True
res = self.eng.receiver_find(self.ctx, fake_id)
self.assertEqual(fake_obj, res)
mock_get.assert_called_once_with(self.ctx, fake_id, project_safe=True)
mock_get.reset_mock()
# Found: project_safe False
res = self.eng.receiver_find(self.ctx, fake_id, False)
self.assertEqual(fake_obj, res)
mock_get.assert_called_once_with(self.ctx, fake_id, project_safe=False)
mock_get.reset_mock()
# Not Found: project_safe True
@mock.patch.object(db_api, 'receiver_get_by_name')
@mock.patch.object(db_api, 'receiver_get')
def test_receiver_find_by_uuid_as_name(self, mock_get, mock_get_name):
mock_get.return_value = None
fake_obj = mock.Mock()
mock_get_name.return_value = fake_obj
res = self.eng.receiver_find(self.ctx, fake_id)
self.assertEqual(fake_obj, res)
mock_get.assert_called_once_with(self.ctx, fake_id, project_safe=True)
mock_get_name.assert_called_once_with(self.ctx, fake_id,
project_safe=True)
mock_get.reset_mock()
mock_get_name.reset_mock()
fake_id = uuidutils.generate_uuid()
res = self.eng.receiver_find(self.ctx, fake_id, project_safe=False)
# Not Found: project_safe False
res = self.eng.receiver_find(self.ctx, fake_id, False)
self.assertEqual(fake_obj, res)
mock_get.assert_called_once_with(self.ctx, fake_id, project_safe=False)
mock_get_name.assert_called_once_with(self.ctx, fake_id,
project_safe=False)
mock_get.reset_mock()
mock_get_name.reset_mock()
# No luck at all
mock_get_name.return_value = None
self.assertRaises(exception.ReceiverNotFound,
self.eng.receiver_find,
self.ctx, fake_id, True)
@mock.patch.object(db_api, 'receiver_get_by_name')
@mock.patch.object(db_api, 'receiver_get_by_short_id')
def test_receiver_find_by_name_short_id(self, x_get_short, x_get_name):
def test_receiver_find_by_name(self, mock_get_name):
fake_obj = mock.Mock()
x_get_name.return_value = fake_obj
fake_id = 'aaaa-bbbb'
mock_get_name.return_value = fake_obj
fake_id = 'not-a-uuid'
# Found: project_safe True
res = self.eng.receiver_find(self.ctx, fake_id)
self.assertEqual(fake_obj, res)
x_get_name.assert_called_once_with(self.ctx, fake_id,
project_safe=True)
x_get_name.reset_mock()
# Found: project_safe False
self.assertEqual(fake_obj, res)
mock_get_name.assert_called_once_with(self.ctx, fake_id,
project_safe=True)
@mock.patch.object(db_api, 'receiver_get_by_short_id')
@mock.patch.object(db_api, 'receiver_get_by_name')
def test_receiver_find_by_short_id(self, mock_get_name, mock_get_shortid):
mock_get_name.return_value = None
fake_obj = mock.Mock()
mock_get_shortid.return_value = fake_obj
fake_id = '12345678'
res = self.eng.receiver_find(self.ctx, fake_id, False)
self.assertEqual(fake_obj, res)
x_get_name.assert_called_once_with(self.ctx, fake_id,
project_safe=False)
x_get_name.reset_mock()
# Not Found: project_safe True
x_get_name.return_value = None
x_get_short.return_value = fake_obj
res = self.eng.receiver_find(self.ctx, fake_id)
self.assertEqual(fake_obj, res)
x_get_name.assert_called_once_with(self.ctx, fake_id,
project_safe=True)
x_get_short.assert_called_once_with(self.ctx, fake_id,
project_safe=True)
x_get_name.reset_mock()
x_get_short.reset_mock()
mock_get_name.assert_called_once_with(self.ctx, fake_id,
project_safe=False)
mock_get_shortid.assert_called_once_with(self.ctx, fake_id,
project_safe=False)
# Not Found: project_safe False
res = self.eng.receiver_find(self.ctx, fake_id, False)
self.assertEqual(fake_obj, res)
x_get_name.assert_called_once_with(self.ctx, fake_id,
project_safe=False)
x_get_short.assert_called_once_with(self.ctx, fake_id,
project_safe=False)
@mock.patch.object(db_api, 'receiver_get_by_name')
def test_receiver_find_not_found(self, mock_get_name):
mock_get_name.return_value = None
fake_id = '12345678' # not a uuid
# No luck at all
x_get_short.return_value = None
self.assertRaises(exception.ReceiverNotFound,
self.assertRaises(exc.ReceiverNotFound,
self.eng.receiver_find,
self.ctx, fake_id, True)
mock_get_name.assert_called_once_with(self.ctx, fake_id,
project_safe=True)
@mock.patch.object(receiver.Receiver, 'load_all')
def test_receiver_list(self, mock_load):
fake_obj = mock.Mock()
fake_obj.to_dict.return_value = {'FOO': 'BAR'}
# NOTE: actual return value is a generator
mock_load.return_value = [fake_obj]
result = self.eng.receiver_list(self.ctx)
self.assertIsInstance(result, list)
self.assertEqual([{'FOO': 'BAR'}], result)
mock_load.assert_called_once_with(self.ctx, limit=None, marker=None,
@ -158,19 +132,20 @@ class ReceiverTest(base.SenlinTestCase):
def test_receiver_list_bad_params(self):
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_list, self.ctx, limit='no')
self.assertEqual(exception.InvalidParameter, ex.exc_info[0])
self.assertEqual(exc.InvalidParameter, ex.exc_info[0])
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_list,
self.ctx, project_safe='yes')
self.assertEqual(exception.InvalidParameter, ex.exc_info[0])
self.assertEqual(exc.InvalidParameter, ex.exc_info[0])
@mock.patch.object(service.EngineService, 'cluster_find')
@mock.patch.object(receiver.Receiver, 'create')
def test_receiver_create_okay(self, mock_create, mock_find):
def test_receiver_create(self, mock_create, mock_find):
fake_cluster = mock.Mock()
fake_cluster.user = self.ctx.user
mock_find.return_value = fake_cluster
fake_receiver = mock.Mock(id='FAKE_RECIEVER')
fake_receiver.to_dict.return_value = {
'id': 'FAKE_RECEIVER',
@ -208,9 +183,9 @@ class ReceiverTest(base.SenlinTestCase):
self.eng.receiver_create,
self.ctx, 'r1', 'webhook', 'C1',
'CLUSTER_RESIZE')
self.assertEqual(exception.SenlinBadRequest, ex.exc_info[0])
self.assertEqual(_("The request is malformed: A receiver named 'r1' "
"already exists."),
self.assertEqual(exc.SenlinBadRequest, ex.exc_info[0])
self.assertEqual("The request is malformed: A receiver named 'r1' "
"already exists.",
six.text_type(ex.exc_info[1]))
def test_receiver_create_bad_type(self):
@ -218,18 +193,18 @@ class ReceiverTest(base.SenlinTestCase):
self.eng.receiver_create,
self.ctx, 'r1', 'rocket', 'C1',
'CLUSTER_RESIZE')
self.assertEqual(exception.SenlinBadRequest, ex.exc_info[0])
self.assertEqual(_("The request is malformed: Receiver type 'rocket' "
"is not supported."),
self.assertEqual(exc.SenlinBadRequest, ex.exc_info[0])
self.assertEqual("The request is malformed: Receiver type 'rocket' "
"is not supported.",
six.text_type(ex.exc_info[1]))
@mock.patch.object(service.EngineService, 'cluster_find')
def test_receiver_create_cluster_not_found(self, mock_find):
mock_find.side_effect = exception.ClusterNotFound(cluster='C1')
mock_find.side_effect = exc.ClusterNotFound(cluster='C1')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_create,
self.ctx, 'r1', 'webhook', 'C1', 'whatever')
self.assertEqual(exception.SenlinBadRequest, ex.exc_info[0])
self.assertEqual(exc.SenlinBadRequest, ex.exc_info[0])
self.assertEqual("The request is malformed: The referenced cluster "
"'C1' is not found.",
six.text_type(ex.exc_info[1]))
@ -244,7 +219,7 @@ class ReceiverTest(base.SenlinTestCase):
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_create,
self.ctx, 'r1', 'webhook', 'C1', 'FLY')
self.assertEqual(exception.Forbidden, ex.exc_info[0])
self.assertEqual(exc.Forbidden, ex.exc_info[0])
fake_receiver = mock.Mock(id='FAKE_RECIEVER')
fake_receiver.to_dict.return_value = {
@ -258,7 +233,7 @@ class ReceiverTest(base.SenlinTestCase):
result = self.eng.receiver_create(self.ctx, 'r1', 'webhook', 'C1',
'CLUSTER_RESIZE')
self.assertIsInstance(result, dict)
# All other tests are done in 'test_receiver_create_okay'
# All other tests are done in 'test_receiver_create'
@mock.patch.object(service.EngineService, 'cluster_find')
def test_receiver_create_bad_action(self, mock_find):
@ -269,7 +244,7 @@ class ReceiverTest(base.SenlinTestCase):
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_create,
self.ctx, 'r1', 'webhook', 'C1', 'DANCE')
self.assertEqual(exception.SenlinBadRequest, ex.exc_info[0])
self.assertEqual(exc.SenlinBadRequest, ex.exc_info[0])
self.assertEqual("The request is malformed: Illegal action 'DANCE' "
"specified.",
six.text_type(ex.exc_info[1]))
@ -277,7 +252,7 @@ class ReceiverTest(base.SenlinTestCase):
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_create,
self.ctx, 'r1', 'webhook', 'C1', 'NODE_JOIN')
self.assertEqual(exception.SenlinBadRequest, ex.exc_info[0])
self.assertEqual(exc.SenlinBadRequest, ex.exc_info[0])
self.assertEqual("The request is malformed: Action 'NODE_JOIN' is "
"not applicable to clusters.",
six.text_type(ex.exc_info[1]))
@ -292,6 +267,7 @@ class ReceiverTest(base.SenlinTestCase):
mock_load.return_value = fake_receiver
res = self.eng.receiver_get(self.ctx, 'FAKE_ID')
self.assertEqual({'FOO': 'BAR'}, res)
mock_find.assert_called_once_with(self.ctx, 'FAKE_ID',
project_safe=True)
@ -299,20 +275,21 @@ class ReceiverTest(base.SenlinTestCase):
receiver_obj=fake_obj,
project_safe=True)
# Simulate not found
mock_find = self.patchobject(self.eng, 'receiver_find')
mock_find.side_effect = exception.ReceiverNotFound(receiver='RR')
@mock.patch.object(service.EngineService, 'receiver_find')
def test_receiver_get_not_found(self, mock_find):
mock_find.side_effect = exc.ReceiverNotFound(receiver='RR')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_get, self.ctx, 'Bogus')
self.assertEqual(exception.ReceiverNotFound, ex.exc_info[0])
self.assertEqual(exc.ReceiverNotFound, ex.exc_info[0])
@mock.patch.object(service.EngineService, 'receiver_find')
@mock.patch.object(db_api, 'receiver_delete')
def test_receiver_delete(self, mock_delete):
def test_receiver_delete(self, mock_delete, mock_find):
fake_obj = mock.Mock()
fake_obj.id = 'FAKE_ID'
mock_find = self.patchobject(self.eng, 'receiver_find',
return_value=fake_obj)
mock_find.return_value = fake_obj
result = self.eng.receiver_delete(self.ctx, 'FAKE_RECEIVER')
@ -320,10 +297,10 @@ class ReceiverTest(base.SenlinTestCase):
mock_find.assert_called_once_with(self.ctx, 'FAKE_RECEIVER')
mock_delete.assert_called_once_with(self.ctx, 'FAKE_ID')
def test_receiver_delete_not_found(self):
mock_find = self.patchobject(self.eng, 'receiver_find')
mock_find.side_effect = exception.ReceiverNotFound(receiver='RR')
@mock.patch.object(service.EngineService, 'receiver_find')
def test_receiver_delete_not_found(self, mock_find):
mock_find.side_effect = exc.ReceiverNotFound(receiver='RR')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_delete, self.ctx, 'Bogus')
self.assertEqual(exception.ReceiverNotFound, ex.exc_info[0])
self.assertEqual(exc.ReceiverNotFound, ex.exc_info[0])