def test_emit_signal_dead_reference(self):
        """Test dead reference while emitting a signal."""
        sample_signal = "sample_signal"
        fake_remote_client = self.mocker.mock()
        fake_remote_client.callRemote(sample_signal)
        self.mocker.throw(DeadReferenceError())
        self.mocker.replay()

        sb = SignalBroadcaster()
        sb.remote_register_to_signals(fake_remote_client, [sample_signal])
        self.assertIn(fake_remote_client, sb.clients_per_signal[sample_signal])
        sb.emit_signal(sample_signal)
        self.assertNotIn(fake_remote_client,
                         sb.clients_per_signal[sample_signal])
    def test_emit_signal_ignore_missing_handlers(self):
        """A missing signal handler should just log a debug line."""
        debugs = []
        self.patch(ipc.logger, "debug", lambda *args: debugs.append(args))

        fake_remote_client = FakeRemoteClient()

        sb = SignalBroadcaster()
        signals = [fake_remote_client.missing_signal]
        sb.remote_register_to_signals(fake_remote_client, signals)
        sb_clients = sb.clients_per_signal[fake_remote_client.missing_signal]
        self.assertIn(fake_remote_client, sb_clients)
        sb.emit_signal(fake_remote_client.missing_signal)

        expected = (
            SignalBroadcaster.MSG_NO_SIGNAL_HANDLER,
            fake_remote_client.missing_signal,
            fake_remote_client,
        )
        self.assertIn(expected, debugs)
    def test_emit_signal_log_other_errors(self):
        """Other errors should be logged as warnings."""
        warnings = []
        self.patch(ipc.logger, "warning", lambda *args: warnings.append(args))

        fake_remote_client = FakeRemoteClient()

        sb = SignalBroadcaster()
        signals = [fake_remote_client.failing_signal]
        sb.remote_register_to_signals(fake_remote_client, signals)
        sb_clients = sb.clients_per_signal[fake_remote_client.failing_signal]
        self.assertIn(fake_remote_client, sb_clients)
        sb.emit_signal(fake_remote_client.failing_signal)

        expected = (
            SignalBroadcaster.MSG_COULD_NOT_EMIT_SIGNAL,
            fake_remote_client.failing_signal,
            fake_remote_client,
            fake_remote_client.random_exception,
        )
        self.assertIn(expected, warnings)
    def test_emit_signal_some_dead_some_not(self):
        """Test a clean reference after a dead one."""
        sample_signal = "sample_signal"
        fake_dead_remote = self.mocker.mock()
        fake_alive_remote = self.mocker.mock()

        fake_dead_remote.callRemote(sample_signal)
        self.mocker.throw(DeadReferenceError())
        fake_alive_remote.callRemote(sample_signal)
        self.mocker.result(defer.succeed(None))
        self.mocker.replay()

        sb = SignalBroadcaster()
        sb.remote_register_to_signals(fake_dead_remote, [sample_signal])
        sb.remote_register_to_signals(fake_alive_remote, [sample_signal])
        sb.emit_signal(sample_signal)
 def setUp(self):
     yield super(TestSignalBroadcaster, self).setUp()
     self.client = self.mocker.mock()
     self.broad_caster = SignalBroadcaster()
class TestSignalBroadcaster(MockerTestCase):
    """Test the signal broadcaster code."""

    @defer.inlineCallbacks
    def setUp(self):
        yield super(TestSignalBroadcaster, self).setUp()
        self.client = self.mocker.mock()
        self.broad_caster = SignalBroadcaster()

    def test_remote_register_to_signals(self):
        """Assert that the client was added."""
        self.mocker.replay()
        signals = ["demo_signal1", "demo_signal2"]
        self.broad_caster.remote_register_to_signals(self.client, signals)
        for sig in signals:
            clients = self.broad_caster.clients_per_signal[sig]
            self.assertTrue(self.client in clients)

    def test_emit_signal(self):
        """Assert that the client method was called."""
        first = 1
        second = 2
        word = 'word'
        signal_name = 'on_test'
        deferred = self.mocker.mock()
        self.client.callRemote(signal_name, first, second, word=word)
        self.mocker.result(deferred)
        deferred.addErrback(ANY, ANY, ANY)
        deferred.addErrback(ANY, ANY, ANY)
        self.mocker.replay()
        signals = [signal_name]
        self.broad_caster.remote_register_to_signals(self.client, signals)
        self.broad_caster.emit_signal(signal_name, first, second, word=word)

    def test_emit_signal_dead_reference(self):
        """Test dead reference while emitting a signal."""
        sample_signal = "sample_signal"
        fake_remote_client = self.mocker.mock()
        fake_remote_client.callRemote(sample_signal)
        self.mocker.throw(DeadReferenceError())
        self.mocker.replay()

        sb = SignalBroadcaster()
        sb.remote_register_to_signals(fake_remote_client, [sample_signal])
        self.assertIn(fake_remote_client, sb.clients_per_signal[sample_signal])
        sb.emit_signal(sample_signal)
        self.assertNotIn(fake_remote_client,
                         sb.clients_per_signal[sample_signal])

    def test_emit_signal_some_dead_some_not(self):
        """Test a clean reference after a dead one."""
        sample_signal = "sample_signal"
        fake_dead_remote = self.mocker.mock()
        fake_alive_remote = self.mocker.mock()

        fake_dead_remote.callRemote(sample_signal)
        self.mocker.throw(DeadReferenceError())
        fake_alive_remote.callRemote(sample_signal)
        self.mocker.result(defer.succeed(None))
        self.mocker.replay()

        sb = SignalBroadcaster()
        sb.remote_register_to_signals(fake_dead_remote, [sample_signal])
        sb.remote_register_to_signals(fake_alive_remote, [sample_signal])
        sb.emit_signal(sample_signal)