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
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):
18 def get_encoding_parameters(self):
19 return {"k": 3, "n": 10}
20 def get_storage_broker(self):
22 def get_history(self):
24 _secret_holder = client.SecretHolder("lease secret")
26 class Node(unittest.TestCase):
27 def test_chk_filenode(self):
28 u = uri.CHKFileURI(key="\x00"*16,
29 uri_extension_hash="\x00"*32,
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)
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)
55 def test_literal_filenode(self):
56 DATA = "I am a short file."
57 u = uri.LiteralFileURI(data=DATA)
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)
73 d[fn1] = 1 # exercise __hash__
75 v = fn1.get_verify_cap()
76 self.failUnlessEqual(v, None)
77 self.failUnlessEqual(fn1.get_repair_cap(), None)
79 d = fn1.download(download.Data())
81 self.failUnlessEqual(res, DATA)
84 d.addCallback(lambda res: fn1.download_to_data())
87 d.addCallback(lambda res: download_to_data(fn1))
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)
97 def test_mutable_filenode(self):
101 rk = hashutil.ssk_readkey_hash(wk)
102 si = hashutil.ssk_storage_index_hash(rk)
104 u = uri.WriteableSSKFileURI("\x00"*16, "\x00"*32)
105 n = MutableFileNode(None, None, client.get_encoding_parameters(),
106 None).init_from_cap(u)
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)
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)
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)
133 nro = n.get_readonly()
134 self.failUnless(isinstance(nro, MutableFileNode))
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
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()
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)
156 d = fn1.check(Monitor())
157 def _check_checker_results(cr):
158 self.failUnlessEqual(cr, None)
159 d.addCallback(_check_checker_results)
161 d.addCallback(lambda res: fn1.check(Monitor(), verify=True))
162 d.addCallback(_check_checker_results)