diff --git a/oslo/messaging/rpc/client.py b/oslo/messaging/rpc/client.py index 7c8c2ad1a..7bd373718 100644 --- a/oslo/messaging/rpc/client.py +++ b/oslo/messaging/rpc/client.py @@ -136,6 +136,10 @@ class _CallContext(object): def call(self, ctxt, method, **kwargs): """Invoke a method and wait for a reply. See RPCClient.call().""" + if self.target.fanout: + raise exceptions.InvalidTarget('A call cannot be used with fanout', + self.target) + msg = self._make_message(ctxt, method, kwargs) msg_ctxt = self.serializer.serialize_context(ctxt) diff --git a/tests/rpc/test_client.py b/tests/rpc/test_client.py index b7e1cff5f..e441e916e 100644 --- a/tests/rpc/test_client.py +++ b/tests/rpc/test_client.py @@ -17,6 +17,7 @@ import testscenarios from oslo.config import cfg from oslo import messaging +from oslo.messaging import exceptions from oslo.messaging import serializer as msg_serializer from tests import utils as test_utils @@ -283,6 +284,26 @@ class TestCallRetry(test_utils.BaseTestCase): client.call({}, 'foo') +class TestCallFanout(test_utils.BaseTestCase): + + scenarios = [ + ('target', dict(prepare=_notset, target={'fanout': True})), + ('prepare', dict(prepare={'fanout': True}, target={})), + ('both', dict(prepare={'fanout': True}, target={'fanout': True})), + ] + + def test_call_fanout(self): + transport = _FakeTransport(self.conf) + client = messaging.RPCClient(transport, + messaging.Target(**self.target)) + + if self.prepare is not _notset: + client = client.prepare(**self.prepare) + + self.assertRaises(exceptions.InvalidTarget, + client.call, {}, 'foo') + + class TestSerializer(test_utils.BaseTestCase): scenarios = [