senlin/senlin/tests/unit/engine/receivers/test_message.py

711 lines
30 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import socket
from unittest import mock
from keystoneauth1 import loading as ks_loading
from oslo_config import cfg
from oslo_utils import uuidutils
from senlin.common import consts
from senlin.common import exception
from senlin.common.i18n import _
from senlin.drivers import base as driver_base
from senlin.engine.actions import base as action_mod
from senlin.engine import dispatcher
from senlin.engine.receivers import message as mmod
from senlin.objects import cluster as co
from senlin.tests.unit.common import base
from senlin.tests.unit.common import utils
UUID = 'aa5f86b8-e52b-4f2b-828a-4c14c770938d'
class TestMessage(base.SenlinTestCase):
def setUp(self):
super(TestMessage, self).setUp()
self.context = utils.dummy_context()
@mock.patch.object(driver_base, 'SenlinDriver')
def test_keystone_client(self, mock_senlindriver):
sd = mock.Mock()
kc = mock.Mock()
sd.identity.return_value = kc
mock_senlindriver.return_value = sd
message = mmod.Message('message', None, None, user='user1',
project='project1')
# cached will be returned
message._keystoneclient = kc
self.assertEqual(kc, message.keystone())
# new keystone client created if no cache found
message._keystoneclient = None
params = mock.Mock()
mock_param = self.patchobject(mmod.Message, '_build_conn_params',
return_value=params)
res = message.keystone()
self.assertEqual(kc, res)
self.assertEqual(kc, message._keystoneclient)
mock_param.assert_called_once_with('user1', 'project1')
sd.identity.assert_called_once_with(params)
@mock.patch.object(driver_base, 'SenlinDriver')
def test_zaqar_client(self, mock_senlindriver):
sd = mock.Mock()
zc = mock.Mock()
sd.message.return_value = zc
mock_senlindriver.return_value = sd
message = mmod.Message('message', None, None, user='user1',
project='project1')
# cached will be returned
message._zaqarclient = zc
self.assertEqual(zc, message.zaqar())
# new zaqar client created if no cache found
message._zaqarclient = None
params = mock.Mock()
mock_param = self.patchobject(mmod.Message, '_build_conn_params',
return_value=params)
res = message.zaqar()
self.assertEqual(zc, res)
self.assertEqual(zc, message._zaqarclient)
mock_param.assert_called_once_with('user1', 'project1')
sd.message.assert_called_once_with(params)
def test_generate_subscriber_url_host_provided(self):
cfg.CONF.set_override('host', 'web.com', 'receiver')
cfg.CONF.set_override('port', '1234', 'receiver')
message = mmod.Message('message', None, None, id=UUID)
res = message._generate_subscriber_url()
expected = 'trust+http://web.com:1234/v1/receivers/%s/notify' % UUID
self.assertEqual(expected, res)
@mock.patch.object(mmod.Message, '_get_base_url')
def test_generate_subscriber_url_host_not_provided(
self, mock_get_base_url):
mock_get_base_url.return_value = 'http://web.com:1234/v1'
message = mmod.Message('message', None, None, id=UUID)
res = message._generate_subscriber_url()
expected = 'trust+http://web.com:1234/v1/receivers/%s/notify' % UUID
self.assertEqual(expected, res)
@mock.patch.object(socket, 'gethostname')
@mock.patch.object(mmod.Message, '_get_base_url')
def test_generate_subscriber_url_no_host_no_base(
self, mock_get_base_url, mock_gethostname):
mock_get_base_url.return_value = None
mock_gethostname.return_value = 'test-host'
message = mmod.Message('message', None, None, id=UUID)
res = message._generate_subscriber_url()
expected = 'trust+http://test-host:8777/v1/receivers/%s/notify' % UUID
self.assertEqual(expected, res)
def test_to_dict(self):
message = mmod.Message('message', None, None, user='user1',
project='project1', id=UUID)
message.channel = {'queue_name': 'test-queue',
'subscription': 'subscription-id'}
res = message.to_dict()
expected_res = {
'name': None,
'id': UUID,
'user': 'user1',
'project': 'project1',
'domain': '',
'type': 'message',
'channel': {'queue_name': 'test-queue'},
'action': None,
'cluster_id': None,
'actor': {},
'params': {},
'created_at': None,
'updated_at': None,
}
self.assertEqual(expected_res, res)
@mock.patch.object(mmod.Message, '_create_queue')
@mock.patch.object(mmod.Message, '_create_subscription')
def test_initialize_channel(self, mock_create_subscription,
mock_create_queue):
mock_sub = mock.Mock()
mock_sub.subscription_id = 'test-subscription-id'
mock_create_subscription.return_value = mock_sub
mock_create_queue.return_value = 'test-queue'
message = mmod.Message('message', None, None)
res = message.initialize_channel(self.context)
expected_channel = {'queue_name': 'test-queue',
'subscription': 'test-subscription-id'}
self.assertEqual(expected_channel, res)
mock_create_queue.assert_called_once_with()
mock_create_subscription.assert_called_once_with('test-queue')
@mock.patch.object(mmod.Message, 'zaqar')
def test_create_queue(self, mock_zaqar):
cfg.CONF.set_override('max_message_size', 8192, 'receiver')
mock_zc = mock.Mock()
mock_zaqar.return_value = mock_zc
message = mmod.Message('message', None, None, id=UUID)
queue_name = 'senlin-receiver-%s' % message.id
kwargs = {
'_max_messages_post_size': 8192,
'description': 'Senlin receiver %s.' % message.id,
'name': queue_name
}
mock_zc.queue_create.return_value = queue_name
res = message._create_queue()
self.assertEqual(queue_name, res)
mock_zc.queue_create.assert_called_once_with(**kwargs)
@mock.patch.object(mmod.Message, 'zaqar')
def test_create_queue_fail(self, mock_zaqar):
cfg.CONF.set_override('max_message_size', 8192, 'receiver')
mock_zc = mock.Mock()
mock_zaqar.return_value = mock_zc
message = mmod.Message('message', None, None, id=UUID)
queue_name = 'senlin-receiver-%s' % message.id
kwargs = {
'_max_messages_post_size': 8192,
'description': 'Senlin receiver %s.' % message.id,
'name': queue_name
}
mock_zc.queue_create.side_effect = exception.InternalError()
self.assertRaises(exception.EResourceCreation, message._create_queue)
mock_zc.queue_create.assert_called_once_with(**kwargs)
@mock.patch.object(mmod.Message, '_generate_subscriber_url')
@mock.patch.object(mmod.Message, '_build_trust')
@mock.patch.object(mmod.Message, 'zaqar')
def test_create_subscription(self, mock_zaqar, mock_build_trust,
mock_generate_subscriber_url):
mock_zc = mock.Mock()
mock_zaqar.return_value = mock_zc
mock_build_trust.return_value = '123abc'
subscriber = 'subscriber_url'
mock_generate_subscriber_url.return_value = subscriber
message = mmod.Message('message', None, None, id=UUID)
queue_name = 'test-queue'
kwargs = {
"ttl": 2 ** 36,
"subscriber": subscriber,
"options": {
"trust_id": "123abc"
}
}
mock_zc.subscription_create.return_value = 'subscription'
res = message._create_subscription(queue_name)
self.assertEqual('subscription', res)
mock_generate_subscriber_url.assert_called_once_with()
mock_zc.subscription_create.assert_called_once_with(queue_name,
**kwargs)
@mock.patch.object(mmod.Message, '_generate_subscriber_url')
@mock.patch.object(mmod.Message, '_build_trust')
@mock.patch.object(mmod.Message, 'zaqar')
def test_create_subscription_fail(self, mock_zaqar, mock_build_trust,
mock_generate_subscriber_url):
mock_zc = mock.Mock()
mock_zaqar.return_value = mock_zc
mock_build_trust.return_value = '123abc'
subscriber = 'subscriber_url'
mock_generate_subscriber_url.return_value = subscriber
message = mmod.Message('message', None, None, id=UUID)
message.id = UUID
queue_name = 'test-queue'
kwargs = {
"ttl": 2 ** 36,
"subscriber": subscriber,
"options": {
"trust_id": "123abc"
}
}
mock_zc.subscription_create.side_effect = exception.InternalError()
self.assertRaises(exception.EResourceCreation,
message._create_subscription, queue_name)
mock_generate_subscriber_url.assert_called_once_with()
mock_zc.subscription_create.assert_called_once_with(queue_name,
**kwargs)
@mock.patch.object(mmod.Message, 'zaqar')
def test_release_channel(self, mock_zaqar):
mock_zc = mock.Mock()
mock_zaqar.return_value = mock_zc
channel = {'queue_name': 'test-queue',
'subscription': 'test-subscription-id'}
message = mmod.Message('message', None, None, id=UUID,
channel=channel)
message.release_channel(self.context)
mock_zc.subscription_delete.assert_called_once_with(
'test-queue', 'test-subscription-id')
mock_zc.queue_delete.assert_called_once_with('test-queue')
@mock.patch.object(mmod.Message, 'zaqar')
def test_release_channel_subscription_delete_fail(self, mock_zaqar):
mock_zc = mock.Mock()
mock_zaqar.return_value = mock_zc
channel = {'queue_name': 'test-queue',
'subscription': 'test-subscription-id'}
message = mmod.Message('message', None, None, id=UUID,
channel=channel)
mock_zc.subscription_delete.side_effect = exception.InternalError()
self.assertRaises(exception.EResourceDeletion,
message.release_channel, self.context)
mock_zc.subscription_delete.assert_called_once_with(
'test-queue', 'test-subscription-id')
@mock.patch.object(mmod.Message, 'zaqar')
def test_release_channel_queue_delete_fail(self, mock_zaqar):
mock_zc = mock.Mock()
mock_zaqar.return_value = mock_zc
channel = {'queue_name': 'test-queue',
'subscription': 'test-subscription-id'}
message = mmod.Message('message', None, None, id=UUID,
channel=channel)
mock_zc.queue_delete.side_effect = exception.InternalError()
self.assertRaises(exception.EResourceDeletion,
message.release_channel, self.context)
mock_zc.subscription_delete.assert_called_once_with(
'test-queue', 'test-subscription-id')
mock_zc.queue_delete.assert_called_once_with('test-queue')
@mock.patch.object(ks_loading, 'load_auth_from_conf_options')
@mock.patch.object(ks_loading, 'load_session_from_conf_options')
@mock.patch.object(mmod.Message, 'keystone')
def test_build_trust_exists(self, mock_keystone, mock_load_session,
mock_load_auth):
mock_auth = mock.Mock()
mock_session = mock.Mock()
mock_session.get_user_id.return_value = 'zaqar-trustee-user-id'
mock_load_session.return_value = mock_session
mock_load_auth.return_value = mock_auth
mock_kc = mock.Mock()
mock_keystone.return_value = mock_kc
mock_trust = mock.Mock()
mock_trust.id = 'mock-trust-id'
message = mmod.Message('message', None, None, id=UUID,
user='user1', project='project1',
params={'notifier_roles': ['test-role']})
mock_kc.trust_get_by_trustor.return_value = mock_trust
res = message._build_trust()
self.assertEqual('mock-trust-id', res)
mock_kc.trust_get_by_trustor.assert_called_once_with(
'user1', 'zaqar-trustee-user-id', 'project1')
mock_load_auth.assert_called_once_with(cfg.CONF, 'zaqar')
mock_load_session.assert_called_once_with(cfg.CONF, 'zaqar')
mock_session.get_user_id.assert_called_once_with(auth=mock_auth)
@mock.patch.object(ks_loading, 'load_auth_from_conf_options')
@mock.patch.object(ks_loading, 'load_session_from_conf_options')
@mock.patch.object(mmod.Message, 'keystone')
def test_build_trust_create_new_multiroles(
self, mock_keystone, mock_load_session, mock_load_auth):
mock_auth = mock.Mock()
mock_session = mock.Mock()
mock_session.get_user_id.return_value = 'zaqar-trustee-user-id'
mock_load_session.return_value = mock_session
mock_load_auth.return_value = mock_auth
mock_kc = mock.Mock()
mock_keystone.return_value = mock_kc
mock_trust = mock.Mock()
mock_trust.id = 'mock-trust-id'
message = mmod.Message('message', None, None, id=UUID,
user='user1', project='project1')
message.notifier_roles = ['test_role']
mock_kc.trust_get_by_trustor.return_value = None
mock_kc.trust_create.return_value = mock_trust
res = message._build_trust()
self.assertEqual('mock-trust-id', res)
mock_kc.trust_get_by_trustor.assert_called_once_with(
'user1', 'zaqar-trustee-user-id', 'project1')
mock_kc.trust_create.assert_called_once_with(
'user1', 'zaqar-trustee-user-id', 'project1', ['test_role'])
@mock.patch.object(ks_loading, 'load_auth_from_conf_options')
@mock.patch.object(ks_loading, 'load_session_from_conf_options')
@mock.patch.object(mmod.Message, 'keystone')
def test_build_trust_create_new_single_admin_role(
self, mock_keystone, mock_load_session, mock_load_auth):
mock_auth = mock.Mock()
mock_session = mock.Mock()
mock_session.get_user_id.return_value = 'zaqar-trustee-user-id'
mock_load_session.return_value = mock_session
mock_load_auth.return_value = mock_auth
mock_kc = mock.Mock()
mock_keystone.return_value = mock_kc
mock_trust = mock.Mock()
mock_trust.id = 'mock-trust-id'
message = mmod.Message('message', None, None, id=UUID,
user='user1', project='project1')
message.notifier_roles = ['admin']
mock_kc.trust_get_by_trustor.return_value = None
mock_kc.trust_create.return_value = mock_trust
res = message._build_trust()
self.assertEqual('mock-trust-id', res)
mock_kc.trust_get_by_trustor.assert_called_once_with(
'user1', 'zaqar-trustee-user-id', 'project1')
mock_kc.trust_create.assert_called_once_with(
'user1', 'zaqar-trustee-user-id', 'project1', ['admin'])
@mock.patch.object(ks_loading, 'load_auth_from_conf_options')
@mock.patch.object(ks_loading, 'load_session_from_conf_options')
@mock.patch.object(mmod.Message, 'keystone')
def test_build_trust_create_new_trust_failed(self, mock_keystone,
mock_load_session,
mock_load_auth):
mock_auth = mock.Mock()
mock_session = mock.Mock()
mock_session.get_user_id.return_value = 'zaqar-trustee-user-id'
mock_load_session.return_value = mock_session
mock_load_auth.return_value = mock_auth
mock_kc = mock.Mock()
mock_keystone.return_value = mock_kc
mock_trust = mock.Mock()
mock_trust.id = 'mock-trust-id'
message = mmod.Message('message', None, None, id=UUID,
user='user1', project='project1')
message.notifier_roles = ['test_role']
mock_kc.trust_get_by_trustor.return_value = None
mock_kc.trust_create.side_effect = exception.InternalError()
self.assertRaises(exception.EResourceCreation,
message._build_trust)
mock_kc.trust_get_by_trustor.assert_called_once_with(
'user1', 'zaqar-trustee-user-id', 'project1')
mock_kc.trust_create.assert_called_once_with(
'user1', 'zaqar-trustee-user-id', 'project1', ['test_role'])
@mock.patch.object(ks_loading, 'load_auth_from_conf_options')
@mock.patch.object(ks_loading, 'load_session_from_conf_options')
@mock.patch.object(mmod.Message, 'keystone')
def test_build_trust_get_trust_exception(self, mock_keystone,
mock_load_session,
mock_load_auth):
mock_auth = mock.Mock()
mock_session = mock.Mock()
mock_session.get_user_id.return_value = 'zaqar-trustee-user-id'
mock_load_session.return_value = mock_session
mock_load_auth.return_value = mock_auth
mock_kc = mock.Mock()
mock_keystone.return_value = mock_kc
mock_trust = mock.Mock()
mock_trust.id = 'mock-trust-id'
message = mmod.Message('message', None, None, id=UUID,
user='user1', project='project1')
mock_kc.trust_get_by_trustor.side_effect = exception.InternalError()
self.assertRaises(exception.EResourceCreation,
message._build_trust)
mock_kc.trust_get_by_trustor.assert_called_once_with(
'user1', 'zaqar-trustee-user-id', 'project1')
@mock.patch.object(co.Cluster, 'get')
def test_find_cluster_by_uuid(self, mock_get):
x_cluster = mock.Mock()
mock_get.return_value = x_cluster
aid = uuidutils.generate_uuid()
message = mmod.Message('message', None, None, id=UUID)
result = message._find_cluster(self.context, aid)
self.assertEqual(x_cluster, result)
mock_get.assert_called_once_with(self.context, aid)
@mock.patch.object(co.Cluster, 'get_by_name')
@mock.patch.object(co.Cluster, 'get')
def test_find_cluster_by_uuid_as_name(self, mock_get, mock_get_name):
x_cluster = mock.Mock()
mock_get_name.return_value = x_cluster
mock_get.return_value = None
aid = uuidutils.generate_uuid()
message = mmod.Message('message', None, None, id=UUID)
result = message._find_cluster(self.context, aid)
self.assertEqual(x_cluster, result)
mock_get.assert_called_once_with(self.context, aid)
mock_get_name.assert_called_once_with(self.context, aid)
@mock.patch.object(co.Cluster, 'get_by_name')
def test_find_cluster_by_name(self, mock_get_name):
x_cluster = mock.Mock()
mock_get_name.return_value = x_cluster
aid = 'this-is-not-uuid'
message = mmod.Message('message', None, None, id=UUID)
result = message._find_cluster(self.context, aid)
self.assertEqual(x_cluster, result)
mock_get_name.assert_called_once_with(self.context, aid)
@mock.patch.object(co.Cluster, 'get_by_short_id')
@mock.patch.object(co.Cluster, 'get_by_name')
def test_find_cluster_by_shortid(self, mock_get_name, mock_get_shortid):
x_cluster = mock.Mock()
mock_get_shortid.return_value = x_cluster
mock_get_name.return_value = None
aid = 'abcd-1234-abcd'
message = mmod.Message('message', None, None, id=UUID)
result = message._find_cluster(self.context, aid)
self.assertEqual(x_cluster, result)
mock_get_name.assert_called_once_with(self.context, aid)
mock_get_shortid.assert_called_once_with(self.context, aid)
@mock.patch.object(co.Cluster, 'get_by_name')
def test_find_cluster_not_found(self, mock_get_name):
mock_get_name.return_value = None
message = mmod.Message('message', None, None, id=UUID)
self.assertRaises(exception.ResourceNotFound, message._find_cluster,
self.context, 'bogus')
mock_get_name.assert_called_once_with(self.context, 'bogus')
@mock.patch.object(dispatcher, 'start_action')
@mock.patch.object(mmod.Message, '_build_action')
@mock.patch.object(mmod.Message, 'zaqar')
def test_notify(self, mock_zaqar, mock_build_action, mock_start_action):
mock_zc = mock.Mock()
mock_zaqar.return_value = mock_zc
mock_claim = mock.Mock()
mock_claim.id = 'claim_id'
message1 = {
'body': {'cluster': 'c1', 'action': 'CLUSTER_SCALE_IN'},
'id': 'ID1'
}
message2 = {
'body': {'cluster': 'c2', 'action': 'CLUSTER_SCALE_OUT'},
'id': 'ID2'
}
mock_claim.messages = [message1, message2]
mock_zc.claim_create.return_value = mock_claim
mock_build_action.side_effect = ['action_id1', 'action_id2']
message = mmod.Message('message', None, None, id=UUID)
message.channel = {'queue_name': 'queue1'}
res = message.notify(self.context)
self.assertEqual(['action_id1', 'action_id2'], res)
mock_zc.claim_create.assert_called_once_with('queue1')
mock_zc.claim_delete.assert_called_once_with('queue1', 'claim_id')
mock_calls = [
mock.call(self.context, message1),
mock.call(self.context, message2)
]
mock_build_action.assert_has_calls(mock_calls)
mock_start_action.assert_called_once_with()
mock_calls2 = [
mock.call('queue1', 'ID1', 'claim_id'),
mock.call('queue1', 'ID2', 'claim_id')
]
mock_zc.message_delete.assert_has_calls(mock_calls2)
@mock.patch.object(mmod.Message, 'zaqar')
def test_notify_no_message(self, mock_zaqar):
mock_zc = mock.Mock()
mock_zaqar.return_value = mock_zc
mock_claim = mock.Mock()
mock_claim.messages = None
mock_zc.claim_create.return_value = mock_claim
message = mmod.Message('message', None, None, id=UUID)
message.channel = {'queue_name': 'queue1'}
res = message.notify(self.context)
self.assertEqual([], res)
mock_zc.claim_create.assert_called_once_with('queue1')
@mock.patch.object(dispatcher, 'start_action')
@mock.patch.object(mmod.Message, '_build_action')
@mock.patch.object(mmod.Message, 'zaqar')
def test_notify_some_actions_building_failed(self, mock_zaqar,
mock_build_action,
mock_start_action):
mock_zc = mock.Mock()
mock_zaqar.return_value = mock_zc
mock_claim = mock.Mock()
mock_claim.id = 'claim_id'
message1 = {
'body': {'cluster': 'c1', 'action': 'CLUSTER_SCALE_IN'},
'id': 'ID1'
}
message2 = {
'body': {'cluster': 'foo', 'action': 'CLUSTER_SCALE_OUT'},
'id': 'ID2'
}
mock_claim.messages = [message1, message2]
mock_zc.claim_create.return_value = mock_claim
mock_build_action.side_effect = [exception.InternalError(),
'action_id1']
message = mmod.Message('message', None, None, id=UUID)
message.channel = {'queue_name': 'queue1'}
res = message.notify(self.context)
self.assertEqual(['action_id1'], res)
mock_zc.claim_create.assert_called_once_with('queue1')
mock_calls = [
mock.call(self.context, message1),
mock.call(self.context, message2)
]
mock_build_action.assert_has_calls(mock_calls)
mock_start_action.assert_called_once_with()
mock_calls2 = [
mock.call('queue1', 'ID1', 'claim_id'),
mock.call('queue1', 'ID2', 'claim_id')
]
mock_zc.message_delete.assert_has_calls(mock_calls2)
@mock.patch.object(mmod.Message, 'zaqar')
def test_notify_claiming_message_failed(self, mock_zaqar):
mock_zc = mock.Mock()
mock_zaqar.return_value = mock_zc
mock_zc.claim_create.side_effect = exception.InternalError()
message = mmod.Message('message', None, None, id=UUID)
message.channel = {'queue_name': 'queue1'}
res = message.notify(self.context)
self.assertIsNone(res)
mock_zc.claim_create.assert_called_once_with('queue1')
@mock.patch.object(action_mod.Action, 'create')
@mock.patch.object(mmod.Message, '_find_cluster')
def test_build_action(self, mock_find_cluster, mock_action_create):
fake_cluster = mock.Mock()
fake_cluster.user = 'user1'
fake_cluster.id = 'cid1'
mock_find_cluster.return_value = fake_cluster
mock_action_create.return_value = 'action_id1'
msg = {
'body': {'cluster': 'c1', 'action': 'CLUSTER_SCALE_IN'},
'id': 'ID123456'
}
message = mmod.Message('message', None, None, id=UUID)
message.id = 'ID654321'
message.user = 'user1'
expected_kwargs = {
'name': 'receiver_ID654321_ID123456',
'cause': consts.CAUSE_RPC,
'status': action_mod.Action.READY,
'inputs': {}
}
res = message._build_action(self.context, msg)
self.assertEqual('action_id1', res)
mock_find_cluster.assert_called_once_with(self.context, 'c1')
mock_action_create.assert_called_once_with(self.context, 'cid1',
'CLUSTER_SCALE_IN',
**expected_kwargs)
def test_build_action_message_body_empty(self):
msg = {
'body': {},
'id': 'ID123456'
}
message = mmod.Message('message', None, None, id=UUID)
ex = self.assertRaises(exception.InternalError, message._build_action,
self.context, msg)
ex_msg = _('Message body is empty.')
self.assertEqual(ex_msg, ex.message)
def test_build_action_no_cluster_in_message_body(self):
msg = {
'body': {'action': 'CLUSTER_SCALE_IN'},
'id': 'ID123456'
}
message = mmod.Message('message', None, None, id=UUID)
ex = self.assertRaises(exception.InternalError, message._build_action,
self.context, msg)
ex_msg = _('Both cluster identity and action must be specified.')
self.assertEqual(ex_msg, ex.message)
def test_build_action_no_action_in_message_body(self):
msg = {
'body': {'cluster': 'c1'},
'id': 'ID123456'
}
message = mmod.Message('message', None, None, id=UUID)
ex = self.assertRaises(exception.InternalError, message._build_action,
self.context, msg)
ex_msg = _('Both cluster identity and action must be specified.')
self.assertEqual(ex_msg, ex.message)
@mock.patch.object(mmod.Message, '_find_cluster')
def test_build_action_cluster_notfound(self, mock_find_cluster):
mock_find_cluster.side_effect = exception.ResourceNotFound(
type='cluster', id='c1')
msg = {
'body': {'cluster': 'c1', 'action': 'CLUSTER_SCALE_IN'},
'id': 'ID123456'
}
message = mmod.Message('message', None, None, id=UUID)
ex = self.assertRaises(exception.InternalError, message._build_action,
self.context, msg)
ex_msg = _('Cluster (c1) cannot be found.')
self.assertEqual(ex_msg, ex.message)
@mock.patch.object(mmod.Message, '_find_cluster')
def test_build_action_permission_denied(self, mock_find_cluster):
fake_cluster = mock.Mock()
fake_cluster.user = 'user1'
mock_find_cluster.return_value = fake_cluster
msg = {
'body': {'cluster': 'c1', 'action': 'CLUSTER_SCALE_IN'},
'id': 'ID123456'
}
message = mmod.Message('message', None, None, id=UUID)
message.user = 'user2'
ex = self.assertRaises(exception.InternalError, message._build_action,
self.context, msg)
ex_msg = _('%(user)s is not allowed to trigger actions on '
'cluster %(cid)s.') % {'user': message.user,
'cid': 'c1'}
self.assertEqual(ex_msg, ex.message)
@mock.patch.object(mmod.Message, '_find_cluster')
def test_build_action_invalid_action_name(self, mock_find_cluster):
fake_cluster = mock.Mock()
fake_cluster.user = 'user1'
mock_find_cluster.return_value = fake_cluster
msg = {
'body': {'cluster': 'c1', 'action': 'foo'},
'id': 'ID123456'
}
message = mmod.Message('message', None, None, id=UUID)
message.user = 'user1'
ex = self.assertRaises(exception.InternalError, message._build_action,
self.context, msg)
ex_msg = _("Illegal cluster action 'foo' specified.")
self.assertEqual(ex_msg, ex.message)