From 47899bb7624001b86dde258f15c23f13b59fb383 Mon Sep 17 00:00:00 2001 From: Erik Olof Gunnar Andersson Date: Sun, 5 May 2019 11:37:25 -0700 Subject: [PATCH] Added sink unit tests We had no coverage of the base sink. This add some basic tests, as well as a fake notification handler that can be used for testing. Change-Id: Ie8657aacd22737f9ebaac4af4b34030e12ab18d0 --- designate/conf/sink.py | 16 ++++ designate/notification_handler/fake.py | 33 ++++++++ .../unit/notification_handler/__init__.py | 0 .../unit/notification_handler/test_fake.py | 63 ++++++++++++++ designate/tests/unit/sink/__init__.py | 0 .../tests/unit/sink/test_notifications.py | 84 +++++++++++++++++++ designate/tests/unit/sink/test_service.py | 45 ++++++++++ setup.cfg | 1 + 8 files changed, 242 insertions(+) create mode 100644 designate/notification_handler/fake.py create mode 100644 designate/tests/unit/notification_handler/__init__.py create mode 100644 designate/tests/unit/notification_handler/test_fake.py create mode 100644 designate/tests/unit/sink/__init__.py create mode 100644 designate/tests/unit/sink/test_notifications.py create mode 100644 designate/tests/unit/sink/test_service.py diff --git a/designate/conf/sink.py b/designate/conf/sink.py index 382847c57..0edcd4f89 100644 --- a/designate/conf/sink.py +++ b/designate/conf/sink.py @@ -20,6 +20,11 @@ SINK_GROUP = cfg.OptGroup( title="Configuration for Sink Service" ) +SINK_FAKE_GROUP = cfg.OptGroup( + name='handler:fake', + title="Configuration for the Fake Notification Handler" +) + SINK_NEUTRON_GROUP = cfg.OptGroup( name='handler:neutron_floatingip', title="Configuration for Neutron Notification Handler" @@ -44,6 +49,15 @@ SINK_OPTS = [ 'by all oslo.messaging drivers.'), ] +SINK_FAKE_OPTS = [ + cfg.ListOpt('notification-topics', default=['notifications'], + help='notification events for the fake notification handler'), + cfg.StrOpt('control-exchange', default='fake', + help='control-exchange for fake notifications'), + cfg.ListOpt('allowed-event-types', default=[], + help='the event types we want the fake handler to accept'), +] + SINK_NEUTRON_OPTS = [ cfg.ListOpt('notification-topics', default=['notifications'], help='notification any events from neutron'), @@ -74,6 +88,8 @@ SINK_NOVA_OPTS = [ def register_opts(conf): conf.register_group(SINK_GROUP) conf.register_opts(SINK_OPTS, group=SINK_GROUP) + conf.register_group(SINK_FAKE_GROUP) + conf.register_opts(SINK_FAKE_OPTS, group=SINK_FAKE_GROUP) conf.register_group(SINK_NEUTRON_GROUP) conf.register_opts(SINK_NEUTRON_OPTS, group=SINK_NEUTRON_GROUP) conf.register_group(SINK_NOVA_GROUP) diff --git a/designate/notification_handler/fake.py b/designate/notification_handler/fake.py new file mode 100644 index 000000000..6dd7e7509 --- /dev/null +++ b/designate/notification_handler/fake.py @@ -0,0 +1,33 @@ +# 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. +from oslo_config import cfg +from oslo_log import log as logging + +from designate.notification_handler import base + +LOG = logging.getLogger(__name__) + + +class FakeHandler(base.NotificationHandler): + __plugin_name__ = 'fake' + + def get_exchange_topics(self): + exchange = cfg.CONF[self.name].control_exchange + topics = cfg.CONF[self.name].notification_topics + return exchange, topics + + def get_event_types(self): + return cfg.CONF[self.name].allowed_event_types + + def process_notification(self, context, event_type, payload): + LOG.info('%s: received notification - %s', + self.name, event_type) diff --git a/designate/tests/unit/notification_handler/__init__.py b/designate/tests/unit/notification_handler/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/designate/tests/unit/notification_handler/test_fake.py b/designate/tests/unit/notification_handler/test_fake.py new file mode 100644 index 000000000..28f6f79f2 --- /dev/null +++ b/designate/tests/unit/notification_handler/test_fake.py @@ -0,0 +1,63 @@ +# 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.mport threading +import mock +import oslotest.base +from oslo_config import cfg + +from designate.notification_handler import fake +from designate.tests import test_notification_handler + +CONF = cfg.CONF + + +class TestFakeHandler(oslotest.base.BaseTestCase, + test_notification_handler.NotificationHandlerMixin): + + @mock.patch('designate.rpc.get_client') + def setUp(self, mock_get_instance): + super(TestFakeHandler, self).setUp() + + CONF.set_override( + 'enabled_notification_handlers', + [fake.FakeHandler.__plugin_name__], + 'service:sink' + ) + CONF.set_override( + 'allowed_event_types', ['compute.instance.create.end'], + 'handler:fake' + ) + + self.handler = fake.FakeHandler() + + def test_get_name(self): + self.assertEqual( + self.handler.name, + 'handler:fake' + ) + + def test_get_canonical_name(self): + self.assertEqual( + self.handler.get_canonical_name(), + 'handler:fake' + ) + + def test_get_exchange_topics(self): + self.assertEqual( + self.handler.get_exchange_topics(), + ('fake', ['notifications']) + ) + + def test_get_event_types(self): + self.assertEqual( + self.handler.get_event_types(), + ['compute.instance.create.end'] + ) diff --git a/designate/tests/unit/sink/__init__.py b/designate/tests/unit/sink/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/designate/tests/unit/sink/test_notifications.py b/designate/tests/unit/sink/test_notifications.py new file mode 100644 index 000000000..7584ae84b --- /dev/null +++ b/designate/tests/unit/sink/test_notifications.py @@ -0,0 +1,84 @@ +# 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.mport threading + +import mock +import oslotest.base +from oslo_config import cfg + +from designate.notification_handler import fake +from designate.sink import service +from designate.tests import fixtures +from designate.tests import test_notification_handler + + +CONF = cfg.CONF + + +class TestSinkNotification(oslotest.base.BaseTestCase, + test_notification_handler.NotificationHandlerMixin): + + def setUp(self): + super(TestSinkNotification, self).setUp() + self.stdlog = fixtures.StandardLogging() + self.useFixture(self.stdlog) + + CONF.set_override( + 'enabled_notification_handlers', + [fake.FakeHandler.__plugin_name__], + 'service:sink' + ) + CONF.set_override( + 'allowed_event_types', ['compute.instance.create.end'], + 'handler:fake' + ) + + self.context = mock.Mock() + self.service = service.Service() + + def test_notification(self): + event_type = 'compute.instance.create.end' + fixture = self.get_notification_fixture('nova', event_type) + + self.service.info(self.context, None, event_type, + fixture['payload'], None) + + self.assertIn( + 'handler:fake: received notification - %s' % event_type, + self.stdlog.logger.output + ) + + def test_notification_with_unknown_event(self): + event_type = 'compute.instance.create.start' + fixture = self.get_notification_fixture('nova', event_type) + + self.service.info(self.context, None, event_type, + fixture['payload'], None) + + self.assertNotIn( + 'handler:fake: received notification - %s' % event_type, + self.stdlog.logger.output + ) + + def test_notification_without_handler(self): + CONF.set_override('enabled_notification_handlers', [], 'service:sink') + self.service = service.Service() + + event_type = 'compute.instance.create.end' + fixture = self.get_notification_fixture('nova', event_type) + + self.service.info(self.context, None, event_type, + fixture['payload'], None) + + self.assertIn( + 'No designate-sink handlers enabled or loaded', + self.stdlog.logger.output + ) diff --git a/designate/tests/unit/sink/test_service.py b/designate/tests/unit/sink/test_service.py new file mode 100644 index 000000000..13ac41bc4 --- /dev/null +++ b/designate/tests/unit/sink/test_service.py @@ -0,0 +1,45 @@ +# 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.mport threading +import mock + +import designate.rpc +from designate import tests +from designate.sink import service +from designate.tests import fixtures + + +class TestSinkService(tests.TestCase): + + def setUp(self): + super(TestSinkService, self).setUp() + self.stdlog = fixtures.StandardLogging() + self.useFixture(self.stdlog) + + self.CONF.set_override('enabled_notification_handlers', ['fake'], + 'service:sink') + + self.service = service.Service() + + @mock.patch.object(designate.rpc, 'get_notification_listener') + def test_service_start(self, mock_notification_listener): + self.service.start() + + self.assertTrue(mock_notification_listener.called) + + @mock.patch.object(designate.rpc, 'get_notification_listener') + def test_service_stop(self, mock_notification_listener): + self.service.stop() + + self.assertIn('Stopping sink service', self.stdlog.logger.output) + + def test_service_name(self): + self.assertEqual('sink', self.service.service_name) diff --git a/setup.cfg b/setup.cfg index 83c282b18..7adf0af2e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -75,6 +75,7 @@ designate.pool_manager.cache = sqlalchemy = designate.pool_manager.cache.impl_sqlalchemy:SQLAlchemyPoolManagerCache designate.notification.handler = + fake = designate.notification_handler.fake:FakeHandler nova_fixed = designate.notification_handler.nova:NovaFixedHandler neutron_floatingip = designate.notification_handler.neutron:NeutronFloatingHandler