Use a registry to configure reporting handlers.

Also ensure that the LogHandler is registered by default.

Change-Id: Ib9e306a0aa45ab6f5c9b543782b5dd7019b72cf1
This commit is contained in:
Daniel Watkins 2015-07-17 13:09:32 +01:00
parent 91a5942fb9
commit b5f5a16704
2 changed files with 39 additions and 21 deletions

View File

@ -12,6 +12,8 @@ report events in a structured manner.
import abc
import logging
from cloudinit.registry import DictRegistry
FINISH_EVENT_TYPE = 'finish'
START_EVENT_TYPE = 'start'
@ -63,7 +65,8 @@ class LogHandler(ReportingHandler):
logger.info(event.as_string())
HANDLERS = [LogHandler()]
handler_registry = DictRegistry()
handler_registry.register_item('_logging', LogHandler())
def report_event(event):
@ -76,7 +79,7 @@ def report_event(event):
The type of the event; this should be a constant from the
reporting module.
"""
for handler in HANDLERS:
for _, handler in handler_registry.registered_items.items():
handler.publish_event(event)

View File

@ -10,17 +10,22 @@ from cloudinit.tests import TestCase
from cloudinit.tests.util import mock
def _fake_registry():
return mock.Mock(registered_items={'a': mock.MagicMock(),
'b': mock.MagicMock()})
class TestReportStartEvent(unittest.TestCase):
@mock.patch('cloudinit.reporting.HANDLERS',
new_callable=lambda: [mock.MagicMock(), mock.MagicMock()])
@mock.patch('cloudinit.reporting.handler_registry',
new_callable=_fake_registry)
def test_report_start_event_passes_something_with_as_string_to_handlers(
self, HANDLERS):
self, handler_registry):
event_name, event_description = 'my_test_event', 'my description'
reporting.report_start_event(event_name, event_description)
expected_string_representation = ': '.join(
['start', event_name, event_description])
for handler in HANDLERS:
for _, handler in handler_registry.registered_items.items():
self.assertEqual(1, handler.publish_event.call_count)
event = handler.publish_event.call_args[0][0]
self.assertEqual(expected_string_representation, event.as_string())
@ -36,42 +41,42 @@ class TestReportFinishEvent(unittest.TestCase):
def assertHandlersPassedObjectWithAsString(
self, handlers, expected_as_string):
for handler in handlers:
for _, handler in handlers.items():
self.assertEqual(1, handler.publish_event.call_count)
event = handler.publish_event.call_args[0][0]
self.assertEqual(expected_as_string, event.as_string())
@mock.patch('cloudinit.reporting.HANDLERS',
new_callable=lambda: [mock.MagicMock(), mock.MagicMock()])
@mock.patch('cloudinit.reporting.handler_registry',
new_callable=_fake_registry)
def test_report_finish_event_passes_something_with_as_string_to_handlers(
self, HANDLERS):
self, handler_registry):
event_name, event_description = self._report_finish_event()
expected_string_representation = ': '.join(
['finish', event_name, event_description])
self.assertHandlersPassedObjectWithAsString(
HANDLERS, expected_string_representation)
handler_registry.registered_items, expected_string_representation)
@mock.patch('cloudinit.reporting.HANDLERS',
new_callable=lambda: [mock.MagicMock(), mock.MagicMock()])
def test_reporting_successful_finish_has_sensible_string_repr(self,
HANDLERS):
@mock.patch('cloudinit.reporting.handler_registry',
new_callable=_fake_registry)
def test_reporting_successful_finish_has_sensible_string_repr(
self, handler_registry):
event_name, event_description = self._report_finish_event(
successful=True)
expected_string_representation = ': '.join(
['finish', event_name, 'success', event_description])
self.assertHandlersPassedObjectWithAsString(
HANDLERS, expected_string_representation)
handler_registry.registered_items, expected_string_representation)
@mock.patch('cloudinit.reporting.HANDLERS',
new_callable=lambda: [mock.MagicMock(), mock.MagicMock()])
def test_reporting_unsuccessful_finish_has_sensible_string_repr(self,
HANDLERS):
@mock.patch('cloudinit.reporting.handler_registry',
new_callable=_fake_registry)
def test_reporting_unsuccessful_finish_has_sensible_string_repr(
self, handler_registry):
event_name, event_description = self._report_finish_event(
successful=False)
expected_string_representation = ': '.join(
['finish', event_name, 'fail', event_description])
self.assertHandlersPassedObjectWithAsString(
HANDLERS, expected_string_representation)
handler_registry.registered_items, expected_string_representation)
class TestReportingEvent(unittest.TestCase):
@ -115,3 +120,13 @@ class TestLogHandler(TestCase):
reporting.LogHandler().publish_event(event)
self.assertIn(event.as_string(),
getLogger.return_value.info.call_args[0][0])
class TestDefaultRegisteredHandler(TestCase):
def test_log_handler_registered_by_default(self):
for _, item in reporting.handler_registry.registered_items.items():
if isinstance(item, reporting.LogHandler):
break
else:
self.fail('No reporting LogHandler registered by default.')