def test_cancel(self): f = transit.InboundConnectionFactory("owner") f.protocol = MockConnection results = [] d = f.whenDone() d.addBoth(results.append) self.assertEqual(results, []) addr1 = address.HostnameAddress("example.com", 1234) addr2 = address.HostnameAddress("example.com", 5678) p1 = f.buildProtocol(addr1) p2 = f.buildProtocol(addr2) f.connectionWasMade(p1) f.connectionWasMade(p2) self.assertEqual(results, []) d.cancel() self.assertEqual(len(results), 1) f = results[0] self.assertIsInstance(f, failure.Failure) self.assertIsInstance(f.value, defer.CancelledError) self.assertEqual(p1._cancelled, True) self.assertEqual(p2._cancelled, True)
def test_timeout(self): clock = task.Clock() owner = MockOwner() factory = MockFactory() addr = address.HostnameAddress("example.com", 1234) c = transit.Connection(owner, None, None, "description") def _callLater(period, func): clock.callLater(period, func) c.callLater = _callLater self.assertEqual(c.state, "too-early") t = c.transport = FakeTransport(c, addr) c.factory = factory c.connectionMade() # the timer should now be running d = c.startNegotiation() results = [] d.addBoth(results.append) # while we're waiting for negotiation, the timer expires clock.advance(transit.TIMEOUT + 1.0) self.assertEqual(t._connected, False) self.assertEqual(len(results), 1) f = results[0] self.assertIsInstance(f, failure.Failure) self.assertIsInstance(f.value, transit.BadHandshake) self.assertEqual(str(f.value), "timeout")
def test_receiver_rejected_rudely(self): # we're on the receiving side, so we wait for the sender to decide owner = MockOwner() factory = MockFactory() addr = address.HostnameAddress("example.com", 1234) c = transit.Connection(owner, None, None, "description") self.assertEqual(c.state, "too-early") t = c.transport = FakeTransport(c, addr) c.factory = factory c.connectionMade() self.assertEqual(factory._connectionWasMade_called, True) self.assertEqual(factory._p, c) owner._state = "wait-for-decision" d = c.startNegotiation() self.assertEqual(c.state, "handshake") self.assertEqual(t.read_buf(), b"send_this") results = [] d.addBoth(results.append) self.assertEqual(results, []) c.dataReceived(b"expect_this") self.assertEqual(c.state, "wait-for-decision") self.assertEqual(results, []) t.loseConnection() self.assertEqual(t._connected, False) self.assertEqual(len(results), 1) f = results[0] self.assertIsInstance(f, failure.Failure) self.assertIsInstance(f.value, transit.BadHandshake) self.assertEqual(str(f.value), "connection lost")
def test_receiver_accepted(self): # we're on the receiving side, so we wait for the sender to decide owner = MockOwner() factory = MockFactory() addr = address.HostnameAddress("example.com", 1234) c = transit.Connection(owner, None, None, "description") self.assertEqual(c.state, "too-early") t = c.transport = FakeTransport(c, addr) c.factory = factory c.connectionMade() self.assertEqual(factory._connectionWasMade_called, True) self.assertEqual(factory._p, c) owner._state = "wait-for-decision" d = c.startNegotiation() self.assertEqual(c.state, "handshake") self.assertEqual(t.read_buf(), b"send_this") results = [] d.addBoth(results.append) self.assertEqual(results, []) c.dataReceived(b"expect_this") self.assertEqual(c.state, "wait-for-decision") self.assertEqual(results, []) c.dataReceived(b"go\n") self.assertEqual(c.state, "records") self.assertEqual(results, [c])
def test_relay_handshake_bad(self): relay_handshake = b"relay handshake" owner = MockOwner() factory = MockFactory() addr = address.HostnameAddress("example.com", 1234) c = transit.Connection(owner, relay_handshake, None, "description") self.assertEqual(c.state, "too-early") t = c.transport = FakeTransport(c, addr) c.factory = factory c.connectionMade() self.assertEqual(factory._connectionWasMade_called, True) self.assertEqual(factory._p, c) self.assertEqual(t.read_buf(), b"") # quiet until startNegotiation owner._state = "go" d = c.startNegotiation() self.assertEqual(t.read_buf(), relay_handshake) self.assertEqual(c.state, "relay") # waiting for OK from relay c.dataReceived(b"not ok\n") self.assertEqual(t._connected, False) self.assertEqual(c.state, "hung up") results = [] d.addBoth(results.append) self.assertEqual(len(results), 1) f = results[0] self.assertIsInstance(f, failure.Failure) self.assertIsInstance(f.value, transit.BadHandshake) self.assertEqual(str(f.value), "got %r want %r" % (b"not ok\n", b"ok\n"))
def test_relay_handshake(self): relay_handshake = b"relay handshake" owner = MockOwner() factory = MockFactory() addr = address.HostnameAddress("example.com", 1234) c = transit.Connection(owner, relay_handshake, None, "description") self.assertEqual(c.state, "too-early") t = c.transport = FakeTransport(c, addr) c.factory = factory c.connectionMade() self.assertEqual(factory._connectionWasMade_called, True) self.assertEqual(factory._p, c) self.assertEqual(t.read_buf(), b"") # quiet until startNegotiation owner._state = "go" d = c.startNegotiation() self.assertEqual(t.read_buf(), relay_handshake) self.assertEqual(c.state, "relay") # waiting for OK from relay c.dataReceived(b"ok\n") self.assertEqual(t.read_buf(), b"send_this") self.assertEqual(c.state, "handshake") results = [] d.addBoth(results.append) self.assertEqual(results, []) c.dataReceived(b"expect_this") self.assertEqual(c.state, "records") self.assertEqual(results, [c]) self.assertEqual(t.read_buf(), b"go\n")
def test_handshake_other_error(self): owner = MockOwner() factory = MockFactory() addr = address.HostnameAddress("example.com", 1234) c = transit.Connection(owner, None, None, "description") self.assertEqual(c.state, "too-early") t = c.transport = FakeTransport(c, addr) c.factory = factory c.connectionMade() self.assertEqual(factory._connectionWasMade_called, True) self.assertEqual(factory._p, c) d = c.startNegotiation() self.assertEqual(c.state, "handshake") self.assertEqual(t.read_buf(), b"send_this") results = [] d.addBoth(results.append) self.assertEqual(results, []) c.state = RandomError("boom") self.assertRaises(RandomError, c.dataReceived, b"surprise!") self.assertEqual(t._connected, False) self.assertEqual(c.state, "hung up") self.assertEqual(len(results), 1) f = results[0] self.assertIsInstance(f, failure.Failure) self.assertIsInstance(f.value, RandomError)
def test_sender_rejecting(self): relay_handshake = None owner = MockOwner() factory = MockFactory() addr = address.HostnameAddress("example.com", 1234) c = transit.Connection(owner, relay_handshake, None, "description") self.assertEqual(c.state, "too-early") t = c.transport = FakeTransport(c, addr) c.factory = factory c.connectionMade() self.assertEqual(factory._connectionWasMade_called, True) self.assertEqual(factory._p, c) owner._state = "nevermind" d = c.startNegotiation() self.assertEqual(c.state, "handshake") self.assertEqual(t.read_buf(), b"send_this") results = [] d.addBoth(results.append) self.assertEqual(results, []) c.dataReceived(b"expect_this") self.assertEqual(t.read_buf(), b"nevermind\n") self.assertEqual(t._connected, False) self.assertEqual(c.state, "hung up") self.assertEqual(len(results), 1) f = results[0] self.assertIsInstance(f, failure.Failure) self.assertIsInstance(f.value, transit.BadHandshake) self.assertEqual(str(f.value), "abandoned")
def test_log_other_errors(self): f = transit.InboundConnectionFactory("owner") f.protocol = MockConnection results = [] d = f.whenDone() d.addBoth(results.append) self.assertEqual(results, []) addr = address.HostnameAddress("example.com", 1234) p1 = f.buildProtocol(addr) # if the Connection protocol throws an unexpected error, that should # get logged to the Twisted logs (as an Unhandled Error in Deferred) # so we can diagnose the bug f.connectionWasMade(p1) our_error = RandomError("boom1") p1._d.errback(our_error) self.assertEqual(len(results), 0) log.msg("=== note: the next RandomError is expected ===") # Make sure the Deferred has gone out of scope, so the UnhandledError # happens quickly. We must manually break the gc cycle. del p1._d gc.collect() # make PyPy happy errors = self.flushLoggedErrors(RandomError) self.assertEqual(1, len(errors)) self.assertEqual(our_error, errors[0].value) log.msg("=== note: the preceding RandomError was expected ===")
def test_describe(self): f = transit.InboundConnectionFactory(None) addrH = address.HostnameAddress("example.com", 1234) self.assertEqual(f._describePeer(addrH), "<-example.com:1234") addr4 = address.IPv4Address("TCP", "1.2.3.4", 1234) self.assertEqual(f._describePeer(addr4), "<-1.2.3.4:1234") addr6 = address.IPv6Address("TCP", "::1", 1234) self.assertEqual(f._describePeer(addr6), "<-::1:1234") addrU = address.UNIXAddress("/dev/unlikely") self.assertEqual(f._describePeer(addrU), "<-UNIXAddress('/dev/unlikely')")
def test_first_success_wins(self): f = transit.InboundConnectionFactory("owner") f.protocol = MockConnection results = [] d = f.whenDone() d.addBoth(results.append) self.assertEqual(results, []) addr1 = address.HostnameAddress("example.com", 1234) addr2 = address.HostnameAddress("example.com", 5678) p1 = f.buildProtocol(addr1) p2 = f.buildProtocol(addr2) f.connectionWasMade(p1) f.connectionWasMade(p2) self.assertEqual(results, []) p1._d.callback(p1) self.assertEqual(results, [p1]) self.assertEqual(p1._cancelled, False) self.assertEqual(p2._cancelled, True)
def test_one_fail_one_success(self): f = transit.InboundConnectionFactory("owner") f.protocol = MockConnection results = [] d = f.whenDone() d.addBoth(results.append) self.assertEqual(results, []) addr1 = address.HostnameAddress("example.com", 1234) addr2 = address.HostnameAddress("example.com", 5678) p1 = f.buildProtocol(addr1) p2 = f.buildProtocol(addr2) f.connectionWasMade(p1) f.connectionWasMade(p2) self.assertEqual(results, []) p1._d.errback(transit.BadHandshake("nope")) self.assertEqual(results, []) p2._d.callback(p2) self.assertEqual(results, [p2])
def test_success(self): f = transit.OutboundConnectionFactory("owner", "relay_handshake", "description") f.protocol = MockConnection addr = address.HostnameAddress("example.com", 1234) p = f.buildProtocol(addr) self.assertIsInstance(p, MockConnection) self.assertEqual(p.owner, "owner") self.assertEqual(p.relay_handshake, "relay_handshake") self.assertEqual(p._start_negotiation_called, False) # meh .start # this is normally called from Connection.connectionMade f.connectionWasMade(p) # no-op for outbound self.assertEqual(p._start_negotiation_called, False)
def make_connection(self): owner = MockOwner() factory = MockFactory() addr = address.HostnameAddress("example.com", 1234) c = transit.Connection(owner, None, None, "description") t = c.transport = FakeTransport(c, addr) c.factory = factory c.connectionMade() owner._state = "go" d = c.startNegotiation() results = [] d.addBoth(results.append) c.dataReceived(b"expect_this") self.assertEqual(results, [c]) t.read_buf() # flush input buffer, prepare for encrypted records return t, c, owner
def test_cancel(self): owner = MockOwner() factory = MockFactory() addr = address.HostnameAddress("example.com", 1234) c = transit.Connection(owner, None, None, "description") self.assertEqual(c.state, "too-early") t = c.transport = FakeTransport(c, addr) c.factory = factory c.connectionMade() d = c.startNegotiation() results = [] d.addBoth(results.append) # while we're waiting for negotiation, we get cancelled d.cancel() self.assertEqual(t._connected, False) self.assertEqual(c.state, "hung up") self.assertEqual(len(results), 1) f = results[0] self.assertIsInstance(f, failure.Failure) self.assertIsInstance(f.value, defer.CancelledError)
def test_success(self): f = transit.InboundConnectionFactory("owner") f.protocol = MockConnection results = [] d = f.whenDone() d.addBoth(results.append) self.assertEqual(results, []) addr = address.HostnameAddress("example.com", 1234) p = f.buildProtocol(addr) self.assertIsInstance(p, MockConnection) self.assertEqual(p.owner, "owner") self.assertEqual(p.relay_handshake, None) self.assertEqual(p._start_negotiation_called, False) # meh .start # this is normally called from Connection.connectionMade f.connectionWasMade(p) self.assertEqual(p._start_negotiation_called, True) self.assertEqual(results, []) self.assertEqual(p._description, "<-example.com:1234") p._d.callback(p) self.assertEqual(results, [p])