def testGetPort2(self): s1, s2, s3 = self.services s1.listenOn("tcp:%d:interface=127.0.0.1" % allocate_tcp_port()) listeners = s1.getListeners() self.failUnlessEqual(len(listeners), 1) # listen on a second port too s1.listenOn("tcp:%d:interface=127.0.0.1" % allocate_tcp_port()) l2 = s1.getListeners() self.failUnlessEqual(len(l2), 2)
def testGetPort2(self): s1,s2,s3 = self.services s1.listenOn("tcp:%d:interface=127.0.0.1" % allocate_tcp_port()) listeners = s1.getListeners() self.failUnlessEqual(len(listeners), 1) # listen on a second port too s1.listenOn("tcp:%d:interface=127.0.0.1" % allocate_tcp_port()) l2 = s1.getListeners() self.failUnlessEqual(len(l2), 2)
def makeServers(self, tubopts={}, lo1={}, lo2={}): self.tub = tub = Tub(certData=certData_high, _test_options=tubopts) tub.startService() self.services.append(tub) self.p1, self.p2 = allocate_tcp_port(), allocate_tcp_port() tub.listenOn("tcp:%d:interface=127.0.0.1" % self.p1, lo1) tub.listenOn("tcp:%d:interface=127.0.0.1" % self.p2, lo2) tub.setLocation("127.0.0.1:%d" % self.p1, "127.0.0.1:%d" % self.p2) self.target = Target() return tub.registerReference(self.target)
def test_referenceable(self): t1 = Tub() t1.setServiceParent(self.s) portnum = allocate_tcp_port() t1.listenOn("tcp:%d:interface=127.0.0.1" % portnum) t1.setLocation("127.0.0.1:%d" % portnum) r1 = Referenceable() # the serialized blob can't keep the reference alive, so you must # arrange for that separately t1.registerReference(r1) t2 = Tub() t2.setServiceParent(self.s) obj = ("graph tangly", r1) d = t1.serialize(obj) del r1; del obj def _done(data): self.failUnless("their-reference" in data) return data d.addCallback(_done) d.addCallback(lambda data: t2.unserialize(data)) def _check(obj2): self.failUnlessEqual(obj2[0], "graph tangly") self.failUnless(isinstance(obj2[1], RemoteReference)) d.addCallback(_check) return d
def test_unreachable_client(self): # A "client-only" Tub has no location set. It should still be # possible to connect to objects in other (location-bearing) server # Tubs, and objects in the client Tub can still be sent to (and used # by) the server Tub. client_tub = Tub() client_tub.setServiceParent(self.s) server_tub = Tub() server_tub.setServiceParent(self.s) portnum = allocate_tcp_port() server_tub.listenOn("tcp:%d:interface=127.0.0.1" % portnum) server_tub.setLocation("tcp:127.0.0.1:%d" % portnum) s = Receiver() # no FURL, not directly reachable r = Receiver() furl = server_tub.registerReference(r) d = client_tub.getReference(furl) d.addCallback(lambda rref: rref.callRemote("call", s)) d.addCallback(lambda res: self.failUnlessEqual(res, 1)) d.addCallback(lambda _: self.failIfEqual(r.obj, None)) def _inspect_obj(_): self.failUnlessEqual(r.obj.getSturdyRef().getURL(), None) d.addCallback(_inspect_obj) d.addCallback(lambda _: r.obj.callRemote("call", 2)) d.addCallback(lambda _: self.failUnlessEqual(s.obj, 2)) return d
def testListenOn(self): s1 = self.services[0] l = s1.listenOn("tcp:%d:interface=127.0.0.1" % allocate_tcp_port()) self.failUnless(isinstance(l, pb.Listener)) self.failUnlessEqual(len(s1.getListeners()), 1) s1.stopListeningOn(l) self.failUnlessEqual(len(s1.getListeners()), 0)
def test_string(self): tubA, tubB = self.makeTubs() portnum = util.allocate_tcp_port() tubA.listenOn("tcp:%d:interface=127.0.0.1" % portnum) tubA.setLocation("tcp:127.0.0.1:%d" % portnum) furl = tubA.registerReference(Target()) yield tubB.getReference(furl)
def test_furlfile(self): cfn = "test_tub.FurlFile.test_furlfile.certfile" t1 = Tub(certFile=cfn) t1.setServiceParent(self.s) portnum = allocate_tcp_port() port1 = "tcp:%d:interface=127.0.0.1" % portnum t1.listenOn(port1) t1.setLocation("127.0.0.1:%d" % portnum) r1 = Referenceable() ffn = "test_tub.FurlFile.test_furlfile.furlfile" furl1 = t1.registerReference(r1, furlFile=ffn) d = defer.maybeDeferred(t1.disownServiceParent) self.failUnless(os.path.exists(ffn)) self.failUnlessEqual(furl1, open(ffn,"r").read().strip()) def _take2(res): t2 = Tub(certFile=cfn) t2.setServiceParent(self.s) t2.listenOn(port1) t2.setLocation("127.0.0.1:%d" % portnum) r2 = Referenceable() furl2 = t2.registerReference(r2, furlFile=ffn) self.failUnlessEqual(furl1, furl2) return t2.disownServiceParent() d.addCallback(_take2) return d
def test_tubid_check(self): t1 = Tub() # gets a new key t1.setServiceParent(self.s) portnum = allocate_tcp_port() port1 = "tcp:%d:interface=127.0.0.1" % portnum t1.listenOn(port1) t1.setLocation("127.0.0.1:%d" % portnum) r1 = Referenceable() ffn = "test_tub.FurlFile.test_tubid_check.furlfile" furl1 = t1.registerReference(r1, furlFile=ffn) d = defer.maybeDeferred(t1.disownServiceParent) self.failUnless(os.path.exists(ffn)) self.failUnlessEqual(furl1, open(ffn,"r").read().strip()) def _take2(res): t2 = Tub() # gets a different key t2.setServiceParent(self.s) t2.listenOn(port1) t2.setLocation("127.0.0.1:%d" % portnum) r2 = Referenceable() self.failUnlessRaises(WrongTubIdError, t2.registerReference, r2, furlFile=ffn) return t2.disownServiceParent() d.addCallback(_take2) return d
def test_nonqualified_port(self): tubA, tubB = self.makeTubs() portnum = util.allocate_tcp_port() tubA.listenOn("%d" % portnum) # this is deprecated tubA.setLocation("tcp:127.0.0.1:%d" % portnum) furl = tubA.registerReference(Target()) yield tubB.getReference(furl)
def test_unreachable_client(self): # A "client-only" Tub has no location set. It should still be # possible to connect to objects in other (location-bearing) server # Tubs, and objects in the client Tub can still be sent to (and used # by) the server Tub. client_tub = Tub() client_tub.setServiceParent(self.s) server_tub = Tub() server_tub.setServiceParent(self.s) portnum = allocate_tcp_port() server_tub.listenOn("tcp:%d:interface=127.0.0.1" % portnum) server_tub.setLocation("tcp:127.0.0.1:%d" % portnum) s = Receiver() # no FURL, not directly reachable r = Receiver() furl = server_tub.registerReference(r) d = client_tub.getReference(furl) d.addCallback(lambda rref: rref.callRemote("call", s)) d.addCallback(lambda res: self.assertEqual(res, 1)) d.addCallback(lambda _: self.assertNotEqual(r.obj, None)) def _inspect_obj(_): self.assertEqual(r.obj.getSturdyRef().getURL(), None) d.addCallback(_inspect_obj) d.addCallback(lambda _: r.obj.callRemote("call", 2)) d.addCallback(lambda _: self.assertEqual(s.obj, 2)) return d
def test_bad_hints(self): self.tubA = Tub() self.tubA.startService() self.services.append(self.tubA) self.tubB = Tub() self.tubB.startService() self.services.append(self.tubB) portnum = allocate_tcp_port() self.tubB.listenOn("tcp:%d:interface=127.0.0.1" % portnum) bad1 = "no-colon" bad2 = "unknown:foo" bad3 = "tcp:300.300.300.300:333" self.tubB.setLocation(bad1, bad2, bad3) target = HelperTarget("bob") url = self.tubB.registerReference(target) rc = self.tubA.connectTo(url, None) ri = rc.getReconnectionInfo() self.assertEqual(ri.state, "connecting") yield self.poll(lambda: rc.getReconnectionInfo().state != "connecting") # now look at the details ri = rc.getReconnectionInfo() self.assertEqual(ri.state, "waiting") ci = ri.connectionInfo self.assertEqual(ci.connected, False) self.assertEqual(ci.winningHint, None) s = ci.connectorStatuses self.assertEqual(set(s.keys()), set([bad1, bad2, bad3])) self.assertEqual(s[bad1], "bad hint: no colon") self.assertEqual(s[bad2], "bad hint: no handler registered") self.assertIn("DNS lookup failed", s[bad3]) ch = ci.connectionHandlers self.assertEqual(ch, {bad2: None, bad3: "tcp"})
def test_furlfile(self): cfn = "test_tub.FurlFile.test_furlfile.certfile" t1 = Tub(certFile=cfn) t1.setServiceParent(self.s) portnum = allocate_tcp_port() port1 = "tcp:%d:interface=127.0.0.1" % portnum t1.listenOn(port1) t1.setLocation("127.0.0.1:%d" % portnum) r1 = Referenceable() ffn = "test_tub.FurlFile.test_furlfile.furlfile" furl1 = t1.registerReference(r1, furlFile=ffn) d = defer.maybeDeferred(t1.disownServiceParent) self.assertTrue(os.path.exists(ffn)) self.assertEqual(furl1, open(ffn, "r").read().strip()) def _take2(res): t2 = Tub(certFile=cfn) t2.setServiceParent(self.s) t2.listenOn(port1) t2.setLocation("127.0.0.1:%d" % portnum) r2 = Referenceable() furl2 = t2.registerReference(r2, furlFile=ffn) self.assertEqual(furl1, furl2) return t2.disownServiceParent() d.addCallback(_take2) return d
def start(self, options): root = static.Data("placeholder", "text/plain") welcome = Welcome(self, options["timestamps"]) root.putChild("", welcome) root.putChild("welcome", welcome) # we used to only do this root.putChild("reload", Reload(self)) root.putChild("all-events", EventView(self)) root.putChild("summary", Summary(self)) root.putChild("flog.css", static.Data(FLOG_CSS, "text/css")) s = server.Site(root) port = options["port"] if not port: port = "tcp:%d:interface=127.0.0.1" % allocate_tcp_port() ep = endpoints.serverFromString(reactor, port) self.lp = yield ep.listen(s) portnum = self.lp.getHost().port # TODO: this makes all sort of assumptions: HTTP-vs-HTTPS, localhost. url = "http://localhost:%d/" % portnum if not options["quiet"]: print "scanning.." self.logfiles = [options.dumpfile] self.load_logfiles() if not options["quiet"]: print "please point your browser at:" print url if options["open"]: import webbrowser webbrowser.open(url) returnValue(url) # for tests
def test_tubid_check(self): t1 = Tub() # gets a new key t1.setServiceParent(self.s) portnum = allocate_tcp_port() port1 = "tcp:%d:interface=127.0.0.1" % portnum t1.listenOn(port1) t1.setLocation("127.0.0.1:%d" % portnum) r1 = Referenceable() ffn = "test_tub.FurlFile.test_tubid_check.furlfile" furl1 = t1.registerReference(r1, furlFile=ffn) d = defer.maybeDeferred(t1.disownServiceParent) self.assertTrue(os.path.exists(ffn)) self.assertEqual(furl1, open(ffn, "r").read().strip()) def _take2(res): t2 = Tub() # gets a different key t2.setServiceParent(self.s) t2.listenOn(port1) t2.setLocation("127.0.0.1:%d" % portnum) r2 = Referenceable() self.assertRaises(WrongTubIdError, t2.registerReference, r2, furlFile=ffn) return t2.disownServiceParent() d.addCallback(_take2) return d
def test_unreachable_gift(self): client_tub = Tub() client_tub.setServiceParent(self.s) server_tub = Tub() server_tub.setServiceParent(self.s) recipient_tub = Tub() recipient_tub.setServiceParent(self.s) portnum = allocate_tcp_port() server_tub.listenOn("tcp:%d:interface=127.0.0.1" % portnum) server_tub.setLocation("tcp:127.0.0.1:%d" % portnum) s = Receiver() # no FURL, not directly reachable r = Receiver() furl = server_tub.registerReference(r) d = client_tub.getReference(furl) d.addCallback(lambda rref: rref.callRemote("call", s)) d.addCallback(lambda res: self.failUnlessEqual(res, 1)) d.addCallback(lambda _: recipient_tub.getReference(furl)) # when server_tub tries to send the lame 's' rref to recipient_tub, # the RemoteReferenceTracker won't have a FURL, so it will be # serialized as a (their-reference furl="") sequence. Then # recipient_tub will try to resolve it, and will throw a # NoLocationHintsError. It might be more natural to send # (their-reference furl=None), but the constraint schema on # their-references forbids non-strings. It might also seem # appropriate to raise a Violation (i.e. server_tub is bad for trying # to send it, rather than foisting the problem off to recipient_tub), # but that causes the connection explode and fall out of sync. d.addCallback(lambda rref: self.shouldFail(NoLocationHintsError, "gift_me", None, rref.callRemote, "gift_me")) return d
def test_unreachable_gift(self): client_tub = Tub() client_tub.setServiceParent(self.s) server_tub = Tub() server_tub.setServiceParent(self.s) recipient_tub = Tub() recipient_tub.setServiceParent(self.s) portnum = allocate_tcp_port() server_tub.listenOn("tcp:%d:interface=127.0.0.1" % portnum) server_tub.setLocation("tcp:127.0.0.1:%d" % portnum) s = Receiver() # no FURL, not directly reachable r = Receiver() furl = server_tub.registerReference(r) d = client_tub.getReference(furl) d.addCallback(lambda rref: rref.callRemote("call", s)) d.addCallback(lambda res: self.assertEqual(res, 1)) d.addCallback(lambda _: recipient_tub.getReference(furl)) # when server_tub tries to send the lame 's' rref to recipient_tub, # the RemoteReferenceTracker won't have a FURL, so it will be # serialized as a (their-reference furl="") sequence. Then # recipient_tub will try to resolve it, and will throw a # NoLocationHintsError. It might be more natural to send # (their-reference furl=None), but the constraint schema on # their-references forbids non-strings. It might also seem # appropriate to raise a Violation (i.e. server_tub is bad for trying # to send it, rather than foisting the problem off to recipient_tub), # but that causes the connection explode and fall out of sync. d.addCallback(lambda rref: self.shouldFail( NoLocationHintsError, "gift_me", None, rref.callRemote, "gift_me")) return d
def test_referenceable(self): t1 = Tub() t1.setServiceParent(self.s) portnum = allocate_tcp_port() t1.listenOn("tcp:%d:interface=127.0.0.1" % portnum) t1.setLocation("127.0.0.1:%d" % portnum) r1 = Referenceable() # the serialized blob can't keep the reference alive, so you must # arrange for that separately t1.registerReference(r1) t2 = Tub() t2.setServiceParent(self.s) obj = ("graph tangly", r1) d = t1.serialize(obj) del r1 del obj def _done(data): self.assertTrue(b"their-reference" in data) return data d.addCallback(_done) d.addCallback(lambda data: t2.unserialize(data)) def _check(obj2): self.assertEqual(obj2[0], "graph tangly") self.assertTrue(isinstance(obj2[1], RemoteReference)) d.addCallback(_check) return d
def test_set_location(self): t = Tub() portnum = allocate_tcp_port() t.listenOn("tcp:%d:interface=127.0.0.1" % portnum) t.setServiceParent(self.s) t.setLocation("127.0.0.1:12345") # setLocation may only be called once self.assertRaises(PBError, t.setLocation, "127.0.0.1:12345")
def test_set_location(self): t = Tub() portnum = allocate_tcp_port() t.listenOn("tcp:%d:interface=127.0.0.1" % portnum) t.setServiceParent(self.s) t.setLocation("127.0.0.1:12345") # setLocation may only be called once self.failUnlessRaises(PBError, t.setLocation, "127.0.0.1:12345")
def test_parsed_endpoint(self): tubA, tubB = self.makeTubs() portnum = util.allocate_tcp_port() ep = endpoints.serverFromString(reactor, "tcp:%d:interface=127.0.0.1" % portnum) tubA.listenOn(ep) tubA.setLocation("tcp:127.0.0.1:%d" % portnum) furl = tubA.registerReference(Target()) yield tubB.getReference(furl)
def test_endpoint(self): tubA, tubB = self.makeTubs() portnum = util.allocate_tcp_port() ep = endpoints.TCP4ServerEndpoint(reactor, portnum, interface="127.0.0.1") tubA.listenOn(ep) tubA.setLocation("tcp:127.0.0.1:%d" % portnum) furl = tubA.registerReference(Target()) yield tubB.getReference(furl)
def makeTub(self, hint_type): tubA = Tub(certData=certData_low) tubA.setServiceParent(self.s) tubB = Tub(certData=certData_high) tubB.setServiceParent(self.s) portnum = util.allocate_tcp_port() tubA.listenOn("tcp:%d:interface=127.0.0.1" % portnum) tubA.setLocation("%s:127.0.0.1:%d" % (hint_type, portnum)) furl = tubA.registerReference(Target()) return furl, tubB
def test_allocate(self): p = util.allocate_tcp_port() self.assertTrue(isinstance(p, int)) self.assertTrue(1 <= p <= 65535, p) # the allocation function should release the port before it # returns, so it should be possible to listen on it immediately ep = endpoints.TCP4ServerEndpoint(reactor, p, interface="127.0.0.1") d = ep.listen(protocol.Factory()) d.addCallback(lambda port: port.stopListening()) return d
def makeServers(self): self.tub = tub = Tub(certData=certData_high) tub.startService() self.services.append(tub) port = allocate_tcp_port() tub.listenOn("tcp:%d:interface=127.0.0.1" % port) tub.setLocation("127.0.0.1:%d" % port) furl1 = tub.registerReference(Target()) furl2 = tub.registerReference(Target()) return furl1, furl2
def test_allocate(self): p = util.allocate_tcp_port() self.failUnless(isinstance(p, int)) self.failUnless(1 <= p <= 65535, p) # the allocation function should release the port before it # returns, so it should be possible to listen on it immediately ep = endpoints.TCP4ServerEndpoint(reactor, p, interface="127.0.0.1") d = ep.listen(protocol.Factory()) d.addCallback(lambda port: port.stopListening()) return d
def makeServer(self, options={}, listenerOptions={}): self.tub = tub = Tub(_test_options=options) tub.startService() self.services.append(tub) portnum = allocate_tcp_port() tub.listenOn("tcp:%d:interface=127.0.0.1" % portnum, _test_options=listenerOptions) tub.setLocation("127.0.0.1:%d" % portnum) self.target = Target() return tub.registerReference(self.target), portnum
def test_nonqualified_port(self): tubA, tubB = self.makeTubs() portnum = util.allocate_tcp_port() import warnings with warnings.catch_warnings(): warnings.simplefilter("ignore") tubA.listenOn("%d" % portnum) # this is deprecated tubA.setLocation("tcp:127.0.0.1:%d" % portnum) furl = tubA.registerReference(Target()) yield tubB.getReference(furl)
def makeServers(self, t1opts={}, t2opts={}, lo1={}, lo2={}): # first we create two Tubs a = Tub(_test_options=t1opts) b = Tub(_test_options=t1opts) # then we figure out which one will be the master, and call it tub1 if a.tubID > b.tubID: # a is the master tub1, tub2 = a, b else: tub1, tub2 = b, a if not self.tub1IsMaster: tub1, tub2 = tub2, tub1 self.tub1 = tub1 self.tub2 = tub2 # now fix up the options and everything else self.tub1phases = [] t1opts['debug_gatherPhases'] = self.tub1phases tub1._test_options = t1opts self.tub2phases = [] t2opts['debug_gatherPhases'] = self.tub2phases tub2._test_options = t2opts # connection[0], the winning connection, will be from tub1 to tub2 tub1.startService() self.services.append(tub1) self.portnum1 = allocate_tcp_port() tub1.listenOn("tcp:%d:interface=127.0.0.1" % self.portnum1, lo1) tub1.setLocation("127.0.0.1:%d" % self.portnum1) self.target1 = Target() self.url1 = tub1.registerReference(self.target1) # connection[1], the abandoned connection, will be from tub2 to tub1 tub2.startService() self.services.append(tub2) self.portnum2 = allocate_tcp_port() tub2.listenOn("tcp:%d:interface=127.0.0.1" % self.portnum2, lo2) tub2.setLocation("127.0.0.1:%d" % self.portnum2) self.target2 = Target() self.url2 = tub2.registerReference(self.target2)
def makeServers(self, t1opts={}, t2opts={}, lo1={}, lo2={}): # first we create two Tubs a = Tub(_test_options=t1opts) b = Tub(_test_options=t1opts) # then we figure out which one will be the master, and call it tub1 if a.tubID > b.tubID: # a is the master tub1,tub2 = a,b else: tub1,tub2 = b,a if not self.tub1IsMaster: tub1,tub2 = tub2,tub1 self.tub1 = tub1 self.tub2 = tub2 # now fix up the options and everything else self.tub1phases = [] t1opts['debug_gatherPhases'] = self.tub1phases tub1._test_options = t1opts self.tub2phases = [] t2opts['debug_gatherPhases'] = self.tub2phases tub2._test_options = t2opts # connection[0], the winning connection, will be from tub1 to tub2 tub1.startService() self.services.append(tub1) self.portnum1 = allocate_tcp_port() tub1.listenOn("tcp:%d:interface=127.0.0.1" % self.portnum1, lo1) tub1.setLocation("127.0.0.1:%d" % self.portnum1) self.target1 = Target() self.url1 = tub1.registerReference(self.target1) # connection[1], the abandoned connection, will be from tub2 to tub1 tub2.startService() self.services.append(tub2) self.portnum2 = allocate_tcp_port() tub2.listenOn("tcp:%d:interface=127.0.0.1" % self.portnum2, lo2) tub2.setLocation("127.0.0.1:%d" % self.portnum2) self.target2 = Target() self.url2 = tub2.registerReference(self.target2)
def createSpecificServer(self, certData, negotiationClass=negotiate.Negotiation): tub = Tub(certData=certData) tub.negotiationClass = negotiationClass tub.startService() self.services.append(tub) portnum = allocate_tcp_port() tub.listenOn("tcp:%d:interface=127.0.0.1" % portnum) tub.setLocation("127.0.0.1:%d" % portnum) target = Target() return tub, target, tub.registerReference(target), portnum
def testPersist(self): t1 = Target() s1, s2 = self.services port = allocate_tcp_port() s1.listenOn("tcp:%d:interface=127.0.0.1" % port) s1.setLocation("127.0.0.1:%d" % port) public_url = s1.registerReference(t1, "name") self.failUnless(public_url.startswith("pb:")) d = defer.maybeDeferred(s1.stopService) d.addCallback(self._testPersist_1, s1, s2, t1, public_url, port) return d
def testPersist(self): t1 = Target() s1,s2 = self.services port = allocate_tcp_port() s1.listenOn("tcp:%d:interface=127.0.0.1" % port) s1.setLocation("127.0.0.1:%d" % port) public_url = s1.registerReference(t1, "name") self.failUnless(public_url.startswith("pb:")) d = defer.maybeDeferred(s1.stopService) d.addCallback(self._testPersist_1, s1, s2, t1, public_url, port) return d
def setUp(self): self.services = [Tub() for i in range(4)] self.tubA, self.tubB, self.tubC, self.tubD = self.services for s in self.services: s.startService() p = allocate_tcp_port() s.listenOn("tcp:%d:interface=127.0.0.1" % p) s.setLocation("127.0.0.1:%d" % p) self.tubIDs = [self.tubA.getShortTubID(), self.tubB.getShortTubID(), self.tubC.getShortTubID(), self.tubD.getShortTubID()]
def getRef(self, target): self.services.append(Tub()) s1 = self.services[0] s2 = self.services[1] s2.startService() portnum = allocate_tcp_port() s1.listenOn("tcp:%d:interface=127.0.0.1" % portnum) s1.setLocation("127.0.0.1:%d" % portnum) public_url = s1.registerReference(target, "target") self.public_url = public_url d = s2.getReference(public_url) return d
def createDuplicateServer(self, oldtub): tub = Tub(certData=oldtub.getCertData()) tub.startService() self.services.append(tub) tub.incarnation = oldtub.incarnation tub.incarnation_string = oldtub.incarnation_string tub.slave_table = oldtub.slave_table.copy() tub.master_table = oldtub.master_table.copy() portnum = allocate_tcp_port() tub.listenOn("tcp:%d:interface=127.0.0.1" % portnum) tub.setLocation("127.0.0.1:%d" % portnum) target = Target() return tub, target, tub.registerReference(target), portnum
def _foolscapEndpointForPortNumber(portnum): """ Create an endpoint that can be passed to ``Tub.listen``. :param portnum: Either an integer port number indicating which TCP/IPv4 port number the endpoint should bind or ``None`` to automatically allocate such a port number. :return: A two-tuple of the integer port number allocated and a Foolscap-compatible endpoint object. """ if portnum is None: # Bury this reactor import here to minimize the chances of it having # the effect of installing the default reactor. from twisted.internet import reactor if fcntl is not None and IReactorSocket.providedBy(reactor): # On POSIX we can take this very safe approach of binding the # actual socket to an address. Once the bind succeeds here, we're # no longer subject to any future EADDRINUSE problems. s = socket.socket() try: s.bind(('', 0)) portnum = s.getsockname()[1] s.listen(1) # File descriptors are a relatively scarce resource. The # cleanup process for the file descriptor we're about to dup # is unfortunately complicated. In particular, it involves # the Python garbage collector. See CleanupEndpoint for # details of that. Here, we need to make sure the garbage # collector actually runs frequently enough to make a # difference. Normally, the garbage collector is triggered by # allocations. It doesn't know about *file descriptor* # allocation though. So ... we'll "teach" it about those, # here. fileDescriptorResource.allocate() fd = os.dup(s.fileno()) flags = fcntl.fcntl(fd, fcntl.F_GETFD) flags = flags | os.O_NONBLOCK | fcntl.FD_CLOEXEC fcntl.fcntl(fd, fcntl.F_SETFD, flags) endpoint = AdoptedStreamServerEndpoint(reactor, fd, socket.AF_INET) return (portnum, CleanupEndpoint(endpoint, fd)) finally: s.close() else: # Get a random port number and fall through. This is necessary on # Windows where Twisted doesn't offer IReactorSocket. This # approach is error prone for the reasons described on # https://tahoe-lafs.org/trac/tahoe-lafs/ticket/2787 portnum = allocate_tcp_port() return (portnum, native_str("tcp:%d" % (portnum, )))
def test_run(self): basedir = "appserver/Server/run" os.makedirs(basedir) serverdir = os.path.join(basedir, "fl") incomingdir = os.path.join(basedir, "incoming") os.mkdir(incomingdir) self.tub = Tub() self.tub.setServiceParent(self.s) portnum = allocate_tcp_port() d = self.run_cli("create", "--location", "localhost:%d" % portnum, "--port", "tcp:%d" % portnum, serverdir) def _check(rc_out_err): rc, out, err = rc_out_err self.assertEqual(rc, 0) self.assertTrue(os.path.isdir(serverdir)) d.addCallback(_check) d.addCallback(lambda ign: self.run_cli("add", serverdir, "upload-file", incomingdir)) def _check_add(rc_out_err): rc, out, err = rc_out_err self.assertEqual(rc, 0) lines = out.splitlines() self.assertTrue(lines[1].startswith("FURL is pb://")) self.furl = lines[1].split()[-1] d.addCallback(_check_add) stdout = StringIO() def _start_server(ign): ap = server.AppServer(serverdir, stdout) ap.setServiceParent(self.s) d.addCallback(_start_server) # make sure the server can actually instantiate a service d.addCallback(lambda _ign: self.tub.getReference(self.furl)) def _got_rref(rref): # great! pass d.addCallback(_got_rref) d.addCallback(lambda ign: self.shouldFail( KeyError, "getReference(bogus)", "unable to find reference for name ", self.tub.getReference, self. furl + ".bogus")) return d
def setUp(self): self.services = [Tub() for i in range(4)] self.tubA, self.tubB, self.tubC, self.tubD = self.services for s in self.services: s.startService() p = allocate_tcp_port() s.listenOn("tcp:%d:interface=127.0.0.1" % p) s.setLocation("127.0.0.1:%d" % p) self.tubIDs = [ self.tubA.getShortTubID(), self.tubB.getShortTubID(), self.tubC.getShortTubID(), self.tubD.getShortTubID() ]
def makeTubs(self, numTubs, mangleLocation=None): self.services = [] self.tub_ports = [] for i in range(numTubs): t = Tub() t.startService() self.services.append(t) portnum = allocate_tcp_port() self.tub_ports.append(portnum) t.listenOn("tcp:%d:interface=127.0.0.1" % portnum) location = "127.0.0.1:%d" % portnum if mangleLocation: location = mangleLocation(portnum) t.setLocation(location) return self.services
def makeTub(self, hint_type, listener_test_options={}, extra_hint=None): tubA = Tub(certData=certData_low) tubA.setServiceParent(self.s) tubB = Tub(certData=certData_high) tubB.setServiceParent(self.s) self._tubA, self._tubB = tubA, tubB portnum = util.allocate_tcp_port() self._portnum = portnum port = "tcp:%d:interface=127.0.0.1" % portnum hint = "%s:127.0.0.1:%d" % (hint_type, portnum) if extra_hint: hint = hint + "," + extra_hint tubA.listenOn(port, _test_options=listener_test_options) tubA.setLocation(hint) self._target = Target() furl = tubA.registerReference(self._target) return furl, tubB, hint
def _testPersist_1(self, res, s1, s2, t1, public_url, port): self.services.remove(s1) s3 = Tub(certData=s1.getCertData()) s3.startService() self.services.append(s3) t2 = Target() newport = allocate_tcp_port() s3.listenOn("tcp:%d:interface=127.0.0.1" % newport) s3.setLocation("127.0.0.1:%d" % newport) s3.registerReference(t2, "name") # now patch the URL to replace the port number newurl = re.sub(":%d/" % port, ":%d/" % newport, public_url) d = s2.getReference(newurl) d.addCallback(lambda rr: rr.callRemote("add", a=1, b=2)) d.addCallback(self.failUnlessEqual, 3) d.addCallback(self._testPersist_2, t1, t2) return d
def test_referenceables_die(self): # serialized data will not keep the referenceable alive t1 = Tub() t1.setServiceParent(self.s) portnum = allocate_tcp_port() t1.listenOn("tcp:%d:interface=127.0.0.1" % portnum) t1.setLocation("127.0.0.1:%d" % portnum) r1 = Referenceable() t2 = Tub() t2.setServiceParent(self.s) obj = ("graph tangly", r1) d = t1.serialize(obj) del r1; del obj gc.collect() d.addCallback(lambda data: self.shouldFail(KeyError, "test_referenceables_die", "unable to find reference for name", t2.unserialize, data)) return d