]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/test/test_client.py
versioning: include an "appname" in the application version string in the versioning...
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / test / test_client.py
1
2 import os
3 from twisted.trial import unittest
4 from twisted.application import service
5 from twisted.python import log
6
7 import allmydata
8 from allmydata import client
9 from allmydata.introducer.client import IntroducerClient
10 from allmydata.util import base32
11 from foolscap.eventual import flushEventualQueue
12 import common_util as testutil
13
14 class FakeIntroducerClient(IntroducerClient):
15     def __init__(self):
16         self._connections = set()
17     def add_peer(self, nodeid):
18         entry = (nodeid, "storage", "rref")
19         self._connections.add(entry)
20     def remove_all_peers(self):
21         self._connections.clear()
22
23 class Basic(unittest.TestCase):
24     def test_loadable(self):
25         basedir = "test_client.Basic.test_loadable"
26         os.mkdir(basedir)
27         open(os.path.join(basedir, "introducer.furl"), "w").write("")
28         open(os.path.join(basedir, "vdrive.furl"), "w").write("")
29         c = client.Client(basedir)
30
31     def test_loadable_without_vdrive(self):
32         basedir = "test_client.Basic.test_loadable_without_vdrive"
33         os.mkdir(basedir)
34         open(os.path.join(basedir, "introducer.furl"), "w").write("")
35         c = client.Client(basedir)
36
37     def test_loadable_old_config_bits(self):
38         basedir = "test_client.Basic.test_loadable_old_config_bits"
39         os.mkdir(basedir)
40         open(os.path.join(basedir, "introducer.furl"), "w").write("")
41         open(os.path.join(basedir, "vdrive.furl"), "w").write("")
42         open(os.path.join(basedir, "no_storage"), "w").write("")
43         open(os.path.join(basedir, "readonly_storage"), "w").write("")
44         open(os.path.join(basedir, "debug_discard_storage"), "w").write("")
45         c = client.Client(basedir)
46         try:
47             c.getServiceNamed("storage")
48             self.fail("that was supposed to fail")
49         except KeyError:
50             pass
51
52     def test_loadable_old_storage_config_bits(self):
53         basedir = "test_client.Basic.test_loadable_old_storage_config_bits"
54         os.mkdir(basedir)
55         open(os.path.join(basedir, "introducer.furl"), "w").write("")
56         open(os.path.join(basedir, "vdrive.furl"), "w").write("")
57         open(os.path.join(basedir, "readonly_storage"), "w").write("")
58         open(os.path.join(basedir, "debug_discard_storage"), "w").write("")
59         c = client.Client(basedir)
60         s = c.getServiceNamed("storage")
61         self.failUnless(s.no_storage)
62         self.failUnless(s.readonly_storage)
63
64     def test_secrets(self):
65         basedir = "test_client.Basic.test_secrets"
66         os.mkdir(basedir)
67         open(os.path.join(basedir, "introducer.furl"), "w").write("")
68         open(os.path.join(basedir, "vdrive.furl"), "w").write("")
69         c = client.Client(basedir)
70         secret_fname = os.path.join(basedir, "private", "secret")
71         self.failUnless(os.path.exists(secret_fname), secret_fname)
72         renew_secret = c.get_renewal_secret()
73         self.failUnless(base32.b2a(renew_secret))
74         cancel_secret = c.get_cancel_secret()
75         self.failUnless(base32.b2a(cancel_secret))
76
77     BASECONFIG = ("[client]\n"
78                   "introducer.furl = \n"
79                   )
80
81     def test_reserved_1(self):
82         basedir = "client.Basic.test_reserved_1"
83         os.mkdir(basedir)
84         f = open(os.path.join(basedir, "tahoe.cfg"), "w")
85         f.write(self.BASECONFIG)
86         f.write("[storage]\n")
87         f.write("enabled = true\n")
88         f.write("reserved_space = 1000\n")
89         f.close()
90         c = client.Client(basedir)
91         self.failUnlessEqual(c.getServiceNamed("storage").reserved_space, 1000)
92
93     def test_reserved_2(self):
94         basedir = "client.Basic.test_reserved_2"
95         os.mkdir(basedir)
96         f = open(os.path.join(basedir, "tahoe.cfg"), "w")
97         f.write(self.BASECONFIG)
98         f.write("[storage]\n")
99         f.write("enabled = true\n")
100         f.write("reserved_space = 10K\n")
101         f.close()
102         c = client.Client(basedir)
103         self.failUnlessEqual(c.getServiceNamed("storage").reserved_space, 10*1000)
104
105     def test_reserved_3(self):
106         basedir = "client.Basic.test_reserved_3"
107         os.mkdir(basedir)
108         f = open(os.path.join(basedir, "tahoe.cfg"), "w")
109         f.write(self.BASECONFIG)
110         f.write("[storage]\n")
111         f.write("enabled = true\n")
112         f.write("reserved_space = 5mB\n")
113         f.close()
114         c = client.Client(basedir)
115         self.failUnlessEqual(c.getServiceNamed("storage").reserved_space,
116                              5*1000*1000)
117
118     def test_reserved_4(self):
119         basedir = "client.Basic.test_reserved_4"
120         os.mkdir(basedir)
121         f = open(os.path.join(basedir, "tahoe.cfg"), "w")
122         f.write(self.BASECONFIG)
123         f.write("[storage]\n")
124         f.write("enabled = true\n")
125         f.write("reserved_space = 78Gb\n")
126         f.close()
127         c = client.Client(basedir)
128         self.failUnlessEqual(c.getServiceNamed("storage").reserved_space,
129                              78*1000*1000*1000)
130
131     def test_reserved_bad(self):
132         basedir = "client.Basic.test_reserved_bad"
133         os.mkdir(basedir)
134         f = open(os.path.join(basedir, "tahoe.cfg"), "w")
135         f.write(self.BASECONFIG)
136         f.write("[storage]\n")
137         f.write("enabled = true\n")
138         f.write("reserved_space = bogus\n")
139         f.close()
140         c = client.Client(basedir)
141         self.failUnlessEqual(c.getServiceNamed("storage").reserved_space, 0)
142
143     def _permute(self, c, key):
144         return [ peerid
145                  for (peerid,rref) in c.get_permuted_peers("storage", key) ]
146
147     def test_permute(self):
148         basedir = "test_client.Basic.test_permute"
149         os.mkdir(basedir)
150         open(os.path.join(basedir, "introducer.furl"), "w").write("")
151         open(os.path.join(basedir, "vdrive.furl"), "w").write("")
152         c = client.Client(basedir)
153         c.introducer_client = FakeIntroducerClient()
154         for k in ["%d" % i for i in range(5)]:
155             c.introducer_client.add_peer(k)
156
157         self.failUnlessEqual(self._permute(c, "one"), ['3','1','0','4','2'])
158         self.failUnlessEqual(self._permute(c, "two"), ['0','4','2','1','3'])
159         c.introducer_client.remove_all_peers()
160         self.failUnlessEqual(self._permute(c, "one"), [])
161
162         c2 = client.Client(basedir)
163         c2.introducer_client = FakeIntroducerClient()
164         for k in ["%d" % i for i in range(5)]:
165             c2.introducer_client.add_peer(k)
166         self.failUnlessEqual(self._permute(c2, "one"), ['3','1','0','4','2'])
167
168     def test_versions(self):
169         basedir = "test_client.Basic.test_versions"
170         os.mkdir(basedir)
171         open(os.path.join(basedir, "introducer.furl"), "w").write("")
172         open(os.path.join(basedir, "vdrive.furl"), "w").write("")
173         c = client.Client(basedir)
174         ss = c.getServiceNamed("storage")
175         verdict = ss.remote_get_version()
176         self.failUnlessEqual(verdict["application-version"],
177                              str(allmydata.__full_version__))
178         self.failIfEqual(str(allmydata.__version__), "unknown")
179         self.failUnless("." in str(allmydata.__full_version__),
180                         "non-numeric version in '%s'" % allmydata.__version__)
181         all_versions = allmydata.get_package_versions_string()
182         self.failUnless("allmydata-tahoe" in all_versions)
183         log.msg("tahoe versions: %s" % all_versions)
184         # also test stats
185         stats = c.get_stats()
186         self.failUnless("node.uptime" in stats)
187         self.failUnless(isinstance(stats["node.uptime"], float))
188
189 def flush_but_dont_ignore(res):
190     d = flushEventualQueue()
191     def _done(ignored):
192         return res
193     d.addCallback(_done)
194     return d
195
196 class Run(unittest.TestCase, testutil.StallMixin):
197
198     def setUp(self):
199         self.sparent = service.MultiService()
200         self.sparent.startService()
201     def tearDown(self):
202         d = self.sparent.stopService()
203         d.addBoth(flush_but_dont_ignore)
204         return d
205
206     def test_loadable(self):
207         basedir = "test_client.Run.test_loadable"
208         os.mkdir(basedir)
209         dummy = "pb://wl74cyahejagspqgy4x5ukrvfnevlknt@127.0.0.1:58889/bogus"
210         open(os.path.join(basedir, "introducer.furl"), "w").write(dummy)
211         open(os.path.join(basedir, "suicide_prevention_hotline"), "w")
212         c = client.Client(basedir)
213
214     def test_reloadable(self):
215         basedir = "test_client.Run.test_reloadable"
216         os.mkdir(basedir)
217         dummy = "pb://wl74cyahejagspqgy4x5ukrvfnevlknt@127.0.0.1:58889/bogus"
218         open(os.path.join(basedir, "introducer.furl"), "w").write(dummy)
219         c1 = client.Client(basedir)
220         c1.setServiceParent(self.sparent)
221
222         # delay to let the service start up completely. I'm not entirely sure
223         # this is necessary.
224         d = self.stall(delay=2.0)
225         d.addCallback(lambda res: c1.disownServiceParent())
226         # the cygwin buildslave seems to need more time to let the old
227         # service completely shut down. When delay=0.1, I saw this test fail,
228         # probably due to the logport trying to reclaim the old socket
229         # number. This suggests that either we're dropping a Deferred
230         # somewhere in the shutdown sequence, or that cygwin is just cranky.
231         d.addCallback(self.stall, delay=2.0)
232         def _restart(res):
233             # TODO: pause for slightly over one second, to let
234             # Client._check_hotline poll the file once. That will exercise
235             # another few lines. Then add another test in which we don't
236             # update the file at all, and watch to see the node shutdown. (to
237             # do this, use a modified node which overrides Node.shutdown(),
238             # also change _check_hotline to use it instead of a raw
239             # reactor.stop, also instrument the shutdown event in an
240             # attribute that we can check)
241             c2 = client.Client(basedir)
242             c2.setServiceParent(self.sparent)
243             return c2.disownServiceParent()
244         d.addCallback(_restart)
245         return d
246