=== modified file 'mandos-ctl' --- mandos-ctl 2019-03-15 23:55:53 +0000 +++ mandos-ctl 2019-03-16 00:10:31 +0000 @@ -102,16 +102,7 @@ mandos_serv_object_manager = dbus.Interface( mandos_dbus_object, dbus_interface=dbus.OBJECT_MANAGER_IFACE) - log.debug("D-Bus: %s:%s:%s.GetManagedObjects()", dbus_busname, - server_dbus_path, dbus.OBJECT_MANAGER_IFACE) - try: - with SilenceLogger("dbus.proxies"): - managed_objects = (mandos_serv_object_manager - .GetManagedObjects()) - except dbus.exceptions.DBusException as e: - log.critical("Failed to access Mandos server through D-Bus:" - "\n%s", e) - sys.exit(1) + managed_objects = get_managed_objects(mandos_serv_object_manager) all_clients = {} for path, ifs_and_props in managed_objects.items(): @@ -446,6 +437,19 @@ return mandos_dbus_object +def get_managed_objects(object_manager): + log.debug("D-Bus: %s:%s:%s.GetManagedObjects()", dbus_busname, + server_dbus_path, dbus.OBJECT_MANAGER_IFACE) + try: + with SilenceLogger("dbus.proxies"): + managed_objects = object_manager.GetManagedObjects() + except dbus.exceptions.DBusException as e: + log.critical("Failed to access Mandos server through D-Bus:" + "\n%s", e) + sys.exit(1) + return managed_objects + + class SilenceLogger(object): "Simple context manager to silence a particular logger" def __init__(self, loggername): @@ -1047,6 +1051,49 @@ return not is_critical +class Test_get_managed_objects(unittest.TestCase): + def test_calls_and_returns_GetManagedObjects(self): + managed_objects = {"/clients/foo": { "Name": "foo"}} + class MockObjectManager(object): + @staticmethod + def GetManagedObjects(): + return managed_objects + retval = get_managed_objects(MockObjectManager()) + self.assertDictEqual(managed_objects, retval) + + def test_logs_and_exits_on_dbus_error(self): + class MockObjectManagerFailing(object): + @staticmethod + def GetManagedObjects(): + raise dbus.exceptions.DBusException("Test") + + if hasattr(self, "assertLogs"): + with self.assertLogs(log, logging.CRITICAL): + with self.assertRaises(SystemExit): + get_managed_objects(MockObjectManagerFailing()) + else: + critical_filter = self.CriticalFilter() + log.addFilter(critical_filter) + try: + with self.assertRaises(SystemExit) as e: + get_managed_objects(MockObjectManagerFailing()) + finally: + log.removeFilter(critical_filter) + self.assertTrue(critical_filter.found) + if isinstance(e.exception.code, int): + self.assertNotEqual(e.exception.code, 0) + else: + self.assertIsNotNone(e.exception.code) + + class CriticalFilter(logging.Filter): + """Don't show, but register, critical messages""" + found = False + def filter(self, record): + is_critical = record.levelno >= logging.CRITICAL + self.found = is_critical or self.found + return not is_critical + + class Test_SilenceLogger(unittest.TestCase): loggername = "mandos-ctl.Test_SilenceLogger" log = logging.getLogger(loggername)