Merge "Tune receiver unit tests in service engine"
This commit is contained in:
commit
1efac4cb6b
|
@ -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)
|
||||
|
|
|
@ -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])
|
||||
|
|
Loading…
Reference in New Issue