def test_connectionLostOnlyAfterUnderlyingCloses(self): """ The user protocol's connectionLost is only called when transport underlying TLS is disconnected. """ class LostProtocol(Protocol): disconnected = None def connectionLost(self, reason): self.disconnected = reason wrapperFactory = TLSMemoryBIOFactory(ClientContextFactory(), True, ClientFactory()) protocol = LostProtocol() tlsProtocol = TLSMemoryBIOProtocol(wrapperFactory, protocol) transport = StringTransport() tlsProtocol.makeConnection(transport) # Pretend TLS shutdown finished cleanly; the underlying transport # should be told to close, but the user protocol should not yet be # notified: tlsProtocol._tlsShutdownFinished(None) self.assertEqual(transport.disconnecting, True) self.assertEqual(protocol.disconnected, None) # Now close the underlying connection; the user protocol should be # notified with the given reason (since TLS closed cleanly): tlsProtocol.connectionLost(Failure(ConnectionLost("ono"))) self.assertTrue(protocol.disconnected.check(ConnectionLost)) self.assertEqual(protocol.disconnected.value.args, ("ono",))