]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/test/check_memory.py
change #!/usr/bin/python to #!/usr/bin/env python
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / test / check_memory.py
1 #! /usr/bin/env python
2
3 import os, shutil
4
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
11
12 class SystemFramework:
13     numnodes = 5
14
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)
21         os.mkdir(basedir)
22         self.sparent = service.MultiService()
23         self.sparent.startService()
24
25     def run(self):
26         log.startLogging(open(os.path.join(self.basedir, "log"), "w"))
27         d = defer.Deferred()
28         eventually(d.callback, None)
29         d.addCallback(lambda res: self.start())
30         d.addErrback(log.err)
31         reactor.run()
32
33     def start(self):
34         print "STARTING"
35         d = self.make_queen()
36         def _more(res):
37             self.make_nodes()
38             self.start_client()
39         d.addCallback(_more)
40         return d
41
42     def tearDown(self):
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())
48         def _done(res):
49             d1 = defer.Deferred()
50             reactor.callLater(self.DISCONNECT_DELAY, d1.callback, None)
51             return d1
52         d.addCallback(_done)
53         return d
54
55     def add_service(self, s):
56         s.setServiceParent(self.sparent)
57         return s
58
59     def make_queen(self):
60         queendir = os.path.join(self.basedir, "queen")
61         os.mkdir(queendir)
62         self.queen = self.add_service(queen.Queen(basedir=queendir))
63         d = self.queen.when_tub_ready()
64         return d
65
66     def make_nodes(self):
67         q = self.queen
68         self.queen_pburl = q.urls["introducer"]
69         vdrive_furl = q.urls["vdrive"]
70         self.nodes = []
71         for i in range(self.numnodes):
72             nodedir = os.path.join(self.basedir, "node%d" % i)
73             os.mkdir(nodedir)
74             f = open(os.path.join(nodedir, "introducer.furl"), "w")
75             f.write(self.queen_pburl)
76             f.close()
77             f = open(os.path.join(nodedir, "vdrive.furl"), "w")
78             f.write(vdrive_furl)
79             f.close()
80             c = self.add_service(client.Client(basedir=nodedir))
81             self.nodes.append(c)
82         # the peers will start running, eventually they will connect to each
83         # other and the queen
84
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")
92         f.close()
93
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")
102         f.close()
103         self.keepalive_file = os.path.join(clientdir, "suicide_prevention_hotline")
104         self.touch_keepalive()
105         # now start updating the mtime.
106
107         pp = ClientWatcher()
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")
112
113     def kill_client(self):
114         try:
115             self.proc.signalProcess("KILL")
116         except error.ProcessExitedAlready:
117             pass
118
119
120 class ClientWatcher(protocol.ProcessProtocol):
121     def outReceived(self, data):
122         print "OUT:", data
123     def errReceived(self, data):
124         print "ERR:", data
125
126
127 if __name__ == '__main__':
128     sf = SystemFramework("_test_memory")
129     sf.run()
130
131
132 # add a config option that looks for a keepalive file, and if it disappears,
133 # shut down the node.