Make reporting handlers configurable.
And configure the LogHandler by default. Change-Id: Ic3a1cebbe8684033fb8d46bf4baebb55a43fc890
This commit is contained in:
parent
b5f5a16704
commit
af671321af
@ -18,6 +18,14 @@ from cloudinit.registry import DictRegistry
|
||||
FINISH_EVENT_TYPE = 'finish'
|
||||
START_EVENT_TYPE = 'start'
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
'logging': {'type': 'log'},
|
||||
}
|
||||
|
||||
|
||||
instantiated_handler_registry = DictRegistry()
|
||||
available_handlers = DictRegistry()
|
||||
|
||||
|
||||
class ReportingEvent(object):
|
||||
"""Encapsulation of event formatting."""
|
||||
@ -65,8 +73,12 @@ class LogHandler(ReportingHandler):
|
||||
logger.info(event.as_string())
|
||||
|
||||
|
||||
handler_registry = DictRegistry()
|
||||
handler_registry.register_item('_logging', LogHandler())
|
||||
def add_configuration(config):
|
||||
for handler_name, handler_config in config.items():
|
||||
handler_config = handler_config.copy()
|
||||
cls = available_handlers.registered_items[handler_config.pop('type')]
|
||||
instance = cls(**handler_config)
|
||||
instantiated_handler_registry.register_item(handler_name, instance)
|
||||
|
||||
|
||||
def report_event(event):
|
||||
@ -79,7 +91,7 @@ def report_event(event):
|
||||
The type of the event; this should be a constant from the
|
||||
reporting module.
|
||||
"""
|
||||
for _, handler in handler_registry.registered_items.items():
|
||||
for _, handler in instantiated_handler_registry.registered_items.items():
|
||||
handler.publish_event(event)
|
||||
|
||||
|
||||
@ -104,3 +116,7 @@ def report_start_event(event_name, event_description):
|
||||
"""
|
||||
event = ReportingEvent(START_EVENT_TYPE, event_name, event_description)
|
||||
return report_event(event)
|
||||
|
||||
|
||||
available_handlers.register_item('log', LogHandler)
|
||||
add_configuration(DEFAULT_CONFIG)
|
||||
|
@ -17,15 +17,16 @@ def _fake_registry():
|
||||
|
||||
class TestReportStartEvent(unittest.TestCase):
|
||||
|
||||
@mock.patch('cloudinit.reporting.handler_registry',
|
||||
@mock.patch('cloudinit.reporting.instantiated_handler_registry',
|
||||
new_callable=_fake_registry)
|
||||
def test_report_start_event_passes_something_with_as_string_to_handlers(
|
||||
self, handler_registry):
|
||||
self, instantiated_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 handler_registry.registered_items.items():
|
||||
for _, handler in (
|
||||
instantiated_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())
|
||||
@ -46,37 +47,40 @@ class TestReportFinishEvent(unittest.TestCase):
|
||||
event = handler.publish_event.call_args[0][0]
|
||||
self.assertEqual(expected_as_string, event.as_string())
|
||||
|
||||
@mock.patch('cloudinit.reporting.handler_registry',
|
||||
@mock.patch('cloudinit.reporting.instantiated_handler_registry',
|
||||
new_callable=_fake_registry)
|
||||
def test_report_finish_event_passes_something_with_as_string_to_handlers(
|
||||
self, handler_registry):
|
||||
self, instantiated_handler_registry):
|
||||
event_name, event_description = self._report_finish_event()
|
||||
expected_string_representation = ': '.join(
|
||||
['finish', event_name, event_description])
|
||||
self.assertHandlersPassedObjectWithAsString(
|
||||
handler_registry.registered_items, expected_string_representation)
|
||||
instantiated_handler_registry.registered_items,
|
||||
expected_string_representation)
|
||||
|
||||
@mock.patch('cloudinit.reporting.handler_registry',
|
||||
@mock.patch('cloudinit.reporting.instantiated_handler_registry',
|
||||
new_callable=_fake_registry)
|
||||
def test_reporting_successful_finish_has_sensible_string_repr(
|
||||
self, handler_registry):
|
||||
self, instantiated_handler_registry):
|
||||
event_name, event_description = self._report_finish_event(
|
||||
successful=True)
|
||||
expected_string_representation = ': '.join(
|
||||
['finish', event_name, 'success', event_description])
|
||||
self.assertHandlersPassedObjectWithAsString(
|
||||
handler_registry.registered_items, expected_string_representation)
|
||||
instantiated_handler_registry.registered_items,
|
||||
expected_string_representation)
|
||||
|
||||
@mock.patch('cloudinit.reporting.handler_registry',
|
||||
@mock.patch('cloudinit.reporting.instantiated_handler_registry',
|
||||
new_callable=_fake_registry)
|
||||
def test_reporting_unsuccessful_finish_has_sensible_string_repr(
|
||||
self, handler_registry):
|
||||
self, instantiated_handler_registry):
|
||||
event_name, event_description = self._report_finish_event(
|
||||
successful=False)
|
||||
expected_string_representation = ': '.join(
|
||||
['finish', event_name, 'fail', event_description])
|
||||
self.assertHandlersPassedObjectWithAsString(
|
||||
handler_registry.registered_items, expected_string_representation)
|
||||
instantiated_handler_registry.registered_items,
|
||||
expected_string_representation)
|
||||
|
||||
|
||||
class TestReportingEvent(unittest.TestCase):
|
||||
@ -125,8 +129,66 @@ class TestLogHandler(TestCase):
|
||||
class TestDefaultRegisteredHandler(TestCase):
|
||||
|
||||
def test_log_handler_registered_by_default(self):
|
||||
for _, item in reporting.handler_registry.registered_items.items():
|
||||
registered_items = (
|
||||
reporting.instantiated_handler_registry.registered_items)
|
||||
for _, item in registered_items.items():
|
||||
if isinstance(item, reporting.LogHandler):
|
||||
break
|
||||
else:
|
||||
self.fail('No reporting LogHandler registered by default.')
|
||||
|
||||
|
||||
class TestReportingConfiguration(TestCase):
|
||||
|
||||
@mock.patch.object(reporting, 'instantiated_handler_registry')
|
||||
def test_empty_configuration_doesnt_add_handlers(
|
||||
self, instantiated_handler_registry):
|
||||
reporting.add_configuration({})
|
||||
self.assertEqual(
|
||||
0, instantiated_handler_registry.register_item.call_count)
|
||||
|
||||
@mock.patch.object(
|
||||
reporting, 'instantiated_handler_registry', reporting.DictRegistry())
|
||||
@mock.patch.object(reporting, 'available_handlers')
|
||||
def test_looks_up_handler_by_type_and_adds_it(self, available_handlers):
|
||||
handler_type_name = 'test_handler'
|
||||
handler_cls = mock.Mock()
|
||||
available_handlers.registered_items = {handler_type_name: handler_cls}
|
||||
handler_name = 'my_test_handler'
|
||||
reporting.add_configuration(
|
||||
{handler_name: {'type': handler_type_name}})
|
||||
self.assertEqual(
|
||||
{handler_name: handler_cls.return_value},
|
||||
reporting.instantiated_handler_registry.registered_items)
|
||||
|
||||
@mock.patch.object(
|
||||
reporting, 'instantiated_handler_registry', reporting.DictRegistry())
|
||||
@mock.patch.object(reporting, 'available_handlers')
|
||||
def test_uses_non_type_parts_of_config_dict_as_kwargs(
|
||||
self, available_handlers):
|
||||
handler_type_name = 'test_handler'
|
||||
handler_cls = mock.Mock()
|
||||
available_handlers.registered_items = {handler_type_name: handler_cls}
|
||||
extra_kwargs = {'foo': 'bar', 'bar': 'baz'}
|
||||
handler_config = extra_kwargs.copy()
|
||||
handler_config.update({'type': handler_type_name})
|
||||
handler_name = 'my_test_handler'
|
||||
reporting.add_configuration({handler_name: handler_config})
|
||||
self.assertEqual(
|
||||
handler_cls.return_value,
|
||||
reporting.instantiated_handler_registry.registered_items[
|
||||
handler_name])
|
||||
self.assertEqual([mock.call(**extra_kwargs)],
|
||||
handler_cls.call_args_list)
|
||||
|
||||
@mock.patch.object(
|
||||
reporting, 'instantiated_handler_registry', reporting.DictRegistry())
|
||||
@mock.patch.object(reporting, 'available_handlers')
|
||||
def test_handler_config_not_modified(self, available_handlers):
|
||||
handler_type_name = 'test_handler'
|
||||
handler_cls = mock.Mock()
|
||||
available_handlers.registered_items = {handler_type_name: handler_cls}
|
||||
handler_config = {'type': handler_type_name, 'foo': 'bar'}
|
||||
expected_handler_config = handler_config.copy()
|
||||
reporting.add_configuration({'my_test_handler': handler_config})
|
||||
self.assertEqual(expected_handler_config, handler_config)
|
||||
|
Loading…
x
Reference in New Issue
Block a user