def test_referenceable(self): t1 = Tub() t1.setServiceParent(self.s) l = t1.listenOn("tcp:0:interface=127.0.0.1") t1.setLocation("127.0.0.1:%d" % l.getPortnum()) 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 test_set_location(self): t = Tub() t.listenOn("tcp:0") 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_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_failure(self): self.basedir = "introducer/NonV1Server/failure" os.makedirs(self.basedir) self.create_tub() i = TooNewServer() i.setServiceParent(self.parent) self.introducer_furl = self.central_tub.registerReference(i) tub = Tub() tub.setOption("expose-remote-exception-types", False) tub.setServiceParent(self.parent) l = tub.listenOn("tcp:0") portnum = l.getPortnum() tub.setLocation("localhost:%d" % portnum) c = IntroducerClient(tub, self.introducer_furl, u"nickname-client", "version", "oldest") announcements = {} def got(serverid, ann_d): announcements[serverid] = ann_d c.subscribe_to("storage", got) c.setServiceParent(self.parent) # now we wait for it to connect and notice the bad version def _got_bad(): return bool(c._introducer_error) or bool(c._publisher) d = self.poll(_got_bad) def _done(res): self.failUnless(c._introducer_error) self.failUnless(c._introducer_error.check(InsufficientVersionError)) d.addCallback(_done) return d
class StatsGathererService(service.MultiService): furl_file = "stats_gatherer.furl" def __init__(self, basedir=".", verbose=False): service.MultiService.__init__(self) self.basedir = basedir self.tub = Tub(certFile=os.path.join(self.basedir, "stats_gatherer.pem")) self.tub.setServiceParent(self) self.tub.setOption("logLocalFailures", True) self.tub.setOption("logRemoteFailures", True) self.tub.setOption("expose-remote-exception-types", False) self.stats_gatherer = JSONStatsGatherer(self.basedir, verbose) self.stats_gatherer.setServiceParent(self) try: with open(os.path.join(self.basedir, "location")) as f: location = f.read().strip() except EnvironmentError: raise ValueError("Unable to find 'location' in BASEDIR, please rebuild your stats-gatherer") try: with open(os.path.join(self.basedir, "port")) as f: port = f.read().strip() except EnvironmentError: raise ValueError("Unable to find 'port' in BASEDIR, please rebuild your stats-gatherer") self.tub.listenOn(port) self.tub.setLocation(location) ff = os.path.join(self.basedir, self.furl_file) self.gatherer_furl = self.tub.registerReference(self.stats_gatherer, furlFile=ff)
def test_furlfile(self): cfn = "test_tub.FurlFile.test_furlfile.certfile" t1 = Tub(certFile=cfn) t1.setServiceParent(self.s) l = t1.listenOn("tcp:0:interface=127.0.0.1") t1.setLocation("127.0.0.1:%d" % l.getPortnum()) port1 = "tcp:%d:interface=127.0.0.1" % l.getPortnum() 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) l = t2.listenOn(port1) t2.setLocation("127.0.0.1:%d" % l.getPortnum()) r2 = Referenceable() furl2 = t2.registerReference(r2, furlFile=ffn) self.failUnlessEqual(furl1, furl2) return t2.disownServiceParent() d.addCallback(_take2) 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.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_empty_location(self): # bug #129: a FURL with no location hints causes a synchronous # exception in Tub.getReference(), instead of an errback'ed Deferred. tubA = Tub() tubA.setServiceParent(self.s) tubB = Tub() tubB.setServiceParent(self.s) # This is a hack to get a FURL with empty location hints. The correct # way to make a Tub unreachable is to not call .setLocation() at all. tubB.setLocation("") r = Receiver(tubB) furl = tubB.registerReference(r) # the buggy behavior is that the following call raises an exception d = tubA.getReference(furl) # whereas it ought to return a Deferred self.assertTrue(isinstance(d, defer.Deferred)) def _check(f): self.assertTrue(isinstance(f, failure.Failure), f) self.assertTrue(f.check(NoLocationHintsError), f) d.addBoth(_check) return d
def test_furlfile(self): cfn = "test_tub.FurlFile.test_furlfile.certfile" t1 = Tub(certFile=cfn) t1.setServiceParent(self.s) l = t1.listenOn("tcp:0:interface=127.0.0.1") t1.setLocation("127.0.0.1:%d" % l.getPortnum()) port1 = "tcp:%d:interface=127.0.0.1" % l.getPortnum() 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) l = t2.listenOn(port1) t2.setLocation("127.0.0.1:%d" % l.getPortnum()) 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) l = t1.listenOn("tcp:0:interface=127.0.0.1") t1.setLocation("127.0.0.1:%d" % l.getPortnum()) port1 = "tcp:%d:interface=127.0.0.1" % l.getPortnum() 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) l = t2.listenOn(port1) t2.setLocation("127.0.0.1:%d" % l.getPortnum()) r2 = Referenceable() self.failUnlessRaises(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_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 get_tub(application): myserver = RemoteControl(application) tub = Tub(certFile=os.path.join(consenso.directories.foolscap_dir, "pb2server.pem")) tub.listenOn("tcp:12345") tub.setLocation("localhost:12345") tub.registerReference(myserver, "remote-control", furlFile=furlfile) return tub
def test_retry(self): tubC = Tub(certData=self.tubB.getCertData()) connects = [] target = HelperTarget("bob") url = self.tubB.registerReference(target, "target") portb = self.tub_ports[1] d1 = defer.Deferred() notifiers = [d1] self.services.remove(self.tubB) # This will fail, since tubB is not listening anymore. Wait until it's # moved to the "waiting" state. yield self.tubB.stopService() rc = self.tubA.connectTo(url, self._connected, notifiers, connects) yield self.poll(lambda: rc.getReconnectionInfo().state == "waiting") self.failUnlessEqual(len(connects), 0) # now start tubC listening on the same port that tubB used to, which # should allow the connection to complete (since they both use the same # certData) self.services.append(tubC) tubC.startService() tubC.listenOn("tcp:%d:interface=127.0.0.1" % portb) tubC.setLocation("tcp:127.0.0.1:%d" % portb) url2 = tubC.registerReference(target, "target") assert url2 == url yield d1 self.failUnlessEqual(len(connects), 1) rc.stopConnecting()
def test_tubid_check(self): t1 = Tub() # gets a new key t1.setServiceParent(self.s) l = t1.listenOn("tcp:0:interface=127.0.0.1") t1.setLocation("127.0.0.1:%d" % l.getPortnum()) port1 = "tcp:%d:interface=127.0.0.1" % l.getPortnum() 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) l = t2.listenOn(port1) t2.setLocation("127.0.0.1:%d" % l.getPortnum()) r2 = Referenceable() self.failUnlessRaises(WrongTubIdError, t2.registerReference, r2, furlFile=ffn) return t2.disownServiceParent() d.addCallback(_take2) 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.failUnlessRaises(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.assertRaises(PBError, t.setLocation, "127.0.0.1:12345")
def _take2(res): t2 = Tub(certFile=cfn) t2.setServiceParent(self.s) l = t2.listenOn(port1) t2.setLocation("127.0.0.1:%d" % l.getPortnum()) r2 = Referenceable() furl2 = t2.registerReference(r2, furlFile=ffn) self.failUnlessEqual(furl1, furl2) return t2.disownServiceParent()
class GatheringBase(service.MultiService, Referenceable): # requires self.furlFile and self.tacFile to be set on the class, both of # which should be relative to the basedir. use_local_addresses = True def __init__(self, basedir): if basedir is None: # This instance was created by a gatherer.tac file. Confirm that # we're running from the right directory (the one with the .tac # file), otherwise we'll put the logfiles in the wrong place. basedir = os.getcwd() tac = os.path.join(basedir, self.tacFile) if not os.path.exists(tac): raise RuntimeError("running in the wrong directory") self.basedir = basedir service.MultiService.__init__(self) def startService(self): service.MultiService.startService(self) certFile = os.path.join(self.basedir, "gatherer.pem") self._tub = Tub(certFile=certFile) self._tub.setServiceParent(self) local_addresses = ["127.0.0.1"] local_address = get_local_ip_for() if self.use_local_addresses and local_address: local_addresses.insert(0, local_address) portnumfile = os.path.join(self.basedir, "portnum") try: desired_portnum = int(open(portnumfile, "r").read()) except (EnvironmentError, ValueError): desired_portnum = 0 l = self._tub.listenOn("tcp:%d" % desired_portnum) got_portnum = l.getPortnum() f = open(portnumfile, "w") f.write("%d\n" % got_portnum) f.close() # we can't do setLocation until we have two things: # portnum: this requires listenOn, if portnum=0 also startService # localip: this just requires a call to get_local_ip_for # so it is safe to do everything in startService, after the upcall local_addresses = [ "%s:%d" % (addr, got_portnum,) for addr in local_addresses ] assert len(local_addresses) >= 1 location = ",".join(local_addresses) self._tub.setLocation(location) self.tub_ready() def tub_ready(self): furlFile = os.path.join(self.basedir, self.furlFile) self.my_furl = self._tub.registerReference(self, furlFile=furlFile) if self.verbose: print "Gatherer waiting at:", self.my_furl
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()
def _take2(res): t2 = Tub() # gets a different key t2.setServiceParent(self.s) l = t2.listenOn(port1) t2.setLocation("127.0.0.1:%d" % l.getPortnum()) r2 = Referenceable() self.failUnlessRaises(WrongTubIdError, t2.registerReference, r2, furlFile=ffn) return t2.disownServiceParent()
def createSpecificServer(self, certData, negotiationClass=negotiate.Negotiation): tub = Tub(certData=certData) tub.negotiationClass = negotiationClass tub.startService() self.services.append(tub) l = tub.listenOn("tcp:0") tub.setLocation("127.0.0.1:%d" % l.getPortnum()) target = Target() return tub, target, tub.registerReference(target), l.getPortnum()
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
class GatheringBase(service.MultiService, Referenceable): # requires self.furlFile and self.tacFile to be set on the class, both of # which should be relative to the basedir. use_local_addresses = True def __init__(self, basedir): service.MultiService.__init__(self) if basedir is None: # This instance was created by a gatherer.tac file. Confirm that # we're running from the right directory (the one with the .tac # file), otherwise we'll put the logfiles in the wrong place. basedir = os.getcwd() tac = os.path.join(basedir, self.tacFile) if not os.path.exists(tac): raise RuntimeError("running in the wrong directory") self.basedir = basedir certFile = os.path.join(self.basedir, "gatherer.pem") portfile = os.path.join(self.basedir, "port") locationfile = os.path.join(self.basedir, "location") furlFile = os.path.join(self.basedir, self.furlFile) # Foolscap-0.11.0 was the last release that used # automatically-determined listening addresses and ports. New ones # (created with "flogtool create-gatherer" or # "create-incident-gathererer" now require --location and --port # arguments to provide these values. If you really don't want to # create a new one, you can write "tcp:3117" (or some other port # number of your choosing) to BASEDIR/port, and "tcp:$HOSTNAME:3117" # (with your hostname or IP address) to BASEDIR/location if (not os.path.exists(portfile) or not os.path.exists(locationfile)): raise ObsoleteGatherer("Please create a new gatherer, with both " "--port and --location") try: with open(portfile, "r") as f: port = f.read().strip() except EnvironmentError: raise ObsoleteGatherer("Please create a new gatherer, with both " "--port and --location") try: with open(locationfile, "r") as f: location = f.read().strip() except EnvironmentError: raise ObsoleteGatherer("Please create a new gatherer, with both " "--port and --location") self._tub = Tub(certFile=certFile) self._tub.setServiceParent(self) self._tub.listenOn(port) self._tub.setLocation(location) self.my_furl = self._tub.registerReference(self, furlFile=furlFile) if self.verbose: print "Gatherer waiting at:", self.my_furl
def TODO_testNonweakrefable(self): # what happens when we register a non-Referenceable? We don't really # need this yet, but as registerReference() becomes more generalized # into just plain register(), we'll want to provide references to # Copyables and ordinary data structures too. Let's just test that # this doesn't cause an error. target = [] tub = Tub() tub.setLocation("bogus:1234567") url = tub.registerReference(target) del url
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 new_tahoe_configuration(deploy_config, bucketname, key_prefix, publichost, privatehost, introducer_port, storageserver_port): """ Create brand new secrets and configuration for use by an introducer/storage pair. """ base_name = dict( organizationName=b"Least Authority Enterprises", organizationalUnitName=b"S4", emailAddress=bucketname, ) keypair = KeyPair.generate(size=2048) introducer_certificate = keypair.selfSignedCert( serialNumber=1, commonName=b"introducer", **base_name ) storage_certificate = keypair.selfSignedCert( serialNumber=1, commonName=b"storage", **base_name ) def pem(key, cert): return b"\n".join((key.dump(FILETYPE_PEM), cert.dump(FILETYPE_PEM))) introducer_tub = Tub(certData=pem(keypair, introducer_certificate)) introducer_tub.setLocation("{}:{}".format(publichost, introducer_port)) storage_tub = Tub(certData=pem(keypair, storage_certificate)) return marshal_tahoe_configuration( introducer_pem=introducer_tub.getCertData().strip(), storage_pem=storage_tub.getCertData().strip(), storage_privkey=keyutil.make_keypair()[0] + b"\n", introducer_port=introducer_port, storageserver_port=storageserver_port, bucket_name=bucketname, key_prefix=key_prefix, publichost=publichost, privatehost=privatehost, # The object of the reference is irrelevant. The furl will # get hooked up to something else when Tahoe really runs. # Just need to pass something _weak referenceable_! Which # rules out a lot of things... introducer_furl=introducer_tub.registerReference(introducer_tub), s3_access_key_id=deploy_config.s3_access_key_id, s3_secret_key=deploy_config.s3_secret_key, log_gatherer_furl=deploy_config.log_gatherer_furl, stats_gatherer_furl=deploy_config.stats_gatherer_furl, )
class AppServer(service.MultiService): def __init__(self, basedir=".", stdout=sys.stdout): service.MultiService.__init__(self) self.basedir = os.path.abspath(basedir) try: umask = open(os.path.join(basedir, "umask")).read().strip() self.umask = int(umask, 8) # octal string like 0022 except EnvironmentError: self.umask = None port = open(os.path.join(basedir, "port")).read().strip() self.tub = Tub(certFile=os.path.join(basedir, "tub.pem")) self.tub.listenOn(port) self.tub.setServiceParent(self) self.tub.registerNameLookupHandler(self.lookup) print >> stdout, "Server Running" self.ready_observers = OneShotObserverList() # make sure we log any problems self.when_ready().addErrback(log.err) def when_ready(self): # return a Deferred that fires (with this AppServer instance) when # the service is running and the location is set. return self.ready_observers.whenFired() def startService(self): if self.umask is not None: os.umask(self.umask) service.MultiService.startService(self) d = self.setMyLocation() d.addBoth(self.ready_observers.fire) def setMyLocation(self): location = open(os.path.join(self.basedir, "location")).read().strip() if location: self.tub.setLocation(location) return defer.succeed(self) d = self.tub.setLocationAutomatically() d.addCallback(lambda ign: self) return d def lookup(self, name): # walk through our configured services, see if we know about this one services = load_service_data(self.basedir)["services"] s = services.get(name) if not s: return None service_basedir = os.path.join(self.basedir, s["relative_basedir"]) service_type = s["type"] service_args = s["args"] s = build_service(service_basedir, self.tub, service_type, service_args) s.setServiceParent(self) return s
def test_duplicate(self): basedir = "test_registration" os.makedirs(basedir) ff = os.path.join(basedir, "duplicate.furl") t1 = HelperTarget() tub = Tub() tub.setLocation("bogus:1234567") u1 = tub.registerReference(t1, "name", furlFile=ff) u2 = tub.registerReference(t1, "name", furlFile=ff) self.failUnlessEqual(u1, u2) self.failUnlessRaises(WrongNameError, tub.registerReference, t1, "newname", furlFile=ff)
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() l = tub.listenOn("tcp:0") tub.setLocation("127.0.0.1:%d" % l.getPortnum()) target = Target() return tub, target, tub.registerReference(target), l.getPortnum()
class AppServer(service.MultiService): def __init__(self, basedir=".", stdout=sys.stdout): service.MultiService.__init__(self) self.basedir = os.path.abspath(basedir) try: umask = open(os.path.join(basedir, "umask")).read().strip() self.umask = int(umask, 8) # octal string like 0022 except EnvironmentError: self.umask = None self.port = open(os.path.join(basedir, "port")).read().strip() self.tub = Tub(certFile=os.path.join(basedir, "tub.pem")) self.tub.listenOn(self.port) self.tub.setServiceParent(self) self.tub.registerNameLookupHandler(self.lookup) self.setMyLocation() print("Server Running", file=stdout) def startService(self): if self.umask is not None: os.umask(self.umask) service.MultiService.startService(self) def setMyLocation(self): location_fn = os.path.join(self.basedir, "location") location = open(location_fn).read().strip() if not location: raise ValueError("This flappserver was created without " "'--location=', and Foolscap no longer uses " "IP-address autodetection. Please edit '%s' " "to contain e.g. 'tcp:example.org:12345', with " "a hostname and port number that match this " "server (we're listening on %s)" % (location_fn, self.port)) self.tub.setLocation(location) def lookup(self, name): # walk through our configured services, see if we know about this one services = load_service_data(self.basedir)["services"] service_desc = services.get(name) if service_desc: service_basedir = os.path.join(self.basedir, service_desc["relative_basedir"]) service_type = service_desc["type"] service_args = [arg for arg in service_desc["args"]] service = build_service(service_basedir, self.tub, service_type, service_args) service.setServiceParent(self) return service
class AppServer(service.MultiService): def __init__(self, basedir=".", stdout=sys.stdout): service.MultiService.__init__(self) self.basedir = os.path.abspath(basedir) try: umask = open(os.path.join(basedir, "umask")).read().strip() self.umask = int(umask, 8) # octal string like 0022 except EnvironmentError: self.umask = None port = open(os.path.join(basedir, "port")).read().strip() self.tub = Tub(certFile=os.path.join(basedir, "tub.pem")) self.tub.listenOn(port) self.tub.setServiceParent(self) self.tub.registerNameLookupHandler(self.lookup) print >>stdout, "Server Running" self.ready_observers = OneShotObserverList() # make sure we log any problems self.when_ready().addErrback(log.err) def when_ready(self): # return a Deferred that fires (with this AppServer instance) when # the service is running and the location is set. return self.ready_observers.whenFired() def startService(self): if self.umask is not None: os.umask(self.umask) service.MultiService.startService(self) d = self.setMyLocation() d.addBoth(self.ready_observers.fire) def setMyLocation(self): location = open(os.path.join(self.basedir, "location")).read().strip() if location: self.tub.setLocation(location) return defer.succeed(self) d = self.tub.setLocationAutomatically() d.addCallback(lambda ign: self) return d def lookup(self, name): # walk through our configured services, see if we know about this one service_basedir = os.path.join(self.basedir, "services", name) if not os.path.exists(service_basedir): return None service_type_f = os.path.join(service_basedir, "service_type") service_type = open(service_type_f).read().strip() service_args_f = os.path.join(service_basedir, "service_args") service_args = eval(open(service_args_f).read().strip()) s = build_service(service_basedir, self.tub, service_type, service_args) s.setServiceParent(self) return s
def testWeak(self): t1 = HelperTarget() tub = Tub() tub.setLocation("bogus:1234567") name = tub._assignName(t1) url = tub.buildURL(name) del url results = [] w1 = weakref.ref(t1, results.append) del t1 gc.collect() # t1 should be dead self.failIf(w1()) self.failUnlessEqual(len(results), 1)
def create_control_tub(): """ Creates a Foolscap Tub for use by the control port. This is a localhost-only ephemeral Tub, with no control over the listening port or location """ control_tub = Tub() portnum = iputil.allocate_tcp_port() port = "tcp:%d:interface=127.0.0.1" % portnum location = "tcp:127.0.0.1:%d" % portnum control_tub.listenOn(port) control_tub.setLocation(location) log.msg("Control Tub location set to %s" % (location,)) return control_tub
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
class AppServer(service.MultiService): def __init__(self, basedir=".", stdout=sys.stdout): service.MultiService.__init__(self) self.basedir = os.path.abspath(basedir) try: umask = open(os.path.join(basedir, "umask")).read().strip() self.umask = int(umask, 8) # octal string like 0022 except EnvironmentError: self.umask = None self.port = open(os.path.join(basedir, "port")).read().strip() self.tub = Tub(certFile=os.path.join(basedir, "tub.pem")) self.tub.listenOn(self.port) self.tub.setServiceParent(self) self.tub.registerNameLookupHandler(self.lookup) self.setMyLocation() print >>stdout, "Server Running" def startService(self): if self.umask is not None: os.umask(self.umask) service.MultiService.startService(self) def setMyLocation(self): location_fn = os.path.join(self.basedir, "location") location = open(location_fn).read().strip() if not location: raise ValueError("This flappserver was created without " "'--location=', and Foolscap no longer uses " "IP-address autodetection. Please edit '%s' " "to contain e.g. 'example.org:12345', with a " "hostname and port number that match this " "server (we're listening on %s)" % (location_fn, self.port)) self.tub.setLocation(location) def lookup(self, name): # walk through our configured services, see if we know about this one services = load_service_data(self.basedir)["services"] s = services.get(name) if not s: return None service_basedir = os.path.join(self.basedir, s["relative_basedir"].encode("utf-8")) service_type = s["type"] service_args = [arg.encode("utf-8") for arg in s["args"]] s = build_service(service_basedir, self.tub, service_type, service_args) s.setServiceParent(self) return s
class Failed(unittest.TestCase): def setUp(self): self.services = [] def tearDown(self): d = defer.DeferredList([s.stopService() for s in self.services]) d.addCallback(flushEventualQueue) return d @defer.inlineCallbacks 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") d = defer.Deferred() reactor.callLater(1.0, d.callback, None) yield d # 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"})
class TubFailures(ExamineFailuresMixin, ShouldFailMixin, unittest.TestCase): def setUp(self): self.s = service.MultiService() self.s.startService() self.target_tub = Tub() self.target_tub.setServiceParent(self.s) l = self.target_tub.listenOn("tcp:0:interface=127.0.0.1") self.target_tub.setLocation("127.0.0.1:%d" % l.getPortnum()) self.source_tub = Tub() self.source_tub.setServiceParent(self.s) def tearDown(self): return self.s.stopService() def setupTarget(self, target): furl = self.target_tub.registerReference(target) d = self.source_tub.getReference(furl) return d def test_raise_not_exposed(self): self.source_tub.setOption("expose-remote-exception-types", False) d = self.setupTarget(TargetWithoutInterfaces()) d.addCallback(lambda rr: self.shouldFail(RemoteException, "one", None, rr.callRemote, "fail")) d.addCallback(self._examine_raise, True) return d def test_raise_yes_exposed(self): self.source_tub.setOption("expose-remote-exception-types", True) d = self.setupTarget(TargetWithoutInterfaces()) d.addCallback(lambda rr: self.shouldFail(ValueError, "one", None, rr.callRemote, "fail")) d.addCallback(self._examine_raise, False) return d def test_raise_default(self): # current default is to expose exceptions. This may change in the # future. d = self.setupTarget(TargetWithoutInterfaces()) d.addCallback(lambda rr: self.shouldFail(ValueError, "one", None, rr.callRemote, "fail")) d.addCallback(self._examine_raise, False) return d
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