diff --git a/cloudinit/reporting.py b/cloudinit/reporting.py index c4097a35..c7a94b58 100644 --- a/cloudinit/reporting.py +++ b/cloudinit/reporting.py @@ -9,6 +9,7 @@ The reporting framework is intended to allow all parts of cloud-init to report events in a structured manner. """ +import abc import logging @@ -45,18 +46,24 @@ class FinishReportingEvent(ReportingEvent): self.event_type, self.name, success_string, self.description) -class LogHandler(object): +class ReportingHandler(object): + + @abc.abstractmethod + def publish_event(self, event): + raise NotImplementedError + + +class LogHandler(ReportingHandler): """Publishes events to the cloud-init log at the ``INFO`` log level.""" - @staticmethod - def publish_event(event): + def publish_event(self, event): """Publish an event to the ``INFO`` log level.""" logger = logging.getLogger( '.'.join([__name__, event.event_type, event.name])) logger.info(event.as_string()) -HANDLERS = [LogHandler] +HANDLERS = [LogHandler()] def report_event(event): diff --git a/cloudinit/tests/test_reporting.py b/cloudinit/tests/test_reporting.py index 431250d6..54e0995a 100644 --- a/cloudinit/tests/test_reporting.py +++ b/cloudinit/tests/test_reporting.py @@ -84,13 +84,20 @@ class TestReportingEvent(unittest.TestCase): self.assertEqual(expected_string_representation, event.as_string()) +class TestReportingHandler(TestCase): + + def test_no_default_publish_event_implementation(self): + self.assertRaises(NotImplementedError, + reporting.ReportingHandler().publish_event, None) + + class TestLogHandler(TestCase): @mock.patch.object(reporting.logging, 'getLogger') def test_appropriate_logger_used(self, getLogger): event_type, event_name = 'test_type', 'test_name' event = reporting.ReportingEvent(event_type, event_name, 'description') - reporting.LogHandler.publish_event(event) + reporting.LogHandler().publish_event(event) self.assertEqual( [mock.call( 'cloudinit.reporting.{0}.{1}'.format(event_type, event_name))], @@ -99,12 +106,12 @@ class TestLogHandler(TestCase): @mock.patch.object(reporting.logging, 'getLogger') def test_single_log_message_at_info_published(self, getLogger): event = reporting.ReportingEvent('type', 'name', 'description') - reporting.LogHandler.publish_event(event) + reporting.LogHandler().publish_event(event) self.assertEqual(1, getLogger.return_value.info.call_count) @mock.patch.object(reporting.logging, 'getLogger') def test_log_message_uses_event_as_string(self, getLogger): event = reporting.ReportingEvent('type', 'name', 'description') - reporting.LogHandler.publish_event(event) + reporting.LogHandler().publish_event(event) self.assertIn(event.as_string(), getLogger.return_value.info.call_args[0][0]) diff --git a/tox.ini b/tox.ini index f23044d5..7b1c0221 100644 --- a/tox.ini +++ b/tox.ini @@ -44,7 +44,7 @@ commands = {posargs} [flake8] builtins = _ -exclude = .venv,.git,.tox,dist,doc,*lib/python*,*egg,build +exclude = .venv,.git,.tox,dist,doc,*lib/python*,*egg,build,.ropeproject # TODO(harlowja): fix these up... ignore = H102,H104,H105