Beispiel #1
0
def test_connection_lost(test_client, mock_treq):
    mock_treq.post.side_effect = ConnectionLost()
    with pytest.raises(ConnectionLost):
        yield test_client.request("POST",
                                  "/test/uri",
                                  SOME_JSON,
                                  is_retry=True)
Beispiel #2
0
    def test_requestFinishAfterConnectionLost(self):
        app = self.app
        request = requestMock(b"/")

        finished = Deferred()

        @app.route("/")
        def root(request):
            request.notifyFinish().addBoth(lambda _: finished.callback(b'foo'))
            return finished

        d = _render(self.kr, request)

        def _eb(result):
            [failure] = self.flushLoggedErrors(RuntimeError)

            self.assertEqual(
                str(failure.value),
                ("Request.finish called on a request after its connection was "
                 "lost; use Request.notifyFinish to keep track of this."))

        d.addErrback(lambda _: finished)
        d.addErrback(_eb)

        self.assertNotFired(d)

        request.connectionLost(ConnectionLost())

        self.assertFired(d)
Beispiel #3
0
    def _init_browser(self):
        # XXX: open at most one browser at a time per client (i.e. per Scrapy
        #      instance), ensure there is no communication between pages of a
        #      browser. If not possible, open one browser per cookiejar but also
        #      allow the user to have separate browsers on the same cookiejar.

        if self._browser is not None:
            return

        factory = pb.PBClientFactory(security=jelly.DummySecurityOptions())
        broker = yield self._client_endpoint.connect(factory)
        if isinstance(self._client_endpoint, ProcessEndpoint):
            atexit.register(broker.transport.signalProcess, "TERM")

        # Endpoints do not call ClientFactory.clientConnectionLost(), so the
        # factory never calls back its own getRootObject() deferreds when an
        # error happens.
        root_dfd = factory.getRootObject()
        broker.notifyOnDisconnect(partial(root_dfd.errback, ConnectionLost()))
        root = yield root_dfd

        if self._downloader is None:
            self._downloader = BrowserRequestDownloader(self._crawler)

        self._browser = yield root.callRemote('open_browser', self._downloader)
Beispiel #4
0
    def _respondToBadRequestAndDisconnect(self, streamID):
        """
        This is a quick and dirty way of responding to bad requests.

        As described by HTTP standard we should be patient and accept the
        whole request from the client before sending a polite bad request
        response, even in the case when clients send tons of data.

        Unlike in the HTTP/1.1 case, this does not actually disconnect the
        underlying transport: there's no need. This instead just sends a 400
        response and terminates the stream.

        @param streamID: The ID of the stream that needs the 100 Continue
        response
        @type streamID: L{int}
        """
        headers = [(b":status", b"400")]
        self.conn.send_headers(headers=headers,
                               stream_id=streamID,
                               end_stream=True)
        stillActive = self._tryToWriteControlData()
        if stillActive:
            stream = self.streams[streamID]
            stream.connectionLost(Failure(ConnectionLost("Invalid request")))
            self._requestDone(streamID)
Beispiel #5
0
    def test_error_sending(self, logger):
        """
        An error sending to one agent does not prevent others from being
        notified.
        """
        control_amp_service = build_control_amp_service(self)
        self.patch(control_amp_service, 'logger', logger)

        connected_protocol = ControlAMP(Clock(), control_amp_service)
        # Patching is bad.
        # https://clusterhq.atlassian.net/browse/FLOC-1603
        connected_protocol.callRemote = lambda *args, **kwargs: succeed({})

        error = ConnectionLost()
        disconnected_protocol = ControlAMP(Clock(), control_amp_service)
        results = [succeed({}), fail(error)]
        # Patching is bad.
        # https://clusterhq.atlassian.net/browse/FLOC-1603
        disconnected_protocol.callRemote = (
            lambda *args, **kwargs: results.pop(0))

        control_amp_service.connected(disconnected_protocol)
        control_amp_service.connected(connected_protocol)
        control_amp_service.node_changed(
            ChangeSource(),
            (NodeState(hostname=u"1.2.3.4"),)
        )

        actions = LoggedAction.ofType(logger.messages, LOG_SEND_TO_AGENT)
        self.assertEqual(
            [action.end_message["exception"] for action in actions
             if not action.succeeded],
            [u"twisted.internet.error.ConnectionLost"])
Beispiel #6
0
 def test_connection_lost(self):
     """
     Connection lost events are passed on to the agent.
     """
     self.client.connectionLost(Failure(ConnectionLost()))
     self.assertEqual(self.agent,
                      FakeAgent(is_connected=True, is_disconnected=True))
Beispiel #7
0
    def test_connection_lost(self):
        # pretend we connected
        self.proto._connectionMade()

        self.proto.connectionLost(Failure(ConnectionLost()))

        messages = ' '.join([str(x[1]) for x in self.proto.log.mock_calls])
        self.assertTrue(' was lost ' in messages)
Beispiel #8
0
 def checkRateLimit(self, hit_args):
     if self.divvyProtocol is None:
         # fail immediately if not connected
         return fail(ConnectionLost("on checkRateLimit"))
     if self.debug_mode:
         self.log.debug("DivvyClient: Checking ratelimit {hit_args}", hit_args=hit_args)
     self.divvyProtocol.checkRateLimit(**hit_args)
     return self.newDeferredResponse()
Beispiel #9
0
    def stopProducing(self):
        """
        Stop producing data.

        This tells the L{H2Connection} that its consumer has died, so it must
        stop producing data for good.
        """
        self.connectionLost(Failure(ConnectionLost("Producing stopped")))
Beispiel #10
0
 def test_finishAfterConnectionLost(self):
     """
     Calling L{Request.finish} after L{Request.connectionLost} has been
     called results in a L{RuntimeError} being raised.
     """
     channel = DummyChannel()
     transport = channel.transport
     req = http.Request(channel, False)
     req.connectionLost(Failure(ConnectionLost("The end.")))
     self.assertRaises(RuntimeError, req.finish)
Beispiel #11
0
 def test_connectionLost(self):
     """
     Ensure that the CGI process ends cleanly when the request connection
     is lost.
     """
     d = DummyChannel()
     request = http.Request(d, True)
     protocol = twcgi.CGIProcessProtocol(request)
     request.connectionLost(failure.Failure(ConnectionLost("Connection done")))
     protocol.processEnded(failure.Failure(error.ProcessTerminated()))
Beispiel #12
0
    def testConnectionLost(self):
        failure = Failure(ConnectionLost("Unit test"))

        with mock.patch.object(self.proto.fsm, 'connectionFailed') as mock_method:
            self.proto.connectionLost(failure)
            mock_method.assert_called()

            mock_method.reset_mock()
            self.proto.disconnected = True
            self.proto.connectionLost(failure)
            mock_method.assert_not_called()
Beispiel #13
0
 def test_connectionLostNotification(self):
     """
     L{Request.connectionLost} triggers all finish notification Deferreds
     and cleans up per-request state.
     """
     d = DummyChannel()
     request = http.Request(d, True)
     finished = request.notifyFinish()
     request.connectionLost(Failure(ConnectionLost("Connection done")))
     self.assertIdentical(request.channel, None)
     return self.assertFailure(finished, ConnectionLost)
Beispiel #14
0
        def massage_error(error):
            if error.check(RemoteAmpError):
                rje = error.value
                errorType = command.reverseErrors.get(rje.errorCode,
                                                      UnknownRemoteError)
                return Failure(errorType(rje.description))

            # In this case the actual AMP implementation closes the connection.
            # Weakly simulate that here by failing how things fail if the
            # connection closes and commands are outstanding.  This is sort of
            # terrible behavior but oh well.  https://tm.tl/7055
            return Failure(ConnectionLost(str(error)))
Beispiel #15
0
    def _requestAborted(self, event):
        """
        Internal handler for when a request is aborted by a remote peer.

        @param event: The Hyper-h2 event that encodes information about the
            reset stream.
        @type event: L{h2.events.StreamReset}
        """
        stream = self.streams[event.stream_id]
        stream.connectionLost(
            ConnectionLost("Stream reset with code %s" % event.error_code))
        self._requestDone(event.stream_id)
Beispiel #16
0
    def disconnected(_):
        """
        Make sure deferreds do not linger on after disconnect.

        This errbacks all deferreds of iq's for which no response has been
        received with a L{ConnectionLost} failure. Otherwise, the deferreds
        will never be fired.
        """
        iqDeferreds = xs.iqDeferreds
        xs.iqDeferreds = {}
        for d in iqDeferreds.itervalues():
            d.errback(ConnectionLost())
Beispiel #17
0
 def test_connection_lost(self):
     """
     When a connection is lost the ``ControlAMP`` is removed from the
     service's set of connections.
     """
     marker = object()
     self.control_amp_service.connections.add(marker)
     self.patch(self.protocol, "callRemote",
                lambda *args, **kwargs: succeed(None))
     self.protocol.makeConnection(StringTransport())
     self.protocol.connectionLost(Failure(ConnectionLost()))
     self.assertEqual(self.control_amp_service.connections, {marker})
Beispiel #18
0
    def test_disconnected(self):
        """
        Pending and future requests fail when the connection goes away.
        """
        d = self.protocol.request(b'api corr stuff')
        self.assertNoResult(d)

        self.transport.disconnectReason = ConnectionLost('Bye.')
        self.transport.reportDisconnect()
        self.failureResultOf(d, ConnectionLost)

        self.failureResultOf(self.protocol.request(b'api corr more'),
                             ConnectionLost)
Beispiel #19
0
 def test_connectionLost_uncleanly(self):
     kp = KafkaProtocol()
     logsave = afkak.protocol.log
     try:
         afkak.protocol.log = MagicMock()
         kp.factory = MagicMock()
         failure = Failure(ConnectionLost())
         kp.connectionLost(failure)
         self.assertIsNone(kp.factory)
         afkak.protocol.log.warning.assert_called_once_with(
             'Lost Connection to Kafka Broker: %r', failure)
     finally:
         afkak.protocol.log = logsave
Beispiel #20
0
 def test_connection_lost(self):
     """
     When a connection is lost the ``ControlAMP`` is removed from the
     service's set of connections.
     """
     marker = object()
     self.control_amp_service.connections.add(marker)
     # Patching is bad.
     # https://clusterhq.atlassian.net/browse/FLOC-1603
     self.patch(self.protocol, "callRemote",
                lambda *args, **kwargs: succeed(None))
     self.protocol.makeConnection(StringTransportWithAbort())
     self.protocol.connectionLost(Failure(ConnectionLost()))
     self.assertEqual(self.control_amp_service.connections, {marker})
Beispiel #21
0
    def test_write_after_connection_lost(self):
        """
        Calling L{Request.write} after L{Request.connectionLost} has been
        called should not throw an exception. L{RuntimeError} will be raised
        when finish is called on the request.

        NOTE: This test is taken from the upstream fix to verify the monkey
              patch: https://github.com/twisted/twisted/commit/169fd1d93b7af06bf0f6893b193ce19970881868
        """
        channel = DummyChannel()
        req = http.Request(channel, False)
        req.connectionLost(Failure(ConnectionLost("The end.")))
        req.write(b"foobar")
        self.assertRaises(RuntimeError, req.finish)
Beispiel #22
0
    def dataReceived(self, data):
        """
        Called whenever a chunk of data is received from the transport.

        @param data: The data received from the transport.
        @type data: L{bytes}
        """
        try:
            events = self.conn.receive_data(data)
        except h2.exceptions.ProtocolError:
            stillActive = self._tryToWriteControlData()
            if stillActive:
                self.transport.loseConnection()
                self.connectionLost(Failure(), _cancelTimeouts=False)
            return

        # Only reset the timeout if we've received an actual H2
        # protocol message
        self.resetTimeout()

        for event in events:
            if isinstance(event, h2.events.RequestReceived):
                self._requestReceived(event)
            elif isinstance(event, h2.events.DataReceived):
                self._requestDataReceived(event)
            elif isinstance(event, h2.events.StreamEnded):
                self._requestEnded(event)
            elif isinstance(event, h2.events.StreamReset):
                self._requestAborted(event)
            elif isinstance(event, h2.events.WindowUpdated):
                self._handleWindowUpdate(event.stream_id)
            elif isinstance(event, h2.events.RemoteSettingsChanged):
                if h2.settings.SettingCodes.INITIAL_WINDOW_SIZE in event.changed_settings:
                    self._handleWindowUpdate(None)
            elif isinstance(event, h2.events.PriorityUpdated):
                self._handlePriorityUpdate(event)
            elif isinstance(event, h2.events.ConnectionTerminated):
                self.transport.loseConnection()
                self.connectionLost(
                    ConnectionLost("Remote peer sent GOAWAY"),
                    _cancelTimeouts=False,
                )

        self._tryToWriteControlData()
Beispiel #23
0
    def test_connectionLost(self):
        """
        L{http.Request.connectionLost} closes L{Request.content} and drops the
        reference to the L{HTTPChannel} to assist with garbage collection.
        """
        req = http.Request(DummyChannel(), None)

        # Cause Request.content to be created at all.
        req.gotLength(10)

        # Grab a reference to content in case the Request drops it later on.
        content = req.content

        # Put some bytes into it
        req.handleContentChunk("hello")

        # Then something goes wrong and content should get closed.
        req.connectionLost(Failure(ConnectionLost("Finished")))
        self.assertTrue(content.closed)
        self.assertIdentical(req.channel, None)
Beispiel #24
0
    def test_cancelsOnConnectionLost(self):
        app = self.app
        request = requestMock(b"/")

        handler_d = Deferred()

        @app.route("/")
        def root(request):
            return handler_d

        d = _render(self.kr, request)

        self.assertNotFired(d)

        request.connectionLost(ConnectionLost())

        handler_d.addErrback(lambda f: f.trap(CancelledError))

        d.addErrback(lambda f: f.trap(ConnectionLost))
        d.addCallback(lambda _: handler_d)
        self.assertFired(d)
Beispiel #25
0
    def test_nack_for_outbound_message(self):
        client = self.web_client()

        # initiate session
        resp_d = client.callRemote('USSD.INIT', self.SESSION_INIT_BODY)

        [msg] = yield self.tx_helper.wait_for_dispatched_inbound(1)

        # cancel the request and mute the resulting error.
        request = self.transport._requests[msg['message_id']]
        request.http_request.connectionLost(ConnectionLost())
        resp_d.cancel()
        resp_d.addErrback(lambda f: None)

        # send response
        rep = yield self.tx_helper.make_dispatch_reply(msg, "ping")
        [nack] = yield self.tx_helper.wait_for_dispatched_events(1)

        self.assertEqual(nack['event_type'], 'nack')
        self.assertEqual(nack['user_message_id'], rep['message_id'])
        self.assertEqual(nack['sent_message_id'], rep['message_id'])
Beispiel #26
0
    def dataReceived(self, data):
        """
        Called whenever a chunk of data is received from the transport.

        @param data: The data received from the transport.
        @type data: L{bytes}
        """
        self.resetTimeout()

        try:
            events = self.conn.receive_data(data)
        except h2.exceptions.ProtocolError:
            # A remote protocol error terminates the connection.
            dataToSend = self.conn.data_to_send()
            self.transport.write(dataToSend)
            self.transport.loseConnection()
            self.connectionLost(Failure())
            return

        for event in events:
            if isinstance(event, h2.events.RequestReceived):
                self._requestReceived(event)
            elif isinstance(event, h2.events.DataReceived):
                self._requestDataReceived(event)
            elif isinstance(event, h2.events.StreamEnded):
                self._requestEnded(event)
            elif isinstance(event, h2.events.StreamReset):
                self._requestAborted(event)
            elif isinstance(event, h2.events.WindowUpdated):
                self._handleWindowUpdate(event)
            elif isinstance(event, h2.events.PriorityUpdated):
                self._handlePriorityUpdate(event)
            elif isinstance(event, h2.events.ConnectionTerminated):
                self.transport.loseConnection()
                self.connectionLost(ConnectionLost("Remote peer sent GOAWAY"))

        dataToSend = self.conn.data_to_send()
        if dataToSend:
            self.transport.write(dataToSend)
Beispiel #27
0
    def test_returnOnlyClosesIfNotLost(self):
        """
        L{loseConnection} will only be called on the transport upon return of
        the connection-handling function if the connection hasn't been lost.

        This is like L{test_returnOnlyClosesIfNotClosed}, but it tests the case
        where the connection was closed by the other side, instead of with an
        explicit call to C{transport.close} by the connection-handling
        function.
        """
        def nothing(transport):
            try:
                transport.read()
            except ConnectionLost:
                pass
            return

        twistedTransport, protocol = self.getTransportAndProtocol(nothing)
        twistedTransport.loseConnection = lambda: self.fail(
            "loseConnection shouldn't be called!")
        protocol.makeConnection(twistedTransport)
        protocol.connectionLost(Failure(ConnectionLost("Woops")))
Beispiel #28
0
    def test_cancelledIsEatenOnConnectionLost(self):
        app = self.app
        request = requestMock(b"/")

        @app.route("/")
        def root(request):
            _d = Deferred()
            request.notifyFinish().addErrback(lambda _: _d.cancel())
            return _d

        d = _render(self.kr, request)

        self.assertNotFired(d)

        request.connectionLost(ConnectionLost())

        def _cb(result):
            self.assertEqual(request.processingFailed.call_count, 0)

        d.addErrback(lambda f: f.trap(ConnectionLost))
        d.addCallback(_cb)
        self.assertFired(d)
Beispiel #29
0
    def test_reconnecting(self):
        transport = yield self.get_transport()
        message_client = transport.message_client
        message_client.connectionLost(Failure(ConnectionLost('foo')))

        config = transport.get_static_config()

        self.assertTrue(transport.delay > config.initial_delay)
        self.assertEqual(transport.retries, 1)
        self.assertTrue(transport.reconnect_call)
        self.clock.advance(transport.delay + 0.1)

        # write something to ensure connectionMade() is called on
        # the protocol
        message_req = yield self.get_next_request()
        message_req.write('')

        event_req = yield self.get_next_request()
        event_req.write('')

        self.assertEqual(transport.delay, config.initial_delay)
        self.assertEqual(transport.retries, 0)
        self.assertFalse(transport.reconnect_call)
Beispiel #30
0
        error = []

        def writeOnClosed(transport):
            # We'll read so that we can get the ConnectionLost.
            try:
                transport.read()
            except Exception, firstE:
                pass
            try:
                transport.write("foo")
            except Exception, secondE:
                assert type(firstE) == type(secondE), (firstE, secondE)
                error.append(secondE)

        twistedTransport, protocol = self.connect(writeOnClosed)
        e = ConnectionLost("Oops!")
        twistedTransport.disconnectReason = Failure(e)
        twistedTransport.reportDisconnect()
        self.assertEquals(error, [e])

    def test_closedTransportOnlyThrowsForIO(self):
        """
        If the I/O greenlet is switched away for a reason other than I/O, a
        connection being lost will not cause the other switched call to
        raise an exception; the exception will be raised the next time an
        I/O operation is done.
        """
        dones = []
        clock = Clock()

        def waitThenRead(transport):