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