5 from twisted.internet import defer, reactor, protocol, error
6 from twisted.application import service
7 from allmydata import client, queen
8 from allmydata.scripts import runner
9 from foolscap.eventual import eventually, flushEventualQueue
10 from twisted.python import log
12 class SystemFramework:
15 def __init__(self, basedir):
16 self.basedir = basedir = os.path.abspath(basedir)
17 if not basedir.startswith(os.path.abspath(".")):
18 raise AssertionError("safety issue: basedir must be a subdir")
19 if os.path.exists(basedir):
20 shutil.rmtree(basedir)
22 self.sparent = service.MultiService()
23 self.sparent.startService()
26 log.startLogging(open(os.path.join(self.basedir, "log"), "w"))
28 eventually(d.callback, None)
29 d.addCallback(lambda res: self.start())
43 os.remove(os.path.join(self.clientdir, "suicide_prevention_hotline"))
44 # the client node will shut down in a few seconds
45 log.msg("shutting down SystemTest services")
46 d = self.sparent.stopService()
47 d.addCallback(lambda res: flushEventualQueue())
50 reactor.callLater(self.DISCONNECT_DELAY, d1.callback, None)
55 def add_service(self, s):
56 s.setServiceParent(self.sparent)
60 queendir = os.path.join(self.basedir, "queen")
62 self.queen = self.add_service(queen.Queen(basedir=queendir))
63 d = self.queen.when_tub_ready()
68 self.queen_pburl = q.urls["introducer"]
69 vdrive_furl = q.urls["vdrive"]
71 for i in range(self.numnodes):
72 nodedir = os.path.join(self.basedir, "node%d" % i)
74 f = open(os.path.join(nodedir, "introducer.furl"), "w")
75 f.write(self.queen_pburl)
77 f = open(os.path.join(nodedir, "vdrive.furl"), "w")
80 c = self.add_service(client.Client(basedir=nodedir))
82 # the peers will start running, eventually they will connect to each
85 def touch_keepalive(self):
86 f = open(self.keepalive_file, "w")
87 f.write("If the node notices this file at startup, it will poll and\n")
88 f.write("terminate as soon as the file goes away. This prevents\n")
89 f.write("leaving processes around if the test harness has an\n")
90 f.write("internal failure and neglects to kill off the node\n")
91 f.write("itself. The contents of this file are ignored.\n")
94 def start_client(self):
95 log.msg("MAKING CLIENT")
96 clientdir = self.clientdir = os.path.join(self.basedir, "client")
97 config = {'basedir': clientdir}
98 runner.create_client(config)
99 log.msg("DONE MAKING CLIENT")
100 f = open(os.path.join(clientdir, "introducer.furl"), "w")
101 f.write(self.queen_pburl + "\n")
103 self.keepalive_file = os.path.join(clientdir, "suicide_prevention_hotline")
104 self.touch_keepalive()
105 # now start updating the mtime.
108 cmd = ["twistd", "-y", "client.tac"]
109 env = os.environ.copy()
110 self.proc = reactor.spawnProcess(pp, cmd[0], cmd, env, path=clientdir)
111 log.msg("CLIENT STARTED")
113 def kill_client(self):
115 self.proc.signalProcess("KILL")
116 except error.ProcessExitedAlready:
120 class ClientWatcher(protocol.ProcessProtocol):
121 def outReceived(self, data):
123 def errReceived(self, data):
127 if __name__ == '__main__':
128 sf = SystemFramework("_test_memory")
132 # add a config option that looks for a keepalive file, and if it disappears,
133 # shut down the node.