Пример #1
0
    def test_connectEvent(self):
        """
        This test checks that we correctly get notifications event for a
        client.  This ought to prevent a regression under Windows using the
        GTK2 reactor.  See #3925.
        """
        reactor = self.buildReactor()

        self.listen(reactor, ServerFactory.forProtocol(Protocol))
        connected = []

        class CheckConnection(Protocol):

            def connectionMade(self):
                connected.append(self)
                reactor.stop()

        clientFactory = Stop(reactor)
        clientFactory.protocol = CheckConnection

        needsRunningReactor(
            reactor, lambda: self.connect(reactor, clientFactory))

        reactor.run()

        self.assertTrue(connected)
Пример #2
0
    def test_stopOnlyCloses(self):
        """
        When the L{IListeningPort} returned by
        L{IReactorSocket.adoptDatagramPort} is stopped using
        C{stopListening}, the underlying socket is closed but not
        shutdown.  This allows another process which still has a
        reference to it to continue reading and writing to it.
        """
        reactor = self.buildReactor()

        portSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.addCleanup(portSocket.close)

        portSocket.setblocking(False)

        # The file descriptor is duplicated by adoptDatagramPort
        port = reactor.adoptDatagramPort(
            portSocket.fileno(), portSocket.family, DatagramProtocol())
        d = port.stopListening()
        def stopped(ignored):
            # Should still be possible to recv on portSocket.  If
            # it was shutdown, the exception would be EINVAL instead.
            exc = self.assertRaises(socket.error, portSocket.recvfrom, 1)
            self.assertEqual(exc.args[0], errno.EAGAIN)
        d.addCallback(stopped)
        d.addErrback(err, "Failed to read on original port.")

        needsRunningReactor(
            reactor,
            lambda: d.addCallback(lambda ignored: reactor.stop()))

        reactor.run()
Пример #3
0
    def test_connectEvent(self):
        """
        This test checks that we correctly get notifications event for a
        client.  This ought to prevent a regression under Windows using the
        GTK2 reactor.  See #3925.
        """
        reactor = self.buildReactor()

        server = reactor.listenTCP(0, serverFactoryFor(Protocol),
                                   interface=self.interface)
        connected = []

        class CheckConnection(Protocol):
            def connectionMade(self):
                connected.append(self)
                reactor.stop()

        clientFactory = Stop(reactor)
        clientFactory.protocol = CheckConnection

        needsRunningReactor(reactor, lambda: reactor.connectTCP(
            self.interface, server.getHost().port, clientFactory))

        reactor.run()

        self.assertTrue(connected)
Пример #4
0
    def test_stopOnlyCloses(self):
        """
        When the L{IListeningPort} returned by
        L{IReactorSocket.adoptStreamPort} is stopped using
        C{stopListening}, the underlying socket is closed but not
        shutdown.  This allows another process which still has a
        reference to it to continue accepting connections over it.
        """
        reactor = self.buildReactor()

        portSocket = socket.socket()
        self.addCleanup(portSocket.close)

        portSocket.listen(1)
        portSocket.setblocking(False)

        # The file descriptor is duplicated by adoptStreamPort
        port = reactor.adoptStreamPort(
            portSocket.fileno(), portSocket.family, ServerFactory())
        d = port.stopListening()
        def stopped(ignored):
            # Should still be possible to accept a connection on
            # portSocket.  If it was shutdown, the exception would be
            # EINVAL instead.
            exc = self.assertRaises(socket.error, portSocket.accept)
            self.assertEqual(exc.args[0], errno.EAGAIN)
        d.addCallback(stopped)
        d.addErrback(err, "Failed to accept on original port.")

        needsRunningReactor(
            reactor,
            lambda: d.addCallback(lambda ignored: reactor.stop()))

        reactor.run()
Пример #5
0
 def test_clientConnectionFailedStopsReactor(self):
     """
     The reactor can be stopped by a client factory's
     C{clientConnectionFailed} method.
     """
     reactor = self.buildReactor()
     needsRunningReactor(reactor, lambda: self.connect(reactor, Stop(reactor)))
     self.runReactor(reactor)
Пример #6
0
    def test_addresses(self):
        """
        A client's transport's C{getHost} and C{getPeer} return L{IPv4Address}
        or L{IPv6Address} instances which have the resolved adddress of the
        local and remote endpoints of the connection respectively as their
        C{host} attribute, not the hostname originally passed in to
        L{connectTCP<twisted.internet.interfaces.IReactorTCP.connectTCP>}, if
        a hostname was used.
        """
        host, port = findFreePort(self.interface, self.family)[:2]
        reactor = self.buildReactor()
        fakeDomain = self.fakeDomainName
        reactor.installResolver(FakeResolver({fakeDomain: self.interface}))

        server = reactor.listenTCP(
            0, serverFactoryFor(Protocol), interface=host)
        serverAddress = server.getHost()

        transportData = {'host': None, 'peer': None, 'instance': None}
        class CheckAddress(Protocol):
            def makeConnection(self, transport):
                transportData['host'] = transport.getHost()
                transportData['peer'] = transport.getPeer()
                transportData['instance'] = transport
                reactor.stop()

        clientFactory = Stop(reactor)
        clientFactory.protocol = CheckAddress

        def connectMe():
            reactor.connectTCP(
                fakeDomain, server.getHost().port, clientFactory,
                bindAddress=(self.interface, port))
        needsRunningReactor(reactor, connectMe)

        self.runReactor(reactor)

        if clientFactory.failReason:
            self.fail(clientFactory.failReason.getTraceback())

        hostAddress = self.addressClass('TCP', self.interface, port)
        peerAddress = self.addressClass('TCP', self.interface,
            serverAddress.port)
        transportRepr = "<%s to %s at %x>" % (
            transportData['instance'].__class__,
            transportData['instance'].addr,
            id(transportData['instance']))

        self.assertEqual({
                'host': transportData['host'],
                'peer': transportData['peer'],
                'repr': repr(transportData['instance']),
                }, {
                'host': hostAddress,
                'peer': peerAddress,
                'repr': transportRepr,
                })
Пример #7
0
 def test_clientConnectionFailedStopsReactor(self):
     """
     The reactor can be stopped by a client factory's
     C{clientConnectionFailed} method.
     """
     host, port = findFreePort(self.interface, self.family)[:2]
     reactor = self.buildReactor()
     needsRunningReactor(
         reactor, lambda: reactor.connectTCP(host, port, Stop(reactor)))
     self.runReactor(reactor)
Пример #8
0
    def test_badContext(self):
        """
        If the context factory passed to L{ITCPTransport.startTLS} raises an
        exception from its C{getContext} method, that exception is raised by
        L{ITCPTransport.startTLS}.
        """
        reactor = self.buildReactor()

        brokenFactory = BrokenContextFactory()
        results = []

        serverFactory = ServerFactory()
        serverFactory.protocol = Protocol

        port = reactor.listenTCP(0, serverFactory, interface=self.interface)
        endpoint = self.endpoints.client(reactor, port.getHost())

        clientFactory = ClientFactory()
        clientFactory.protocol = Protocol
        connectDeferred = endpoint.connect(clientFactory)

        def connected(protocol):
            if not ITLSTransport.providedBy(protocol.transport):
                results.append("skip")
            else:
                results.append(self.assertRaises(ValueError,
                                                 protocol.transport.startTLS,
                                                 brokenFactory))

        def connectFailed(failure):
            results.append(failure)

        def whenRun():
            connectDeferred.addCallback(connected)
            connectDeferred.addErrback(connectFailed)
            connectDeferred.addBoth(lambda ign: reactor.stop())
        needsRunningReactor(reactor, whenRun)

        self.runReactor(reactor)

        self.assertEqual(len(results), 1,
                         "more than one callback result: %s" % (results,))

        if isinstance(results[0], Failure):
            # self.fail(Failure)
            results[0].raiseException()
        if results[0] == "skip":
            raise SkipTest("Reactor does not support ITLSTransport")
        self.assertEqual(BrokenContextFactory.message, str(results[0]))
Пример #9
0
    def test_writeAfterDisconnect(self):
        """
        After a connection is disconnected, L{ITransport.write} and
        L{ITransport.writeSequence} are no-ops.
        """
        reactor = self.buildReactor()

        finished = []

        serverConnectionLostDeferred = Deferred()
        protocol = lambda: ClosingLaterProtocol(serverConnectionLostDeferred)
        portDeferred = self.endpoints.server(reactor).listen(
            ServerFactory.forProtocol(protocol)
        )

        def listening(port):
            msg("Listening on %r" % (port.getHost(),))
            endpoint = self.endpoints.client(reactor, port.getHost())

            lostConnectionDeferred = Deferred()
            protocol = lambda: ClosingLaterProtocol(lostConnectionDeferred)
            client = endpoint.connect(ClientFactory.forProtocol(protocol))

            def write(proto):
                msg("About to write to %r" % (proto,))
                proto.transport.write(b"x")

            client.addCallbacks(write, lostConnectionDeferred.errback)

            def disconnected(proto):
                msg("%r disconnected" % (proto,))
                proto.transport.write(b"some bytes to get lost")
                proto.transport.writeSequence([b"some", b"more"])
                finished.append(True)

            lostConnectionDeferred.addCallback(disconnected)
            serverConnectionLostDeferred.addCallback(disconnected)
            return gatherResults([lostConnectionDeferred, serverConnectionLostDeferred])

        def onListen():
            portDeferred.addCallback(listening)
            portDeferred.addErrback(err)
            portDeferred.addCallback(lambda ignored: reactor.stop())

        needsRunningReactor(reactor, onListen)

        self.runReactor(reactor)
        self.assertEqual(finished, [True, True])
Пример #10
0
    def test_writeAfterDisconnect(self):
        """
        After a connection is disconnected, L{ITransport.write} and
        L{ITransport.writeSequence} are no-ops.
        """
        reactor = self.buildReactor()

        finished = []

        serverConnectionLostDeferred = Deferred()
        protocol = lambda: ClosingLaterProtocol(serverConnectionLostDeferred)
        portDeferred = self.endpoints.server(reactor).listen(ServerFactory.forProtocol(protocol))

        def listening(port):
            msg("Listening on %r" % (port.getHost(),))
            endpoint = self.endpoints.client(reactor, port.getHost())

            lostConnectionDeferred = Deferred()
            protocol = lambda: ClosingLaterProtocol(lostConnectionDeferred)
            client = endpoint.connect(ClientFactory.forProtocol(protocol))

            def write(proto):
                msg("About to write to %r" % (proto,))
                proto.transport.write(b"x")

            client.addCallbacks(write, lostConnectionDeferred.errback)

            def disconnected(proto):
                msg("%r disconnected" % (proto,))
                proto.transport.write(b"some bytes to get lost")
                proto.transport.writeSequence([b"some", b"more"])
                finished.append(True)

            lostConnectionDeferred.addCallback(disconnected)
            serverConnectionLostDeferred.addCallback(disconnected)
            return gatherResults([lostConnectionDeferred, serverConnectionLostDeferred])

        def onListen():
            portDeferred.addCallback(listening)
            portDeferred.addErrback(err)
            portDeferred.addCallback(lambda ignored: reactor.stop())

        needsRunningReactor(reactor, onListen)

        self.runReactor(reactor)
        self.assertEqual(finished, [True, True])
Пример #11
0
    def test_addresses(self):
        """
        A client's transport's C{getHost} and C{getPeer} return L{IPv4Address}
        instances which have the dotted-quad string form of the resolved
        adddress of the local and remote endpoints of the connection
        respectively as their C{host} attribute, not the hostname originally
        passed in to L{connectTCP
        <twisted.internet.interfaces.IReactorTCP.connectTCP>}, if a hostname
        was used.
        """
        host, port = findFreePort(self.interface, self.family)[:2]
        reactor = self.buildReactor()
        fakeDomain = self.fakeDomainName
        reactor.installResolver(FakeResolver({fakeDomain: self.interface}))

        server = reactor.listenTCP(
            0, serverFactoryFor(Protocol), interface=host)
        serverAddress = server.getHost()

        addresses = {'host': None, 'peer': None}
        class CheckAddress(Protocol):
            def makeConnection(self, transport):
                addresses['host'] = transport.getHost()
                addresses['peer'] = transport.getPeer()
                reactor.stop()

        clientFactory = Stop(reactor)
        clientFactory.protocol = CheckAddress

        def connectMe():
            reactor.connectTCP(
                fakeDomain, server.getHost().port, clientFactory,
                bindAddress=(self.interface, port))
        needsRunningReactor(reactor, connectMe)

        self.runReactor(reactor)

        if clientFactory.failReason:
            self.fail(clientFactory.failReason.getTraceback())

        self.assertEqual(
            addresses['host'],
            self.addressClass('TCP', self.interface, port))
        self.assertEqual(
            addresses['peer'],
            self.addressClass('TCP', self.interface, serverAddress.port))
Пример #12
0
    def test_protocolGarbageAfterLostConnection(self):
        """
        After the connection a protocol is being used for is closed, the
        reactor discards all of its references to the protocol.
        """
        lostConnectionDeferred = Deferred()
        clientProtocol = ClosingLaterProtocol(lostConnectionDeferred)
        clientRef = ref(clientProtocol)

        reactor = self.buildReactor()
        portDeferred = self.endpoints.server(reactor).listen(
            ServerFactory.forProtocol(Protocol))

        def listening(port):
            msg(f"Listening on {port.getHost()!r}")
            endpoint = self.endpoints.client(reactor, port.getHost())

            client = endpoint.connect(
                ClientFactory.forProtocol(lambda: clientProtocol))

            def disconnect(proto):
                msg(f"About to disconnect {proto!r}")
                proto.transport.loseConnection()

            client.addCallback(disconnect)
            client.addErrback(lostConnectionDeferred.errback)
            return lostConnectionDeferred

        def onListening():
            portDeferred.addCallback(listening)
            portDeferred.addErrback(err)
            portDeferred.addBoth(lambda ignored: reactor.stop())

        needsRunningReactor(reactor, onListening)

        self.runReactor(reactor)

        # Drop the reference and get the garbage collector to tell us if there
        # are no references to the protocol instance left in the reactor.
        clientProtocol = None
        collect()
        self.assertIsNone(clientRef())
Пример #13
0
    def test_stopOnlyCloses(self):
        """
        When the L{IListeningPort} returned by
        L{IReactorSocket.adoptStreamPort} is stopped using
        C{stopListening}, the underlying socket is closed but not
        shutdown.  This allows another process which still has a
        reference to it to continue accepting connections over it.
        """
        reactor = self.buildReactor()

        portSocket = socket.socket()
        self.addCleanup(portSocket.close)

        portSocket.bind(("127.0.0.1", 0))
        portSocket.listen(1)
        portSocket.setblocking(False)

        # The file descriptor is duplicated by adoptStreamPort
        port = reactor.adoptStreamPort(
            portSocket.fileno(), portSocket.family, ServerFactory()
        )
        d = port.stopListening()

        def stopped(ignored):
            # Should still be possible to accept a connection on
            # portSocket.  If it was shutdown, the exception would be
            # EINVAL instead.
            exc = self.assertRaises(socket.error, portSocket.accept)
            if platform.isWindows():
                self.assertEqual(exc.args[0], errno.WSAEWOULDBLOCK)
            else:
                self.assertEqual(exc.args[0], errno.EAGAIN)

        d.addCallback(stopped)
        d.addErrback(err, "Failed to accept on original port.")

        needsRunningReactor(
            reactor, lambda: d.addCallback(lambda ignored: reactor.stop())
        )

        reactor.run()
Пример #14
0
    def test_protocolGarbageAfterLostConnection(self):
        """
        After the connection a protocol is being used for is closed, the
        reactor discards all of its references to the protocol.
        """
        lostConnectionDeferred = Deferred()
        clientProtocol = ClosingLaterProtocol(lostConnectionDeferred)
        clientRef = ref(clientProtocol)

        reactor = self.buildReactor()
        portDeferred = self.endpoints.server(reactor).listen(ServerFactory.forProtocol(Protocol))

        def listening(port):
            msg("Listening on %r" % (port.getHost(),))
            endpoint = self.endpoints.client(reactor, port.getHost())

            client = endpoint.connect(ClientFactory.forProtocol(lambda: clientProtocol))

            def disconnect(proto):
                msg("About to disconnect %r" % (proto,))
                proto.transport.loseConnection()

            client.addCallback(disconnect)
            client.addErrback(lostConnectionDeferred.errback)
            return lostConnectionDeferred

        def onListening():
            portDeferred.addCallback(listening)
            portDeferred.addErrback(err)
            portDeferred.addBoth(lambda ignored: reactor.stop())

        needsRunningReactor(reactor, onListening)

        self.runReactor(reactor)

        # Drop the reference and get the garbage collector to tell us if there
        # are no references to the protocol instance left in the reactor.
        clientProtocol = None
        collect()
        self.assertIdentical(None, clientRef())
Пример #15
0
def runProtocolsWithReactor(
    reactorBuilder, serverProtocol, clientProtocol, endpointCreator
):
    """
    Connect two protocols using endpoints and a new reactor instance.

    A new reactor will be created and run, with the client and server protocol
    instances connected to each other using the given endpoint creator. The
    protocols should run through some set of tests, then disconnect; when both
    have disconnected the reactor will be stopped and the function will
    return.

    @param reactorBuilder: A L{ReactorBuilder} instance.

    @param serverProtocol: A L{ConnectableProtocol} that will be the server.

    @param clientProtocol: A L{ConnectableProtocol} that will be the client.

    @param endpointCreator: An instance of L{EndpointCreator}.

    @return: The reactor run by this test.
    """
    reactor = reactorBuilder.buildReactor()
    serverProtocol._setAttributes(reactor, Deferred())
    clientProtocol._setAttributes(reactor, Deferred())
    serverFactory = _SingleProtocolFactory(serverProtocol)
    clientFactory = _SingleProtocolFactory(clientProtocol)

    # Listen on a port:
    serverEndpoint = endpointCreator.server(reactor)
    d = serverEndpoint.listen(serverFactory)

    # Connect to the port:
    def gotPort(p):
        clientEndpoint = endpointCreator.client(reactor, p.getHost())
        return clientEndpoint.connect(clientFactory)

    d.addCallback(gotPort)

    # Stop reactor when both connections are lost:
    def failed(result):
        log.err(result, "Connection setup failed.")

    disconnected = gatherResults([serverProtocol._done, clientProtocol._done])
    d.addCallback(lambda _: disconnected)
    d.addErrback(failed)
    d.addCallback(lambda _: needsRunningReactor(reactor, reactor.stop))

    reactorBuilder.runReactor(reactor)
    return reactor
Пример #16
0
    def test_connectEvent(self):
        """
        This test checks that we correctly get notifications event for a
        client.  This ought to prevent a regression under Windows using the
        GTK2 reactor.  See #3925.
        """
        reactor = self.buildReactor()

        self.listen(reactor, ServerFactory.forProtocol(Protocol))
        connected = []

        class CheckConnection(Protocol):
            def connectionMade(self):
                connected.append(self)
                reactor.stop()

        clientFactory = Stop(reactor)
        clientFactory.protocol = CheckConnection

        needsRunningReactor(reactor, lambda: self.connect(reactor, clientFactory))

        reactor.run()

        self.assertTrue(connected)
Пример #17
0
def runProtocolsWithReactor(reactorBuilder, serverProtocol, clientProtocol,
                            endpointCreator):
    """
    Connect two protocols using endpoints and a new reactor instance.

    A new reactor will be created and run, with the client and server protocol
    instances connected to each other using the given endpoint creator. The
    protocols should run through some set of tests, then disconnect; when both
    have disconnected the reactor will be stopped and the function will
    return.

    @param reactorBuilder: A L{ReactorBuilder} instance.

    @param serverProtocol: A L{ConnectableProtocol} that will be the server.

    @param clientProtocol: A L{ConnectableProtocol} that will be the client.

    @param endpointCreator: An instance of L{EndpointCreator}.

    @return: The reactor run by this test.
    """
    reactor = reactorBuilder.buildReactor()
    serverProtocol._setAttributes(reactor, Deferred())
    clientProtocol._setAttributes(reactor, Deferred())
    serverFactory = _SingleProtocolFactory(serverProtocol)
    clientFactory = _SingleProtocolFactory(clientProtocol)

    # Listen on a port:
    serverEndpoint = endpointCreator.server(reactor)
    d = serverEndpoint.listen(serverFactory)

    # Connect to the port:
    def gotPort(p):
        clientEndpoint = endpointCreator.client(
            reactor, p.getHost())
        return clientEndpoint.connect(clientFactory)
    d.addCallback(gotPort)

    # Stop reactor when both connections are lost:
    def failed(result):
        log.err(result, "Connection setup failed.")
    disconnected = gatherResults([serverProtocol._done, clientProtocol._done])
    d.addCallback(lambda _: disconnected)
    d.addErrback(failed)
    d.addCallback(lambda _: needsRunningReactor(reactor, reactor.stop))

    reactorBuilder.runReactor(reactor)
    return reactor