def test_handling_ping_error_then_reconnecting(self):
        engine_manager = self.make_engine_manager()
        engine_manager.engine = mocked_engine = self.mocker.engine
        mocked_connection = self.mocker.connection
        fake_error = FakeError()
        mocked_engine.connect.side_effect = lambda: mocked_connection
        mocked_connection.execute.side_effect = util.get_callable_with_different_side_effects(
            [
                None,
                fake_error,
                lambda *a, **kw: reactor.callFromThread(reactor.callLater, 0, engine_manager.stopService),
            ]
        )

        engine_manager.startService()

        self.assertEquals((yield self.events.get()), ("connected", mocked_engine))

        event = yield self.events.get()
        self.assertEquals(event[0], "lost")
        self.assertTrue(event[1].value is fake_error)

        self.assertEquals((yield self.events.get()), ("connected", mocked_engine))

        self.failIf(self.events.size > 0)
        yield util.wait(0)

        self.assertEquals(
            self.mocker.mock_calls,
            [
                # First ping succeeds.
                mock.call.engine.connect(),
                mock.call.connection.execute("SELECT 'ping'"),
                mock.call.connection.close(),
                # This one fails. The engine is disposed as a result.
                mock.call.engine.connect(),
                mock.call.connection.execute("SELECT 'ping'"),
                mock.call.connection.close(),
                mock.call.engine.dispose(),
                # After this ping we stop the service.
                mock.call.engine.connect(),
                mock.call.connection.execute("SELECT 'ping'"),
                mock.call.connection.close(),
                mock.call.engine.dispose(),
            ],
        )
    def test_handling_connect_error(self):
        """ If an error occurs on connect, another attempt should be made. """
        engine_manager = self.make_engine_manager()
        engine_manager.engine = mocked_engine = self.mocker.engine
        mocked_connection = self.mocker.connection
        fake_error = FakeError()
        mocked_engine.connect.side_effect = util.get_callable_with_different_side_effects(
            [fake_error, mocked_connection]
        )

        engine_manager.startService()
        event = yield self.events.get()
        self.assertEquals(event[0], "failed")
        self.assertTrue(event[1].value is fake_error)

        event = yield self.events.get()
        self.assertEquals(event, ("connected", mocked_engine))

        yield util.wait(0)
        engine_manager.stopService()
        yield util.wait(0)

        self.failIf(self.events.size > 0)
        self.assertEquals(
            self.mocker.mock_calls,
            [
                mock.call.engine.connect(),
                mock.call.engine.dispose(),  # The first connect fails, so the engine is disposed.
                mock.call.engine.connect(),
                mock.call.connection(),
                mock.call.connection().execute("SELECT 'ping'"),
                mock.call.connection().close(),
                mock.call.engine.dispose(),  # and disposed when the service stops.
                mock.call.engine.dispose(),  # and disposed when the service stops.
            ],
        )