]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/test/test_filenode.py
immutable/literal.py: Implement interface changes in literal nodes.
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / test / test_filenode.py
1
2 from twisted.trial import unittest
3 from allmydata import uri, client
4 from allmydata.monitor import Monitor
5 from allmydata.immutable.literal import LiteralFileNode
6 from allmydata.immutable.filenode import ImmutableFileNode
7 from allmydata.mutable.filenode import MutableFileNode
8 from allmydata.util import hashutil
9 from allmydata.util.consumer import download_to_data
10
11 class NotANode:
12     pass
13
14 class FakeClient:
15     # just enough to let the node acquire a downloader (which it won't use),
16     # and to get default encoding parameters
17     def getServiceNamed(self, name):
18         return None
19     def get_encoding_parameters(self):
20         return {"k": 3, "n": 10}
21     def get_storage_broker(self):
22         return None
23     def get_history(self):
24         return None
25     _secret_holder = client.SecretHolder("lease secret", "convergence secret")
26
27 class Node(unittest.TestCase):
28     def test_chk_filenode(self):
29         u = uri.CHKFileURI(key="\x00"*16,
30                            uri_extension_hash="\x00"*32,
31                            needed_shares=3,
32                            total_shares=10,
33                            size=1000)
34         fn1 = ImmutableFileNode(u, None, None, None, None)
35         fn2 = ImmutableFileNode(u, None, None, None, None)
36         self.failUnlessEqual(fn1, fn2)
37         self.failIfEqual(fn1, "I am not a filenode")
38         self.failIfEqual(fn1, NotANode())
39         self.failUnlessEqual(fn1.get_uri(), u.to_string())
40         self.failUnlessEqual(fn1.get_cap(), u)
41         self.failUnlessEqual(fn1.get_readcap(), u)
42         self.failUnless(fn1.is_readonly())
43         self.failIf(fn1.is_mutable())
44         self.failIf(fn1.is_unknown())
45         self.failUnless(fn1.is_allowed_in_immutable_directory())
46         self.failUnlessEqual(fn1.get_write_uri(), None)
47         self.failUnlessEqual(fn1.get_readonly_uri(), u.to_string())
48         self.failUnlessEqual(fn1.get_size(), 1000)
49         self.failUnlessEqual(fn1.get_storage_index(), u.get_storage_index())
50         fn1.raise_error()
51         fn2.raise_error()
52         d = {}
53         d[fn1] = 1 # exercise __hash__
54         v = fn1.get_verify_cap()
55         self.failUnless(isinstance(v, uri.CHKFileVerifierURI))
56         self.failUnlessEqual(fn1.get_repair_cap(), v)
57         self.failUnless(v.is_readonly())
58         self.failIf(v.is_mutable())
59
60
61     def test_literal_filenode(self):
62         DATA = "I am a short file."
63         u = uri.LiteralFileURI(data=DATA)
64         fn1 = LiteralFileNode(u)
65         fn2 = LiteralFileNode(u)
66         self.failUnlessEqual(fn1, fn2)
67         self.failIfEqual(fn1, "I am not a filenode")
68         self.failIfEqual(fn1, NotANode())
69         self.failUnlessEqual(fn1.get_uri(), u.to_string())
70         self.failUnlessEqual(fn1.get_cap(), u)
71         self.failUnlessEqual(fn1.get_readcap(), u)
72         self.failUnless(fn1.is_readonly())
73         self.failIf(fn1.is_mutable())
74         self.failIf(fn1.is_unknown())
75         self.failUnless(fn1.is_allowed_in_immutable_directory())
76         self.failUnlessEqual(fn1.get_write_uri(), None)
77         self.failUnlessEqual(fn1.get_readonly_uri(), u.to_string())
78         self.failUnlessEqual(fn1.get_size(), len(DATA))
79         self.failUnlessEqual(fn1.get_storage_index(), None)
80         fn1.raise_error()
81         fn2.raise_error()
82         d = {}
83         d[fn1] = 1 # exercise __hash__
84
85         v = fn1.get_verify_cap()
86         self.failUnlessEqual(v, None)
87         self.failUnlessEqual(fn1.get_repair_cap(), None)
88
89         d = download_to_data(fn1)
90         def _check(res):
91             self.failUnlessEqual(res, DATA)
92         d.addCallback(_check)
93
94         d.addCallback(lambda res: download_to_data(fn1, 1, 5))
95         def _check_segment(res):
96             self.failUnlessEqual(res, DATA[1:1+5])
97         d.addCallback(_check_segment)
98         d.addCallback(lambda ignored: fn1.get_best_readable_version())
99         d.addCallback(lambda fn2: self.failUnlessEqual(fn1, fn2))
100         d.addCallback(lambda ignored:
101             fn1.get_size_of_best_version())
102         d.addCallback(lambda size:
103             self.failUnlessEqual(size, len(DATA)))
104         d.addCallback(lambda ignored:
105             fn1.download_to_data())
106         d.addCallback(lambda data:
107             self.failUnlessEqual(data, DATA))
108         d.addCallback(lambda ignored:
109             fn1.download_best_version())
110         d.addCallback(lambda data:
111             self.failUnlessEqual(data, DATA))
112
113         return d
114
115     def test_mutable_filenode(self):
116         client = FakeClient()
117         wk = "\x00"*16
118         rk = hashutil.ssk_readkey_hash(wk)
119         si = hashutil.ssk_storage_index_hash(rk)
120
121         u = uri.WriteableSSKFileURI("\x00"*16, "\x00"*32)
122         n = MutableFileNode(None, None, client.get_encoding_parameters(),
123                             None).init_from_cap(u)
124
125         self.failUnlessEqual(n.get_writekey(), wk)
126         self.failUnlessEqual(n.get_readkey(), rk)
127         self.failUnlessEqual(n.get_storage_index(), si)
128         # these items are populated on first read (or create), so until that
129         # happens they'll be None
130         self.failUnlessEqual(n.get_privkey(), None)
131         self.failUnlessEqual(n.get_encprivkey(), None)
132         self.failUnlessEqual(n.get_pubkey(), None)
133
134         self.failUnlessEqual(n.get_uri(), u.to_string())
135         self.failUnlessEqual(n.get_write_uri(), u.to_string())
136         self.failUnlessEqual(n.get_readonly_uri(), u.get_readonly().to_string())
137         self.failUnlessEqual(n.get_cap(), u)
138         self.failUnlessEqual(n.get_readcap(), u.get_readonly())
139         self.failUnless(n.is_mutable())
140         self.failIf(n.is_readonly())
141         self.failIf(n.is_unknown())
142         self.failIf(n.is_allowed_in_immutable_directory())
143         n.raise_error()
144
145         n2 = MutableFileNode(None, None, client.get_encoding_parameters(),
146                              None).init_from_cap(u)
147         self.failUnlessEqual(n, n2)
148         self.failIfEqual(n, "not even the right type")
149         self.failIfEqual(n, u) # not the right class
150         n.raise_error()
151         d = {n: "can these be used as dictionary keys?"}
152         d[n2] = "replace the old one"
153         self.failUnlessEqual(len(d), 1)
154
155         nro = n.get_readonly()
156         self.failUnless(isinstance(nro, MutableFileNode))
157
158         self.failUnlessEqual(nro.get_readonly(), nro)
159         self.failUnlessEqual(nro.get_cap(), u.get_readonly())
160         self.failUnlessEqual(nro.get_readcap(), u.get_readonly())
161         self.failUnless(nro.is_mutable())
162         self.failUnless(nro.is_readonly())
163         self.failIf(nro.is_unknown())
164         self.failIf(nro.is_allowed_in_immutable_directory())
165         nro_u = nro.get_uri()
166         self.failUnlessEqual(nro_u, nro.get_readonly_uri())
167         self.failUnlessEqual(nro_u, u.get_readonly().to_string())
168         self.failUnlessEqual(nro.get_write_uri(), None)
169         self.failUnlessEqual(nro.get_repair_cap(), None) # RSAmut needs writecap
170         nro.raise_error()
171
172         v = n.get_verify_cap()
173         self.failUnless(isinstance(v, uri.SSKVerifierURI))
174         self.failUnlessEqual(n.get_repair_cap(), n._uri) # TODO: n.get_uri()
175
176 class LiteralChecker(unittest.TestCase):
177     def test_literal_filenode(self):
178         DATA = "I am a short file."
179         u = uri.LiteralFileURI(data=DATA)
180         fn1 = LiteralFileNode(u)
181
182         d = fn1.check(Monitor())
183         def _check_checker_results(cr):
184             self.failUnlessEqual(cr, None)
185         d.addCallback(_check_checker_results)
186
187         d.addCallback(lambda res: fn1.check(Monitor(), verify=True))
188         d.addCallback(_check_checker_results)
189
190         return d