]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/test/test_client.py
setup: finish switching from Tahoe's versions of autoversioning tools to pyutil's...
[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.internet import reactor, defer
6
7 import allmydata
8 from allmydata import client, introducer
9 from allmydata.util import idlib
10 from foolscap.eventual import flushEventualQueue
11
12 class FakeIntroducerClient(introducer.IntroducerClient):
13     def __init__(self):
14         self.connections = {}
15
16 def permute(c, key):
17     return [ y for x, y, z in c.get_permuted_peers(key) ]
18
19 class Basic(unittest.TestCase):
20     def test_loadable(self):
21         basedir = "test_client.Basic.test_loadable"
22         os.mkdir(basedir)
23         open(os.path.join(basedir, "introducer.furl"), "w").write("")
24         open(os.path.join(basedir, "vdrive.furl"), "w").write("")
25         c = client.Client(basedir)
26
27     def test_loadable_without_vdrive(self):
28         basedir = "test_client.Basic.test_loadable_without_vdrive"
29         os.mkdir(basedir)
30         open(os.path.join(basedir, "introducer.furl"), "w").write("")
31         c = client.Client(basedir)
32
33     def test_secrets(self):
34         basedir = "test_client.Basic.test_secrets"
35         os.mkdir(basedir)
36         open(os.path.join(basedir, "introducer.furl"), "w").write("")
37         open(os.path.join(basedir, "vdrive.furl"), "w").write("")
38         c = client.Client(basedir)
39         secret_fname = os.path.join(basedir, "private", "secret")
40         self.failUnless(os.path.exists(secret_fname), secret_fname)
41         renew_secret = c.get_renewal_secret()
42         self.failUnless(idlib.b2a(renew_secret))
43         cancel_secret = c.get_cancel_secret()
44         self.failUnless(idlib.b2a(cancel_secret))
45
46     def test_sizelimit_1(self):
47         basedir = "client.Basic.test_sizelimit_1"
48         os.mkdir(basedir)
49         open(os.path.join(basedir, "introducer.furl"), "w").write("")
50         open(os.path.join(basedir, "vdrive.furl"), "w").write("")
51         open(os.path.join(basedir, "sizelimit"), "w").write("1000")
52         c = client.Client(basedir)
53         self.failUnlessEqual(c.getServiceNamed("storageserver").sizelimit,
54                              1000)
55
56     def test_sizelimit_2(self):
57         basedir = "client.Basic.test_sizelimit_2"
58         os.mkdir(basedir)
59         open(os.path.join(basedir, "introducer.furl"), "w").write("")
60         open(os.path.join(basedir, "vdrive.furl"), "w").write("")
61         open(os.path.join(basedir, "sizelimit"), "w").write("10K")
62         c = client.Client(basedir)
63         self.failUnlessEqual(c.getServiceNamed("storageserver").sizelimit,
64                              10*1000)
65
66     def test_sizelimit_3(self):
67         basedir = "client.Basic.test_sizelimit_3"
68         os.mkdir(basedir)
69         open(os.path.join(basedir, "introducer.furl"), "w").write("")
70         open(os.path.join(basedir, "vdrive.furl"), "w").write("")
71         open(os.path.join(basedir, "sizelimit"), "w").write("5mB")
72         c = client.Client(basedir)
73         self.failUnlessEqual(c.getServiceNamed("storageserver").sizelimit,
74                              5*1000*1000)
75
76     def test_sizelimit_4(self):
77         basedir = "client.Basic.test_sizelimit_4"
78         os.mkdir(basedir)
79         open(os.path.join(basedir, "introducer.furl"), "w").write("")
80         open(os.path.join(basedir, "vdrive.furl"), "w").write("")
81         open(os.path.join(basedir, "sizelimit"), "w").write("78Gb")
82         c = client.Client(basedir)
83         self.failUnlessEqual(c.getServiceNamed("storageserver").sizelimit,
84                              78*1000*1000*1000)
85
86     def test_sizelimit_bad(self):
87         basedir = "client.Basic.test_sizelimit_bad"
88         os.mkdir(basedir)
89         open(os.path.join(basedir, "introducer.furl"), "w").write("")
90         open(os.path.join(basedir, "vdrive.furl"), "w").write("")
91         open(os.path.join(basedir, "sizelimit"), "w").write("bogus")
92         c = client.Client(basedir)
93         self.failUnlessEqual(c.getServiceNamed("storageserver").sizelimit,
94                              None)
95
96     def test_permute(self):
97         basedir = "test_client.Basic.test_permute"
98         os.mkdir(basedir)
99         open(os.path.join(basedir, "introducer.furl"), "w").write("")
100         open(os.path.join(basedir, "vdrive.furl"), "w").write("")
101         c = client.Client(basedir)
102         c.introducer_client = FakeIntroducerClient()
103         for k in ["%d" % i for i in range(5)]:
104             c.introducer_client.connections[k] = None
105         self.failUnlessEqual(permute(c, "one"), ['3','1','0','4','2'])
106         self.failUnlessEqual(permute(c, "two"), ['0','4','2','1','3'])
107         c.introducer_client.connections.clear()
108         self.failUnlessEqual(permute(c, "one"), [])
109
110         c2 = client.Client(basedir)
111         c2.introducer_client = FakeIntroducerClient()
112         for k in ["%d" % i for i in range(5)]:
113             c2.introducer_client.connections[k] = None
114         self.failUnlessEqual(permute(c2, "one"), ['3','1','0','4','2'])
115
116     def test_versions(self):
117         basedir = "test_client.Basic.test_versions"
118         os.mkdir(basedir)
119         open(os.path.join(basedir, "introducer.furl"), "w").write("")
120         open(os.path.join(basedir, "vdrive.furl"), "w").write("")
121         c = client.Client(basedir)
122         mine, oldest = c.remote_get_versions()
123         self.failUnlessEqual(mine, allmydata.__version__)
124
125 def flush_but_dont_ignore(res):
126     d = flushEventualQueue()
127     def _done(ignored):
128         return res
129     d.addCallback(_done)
130     return d
131
132 class Run(unittest.TestCase):
133
134     def setUp(self):
135         self.sparent = service.MultiService()
136         self.sparent.startService()
137     def tearDown(self):
138         d = self.sparent.stopService()
139         d.addBoth(flush_but_dont_ignore)
140         return d
141
142     def test_loadable(self):
143         basedir = "test_client.Run.test_loadable"
144         os.mkdir(basedir)
145         dummy = "pb://wl74cyahejagspqgy4x5ukrvfnevlknt@127.0.0.1:58889/bogus"
146         open(os.path.join(basedir, "introducer.furl"), "w").write(dummy)
147         open(os.path.join(basedir, "suicide_prevention_hotline"), "w")
148         c = client.Client(basedir)
149
150     def stall(self, res=None, delay=1):
151         d = defer.Deferred()
152         reactor.callLater(delay, d.callback, res)
153         return d
154
155     def test_reloadable(self):
156         basedir = "test_client.Run.test_reloadable"
157         os.mkdir(basedir)
158         dummy = "pb://wl74cyahejagspqgy4x5ukrvfnevlknt@127.0.0.1:58889/bogus"
159         open(os.path.join(basedir, "introducer.furl"), "w").write(dummy)
160         c1 = client.Client(basedir)
161         c1.setServiceParent(self.sparent)
162
163         # delay to let the service start up completely. I'm not entirely sure
164         # this is necessary.
165         d = self.stall(delay=2.0)
166         d.addCallback(lambda res: c1.disownServiceParent())
167         # the cygwin buildslave seems to need more time to let the old
168         # service completely shut down. When delay=0.1, I saw this test fail,
169         # probably due to the logport trying to reclaim the old socket
170         # number. This suggests that either we're dropping a Deferred
171         # somewhere in the shutdown sequence, or that cygwin is just cranky.
172         d.addCallback(self.stall, delay=2.0)
173         def _restart(res):
174             # TODO: pause for slightly over one second, to let
175             # Client._check_hotline poll the file once. That will exercise
176             # another few lines. Then add another test in which we don't
177             # update the file at all, and watch to see the node shutdown. (to
178             # do this, use a modified node which overrides Node.shutdown(),
179             # also change _check_hotline to use it instead of a raw
180             # reactor.stop, also instrument the shutdown event in an
181             # attribute that we can check)
182             c2 = client.Client(basedir)
183             c2.setServiceParent(self.sparent)
184             return c2.disownServiceParent()
185         d.addCallback(_restart)
186         return d
187