Skip to content

Commit

Permalink
WIP new test, failing
Browse files Browse the repository at this point in the history
  • Loading branch information
warner committed Sep 3, 2015
1 parent 2fa6aa9 commit 1375de3
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
7 changes: 7 additions & 0 deletions foolscap/connection.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

from twisted.python.failure import Failure
from twisted.internet import protocol, reactor, endpoints, error
from foolscap.eventual import eventually
from foolscap.tokens import (NoLocationHintsError, NegotiationError,
RemoteNegotiationError)
from foolscap.logging import log
Expand Down Expand Up @@ -141,8 +142,13 @@ def shutdown(self):
self.cancelRemainingConnections()

def cancelRemainingConnections(self):
import traceback
print "=== cancelRemainingConnections"
traceback.print_stack(limit=5)
for d in list(self.pendingConnections):
print " cancel", d
d.cancel()
print " did cancel", d
# this will trigger self._connectionFailed(), via the errback,
# with a ConnectingCancelledError
for n in self.pendingNegotiations.keys():
Expand All @@ -161,6 +167,7 @@ def connectToAll(self):
f = TubConnectorFactory(self, host, lp)
ep = BEST_TCP_ENDPOINT(reactor, host, port)
d = ep.connect(f)
print "- add", d
self.pendingConnections.add(d)
def _remove(res, d=d):
self.pendingConnections.remove(d)
Expand Down
1 change: 1 addition & 0 deletions foolscap/negotiate.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ def initClient(self, connector, targetHost):

def initServer(self, listener):
# servers do listenTCP and respond to the GET
#time.sleep(1)
self.log("initServer", listener=repr(listener))
self.isClient = False
self.listener = listener
Expand Down
34 changes: 34 additions & 0 deletions foolscap/test/test_negotiate.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,40 @@ def test5(self):
return d
test5.timeout = 10

class ThreeInParallel(BaseMixin, unittest.TestCase):
# Reentrancy bugs can appear when multiple connections are abandoned at
# the same time. Create three hints, of which one wins, to exercise two
# being abandoned together.

def makeServers(self, tubopts={}):
self.tub = tub = Tub(certData=certData_high, options=tubopts)
tub.startService()
self.services.append(tub)
port = tub.listenOn("tcp:0").getPortnum()
tub.setLocation("127.0.0.1:%d" % port,
"127.0.0.2:%d" % port,
"127.0.0.3:%d" % port)
self.target = Target()
return tub.registerReference(self.target)

def connect(self, url):
self.client = client = Tub(certData_low)
client.startService()
self.services.append(client)
d = client.getReference(url)
return d

def test1(self):
# in this test, we stop listening on the second port, so the second
# connection will terminate with an ECONNREFUSED before the first one
# completes. We also slow down the first port so we're sure to
# recognize the failed second connection before starting negotiation
# on the first.
url = self.makeServers()
d = self.connect(url)
d.addCallback(self.stall, 0.5)
return d
test1.timeout = 10

class CrossfireMixin(BaseMixin):
# testSimultaneous*: similar to Parallel, but connection[0] is initiated
Expand Down

0 comments on commit 1375de3

Please sign in to comment.