def tearDown(self): d3 = Deferred() self._serverProtocol.notifyOnDisconnect(lambda: d3.callback(None)) return DeferredList([ maybeDeferred(self.serverPort.stopListening), maybeDeferred(self.clientConn.disconnect), d3 ])
def test_disorderlyShutdown(self): """ If a L{TLSMemoryBIOProtocol} loses its connection unexpectedly, this is reported to the application. """ clientConnectionLost = Deferred() clientFactory = ClientFactory() clientFactory.protocol = ( lambda: ConnectionLostNotifyingProtocol(clientConnectionLost)) clientContextFactory = HandshakeCallbackContextFactory() wrapperFactory = TLSMemoryBIOFactory(clientContextFactory, True, clientFactory) sslClientProtocol = wrapperFactory.buildProtocol(None) # Client speaks first, so the server can be dumb. serverProtocol = Protocol() connectionDeferred = loopbackAsync(serverProtocol, sslClientProtocol) # Now destroy the connection. serverProtocol.transport.loseConnection() # And when the connection completely dies, check the reason. def cbDisconnected(clientProtocol): clientProtocol.lostConnectionReason.trap(Error) clientConnectionLost.addCallback(cbDisconnected) return clientConnectionLost
def test_disorderlyShutdown(self): """ If a L{TLSMemoryBIOProtocol} loses its connection unexpectedly, this is reported to the application. """ clientConnectionLost = Deferred() clientFactory = ClientFactory() clientFactory.protocol = lambda: ConnectionLostNotifyingProtocol(clientConnectionLost) clientContextFactory = HandshakeCallbackContextFactory() wrapperFactory = TLSMemoryBIOFactory(clientContextFactory, True, clientFactory) sslClientProtocol = wrapperFactory.buildProtocol(None) # Client speaks first, so the server can be dumb. serverProtocol = Protocol() connectionDeferred = loopbackAsync(serverProtocol, sslClientProtocol) # Now destroy the connection. serverProtocol.transport.loseConnection() # And when the connection completely dies, check the reason. def cbDisconnected(clientProtocol): clientProtocol.lostConnectionReason.trap(Error) clientConnectionLost.addCallback(cbDisconnected) return clientConnectionLost
def testFileResponse(self): d = Deferred() d.addCallback(self.fileResponse) self.client.cookies['iCookies'][1234] = (d, None) m = msn.MSNMessage() m.setHeader('Content-Type', 'text/x-msmsgsinvite; charset=UTF-8') m.message += 'Invitation-Command: ACCEPT\r\n' m.message += 'Invitation-Cookie: 1234\r\n\r\n' self.client.checkMessage(m) self.failUnless((self.client.state == 'RESPONSE'), msg='Failed to detect file transfer response')
def test_spawnProcessEarlyIsReaped(self): """ If, before the reactor is started with L{IReactorCore.run}, a process is started with L{IReactorProcess.spawnProcess} and terminates, the process is reaped once the reactor is started. """ reactor = self.buildReactor() # Create the process with no shared file descriptors, so that there # are no other events for the reactor to notice and "cheat" with. # We want to be sure it's really dealing with the process exiting, # not some associated event. if self.usePTY: childFDs = None else: childFDs = {} # Arrange to notice the SIGCHLD. signaled = threading.Event() def handler(*args): signaled.set() signal.signal(signal.SIGCHLD, handler) # Start a process - before starting the reactor! ended = Deferred() reactor.spawnProcess( _ShutdownCallbackProcessProtocol(ended), sys.executable, [sys.executable, "-c", ""], usePTY=self.usePTY, childFDs=childFDs) # Wait for the SIGCHLD (which might have been delivered before we got # here, but that's okay because the signal handler was installed above, # before we could have gotten it). signaled.wait(120) if not signaled.isSet(): self.fail("Timed out waiting for child process to exit.") # Capture the processEnded callback. result = [] ended.addCallback(result.append) if result: # The synchronous path through spawnProcess / Process.__init__ / # registerReapProcessHandler was encountered. There's no reason to # start the reactor, because everything is done already. return # Otherwise, though, start the reactor so it can tell us the process # exited. ended.addCallback(lambda ignored: reactor.stop()) self.runReactor(reactor) # Make sure the reactor stopped because the Deferred fired. self.assertTrue(result)
def testFileInfo(self): d = Deferred() d.addCallback(self.fileInfo) self.client.cookies['external'][1234] = (d, None) m = msn.MSNMessage() m.setHeader('Content-Type', 'text/x-msmsgsinvite; charset=UTF-8') m.message += 'Invitation-Command: ACCEPT\r\n' m.message += 'Invitation-Cookie: 1234\r\n' m.message += 'IP-Address: 192.168.0.1\r\n' m.message += 'Port: 6891\r\n' m.message += 'AuthCookie: 4321\r\n\r\n' self.client.checkMessage(m) self.failUnless((self.client.state == 'INFO'), msg='Failed to detect file transfer info')
def __init__(self, command, **kwargs): """ Create a command. @param command: the name of the command. @type command: C{str} @param kwargs: this values will be stored as attributes of the object for future use """ self.command = command self._deferred = Deferred() for k, v in kwargs.items(): setattr(self, k, v)
def test_stdin(self): """ Making sure getPassword accepts a password from standard input by running a child process which uses getPassword to read in a string which it then writes it out again. Write a string to the child process and then read one and make sure it is the right string. """ p = PasswordTestingProcessProtocol() p.finished = Deferred() reactor.spawnProcess( p, sys.executable, [ sys.executable, '-c', ('import sys\n' 'from reqs.twisted.python.util import getPassword\n' 'sys.stdout.write(getPassword())\n' 'sys.stdout.flush()\n') ], env={'PYTHONPATH': os.pathsep.join(sys.path)}) def processFinished((reason, output)): reason.trap(ProcessDone) self.assertIn((1, 'secret'), output) return p.finished.addCallback(processFinished)
class HandshakeCallbackContextFactory: """ L{HandshakeCallbackContextFactory} is a factory for SSL contexts which allows applications to get notification when the SSL handshake completes. @ivar _finished: A L{Deferred} which will be called back when the handshake is done. """ # pyOpenSSL needs to expose this. # https://bugs.launchpad.net/pyopenssl/+bug/372832 SSL_CB_HANDSHAKE_DONE = 0x20 def __init__(self): self._finished = Deferred() def factoryAndDeferred(cls): """ Create a new L{HandshakeCallbackContextFactory} and return a two-tuple of it and a L{Deferred} which will fire when a connection created with it completes a TLS handshake. """ contextFactory = cls() return contextFactory, contextFactory._finished factoryAndDeferred = classmethod(factoryAndDeferred) def _info(self, connection, where, ret): """ This is the "info callback" on the context. It will be called periodically by pyOpenSSL with information about the state of a connection. When it indicates the handshake is complete, it will fire C{self._finished}. """ if where & self.SSL_CB_HANDSHAKE_DONE: self._finished.callback(None) def getContext(self): """ Create and return an SSL context configured to use L{self._info} as the info callback. """ context = Context(TLSv1_METHOD) context.set_info_callback(self._info) return context
def test_returnValueNonLocalDeferred(self): """ L{returnValue} will emit a non-local warning in the case where the L{inlineCallbacks}-decorated function has already yielded a Deferred and therefore moved its generator function along. """ cause = Deferred() @inlineCallbacks def inline(): yield cause self.mistakenMethod() returnValue(2) effect = inline() results = [] effect.addCallback(results.append) self.assertEquals(results, []) cause.callback(1) self.assertMistakenMethodWarning(results)
def test_processExited(self): """ L{IProcessProtocol.processExited} is called when the child process exits, even if file descriptors associated with the child are still open. """ exited = Deferred() allLost = Deferred() lost = [] class Waiter(ProcessProtocol): def childDataReceived(self, fd, data): msg('childDataReceived(%d, %r)' % (fd, data)) def childConnectionLost(self, childFD): msg('childConnectionLost(%d)' % (childFD,)) lost.append(childFD) if len(lost) == 3: allLost.callback(None) def processExited(self, reason): msg('processExited(%r)' % (reason,)) # See test_processExitedWithSignal exited.callback([reason]) self.transport.loseConnection() reactor = self.buildReactor() reactor.callWhenRunning( reactor.spawnProcess, Waiter(), sys.executable, [sys.executable, self.keepStdioOpenProgram, "child", self.keepStdioOpenArg], usePTY=self.usePTY) def cbExited((failure,)): failure.trap(ProcessDone) msg('cbExited; lost = %s' % (lost,)) self.assertEqual(lost, []) return allLost exited.addCallback(cbExited) def cbAllLost(ignored): self.assertEqual(set(lost), set([0, 1, 2])) exited.addCallback(cbAllLost) exited.addErrback(err) exited.addCallback(lambda ign: reactor.stop()) self.runReactor(reactor)
def test_stopStartReading(self): """ This test checks transport read state! There are three bits of it: 1) The transport producer is paused -- transport.reading is False) 2) The transport is about to schedule an OS read, on the next reactor iteration -- transport._readScheduled 3) The OS has a pending asynchronous read on our behalf -- transport._readScheduledInOS if 3) is not implemented, it is possible to trick IOCPReactor into scheduling an OS read before the previous one finishes """ sf = ServerFactory() sf.protocol = StopStartReadingProtocol sf.ready_d = Deferred() sf.stop_d = Deferred() p = reactor.listenTCP(0, sf) port = p.getHost().port cc = ClientCreator(reactor, Protocol) def proceed(protos, port): log.msg('PROCEEDING WITH THE TESTATHRON') self.assert_(protos[0]) self.assert_(protos[1]) protos = protos[0][1], protos[1][1] protos[0].transport.write( 'x' * (2 * protos[0].transport.readBufferSize) + 'y' * (2 * protos[0].transport.readBufferSize)) return sf.stop_d.addCallback(cleanup, protos, port) def cleanup(data, protos, port): self.assert_(data == 'x'*(2*protos[0].transport.readBufferSize)+ 'y'*(2*protos[0].transport.readBufferSize), 'did not get the right data') return DeferredList([ maybeDeferred(protos[0].transport.loseConnection), maybeDeferred(protos[1].transport.loseConnection), maybeDeferred(port.stopListening)]) return (DeferredList([cc.connectTCP('127.0.0.1', port), sf.ready_d]) .addCallback(proceed, p))
class Command(object): """ Wrap a client action into an object, that holds the values used in the protocol. @ivar _deferred: the L{Deferred} object that will be fired when the result arrives. @type _deferred: L{Deferred} @ivar command: name of the command sent to the server. @type command: C{str} """ def __init__(self, command, **kwargs): """ Create a command. @param command: the name of the command. @type command: C{str} @param kwargs: this values will be stored as attributes of the object for future use """ self.command = command self._deferred = Deferred() for k, v in kwargs.items(): setattr(self, k, v) def success(self, value): """ Shortcut method to fire the underlying deferred. """ self._deferred.callback(value) def fail(self, error): """ Make the underlying deferred fails. """ self._deferred.errback(error)
def test_loseConnectionAfterHandshake(self): """ L{TLSMemoryBIOProtocol.loseConnection} sends a TLS close alert and shuts down the underlying connection. """ clientConnectionLost = Deferred() clientFactory = ClientFactory() clientFactory.protocol = ( lambda: ConnectionLostNotifyingProtocol(clientConnectionLost)) clientContextFactory, handshakeDeferred = ( HandshakeCallbackContextFactory.factoryAndDeferred()) wrapperFactory = TLSMemoryBIOFactory(clientContextFactory, True, clientFactory) sslClientProtocol = wrapperFactory.buildProtocol(None) serverProtocol = Protocol() serverFactory = ServerFactory() serverFactory.protocol = lambda: serverProtocol serverContextFactory = DefaultOpenSSLContextFactory(certPath, certPath) wrapperFactory = TLSMemoryBIOFactory(serverContextFactory, False, serverFactory) sslServerProtocol = wrapperFactory.buildProtocol(None) connectionDeferred = loopbackAsync(sslServerProtocol, sslClientProtocol) # Wait for the handshake before dropping the connection. def cbHandshake(ignored): serverProtocol.transport.loseConnection() # Now wait for the client to notice. return clientConnectionLost handshakeDeferred.addCallback(cbHandshake) # Wait for the connection to end, then make sure the client was # notified of a handshake failure. def cbConnectionDone(clientProtocol): clientProtocol.lostConnectionReason.trap(ConnectionDone) # The server should have closed its underlying transport, in # addition to whatever it did to shut down the TLS layer. self.assertTrue(serverProtocol.transport.q.disconnect) # The client should also have closed its underlying transport once # it saw the server shut down the TLS layer, so as to avoid relying # on the server to close the underlying connection. self.assertTrue(clientProtocol.transport.q.disconnect) handshakeDeferred.addCallback(cbConnectionDone) return handshakeDeferred
def test_handshakeFailure(self): """ L{TLSMemoryBIOProtocol} reports errors in the handshake process to the application-level protocol object using its C{connectionLost} method and disconnects the underlying transport. """ clientConnectionLost = Deferred() clientFactory = ClientFactory() clientFactory.protocol = ( lambda: ConnectionLostNotifyingProtocol(clientConnectionLost)) clientContextFactory = HandshakeCallbackContextFactory() wrapperFactory = TLSMemoryBIOFactory(clientContextFactory, True, clientFactory) sslClientProtocol = wrapperFactory.buildProtocol(None) serverConnectionLost = Deferred() serverFactory = ServerFactory() serverFactory.protocol = ( lambda: ConnectionLostNotifyingProtocol(serverConnectionLost)) # This context factory rejects any clients which do not present a # certificate. certificateData = FilePath(certPath).getContent() certificate = PrivateCertificate.loadPEM(certificateData) serverContextFactory = certificate.options(certificate) wrapperFactory = TLSMemoryBIOFactory(serverContextFactory, False, serverFactory) sslServerProtocol = wrapperFactory.buildProtocol(None) connectionDeferred = loopbackAsync(sslServerProtocol, sslClientProtocol) def cbConnectionLost(protocol): # The connection should close on its own in response to the error # induced by the client not supplying the required certificate. # After that, check to make sure the protocol's connectionLost was # called with the right thing. protocol.lostConnectionReason.trap(Error) clientConnectionLost.addCallback(cbConnectionLost) serverConnectionLost.addCallback(cbConnectionLost) # Additionally, the underlying transport should have been told to # go away. return gatherResults( [clientConnectionLost, serverConnectionLost, connectionDeferred])
def test_spawnProcessEarlyIsReaped(self): """ If, before the reactor is started with L{IReactorCore.run}, a process is started with L{IReactorProcess.spawnProcess} and terminates, the process is reaped once the reactor is started. """ reactor = self.buildReactor() # Create the process with no shared file descriptors, so that there # are no other events for the reactor to notice and "cheat" with. # We want to be sure it's really dealing with the process exiting, # not some associated event. if self.usePTY: childFDs = None else: childFDs = {} # Arrange to notice the SIGCHLD. signaled = threading.Event() def handler(*args): signaled.set() signal.signal(signal.SIGCHLD, handler) # Start a process - before starting the reactor! ended = Deferred() reactor.spawnProcess(_ShutdownCallbackProcessProtocol(ended), sys.executable, [sys.executable, "-c", ""], usePTY=self.usePTY, childFDs=childFDs) # Wait for the SIGCHLD (which might have been delivered before we got # here, but that's okay because the signal handler was installed above, # before we could have gotten it). signaled.wait(120) if not signaled.isSet(): self.fail("Timed out waiting for child process to exit.") # Capture the processEnded callback. result = [] ended.addCallback(result.append) if result: # The synchronous path through spawnProcess / Process.__init__ / # registerReapProcessHandler was encountered. There's no reason to # start the reactor, because everything is done already. return # Otherwise, though, start the reactor so it can tell us the process # exited. ended.addCallback(lambda ignored: reactor.stop()) self.runReactor(reactor) # Make sure the reactor stopped because the Deferred fired. self.assertTrue(result)
def test_processEnded(self): """ L{IProcessProtocol.processEnded} is called after the child process exits and L{IProcessProtocol.childConnectionLost} is called for each of its file descriptors. """ ended = Deferred() lost = [] class Ender(ProcessProtocol): def childDataReceived(self, fd, data): msg('childDataReceived(%d, %r)' % (fd, data)) self.transport.loseConnection() def childConnectionLost(self, childFD): msg('childConnectionLost(%d)' % (childFD, )) lost.append(childFD) def processExited(self, reason): msg('processExited(%r)' % (reason, )) def processEnded(self, reason): msg('processEnded(%r)' % (reason, )) ended.callback([reason]) reactor = self.buildReactor() reactor.callWhenRunning(reactor.spawnProcess, Ender(), sys.executable, [ sys.executable, self.keepStdioOpenProgram, "child", self.keepStdioOpenArg ], usePTY=self.usePTY) def cbEnded((failure, )): failure.trap(ProcessDone) self.assertEqual(set(lost), set([0, 1, 2])) ended.addCallback(cbEnded) ended.addErrback(err) ended.addCallback(lambda ign: reactor.stop()) self.runReactor(reactor)
def test_processEnded(self): """ L{IProcessProtocol.processEnded} is called after the child process exits and L{IProcessProtocol.childConnectionLost} is called for each of its file descriptors. """ ended = Deferred() lost = [] class Ender(ProcessProtocol): def childDataReceived(self, fd, data): msg('childDataReceived(%d, %r)' % (fd, data)) self.transport.loseConnection() def childConnectionLost(self, childFD): msg('childConnectionLost(%d)' % (childFD,)) lost.append(childFD) def processExited(self, reason): msg('processExited(%r)' % (reason,)) def processEnded(self, reason): msg('processEnded(%r)' % (reason,)) ended.callback([reason]) reactor = self.buildReactor() reactor.callWhenRunning( reactor.spawnProcess, Ender(), sys.executable, [sys.executable, self.keepStdioOpenProgram, "child", self.keepStdioOpenArg], usePTY=self.usePTY) def cbEnded((failure,)): failure.trap(ProcessDone) self.assertEqual(set(lost), set([0, 1, 2])) ended.addCallback(cbEnded) ended.addErrback(err) ended.addCallback(lambda ign: reactor.stop()) self.runReactor(reactor)
def test_handshakeFailure(self): """ L{TLSMemoryBIOProtocol} reports errors in the handshake process to the application-level protocol object using its C{connectionLost} method and disconnects the underlying transport. """ clientConnectionLost = Deferred() clientFactory = ClientFactory() clientFactory.protocol = lambda: ConnectionLostNotifyingProtocol(clientConnectionLost) clientContextFactory = HandshakeCallbackContextFactory() wrapperFactory = TLSMemoryBIOFactory(clientContextFactory, True, clientFactory) sslClientProtocol = wrapperFactory.buildProtocol(None) serverConnectionLost = Deferred() serverFactory = ServerFactory() serverFactory.protocol = lambda: ConnectionLostNotifyingProtocol(serverConnectionLost) # This context factory rejects any clients which do not present a # certificate. certificateData = FilePath(certPath).getContent() certificate = PrivateCertificate.loadPEM(certificateData) serverContextFactory = certificate.options(certificate) wrapperFactory = TLSMemoryBIOFactory(serverContextFactory, False, serverFactory) sslServerProtocol = wrapperFactory.buildProtocol(None) connectionDeferred = loopbackAsync(sslServerProtocol, sslClientProtocol) def cbConnectionLost(protocol): # The connection should close on its own in response to the error # induced by the client not supplying the required certificate. # After that, check to make sure the protocol's connectionLost was # called with the right thing. protocol.lostConnectionReason.trap(Error) clientConnectionLost.addCallback(cbConnectionLost) serverConnectionLost.addCallback(cbConnectionLost) # Additionally, the underlying transport should have been told to # go away. return gatherResults([clientConnectionLost, serverConnectionLost, connectionDeferred])
def __init__(self): Deferred.__init__(self) NotKnown.__init__(self) self.pause()
def setUp(self): self.result = [] self.deferred = Deferred() self.deferred.addCallback(lambda r: self.result.append(r)) self.deferred.addErrback(printError)
def trigger(): events.append('trigger') d = Deferred() d.addCallback(callback) reactor.callLater(0, d.callback, None) return d
def __init__(self): self._finished = Deferred()
def test_processExited(self): """ L{IProcessProtocol.processExited} is called when the child process exits, even if file descriptors associated with the child are still open. """ exited = Deferred() allLost = Deferred() lost = [] class Waiter(ProcessProtocol): def childDataReceived(self, fd, data): msg('childDataReceived(%d, %r)' % (fd, data)) def childConnectionLost(self, childFD): msg('childConnectionLost(%d)' % (childFD, )) lost.append(childFD) if len(lost) == 3: allLost.callback(None) def processExited(self, reason): msg('processExited(%r)' % (reason, )) # See test_processExitedWithSignal exited.callback([reason]) self.transport.loseConnection() reactor = self.buildReactor() reactor.callWhenRunning(reactor.spawnProcess, Waiter(), sys.executable, [ sys.executable, self.keepStdioOpenProgram, "child", self.keepStdioOpenArg ], usePTY=self.usePTY) def cbExited((failure, )): failure.trap(ProcessDone) msg('cbExited; lost = %s' % (lost, )) self.assertEqual(lost, []) return allLost exited.addCallback(cbExited) def cbAllLost(ignored): self.assertEqual(set(lost), set([0, 1, 2])) exited.addCallback(cbAllLost) exited.addErrback(err) exited.addCallback(lambda ign: reactor.stop()) self.runReactor(reactor)
def test_disconnectAfterWriteAfterStartTLS(self): """ L{ITCPTransport.loseConnection} ends a connection which was set up with L{ITLSTransport.startTLS} and which has recently been written to. This is intended to verify that a socket send error masked by the TLS implementation doesn't prevent the connection from being reported as closed. """ class ShortProtocol(Protocol): def connectionMade(self): if not ITLSTransport.providedBy(self.transport): # Functionality isn't available to be tested. finished = self.factory.finished self.factory.finished = None finished.errback(SkipTest("No ITLSTransport support")) return # Switch the transport to TLS. self.transport.startTLS(self.factory.context) # Force TLS to really get negotiated. If nobody talks, nothing # will happen. self.transport.write("x") def dataReceived(self, data): # Stuff some bytes into the socket. This mostly has the effect # of causing the next write to fail with ENOTCONN or EPIPE. # With the pyOpenSSL implementation of ITLSTransport, the error # is swallowed outside of the control of Twisted. self.transport.write("y") # Now close the connection, which requires a TLS close alert to # be sent. self.transport.loseConnection() def connectionLost(self, reason): # This is the success case. The client and the server want to # get here. finished = self.factory.finished if finished is not None: self.factory.finished = None finished.callback(reason) serverFactory = ServerFactory() serverFactory.finished = Deferred() serverFactory.protocol = ShortProtocol serverFactory.context = self.getServerContext() clientFactory = ClientFactory() clientFactory.finished = Deferred() clientFactory.protocol = ShortProtocol clientFactory.context = ClientContextFactory() clientFactory.context.method = serverFactory.context.method lostConnectionResults = [] finished = DeferredList( [serverFactory.finished, clientFactory.finished], consumeErrors=True) def cbFinished(results): lostConnectionResults.extend([results[0][1], results[1][1]]) finished.addCallback(cbFinished) reactor = self.buildReactor() port = reactor.listenTCP(0, serverFactory, interface='127.0.0.1') self.addCleanup(port.stopListening) connector = reactor.connectTCP( port.getHost().host, port.getHost().port, clientFactory) self.addCleanup(connector.disconnect) finished.addCallback(lambda ign: reactor.stop()) self.runReactor(reactor) lostConnectionResults[0].trap(ConnectionClosed) lostConnectionResults[1].trap(ConnectionClosed)
def test_childConnectionLost(self): """ L{IProcessProtocol.childConnectionLost} is called each time a file descriptor associated with a child process is closed. """ connected = Deferred() lost = {0: Deferred(), 1: Deferred(), 2: Deferred()} class Closer(ProcessProtocol): def makeConnection(self, transport): connected.callback(transport) def childConnectionLost(self, childFD): lost[childFD].callback(None) source = ( "import os, sys\n" "while 1:\n" " line = sys.stdin.readline().strip()\n" " if not line:\n" " break\n" " os.close(int(line))\n") reactor = self.buildReactor() reactor.callWhenRunning( reactor.spawnProcess, Closer(), sys.executable, [sys.executable, "-c", source], usePTY=self.usePTY) def cbConnected(transport): transport.write('2\n') return lost[2].addCallback(lambda ign: transport) connected.addCallback(cbConnected) def lostSecond(transport): transport.write('1\n') return lost[1].addCallback(lambda ign: transport) connected.addCallback(lostSecond) def lostFirst(transport): transport.write('\n') connected.addCallback(lostFirst) connected.addErrback(err) def cbEnded(ignored): reactor.stop() connected.addCallback(cbEnded) self.runReactor(reactor)
def __init__(self): PosixReactorBase.__init__(self) self.iterationTimeout = Deferred() self.now = 100
def login(self, credentials, mind, *interfaces): d = Deferred() self.logins.append((credentials, mind, interfaces, d)) return d
def test_processExitedWithSignal(self): """ The C{reason} argument passed to L{IProcessProtocol.processExited} is a L{ProcessTerminated} instance if the child process exits with a signal. """ sigName = 'TERM' sigNum = getattr(signal, 'SIG' + sigName) exited = Deferred() source = ( "import sys\n" # Talk so the parent process knows the process is running. This is # necessary because ProcessProtocol.makeConnection may be called # before this process is exec'd. It would be unfortunate if we # SIGTERM'd the Twisted process while it was on its way to doing # the exec. "sys.stdout.write('x')\n" "sys.stdout.flush()\n" "sys.stdin.read()\n") class Exiter(ProcessProtocol): def childDataReceived(self, fd, data): msg('childDataReceived(%d, %r)' % (fd, data)) self.transport.signalProcess(sigName) def childConnectionLost(self, fd): msg('childConnectionLost(%d)' % (fd,)) def processExited(self, reason): msg('processExited(%r)' % (reason,)) # Protect the Deferred from the failure so that it follows # the callback chain. This doesn't use the errback chain # because it wants to make sure reason is a Failure. An # Exception would also make an errback-based test pass, and # that would be wrong. exited.callback([reason]) def processEnded(self, reason): msg('processEnded(%r)' % (reason,)) reactor = self.buildReactor() reactor.callWhenRunning( reactor.spawnProcess, Exiter(), sys.executable, [sys.executable, "-c", source], usePTY=self.usePTY) def cbExited((failure,)): # Trapping implicitly verifies that it's a Failure (rather than # an exception) and explicitly makes sure it's the right type. failure.trap(ProcessTerminated) err = failure.value if platform.isWindows(): # Windows can't really /have/ signals, so it certainly can't # report them as the reason for termination. Maybe there's # something better we could be doing here, anyway? Hard to # say. Anyway, this inconsistency between different platforms # is extremely unfortunate and I would remove it if I # could. -exarkun self.assertIdentical(err.signal, None) self.assertEqual(err.exitCode, 1) else: self.assertEqual(err.signal, sigNum) self.assertIdentical(err.exitCode, None) exited.addCallback(cbExited) exited.addErrback(err) exited.addCallback(lambda ign: reactor.stop()) self.runReactor(reactor)
class PassportTests(unittest.TestCase): def setUp(self): self.result = [] self.deferred = Deferred() self.deferred.addCallback(lambda r: self.result.append(r)) self.deferred.addErrback(printError) def test_nexus(self): """ When L{msn.PassportNexus} receives enough information to identify the address of the login server, it fires the L{Deferred} passed to its initializer with that address. """ protocol = msn.PassportNexus(self.deferred, 'https://foobar.com/somepage.quux') headers = { 'Content-Length': '0', 'Content-Type': 'text/html', 'PassportURLs': 'DARealm=Passport.Net,DALogin=login.myserver.com/,DAReg=reg.myserver.com' } transport = StringTransport() protocol.makeConnection(transport) protocol.dataReceived('HTTP/1.0 200 OK\r\n') for (h, v) in headers.items(): protocol.dataReceived('%s: %s\r\n' % (h, v)) protocol.dataReceived('\r\n') self.assertEquals(self.result[0], "https://login.myserver.com/") def _doLoginTest(self, response, headers): protocol = msn.PassportLogin(self.deferred, '*****@*****.**', 'testpass', 'https://foo.com/', 'a') protocol.makeConnection(StringTransport()) protocol.dataReceived(response) for (h, v) in headers.items(): protocol.dataReceived('%s: %s\r\n' % (h, v)) protocol.dataReceived('\r\n') def testPassportLoginSuccess(self): headers = { 'Content-Length': '0', 'Content-Type': 'text/html', 'Authentication-Info': "Passport1.4 da-status=success,tname=MSPAuth," + "tname=MSPProf,tname=MSPSec,from-PP='somekey'," + "ru=http://messenger.msn.com" } self._doLoginTest('HTTP/1.1 200 OK\r\n', headers) self.failUnless(self.result[0] == (msn.LOGIN_SUCCESS, 'somekey')) def testPassportLoginFailure(self): headers = { 'Content-Type': 'text/html', 'WWW-Authenticate': 'Passport1.4 da-status=failed,' + 'srealm=Passport.NET,ts=-3,prompt,cburl=http://host.com,' + 'cbtxt=the%20error%20message' } self._doLoginTest('HTTP/1.1 401 Unauthorized\r\n', headers) self.failUnless(self.result[0] == (msn.LOGIN_FAILURE, 'the error message')) def testPassportLoginRedirect(self): headers = { 'Content-Type': 'text/html', 'Authentication-Info': 'Passport1.4 da-status=redir', 'Location': 'https://newlogin.host.com/' } self._doLoginTest('HTTP/1.1 302 Found\r\n', headers) self.failUnless(self.result[0] == (msn.LOGIN_REDIRECT, 'https://newlogin.host.com/', 'a'))
def test_processExitedWithSignal(self): """ The C{reason} argument passed to L{IProcessProtocol.processExited} is a L{ProcessTerminated} instance if the child process exits with a signal. """ sigName = 'TERM' sigNum = getattr(signal, 'SIG' + sigName) exited = Deferred() source = ( "import sys\n" # Talk so the parent process knows the process is running. This is # necessary because ProcessProtocol.makeConnection may be called # before this process is exec'd. It would be unfortunate if we # SIGTERM'd the Twisted process while it was on its way to doing # the exec. "sys.stdout.write('x')\n" "sys.stdout.flush()\n" "sys.stdin.read()\n") class Exiter(ProcessProtocol): def childDataReceived(self, fd, data): msg('childDataReceived(%d, %r)' % (fd, data)) self.transport.signalProcess(sigName) def childConnectionLost(self, fd): msg('childConnectionLost(%d)' % (fd, )) def processExited(self, reason): msg('processExited(%r)' % (reason, )) # Protect the Deferred from the failure so that it follows # the callback chain. This doesn't use the errback chain # because it wants to make sure reason is a Failure. An # Exception would also make an errback-based test pass, and # that would be wrong. exited.callback([reason]) def processEnded(self, reason): msg('processEnded(%r)' % (reason, )) reactor = self.buildReactor() reactor.callWhenRunning(reactor.spawnProcess, Exiter(), sys.executable, [sys.executable, "-c", source], usePTY=self.usePTY) def cbExited((failure, )): # Trapping implicitly verifies that it's a Failure (rather than # an exception) and explicitly makes sure it's the right type. failure.trap(ProcessTerminated) err = failure.value if platform.isWindows(): # Windows can't really /have/ signals, so it certainly can't # report them as the reason for termination. Maybe there's # something better we could be doing here, anyway? Hard to # say. Anyway, this inconsistency between different platforms # is extremely unfortunate and I would remove it if I # could. -exarkun self.assertIdentical(err.signal, None) self.assertEqual(err.exitCode, 1) else: self.assertEqual(err.signal, sigNum) self.assertIdentical(err.exitCode, None) exited.addCallback(cbExited) exited.addErrback(err) exited.addCallback(lambda ign: reactor.stop()) self.runReactor(reactor)
def test_childConnectionLost(self): """ L{IProcessProtocol.childConnectionLost} is called each time a file descriptor associated with a child process is closed. """ connected = Deferred() lost = {0: Deferred(), 1: Deferred(), 2: Deferred()} class Closer(ProcessProtocol): def makeConnection(self, transport): connected.callback(transport) def childConnectionLost(self, childFD): lost[childFD].callback(None) source = ("import os, sys\n" "while 1:\n" " line = sys.stdin.readline().strip()\n" " if not line:\n" " break\n" " os.close(int(line))\n") reactor = self.buildReactor() reactor.callWhenRunning(reactor.spawnProcess, Closer(), sys.executable, [sys.executable, "-c", source], usePTY=self.usePTY) def cbConnected(transport): transport.write('2\n') return lost[2].addCallback(lambda ign: transport) connected.addCallback(cbConnected) def lostSecond(transport): transport.write('1\n') return lost[1].addCallback(lambda ign: transport) connected.addCallback(lostSecond) def lostFirst(transport): transport.write('\n') connected.addCallback(lostFirst) connected.addErrback(err) def cbEnded(ignored): reactor.stop() connected.addCallback(cbEnded) self.runReactor(reactor)
def tearDown(self): d3 = Deferred() self._serverProtocol.notifyOnDisconnect(lambda: d3.callback(None)) return DeferredList([ maybeDeferred(self.serverPort.stopListening), maybeDeferred(self.clientConn.disconnect), d3])
class PassportTests(unittest.TestCase): def setUp(self): self.result = [] self.deferred = Deferred() self.deferred.addCallback(lambda r: self.result.append(r)) self.deferred.addErrback(printError) def test_nexus(self): """ When L{msn.PassportNexus} receives enough information to identify the address of the login server, it fires the L{Deferred} passed to its initializer with that address. """ protocol = msn.PassportNexus(self.deferred, 'https://foobar.com/somepage.quux') headers = { 'Content-Length' : '0', 'Content-Type' : 'text/html', 'PassportURLs' : 'DARealm=Passport.Net,DALogin=login.myserver.com/,DAReg=reg.myserver.com' } transport = StringTransport() protocol.makeConnection(transport) protocol.dataReceived('HTTP/1.0 200 OK\r\n') for (h, v) in headers.items(): protocol.dataReceived('%s: %s\r\n' % (h,v)) protocol.dataReceived('\r\n') self.assertEquals(self.result[0], "https://login.myserver.com/") def _doLoginTest(self, response, headers): protocol = msn.PassportLogin(self.deferred,'*****@*****.**','testpass','https://foo.com/', 'a') protocol.makeConnection(StringTransport()) protocol.dataReceived(response) for (h,v) in headers.items(): protocol.dataReceived('%s: %s\r\n' % (h,v)) protocol.dataReceived('\r\n') def testPassportLoginSuccess(self): headers = { 'Content-Length' : '0', 'Content-Type' : 'text/html', 'Authentication-Info' : "Passport1.4 da-status=success,tname=MSPAuth," + "tname=MSPProf,tname=MSPSec,from-PP='somekey'," + "ru=http://messenger.msn.com" } self._doLoginTest('HTTP/1.1 200 OK\r\n', headers) self.failUnless(self.result[0] == (msn.LOGIN_SUCCESS, 'somekey')) def testPassportLoginFailure(self): headers = { 'Content-Type' : 'text/html', 'WWW-Authenticate' : 'Passport1.4 da-status=failed,' + 'srealm=Passport.NET,ts=-3,prompt,cburl=http://host.com,' + 'cbtxt=the%20error%20message' } self._doLoginTest('HTTP/1.1 401 Unauthorized\r\n', headers) self.failUnless(self.result[0] == (msn.LOGIN_FAILURE, 'the error message')) def testPassportLoginRedirect(self): headers = { 'Content-Type' : 'text/html', 'Authentication-Info' : 'Passport1.4 da-status=redir', 'Location' : 'https://newlogin.host.com/' } self._doLoginTest('HTTP/1.1 302 Found\r\n', headers) self.failUnless(self.result[0] == (msn.LOGIN_REDIRECT, 'https://newlogin.host.com/', 'a'))