2 from twisted.trial import unittest
3 from allmydata import uri
4 from allmydata.util import hashutil, base32
5 from allmydata.interfaces import IURI, IFileURI, IDirnodeURI, IMutableFileURI, \
8 class Literal(unittest.TestCase):
9 def _help_test(self, data):
10 u = uri.LiteralFileURI(data)
11 self.failUnless(IURI.providedBy(u))
12 self.failUnless(IFileURI.providedBy(u))
13 self.failIf(IDirnodeURI.providedBy(u))
14 self.failUnlessEqual(u.data, data)
15 self.failUnlessEqual(u.get_size(), len(data))
16 self.failUnless(u.is_readonly())
17 self.failIf(u.is_mutable())
19 u2 = uri.from_string(u.to_string())
20 self.failUnless(IURI.providedBy(u2))
21 self.failUnless(IFileURI.providedBy(u2))
22 self.failIf(IDirnodeURI.providedBy(u2))
23 self.failUnlessEqual(u2.data, data)
24 self.failUnlessEqual(u2.get_size(), len(data))
25 self.failUnless(u.is_readonly())
26 self.failIf(u.is_mutable())
29 self.failUnlessIdentical(u, u3)
30 self.failUnlessEqual(u.get_verify_cap(), None)
32 he = u.to_human_encoding()
33 u_h = uri.LiteralFileURI.init_from_human_encoding(he)
34 self.failUnlessEqual(u, u_h)
37 data = "" # This data is some *very* small data!
38 return self._help_test(data)
41 data = "This is some small data"
42 return self._help_test(data)
44 def test_nonascii(self):
45 data = "This contains \x00 and URI:LIT: and \n, oh my."
46 return self._help_test(data)
48 class Compare(unittest.TestCase):
49 def test_compare(self):
50 lit1 = uri.LiteralFileURI("some data")
51 fileURI = 'URI:CHK:f5ahxa25t4qkktywz6teyfvcx4:opuioq7tj2y6idzfp6cazehtmgs5fdcebcz3cygrxyydvcozrmeq:3:10:345834'
52 chk1 = uri.CHKFileURI.init_from_string(fileURI)
53 chk2 = uri.CHKFileURI.init_from_string(fileURI)
54 self.failIfEqual(lit1, chk1)
55 self.failUnlessEqual(chk1, chk2)
56 self.failIfEqual(chk1, "not actually a URI")
57 # these should be hashable too
58 s = set([lit1, chk1, chk2])
59 self.failUnlessEqual(len(s), 2) # since chk1==chk2
61 def test_is_uri(self):
62 lit1 = uri.LiteralFileURI("some data").to_string()
63 self.failUnless(uri.is_uri(lit1))
64 self.failIf(uri.is_uri(None))
66 class CHKFile(unittest.TestCase):
68 key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
69 storage_index = hashutil.storage_index_hash(key)
70 uri_extension_hash = hashutil.uri_extension_hash("stuff")
74 u = uri.CHKFileURI(key=key,
75 uri_extension_hash=uri_extension_hash,
76 needed_shares=needed_shares,
77 total_shares=total_shares,
79 self.failUnlessEqual(u.storage_index, storage_index)
80 self.failUnlessEqual(u.key, key)
81 self.failUnlessEqual(u.uri_extension_hash, uri_extension_hash)
82 self.failUnlessEqual(u.needed_shares, needed_shares)
83 self.failUnlessEqual(u.total_shares, total_shares)
84 self.failUnlessEqual(u.size, size)
85 self.failUnless(u.is_readonly())
86 self.failIf(u.is_mutable())
87 self.failUnless(IURI.providedBy(u))
88 self.failUnless(IFileURI.providedBy(u))
89 self.failIf(IDirnodeURI.providedBy(u))
90 self.failUnlessEqual(u.get_size(), 1234)
91 self.failUnless(u.is_readonly())
92 self.failIf(u.is_mutable())
93 u_ro = u.get_readonly()
94 self.failUnlessIdentical(u, u_ro)
95 he = u.to_human_encoding()
96 self.failUnlessEqual(he, "http://127.0.0.1:3456/uri/" + u.to_string())
97 self.failUnlessEqual(uri.CHKFileURI.init_from_human_encoding(he), u)
99 u2 = uri.from_string(u.to_string())
100 self.failUnlessEqual(u2.storage_index, storage_index)
101 self.failUnlessEqual(u2.key, key)
102 self.failUnlessEqual(u2.uri_extension_hash, uri_extension_hash)
103 self.failUnlessEqual(u2.needed_shares, needed_shares)
104 self.failUnlessEqual(u2.total_shares, total_shares)
105 self.failUnlessEqual(u2.size, size)
106 self.failUnless(u2.is_readonly())
107 self.failIf(u2.is_mutable())
108 self.failUnless(IURI.providedBy(u2))
109 self.failUnless(IFileURI.providedBy(u2))
110 self.failIf(IDirnodeURI.providedBy(u2))
111 self.failUnlessEqual(u2.get_size(), 1234)
112 self.failUnless(u2.is_readonly())
113 self.failIf(u2.is_mutable())
115 v = u.get_verify_cap()
116 self.failUnless(isinstance(v.to_string(), str))
117 v2 = uri.from_string(v.to_string())
118 self.failUnlessEqual(v, v2)
119 he = v.to_human_encoding()
120 v2_h = uri.CHKFileVerifierURI.init_from_human_encoding(he)
121 self.failUnlessEqual(v2, v2_h)
123 v3 = uri.CHKFileVerifierURI(storage_index="\x00"*16,
124 uri_extension_hash="\x00"*32,
128 self.failUnless(isinstance(v3.to_string(), str))
130 def test_pack_badly(self):
131 key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
132 storage_index = hashutil.storage_index_hash(key)
133 uri_extension_hash = hashutil.uri_extension_hash("stuff")
137 self.failUnlessRaises(TypeError,
140 uri_extension_hash=uri_extension_hash,
141 needed_shares=needed_shares,
142 total_shares=total_shares,
145 bogus_extra_argument="reject me",
147 self.failUnlessRaises(TypeError,
148 uri.CHKFileVerifierURI,
150 self.failUnlessRaises(TypeError,
151 uri.CHKFileVerifierURI,
152 storage_index=storage_index,
153 uri_extension_hash=uri_extension_hash,
156 # leave size= missing
160 class Extension(unittest.TestCase):
162 data = {"stuff": "value",
165 "big_hash": hashutil.tagged_hash("foo", "bar"),
167 ext = uri.pack_extension(data)
168 d = uri.unpack_extension(ext)
169 self.failUnlessEqual(d["stuff"], "value")
170 self.failUnlessEqual(d["size"], 12)
171 self.failUnlessEqual(d["big_hash"], hashutil.tagged_hash("foo", "bar"))
173 readable = uri.unpack_extension_readable(ext)
174 self.failUnlessEqual(readable["needed_shares"], 3)
175 self.failUnlessEqual(readable["stuff"], "value")
176 self.failUnlessEqual(readable["size"], 12)
177 self.failUnlessEqual(readable["big_hash"],
178 base32.b2a(hashutil.tagged_hash("foo", "bar")))
179 self.failUnlessEqual(readable["UEB_hash"],
180 base32.b2a(hashutil.uri_extension_hash(ext)))
182 class Invalid(unittest.TestCase):
183 def test_from_future(self):
184 # any URI type that we don't recognize should be treated as unknown
185 future_uri = "I am a URI from the future. Whatever you do, don't "
186 u = uri.from_string(future_uri)
187 self.failUnless(isinstance(u, uri.UnknownURI))
188 self.failUnlessEqual(u.to_string(), future_uri)
190 class Constraint(unittest.TestCase):
191 def test_constraint(self):
192 good="http://127.0.0.1:3456/uri/URI%3ADIR2%3Agh3l5rbvnv2333mrfvalmjfr4i%3Alz6l7u3z3b7g37s4zkdmfpx5ly4ib4m6thrpbusi6ys62qtc6mma/"
193 uri.DirectoryURI.init_from_human_encoding(good)
194 self.failUnlessRaises(uri.BadURIError, uri.DirectoryURI.init_from_string, good)
196 self.failUnlessRaises(uri.BadURIError, uri.DirectoryURI.init_from_human_encoding, bad)
197 self.failUnlessRaises(uri.BadURIError, uri.DirectoryURI.init_from_string, bad)
198 fileURI = 'URI:CHK:gh3l5rbvnv2333mrfvalmjfr4i:lz6l7u3z3b7g37s4zkdmfpx5ly4ib4m6thrpbusi6ys62qtc6mma:3:10:345834'
199 uri.CHKFileURI.init_from_string(fileURI)
201 class Mutable(unittest.TestCase):
203 writekey = "\x01" * 16
204 fingerprint = "\x02" * 32
206 u = uri.WriteableSSKFileURI(writekey, fingerprint)
207 self.failUnlessEqual(u.writekey, writekey)
208 self.failUnlessEqual(u.fingerprint, fingerprint)
209 self.failIf(u.is_readonly())
210 self.failUnless(u.is_mutable())
211 self.failUnless(IURI.providedBy(u))
212 self.failUnless(IMutableFileURI.providedBy(u))
213 self.failIf(IDirnodeURI.providedBy(u))
214 self.failUnless("WriteableSSKFileURI" in str(u))
216 he = u.to_human_encoding()
217 u_h = uri.WriteableSSKFileURI.init_from_human_encoding(he)
218 self.failUnlessEqual(u, u_h)
220 u2 = uri.from_string(u.to_string())
221 self.failUnlessEqual(u2.writekey, writekey)
222 self.failUnlessEqual(u2.fingerprint, fingerprint)
223 self.failIf(u2.is_readonly())
224 self.failUnless(u2.is_mutable())
225 self.failUnless(IURI.providedBy(u2))
226 self.failUnless(IMutableFileURI.providedBy(u2))
227 self.failIf(IDirnodeURI.providedBy(u2))
229 u3 = u2.get_readonly()
230 readkey = hashutil.ssk_readkey_hash(writekey)
231 self.failUnlessEqual(u3.fingerprint, fingerprint)
232 self.failUnlessEqual(u3.readkey, readkey)
233 self.failUnless(u3.is_readonly())
234 self.failUnless(u3.is_mutable())
235 self.failUnless(IURI.providedBy(u3))
236 self.failUnless(IMutableFileURI.providedBy(u3))
237 self.failIf(IDirnodeURI.providedBy(u3))
239 he = u3.to_human_encoding()
240 u3_h = uri.ReadonlySSKFileURI.init_from_human_encoding(he)
241 self.failUnlessEqual(u3, u3_h)
243 u4 = uri.ReadonlySSKFileURI(readkey, fingerprint)
244 self.failUnlessEqual(u4.fingerprint, fingerprint)
245 self.failUnlessEqual(u4.readkey, readkey)
246 self.failUnless(u4.is_readonly())
247 self.failUnless(u4.is_mutable())
248 self.failUnless(IURI.providedBy(u4))
249 self.failUnless(IMutableFileURI.providedBy(u4))
250 self.failIf(IDirnodeURI.providedBy(u4))
252 u4a = uri.from_string(u4.to_string())
253 self.failUnlessEqual(u4a, u4)
254 self.failUnless("ReadonlySSKFileURI" in str(u4a))
255 self.failUnlessIdentical(u4a.get_readonly(), u4a)
257 u5 = u4.get_verify_cap()
258 self.failUnless(IVerifierURI.providedBy(u5))
259 self.failUnlessEqual(u5.storage_index, u.storage_index)
260 u7 = u.get_verify_cap()
261 self.failUnless(IVerifierURI.providedBy(u7))
262 self.failUnlessEqual(u7.storage_index, u.storage_index)
264 he = u5.to_human_encoding()
265 u5_h = uri.SSKVerifierURI.init_from_human_encoding(he)
266 self.failUnlessEqual(u5, u5_h)
269 class Dirnode(unittest.TestCase):
271 writekey = "\x01" * 16
272 fingerprint = "\x02" * 32
274 n = uri.WriteableSSKFileURI(writekey, fingerprint)
275 u1 = uri.DirectoryURI(n)
276 self.failIf(u1.is_readonly())
277 self.failUnless(u1.is_mutable())
278 self.failUnless(IURI.providedBy(u1))
279 self.failIf(IFileURI.providedBy(u1))
280 self.failUnless(IDirnodeURI.providedBy(u1))
281 self.failUnless("DirectoryURI" in str(u1))
282 u1_filenode = u1.get_filenode_cap()
283 self.failUnless(u1_filenode.is_mutable())
284 self.failIf(u1_filenode.is_readonly())
286 u2 = uri.from_string(u1.to_string())
287 self.failUnlessEqual(u1.to_string(), u2.to_string())
288 self.failIf(u2.is_readonly())
289 self.failUnless(u2.is_mutable())
290 self.failUnless(IURI.providedBy(u2))
291 self.failIf(IFileURI.providedBy(u2))
292 self.failUnless(IDirnodeURI.providedBy(u2))
294 u3 = u2.get_readonly()
295 self.failUnless(u3.is_readonly())
296 self.failUnless(u3.is_mutable())
297 self.failUnless(IURI.providedBy(u3))
298 self.failIf(IFileURI.providedBy(u3))
299 self.failUnless(IDirnodeURI.providedBy(u3))
300 u3n = u3._filenode_uri
301 self.failUnless(u3n.is_readonly())
302 self.failUnless(u3n.is_mutable())
303 u3_filenode = u3.get_filenode_cap()
304 self.failUnless(u3_filenode.is_mutable())
305 self.failUnless(u3_filenode.is_readonly())
307 u3a = uri.from_string(u3.to_string())
308 self.failUnlessIdentical(u3a, u3a.get_readonly())
310 u4 = uri.ReadonlyDirectoryURI(u2._filenode_uri.get_readonly())
311 self.failUnlessEqual(u4.to_string(), u3.to_string())
312 self.failUnless(u4.is_readonly())
313 self.failUnless(u4.is_mutable())
314 self.failUnless(IURI.providedBy(u4))
315 self.failIf(IFileURI.providedBy(u4))
316 self.failUnless(IDirnodeURI.providedBy(u4))
318 u4_verifier = u4.get_verify_cap()
319 u4_verifier_filenode = u4_verifier.get_filenode_cap()
320 self.failUnless(isinstance(u4_verifier_filenode, uri.SSKVerifierURI))
322 verifiers = [u1.get_verify_cap(), u2.get_verify_cap(),
323 u3.get_verify_cap(), u4.get_verify_cap(),
324 uri.DirectoryURIVerifier(n.get_verify_cap()),
327 self.failUnless(IVerifierURI.providedBy(v))
328 self.failUnlessEqual(v._filenode_uri,
329 u1.get_verify_cap()._filenode_uri)
331 def test_immutable(self):
332 readkey = "\x01" * 16
333 uri_extension_hash = hashutil.uri_extension_hash("stuff")
338 fnuri = uri.CHKFileURI(key=readkey,
339 uri_extension_hash=uri_extension_hash,
340 needed_shares=needed_shares,
341 total_shares=total_shares,
343 fncap = fnuri.to_string()
344 self.failUnlessEqual(fncap, "URI:CHK:aeaqcaibaeaqcaibaeaqcaibae:nf3nimquen7aeqm36ekgxomalstenpkvsdmf6fplj7swdatbv5oa:3:10:1234")
345 u1 = uri.ImmutableDirectoryURI(fnuri)
346 self.failUnless(u1.is_readonly())
347 self.failIf(u1.is_mutable())
348 self.failUnless(IURI.providedBy(u1))
349 self.failIf(IFileURI.providedBy(u1))
350 self.failUnless(IDirnodeURI.providedBy(u1))
351 self.failUnless("DirectoryURI" in str(u1))
352 u1_filenode = u1.get_filenode_cap()
353 self.failIf(u1_filenode.is_mutable())
354 self.failUnless(u1_filenode.is_readonly())
355 self.failUnlessEqual(u1_filenode.to_string(), fncap)
356 self.failUnless(str(u1))
358 u2 = uri.from_string(u1.to_string())
359 self.failUnlessEqual(u1.to_string(), u2.to_string())
360 self.failUnless(u2.is_readonly())
361 self.failIf(u2.is_mutable())
362 self.failUnless(IURI.providedBy(u2))
363 self.failIf(IFileURI.providedBy(u2))
364 self.failUnless(IDirnodeURI.providedBy(u2))
366 u3 = u2.get_readonly()
367 self.failUnlessEqual(u3.to_string(), u2.to_string())
368 self.failUnless(str(u3))
370 u2_verifier = u2.get_verify_cap()
371 self.failUnless(isinstance(u2_verifier,
372 uri.ImmutableDirectoryURIVerifier),
374 self.failUnless(IVerifierURI.providedBy(u2_verifier))
375 u2vs = u2_verifier.to_string()
376 # URI:DIR2-CHK-Verifier:$key:$ueb:$k:$n:$size
377 self.failUnless(u2vs.startswith("URI:DIR2-CHK-Verifier:"), u2vs)
378 u2_verifier_fileuri = u2_verifier.get_filenode_cap()
379 self.failUnless(IVerifierURI.providedBy(u2_verifier_fileuri))
380 u2vfs = u2_verifier_fileuri.to_string()
381 # URI:CHK-Verifier:$key:$ueb:$k:$n:$size
382 self.failUnlessEqual(u2vfs, fnuri.get_verify_cap().to_string())
383 self.failUnlessEqual(u2vs[len("URI:DIR2-"):], u2vfs[len("URI:"):])
384 self.failUnless(str(u2_verifier))
386 def test_literal(self):
387 u0 = uri.LiteralFileURI("data")
388 u1 = uri.LiteralDirectoryURI(u0)
389 self.failUnless(str(u1))
390 self.failUnlessEqual(u1.to_string(), "URI:DIR2-LIT:mrqxiyi")
391 self.failUnless(u1.is_readonly())
392 self.failIf(u1.is_mutable())
393 self.failUnless(IURI.providedBy(u1))
394 self.failIf(IFileURI.providedBy(u1))
395 self.failUnless(IDirnodeURI.providedBy(u1))
396 self.failUnlessEqual(u1.get_verify_cap(), None)