3 from twisted.trial import unittest
4 from twisted.application import service
5 from twisted.python import log
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
14 class FakeIntroducerClient(IntroducerClient):
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()
23 class Basic(unittest.TestCase):
24 def test_loadable(self):
25 basedir = "test_client.Basic.test_loadable"
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)
31 def test_loadable_without_vdrive(self):
32 basedir = "test_client.Basic.test_loadable_without_vdrive"
34 open(os.path.join(basedir, "introducer.furl"), "w").write("")
35 c = client.Client(basedir)
37 def test_loadable_old_config_bits(self):
38 basedir = "test_client.Basic.test_loadable_old_config_bits"
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)
47 c.getServiceNamed("storage")
48 self.fail("that was supposed to fail")
52 def test_loadable_old_storage_config_bits(self):
53 basedir = "test_client.Basic.test_loadable_old_storage_config_bits"
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)
64 def test_secrets(self):
65 basedir = "test_client.Basic.test_secrets"
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))
77 BASECONFIG = ("[client]\n"
78 "introducer.furl = \n"
81 def test_reserved_1(self):
82 basedir = "client.Basic.test_reserved_1"
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")
90 c = client.Client(basedir)
91 self.failUnlessEqual(c.getServiceNamed("storage").reserved_space, 1000)
93 def test_reserved_2(self):
94 basedir = "client.Basic.test_reserved_2"
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")
102 c = client.Client(basedir)
103 self.failUnlessEqual(c.getServiceNamed("storage").reserved_space, 10*1000)
105 def test_reserved_3(self):
106 basedir = "client.Basic.test_reserved_3"
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")
114 c = client.Client(basedir)
115 self.failUnlessEqual(c.getServiceNamed("storage").reserved_space,
118 def test_reserved_4(self):
119 basedir = "client.Basic.test_reserved_4"
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")
127 c = client.Client(basedir)
128 self.failUnlessEqual(c.getServiceNamed("storage").reserved_space,
131 def test_reserved_bad(self):
132 basedir = "client.Basic.test_reserved_bad"
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")
140 c = client.Client(basedir)
141 self.failUnlessEqual(c.getServiceNamed("storage").reserved_space, 0)
143 def _permute(self, c, key):
145 for (peerid,rref) in c.get_permuted_peers("storage", key) ]
147 def test_permute(self):
148 basedir = "test_client.Basic.test_permute"
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)
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"), [])
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'])
168 def test_versions(self):
169 basedir = "test_client.Basic.test_versions"
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)
185 stats = c.get_stats()
186 self.failUnless("node.uptime" in stats)
187 self.failUnless(isinstance(stats["node.uptime"], float))
189 def flush_but_dont_ignore(res):
190 d = flushEventualQueue()
196 class Run(unittest.TestCase, testutil.StallMixin):
199 self.sparent = service.MultiService()
200 self.sparent.startService()
202 d = self.sparent.stopService()
203 d.addBoth(flush_but_dont_ignore)
206 def test_loadable(self):
207 basedir = "test_client.Run.test_loadable"
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)
214 def test_reloadable(self):
215 basedir = "test_client.Run.test_reloadable"
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)
222 # delay to let the service start up completely. I'm not entirely sure
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)
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)