def test_register_not_starts_registrar_not_connected(self): listener = PostgresListenerService() channel = factory.make_name("channel", sep="_").lower() listener.register(channel, sentinel.handler) self.assertIsNone(listener.channelRegistrarDone) self.assertEqual([sentinel.handler], listener.listeners[channel]) self.assertNotIn(channel, listener.registeredChannels)
def test_unregister_removes_handler_others(self): listener = PostgresListenerService() channel = factory.make_name("channel", sep="_").lower() listener.register(channel, sentinel.handler1) listener.register(channel, sentinel.handler2) listener.unregister(channel, sentinel.handler2) self.assertEquals({channel: [sentinel.handler1]}, listener.listeners)
def test_unregister_calls_unregisterChannel_when_connected(self): listener = PostgresListenerService() channel = factory.make_name("channel") listener.register(channel, sentinel.handler) listener.registeredChannels = True listener.connection = sentinel.connection mock_unregisterChannel = self.patch(listener, "unregisterChannel") listener.unregister(channel, sentinel.handler) self.assertThat(mock_unregisterChannel, MockCalledOnceWith(channel))
def test_stopService_handles_canceling_startup(self): listener = PostgresListenerService() service = RackControllerService(sentinel.ipcWorker, listener) service.processId = random.randint(0, 100) service.starting = Deferred() listener.register(f"sys_core_{service.processId}", service.coreHandler) yield service.stopService() self.assertNotIn(f"sys_core_{service.processId}", listener.listeners) self.assertIsNone(service.starting)
def test_unregister_doesnt_call_unregisterChannel_multi_handlers(self): listener = PostgresListenerService() channel = factory.make_name("channel", sep="_").lower() listener.register(channel, sentinel.handler) listener.register(channel, sentinel.other_handler) listener.registeredChannels = True listener.connection = sentinel.connection mock_unregisterChannel = self.patch(listener, "unregisterChannel") listener.unregister(channel, sentinel.handler) self.assertThat(mock_unregisterChannel, MockNotCalled())
def test__calls_handler_on_notification(self): listener = PostgresListenerService() dv = DeferredValue() listener.register("machine", lambda *args: dv.set(args)) yield listener.startService() try: yield deferToDatabase(self.send_notification, "machine_create", 1) yield dv.get(timeout=2) self.assertEqual(('create', '1'), dv.value) finally: yield listener.stopService()
def test_coreHandler_unwatch_doesnt_call_unregister(self): processId = random.randint(0, 100) rack_id = random.randint(0, 100) listener = PostgresListenerService() service = RackControllerService(sentinel.ipcWorker, listener) self.assertNotIn(rack_id, service.watching) listener.register(f"sys_dhcp_{rack_id}", service.dhcpHandler) service.processId = processId service.coreHandler("sys_core_%d" % processId, "unwatch_%d" % rack_id) self.assertEqual({f"sys_dhcp_{rack_id}": [service.dhcpHandler]}, listener.listeners)
def test_register_adds_channel_and_handler(self): listener = PostgresListenerService() channel = factory.make_name("channel", sep="_").lower() listener.register(channel, sentinel.handler) yield listener.startService() try: yield listener.channelRegistrarDone self.assertEqual([sentinel.handler], listener.listeners[channel]) self.assertIn(channel, listener.registeredChannels) finally: yield listener.stopService()
def test_unregister_doesnt_call_unregisterChannel_multi_handlers(self): listener = PostgresListenerService() listener.HANDLE_NOTIFY_DELAY = listener.CHANNEL_REGISTRAR_DELAY = 0 channel = factory.make_name("channel", sep="_").lower() listener.register(channel, sentinel.handler) listener.register(channel, sentinel.other_handler) listener.registeredChannels = set() listener.connection = MagicMock() mock_unregisterChannel = self.patch(listener, "unregisterChannel") listener.unregister(channel, sentinel.handler) yield listener.channelRegistrarDone self.assertThat(mock_unregisterChannel, MockNotCalled())
def test_calls_handler_on_notification(self): listener = PostgresListenerService() listener.HANDLE_NOTIFY_DELAY = listener.CHANNEL_REGISTRAR_DELAY = 0 dv = DeferredValue() listener.register("machine", lambda *args: dv.set(args)) yield listener.startService() yield listener.channelRegistrarDone try: yield deferToDatabase(self.send_notification, "machine_create", 1) yield dv.get(timeout=2) self.assertEqual(("create", "1"), dv.value) finally: yield listener.stopService()
def test_coreHandler_unwatch_calls_unregister(self): processId = random.randint(0, 100) rack_id = random.randint(0, 100) listener = PostgresListenerService() service = RackControllerService(sentinel.ipcWorker, listener) service.processId = processId service.watching = {rack_id} service.needsDHCPUpdate = {rack_id} listener.register(f"sys_dhcp_{rack_id}", service.dhcpHandler) service.coreHandler("sys_core_%d" % processId, "unwatch_%d" % rack_id) self.assertNotIn(f"sys_dhcp_{rack_id}", listener.listeners) self.assertEquals(set(), service.watching) self.assertEquals(set(), service.needsDHCPUpdate)
def test__calls_handler_on_notification_with_delayed_registration(self): listener = PostgresListenerService() dv = DeferredValue() yield listener.startService() try: # Register after the service has been started. The handler should # still be called. listener.register("machine", lambda *args: dv.set(args)) yield deferToDatabase(self.send_notification, "machine_create", 1) yield dv.get(timeout=2) self.assertEqual(('create', '1'), dv.value) finally: yield listener.stopService()
def test_unregister_calls_unregisterChannel_when_connected(self): listener = PostgresListenerService() channel = factory.make_name("channel", sep="_").lower() listener.register(channel, sentinel.handler) yield listener.startService() try: yield listener.channelRegistrarDone self.assertIn(channel, listener.registeredChannels) listener.unregister(channel, sentinel.handler) yield listener.channelRegistrarDone finally: yield listener.stopService() self.assertNotIn(channel, listener.registeredChannels)
def test__calls_system_handler_on_notification(self): listener = PostgresListenerService() # Change notifications to a frozenset. This makes sure that # the system message does not go into the queue. Instead if should # call the handler directly in `doRead`. listener.notifications = frozenset() dv = DeferredValue() listener.register("sys_test", lambda *args: dv.set(args)) yield listener.startService() try: yield deferToDatabase(self.send_notification, "sys_test", 1) yield dv.get(timeout=2) self.assertEqual(("sys_test", "1"), dv.value) finally: yield listener.stopService()
def test_stopService_calls_unregister_for_all_watching(self): processId = random.randint(0, 100) watching = {random.randint(0, 100) for _ in range(3)} listener = PostgresListenerService() service = RackControllerService(sentinel.ipcWorker, listener) service.processId = processId service.watching = watching listener.register(f"sys_core_{processId}", service.coreHandler) for watch_id in watching: listener.register(f"sys_dhcp_{watch_id}", service.dhcpHandler) yield service.stopService() self.assertNotIn(f"sys_core_{processId}", listener.listeners) for watch_id in watching: self.assertNotIn(f"sys_dhcp_{watch_id}", listener.listeners)
def test__tryConnection_reregisters_channels(self): listener = PostgresListenerService() handler = object() listener.register("channel", handler) yield listener.startService() yield listener.channelRegistrarDone listener.registerChannel = Mock() yield listener.stopService() yield listener.tryConnection() yield listener.channelRegistrarDone try: self.assertEqual([call("channel")], listener.registerChannel.mock_calls) self.assertEqual({"channel": [handler]}, listener.listeners) self.assertEqual(set(["channel"]), listener.registeredChannels) finally: yield listener.stopService()
def test_unregister_raises_error_if_handler_does_not_match(self): listener = PostgresListenerService() channel = factory.make_name("channel", sep="_").lower() listener.register(channel, sentinel.handler) with ExpectedException(PostgresListenerUnregistrationError): listener.unregister(channel, sentinel.other_handler)
def test_raises_error_if_system_handler_registered_more_than_once(self): channel = factory.make_name("sys_", sep="") listener = PostgresListenerService() listener.register(channel, lambda *args: None) with ExpectedException(PostgresListenerRegistrationError): listener.register(channel, lambda *args: None)
def test_register_adds_channel_and_handler(self): listener = PostgresListenerService() channel = factory.make_name("channel") listener.register(channel, sentinel.handler) self.assertEqual([sentinel.handler], listener.listeners[channel])
def test_unregister_removes_handler(self): listener = PostgresListenerService() channel = factory.make_name("channel") listener.register(channel, sentinel.handler) listener.unregister(channel, sentinel.handler) self.assertEquals({channel: []}, listener.listeners)