summaryrefslogtreecommitdiff
path: root/nova/tests/unit/test_rpc.py
diff options
context:
space:
mode:
authorRyan Rossiter <rlrossit@us.ibm.com>2016-01-14 00:21:02 +0000
committerRyan Rossiter <rlrossit@us.ibm.com>2016-01-25 17:14:29 +0000
commit9a46586dcf96db567a999380dcaef02bdfd1592a (patch)
tree79386dff2fddb9f7106abeeb0245729cd0043d48 /nova/tests/unit/test_rpc.py
parentc6c48b8bb78439059bdabed1c88902d4c6bfe48c (diff)
downloadnova-9a46586dcf96db567a999380dcaef02bdfd1592a.tar.gz
Add tests for nova.rpc module
This change adds test for the nova.rpc module, including the public functions and 2 classes within the module. Change-Id: I368ed5146210948c95de5a647097b98dcf8a3ca6 Closes-bug: #1533741
Diffstat (limited to 'nova/tests/unit/test_rpc.py')
-rw-r--r--nova/tests/unit/test_rpc.py322
1 files changed, 322 insertions, 0 deletions
diff --git a/nova/tests/unit/test_rpc.py b/nova/tests/unit/test_rpc.py
new file mode 100644
index 0000000000..e098ef1009
--- /dev/null
+++ b/nova/tests/unit/test_rpc.py
@@ -0,0 +1,322 @@
+# Copyright 2016 IBM Corp.
+#
+# 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 copy
+
+import fixtures
+import mock
+import oslo_messaging as messaging
+from oslo_serialization import jsonutils
+import testtools
+
+from nova import context
+from nova import rpc
+from nova import test
+
+
+# Make a class that resets all of the global variables in nova.rpc
+class RPCResetFixture(fixtures.Fixture):
+ def _setUp(self):
+ self.trans = copy.copy(rpc.TRANSPORT)
+ self.noti = copy.copy(rpc.NOTIFIER)
+ self.all_mods = copy.copy(rpc.ALLOWED_EXMODS)
+ self.ext_mods = copy.copy(rpc.EXTRA_EXMODS)
+ self.addCleanup(self._reset_everything)
+
+ def _reset_everything(self):
+ rpc.TRANSPORT = self.trans
+ rpc.NOTIFIER = self.noti
+ rpc.ALLOWED_EXMODS = self.all_mods
+ rpc.EXTRA_EXMODS = self.ext_mods
+
+
+# We can't import nova.test.TestCase because that sets up an RPCFixture
+# that pretty much nullifies all of this testing
+class TestRPC(testtools.TestCase):
+ def setUp(self):
+ super(TestRPC, self).setUp()
+ self.useFixture(RPCResetFixture())
+
+ @mock.patch.object(rpc, 'get_allowed_exmods')
+ @mock.patch.object(rpc, 'RequestContextSerializer')
+ @mock.patch.object(messaging, 'get_transport')
+ @mock.patch.object(messaging, 'Notifier')
+ def test_init_unversioned(self, mock_notif, mock_trans, mock_ser,
+ mock_exmods):
+ # The expected call to get the legacy notifier will require no new
+ # kwargs, and we expect the new notifier will need the noop driver
+ expected = [{}, {'driver': 'noop'}]
+ self._test_init(mock_notif, mock_trans, mock_ser, mock_exmods,
+ 'unversioned', expected)
+
+ @mock.patch.object(rpc, 'get_allowed_exmods')
+ @mock.patch.object(rpc, 'RequestContextSerializer')
+ @mock.patch.object(messaging, 'get_transport')
+ @mock.patch.object(messaging, 'Notifier')
+ def test_init_both(self, mock_notif, mock_trans, mock_ser, mock_exmods):
+ expected = [{}, {'topic': 'versioned_notifications'}]
+ self._test_init(mock_notif, mock_trans, mock_ser, mock_exmods,
+ 'both', expected)
+
+ @mock.patch.object(rpc, 'get_allowed_exmods')
+ @mock.patch.object(rpc, 'RequestContextSerializer')
+ @mock.patch.object(messaging, 'get_transport')
+ @mock.patch.object(messaging, 'Notifier')
+ def test_init_versioned(self, mock_notif, mock_trans, mock_ser,
+ mock_exmods):
+ expected = [{'driver': 'noop'}, {'topic': 'versioned_notifications'}]
+ self._test_init(mock_notif, mock_trans, mock_ser, mock_exmods,
+ 'versioned', expected)
+
+ def test_cleanup_transport_null(self):
+ rpc.LEGACY_NOTIFIER = mock.Mock()
+ rpc.NOTIFIER = mock.Mock()
+ self.assertRaises(AssertionError, rpc.cleanup)
+
+ def test_cleanup_legacy_notifier_null(self):
+ rpc.TRANSPORT = mock.Mock()
+ rpc.NOTIFIER = mock.Mock()
+ self.assertRaises(AssertionError, rpc.cleanup)
+
+ def test_cleanup_notifier_null(self):
+ rpc.TRANSPORT = mock.Mock()
+ rpc.LEGACY_NOTIFIER = mock.Mock()
+ self.assertRaises(AssertionError, rpc.cleanup)
+
+ def test_cleanup(self):
+ rpc.LEGACY_NOTIFIER = mock.Mock()
+ rpc.NOTIFIER = mock.Mock()
+ rpc.TRANSPORT = mock.Mock()
+ trans_cleanup = mock.Mock()
+ rpc.TRANSPORT.cleanup = trans_cleanup
+
+ rpc.cleanup()
+
+ trans_cleanup.assert_called_once_with()
+ self.assertIsNone(rpc.TRANSPORT)
+ self.assertIsNone(rpc.LEGACY_NOTIFIER)
+ self.assertIsNone(rpc.NOTIFIER)
+
+ @mock.patch.object(messaging, 'set_transport_defaults')
+ def test_set_defaults(self, mock_set):
+ control_exchange = mock.Mock()
+
+ rpc.set_defaults(control_exchange)
+
+ mock_set.assert_called_once_with(control_exchange)
+
+ def test_add_extra_exmods(self):
+ rpc.EXTRA_EXMODS = []
+
+ rpc.add_extra_exmods('foo', 'bar')
+
+ self.assertEqual(['foo', 'bar'], rpc.EXTRA_EXMODS)
+
+ def test_clear_extra_exmods(self):
+ rpc.EXTRA_EXMODS = ['foo', 'bar']
+
+ rpc.clear_extra_exmods()
+
+ self.assertEqual(0, len(rpc.EXTRA_EXMODS))
+
+ def test_get_allowed_exmods(self):
+ rpc.ALLOWED_EXMODS = ['foo']
+ rpc.EXTRA_EXMODS = ['bar']
+
+ exmods = rpc.get_allowed_exmods()
+
+ self.assertEqual(['foo', 'bar'], exmods)
+
+ @mock.patch.object(messaging, 'TransportURL')
+ def test_get_transport_url(self, mock_url):
+ conf = mock.Mock()
+ rpc.CONF = conf
+ mock_url.parse.return_value = 'foo'
+
+ url = rpc.get_transport_url(url_str='bar')
+
+ self.assertEqual('foo', url)
+ mock_url.parse.assert_called_once_with(conf, 'bar',
+ rpc.TRANSPORT_ALIASES)
+
+ @mock.patch.object(messaging, 'TransportURL')
+ def test_get_transport_url_null(self, mock_url):
+ conf = mock.Mock()
+ rpc.CONF = conf
+ mock_url.parse.return_value = 'foo'
+
+ url = rpc.get_transport_url()
+
+ self.assertEqual('foo', url)
+ mock_url.parse.assert_called_once_with(conf, None,
+ rpc.TRANSPORT_ALIASES)
+
+ @mock.patch.object(rpc, 'RequestContextSerializer')
+ @mock.patch.object(messaging, 'RPCClient')
+ def test_get_client(self, mock_client, mock_ser):
+ rpc.TRANSPORT = mock.Mock()
+ tgt = mock.Mock()
+ ser = mock.Mock()
+ mock_client.return_value = 'client'
+ mock_ser.return_value = ser
+
+ client = rpc.get_client(tgt, version_cap='1.0', serializer='foo')
+
+ mock_ser.assert_called_once_with('foo')
+ mock_client.assert_called_once_with(rpc.TRANSPORT,
+ tgt, version_cap='1.0',
+ serializer=ser)
+ self.assertEqual('client', client)
+
+ @mock.patch.object(rpc, 'RequestContextSerializer')
+ @mock.patch.object(messaging, 'get_rpc_server')
+ def test_get_server(self, mock_get, mock_ser):
+ rpc.TRANSPORT = mock.Mock()
+ ser = mock.Mock()
+ tgt = mock.Mock()
+ ends = mock.Mock()
+ mock_ser.return_value = ser
+ mock_get.return_value = 'server'
+
+ server = rpc.get_server(tgt, ends, serializer='foo')
+
+ mock_ser.assert_called_once_with('foo')
+ mock_get.assert_called_once_with(rpc.TRANSPORT, tgt, ends,
+ executor='eventlet', serializer=ser)
+ self.assertEqual('server', server)
+
+ def test_get_notifier(self):
+ rpc.LEGACY_NOTIFIER = mock.Mock()
+ mock_prep = mock.Mock()
+ mock_prep.return_value = 'notifier'
+ rpc.LEGACY_NOTIFIER.prepare = mock_prep
+
+ notifier = rpc.get_notifier('service', publisher_id='foo')
+
+ mock_prep.assert_called_once_with(publisher_id='foo')
+ self.assertEqual('notifier', notifier)
+
+ def test_get_notifier_null_publisher(self):
+ rpc.LEGACY_NOTIFIER = mock.Mock()
+ mock_prep = mock.Mock()
+ mock_prep.return_value = 'notifier'
+ rpc.LEGACY_NOTIFIER.prepare = mock_prep
+
+ notifier = rpc.get_notifier('service', host='bar')
+
+ mock_prep.assert_called_once_with(publisher_id='service.bar')
+ self.assertEqual('notifier', notifier)
+
+ def test_get_versioned_notifier(self):
+ rpc.NOTIFIER = mock.Mock()
+ mock_prep = mock.Mock()
+ mock_prep.return_value = 'notifier'
+ rpc.NOTIFIER.prepare = mock_prep
+
+ notifier = rpc.get_versioned_notifier('service.foo')
+
+ mock_prep.assert_called_once_with(publisher_id='service.foo')
+ self.assertEqual('notifier', notifier)
+
+ def _test_init(self, mock_notif, mock_trans, mock_ser, mock_exmods,
+ notif_format, expected_driver_topic_kwargs):
+ legacy_notifier = mock.Mock()
+ notifier = mock.Mock()
+ transport = mock.Mock()
+ serializer = mock.Mock()
+ conf = mock.Mock()
+
+ conf.notification_format = notif_format
+ mock_exmods.return_value = ['foo']
+ mock_trans.return_value = transport
+ mock_ser.return_value = serializer
+ mock_notif.side_effect = [legacy_notifier, notifier]
+
+ rpc.init(conf)
+
+ mock_exmods.assert_called_once_with()
+ mock_trans.assert_called_once_with(conf,
+ allowed_remote_exmods=['foo'],
+ aliases=rpc.TRANSPORT_ALIASES)
+ self.assertIsNotNone(rpc.TRANSPORT)
+ self.assertIsNotNone(rpc.LEGACY_NOTIFIER)
+ self.assertIsNotNone(rpc.NOTIFIER)
+ self.assertEqual(legacy_notifier, rpc.LEGACY_NOTIFIER)
+ self.assertEqual(notifier, rpc.NOTIFIER)
+
+ expected_calls = []
+ for kwargs in expected_driver_topic_kwargs:
+ expected_kwargs = {'serializer': serializer}
+ expected_kwargs.update(kwargs)
+ expected_calls.append(((transport,), expected_kwargs))
+
+ self.assertEqual(expected_calls, mock_notif.call_args_list,
+ "The calls to messaging.Notifier() did not create "
+ "the legacy and versioned notifiers properly.")
+
+
+class TestJsonPayloadSerializer(test.TestCase):
+ def test_serialize_entity(self):
+ with mock.patch.object(jsonutils, 'to_primitive') as mock_prim:
+ rpc.JsonPayloadSerializer.serialize_entity('context', 'entity')
+
+ mock_prim.assert_called_once_with('entity', convert_instances=True)
+
+
+class TestRequestContextSerializer(test.TestCase):
+ def setUp(self):
+ super(TestRequestContextSerializer, self).setUp()
+ self.mock_base = mock.Mock()
+ self.ser = rpc.RequestContextSerializer(self.mock_base)
+ self.ser_null = rpc.RequestContextSerializer(None)
+
+ def test_serialize_entity(self):
+ self.mock_base.serialize_entity.return_value = 'foo'
+
+ ser_ent = self.ser.serialize_entity('context', 'entity')
+
+ self.mock_base.serialize_entity.assert_called_once_with('context',
+ 'entity')
+ self.assertEqual('foo', ser_ent)
+
+ def test_serialize_entity_null_base(self):
+ ser_ent = self.ser_null.serialize_entity('context', 'entity')
+
+ self.assertEqual('entity', ser_ent)
+
+ def test_deserialize_entity(self):
+ self.mock_base.deserialize_entity.return_value = 'foo'
+
+ deser_ent = self.ser.deserialize_entity('context', 'entity')
+
+ self.mock_base.deserialize_entity.assert_called_once_with('context',
+ 'entity')
+ self.assertEqual('foo', deser_ent)
+
+ def test_deserialize_entity_null_base(self):
+ deser_ent = self.ser_null.deserialize_entity('context', 'entity')
+
+ self.assertEqual('entity', deser_ent)
+
+ def test_serialize_context(self):
+ context = mock.Mock()
+
+ self.ser.serialize_context(context)
+
+ context.to_dict.assert_called_once_with()
+
+ @mock.patch.object(context, 'RequestContext')
+ def test_deserialize_context(self, mock_req):
+ self.ser.deserialize_context('context')
+
+ mock_req.from_dict.assert_called_once_with('context')