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, \
6 IVerifierURI, CapConstraintError
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(u2.is_readonly())
26 self.failIf(u2.is_mutable())
28 u2i = uri.from_string(u.to_string(), deep_immutable=True)
29 self.failUnless(IFileURI.providedBy(u2i))
30 self.failIf(IDirnodeURI.providedBy(u2i))
31 self.failUnlessEqual(u2i.data, data)
32 self.failUnlessEqual(u2i.get_size(), len(data))
33 self.failUnless(u2i.is_readonly())
34 self.failIf(u2i.is_mutable())
37 self.failUnlessIdentical(u, u3)
38 self.failUnlessEqual(u.get_verify_cap(), None)
40 he = u.to_human_encoding()
41 u_h = uri.LiteralFileURI.init_from_human_encoding(he)
42 self.failUnlessEqual(u, u_h)
45 data = "" # This data is some *very* small data!
46 return self._help_test(data)
49 data = "This is some small data"
50 return self._help_test(data)
52 def test_nonascii(self):
53 data = "This contains \x00 and URI:LIT: and \n, oh my."
54 return self._help_test(data)
56 class Compare(unittest.TestCase):
57 def test_compare(self):
58 lit1 = uri.LiteralFileURI("some data")
59 fileURI = 'URI:CHK:f5ahxa25t4qkktywz6teyfvcx4:opuioq7tj2y6idzfp6cazehtmgs5fdcebcz3cygrxyydvcozrmeq:3:10:345834'
60 chk1 = uri.CHKFileURI.init_from_string(fileURI)
61 chk2 = uri.CHKFileURI.init_from_string(fileURI)
62 unk = uri.UnknownURI("lafs://from_the_future")
63 self.failIfEqual(lit1, chk1)
64 self.failUnlessEqual(chk1, chk2)
65 self.failIfEqual(chk1, "not actually a URI")
66 # these should be hashable too
67 s = set([lit1, chk1, chk2, unk])
68 self.failUnlessEqual(len(s), 3) # since chk1==chk2
70 def test_is_uri(self):
71 lit1 = uri.LiteralFileURI("some data").to_string()
72 self.failUnless(uri.is_uri(lit1))
73 self.failIf(uri.is_uri(None))
75 def test_is_literal_file_uri(self):
76 lit1 = uri.LiteralFileURI("some data").to_string()
77 self.failUnless(uri.is_literal_file_uri(lit1))
78 self.failIf(uri.is_literal_file_uri(None))
79 self.failIf(uri.is_literal_file_uri("foo"))
80 self.failIf(uri.is_literal_file_uri("ro.foo"))
81 self.failIf(uri.is_literal_file_uri("URI:LITfoo"))
82 self.failUnless(uri.is_literal_file_uri("ro.URI:LIT:foo"))
83 self.failUnless(uri.is_literal_file_uri("imm.URI:LIT:foo"))
85 def test_has_uri_prefix(self):
86 self.failUnless(uri.has_uri_prefix("URI:foo"))
87 self.failUnless(uri.has_uri_prefix("ro.URI:foo"))
88 self.failUnless(uri.has_uri_prefix("imm.URI:foo"))
89 self.failIf(uri.has_uri_prefix(None))
90 self.failIf(uri.has_uri_prefix("foo"))
92 class CHKFile(unittest.TestCase):
94 key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
95 storage_index = hashutil.storage_index_hash(key)
96 uri_extension_hash = hashutil.uri_extension_hash("stuff")
100 u = uri.CHKFileURI(key=key,
101 uri_extension_hash=uri_extension_hash,
102 needed_shares=needed_shares,
103 total_shares=total_shares,
105 self.failUnlessEqual(u.get_storage_index(), storage_index)
106 self.failUnlessEqual(u.key, key)
107 self.failUnlessEqual(u.uri_extension_hash, uri_extension_hash)
108 self.failUnlessEqual(u.needed_shares, needed_shares)
109 self.failUnlessEqual(u.total_shares, total_shares)
110 self.failUnlessEqual(u.size, size)
111 self.failUnless(u.is_readonly())
112 self.failIf(u.is_mutable())
113 self.failUnless(IURI.providedBy(u))
114 self.failUnless(IFileURI.providedBy(u))
115 self.failIf(IDirnodeURI.providedBy(u))
116 self.failUnlessEqual(u.get_size(), 1234)
118 u_ro = u.get_readonly()
119 self.failUnlessIdentical(u, u_ro)
120 he = u.to_human_encoding()
121 self.failUnlessEqual(he, "http://127.0.0.1:3456/uri/" + u.to_string())
122 self.failUnlessEqual(uri.CHKFileURI.init_from_human_encoding(he), u)
124 u2 = uri.from_string(u.to_string())
125 self.failUnlessEqual(u2.get_storage_index(), storage_index)
126 self.failUnlessEqual(u2.key, key)
127 self.failUnlessEqual(u2.uri_extension_hash, uri_extension_hash)
128 self.failUnlessEqual(u2.needed_shares, needed_shares)
129 self.failUnlessEqual(u2.total_shares, total_shares)
130 self.failUnlessEqual(u2.size, size)
131 self.failUnless(u2.is_readonly())
132 self.failIf(u2.is_mutable())
133 self.failUnless(IURI.providedBy(u2))
134 self.failUnless(IFileURI.providedBy(u2))
135 self.failIf(IDirnodeURI.providedBy(u2))
136 self.failUnlessEqual(u2.get_size(), 1234)
138 u2i = uri.from_string(u.to_string(), deep_immutable=True)
139 self.failUnlessEqual(u.to_string(), u2i.to_string())
140 u2ro = uri.from_string(uri.ALLEGED_READONLY_PREFIX + u.to_string())
141 self.failUnlessEqual(u.to_string(), u2ro.to_string())
142 u2imm = uri.from_string(uri.ALLEGED_IMMUTABLE_PREFIX + u.to_string())
143 self.failUnlessEqual(u.to_string(), u2imm.to_string())
145 v = u.get_verify_cap()
146 self.failUnless(isinstance(v.to_string(), str))
147 self.failUnless(v.is_readonly())
148 self.failIf(v.is_mutable())
150 v2 = uri.from_string(v.to_string())
151 self.failUnlessEqual(v, v2)
152 he = v.to_human_encoding()
153 v2_h = uri.CHKFileVerifierURI.init_from_human_encoding(he)
154 self.failUnlessEqual(v2, v2_h)
156 v3 = uri.CHKFileVerifierURI(storage_index="\x00"*16,
157 uri_extension_hash="\x00"*32,
161 self.failUnless(isinstance(v3.to_string(), str))
162 self.failUnless(v3.is_readonly())
163 self.failIf(v3.is_mutable())
165 def test_pack_badly(self):
166 key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
167 storage_index = hashutil.storage_index_hash(key)
168 uri_extension_hash = hashutil.uri_extension_hash("stuff")
172 self.failUnlessRaises(TypeError,
175 uri_extension_hash=uri_extension_hash,
176 needed_shares=needed_shares,
177 total_shares=total_shares,
180 bogus_extra_argument="reject me",
182 self.failUnlessRaises(TypeError,
183 uri.CHKFileVerifierURI,
185 self.failUnlessRaises(TypeError,
186 uri.CHKFileVerifierURI,
187 storage_index=storage_index,
188 uri_extension_hash=uri_extension_hash,
191 # leave size= missing
195 class Extension(unittest.TestCase):
197 data = {"stuff": "value",
200 "big_hash": hashutil.tagged_hash("foo", "bar"),
202 ext = uri.pack_extension(data)
203 d = uri.unpack_extension(ext)
204 self.failUnlessEqual(d["stuff"], "value")
205 self.failUnlessEqual(d["size"], 12)
206 self.failUnlessEqual(d["big_hash"], hashutil.tagged_hash("foo", "bar"))
208 readable = uri.unpack_extension_readable(ext)
209 self.failUnlessEqual(readable["needed_shares"], 3)
210 self.failUnlessEqual(readable["stuff"], "value")
211 self.failUnlessEqual(readable["size"], 12)
212 self.failUnlessEqual(readable["big_hash"],
213 base32.b2a(hashutil.tagged_hash("foo", "bar")))
214 self.failUnlessEqual(readable["UEB_hash"],
215 base32.b2a(hashutil.uri_extension_hash(ext)))
217 class Unknown(unittest.TestCase):
218 def test_from_future(self):
219 # any URI type that we don't recognize should be treated as unknown
220 future_uri = "I am a URI from the future. Whatever you do, don't "
221 u = uri.from_string(future_uri)
222 self.failUnless(isinstance(u, uri.UnknownURI))
223 self.failUnlessEqual(u.to_string(), future_uri)
224 self.failUnless(u.get_readonly() is None)
225 self.failUnless(u.get_error() is None)
227 u2 = uri.UnknownURI(future_uri, error=CapConstraintError("..."))
228 self.failUnlessEqual(u.to_string(), future_uri)
229 self.failUnless(u2.get_readonly() is None)
230 self.failUnless(isinstance(u2.get_error(), CapConstraintError))
232 class Constraint(unittest.TestCase):
233 def test_constraint(self):
234 good="http://127.0.0.1:3456/uri/URI%3ADIR2%3Agh3l5rbvnv2333mrfvalmjfr4i%3Alz6l7u3z3b7g37s4zkdmfpx5ly4ib4m6thrpbusi6ys62qtc6mma/"
235 uri.DirectoryURI.init_from_human_encoding(good)
236 self.failUnlessRaises(uri.BadURIError, uri.DirectoryURI.init_from_string, good)
238 self.failUnlessRaises(uri.BadURIError, uri.DirectoryURI.init_from_human_encoding, bad)
239 self.failUnlessRaises(uri.BadURIError, uri.DirectoryURI.init_from_string, bad)
240 fileURI = 'URI:CHK:gh3l5rbvnv2333mrfvalmjfr4i:lz6l7u3z3b7g37s4zkdmfpx5ly4ib4m6thrpbusi6ys62qtc6mma:3:10:345834'
241 uri.CHKFileURI.init_from_string(fileURI)
243 class Mutable(unittest.TestCase):
245 writekey = "\x01" * 16
246 fingerprint = "\x02" * 32
248 u = uri.WriteableSSKFileURI(writekey, fingerprint)
249 self.failUnlessEqual(u.writekey, writekey)
250 self.failUnlessEqual(u.fingerprint, fingerprint)
251 self.failIf(u.is_readonly())
252 self.failUnless(u.is_mutable())
253 self.failUnless(IURI.providedBy(u))
254 self.failUnless(IMutableFileURI.providedBy(u))
255 self.failIf(IDirnodeURI.providedBy(u))
256 self.failUnless("WriteableSSKFileURI" in str(u))
258 he = u.to_human_encoding()
259 u_h = uri.WriteableSSKFileURI.init_from_human_encoding(he)
260 self.failUnlessEqual(u, u_h)
262 u2 = uri.from_string(u.to_string())
263 self.failUnlessEqual(u2.writekey, writekey)
264 self.failUnlessEqual(u2.fingerprint, fingerprint)
265 self.failIf(u2.is_readonly())
266 self.failUnless(u2.is_mutable())
267 self.failUnless(IURI.providedBy(u2))
268 self.failUnless(IMutableFileURI.providedBy(u2))
269 self.failIf(IDirnodeURI.providedBy(u2))
271 u2i = uri.from_string(u.to_string(), deep_immutable=True)
272 self.failUnless(isinstance(u2i, uri.UnknownURI), u2i)
273 u2ro = uri.from_string(uri.ALLEGED_READONLY_PREFIX + u.to_string())
274 self.failUnless(isinstance(u2ro, uri.UnknownURI), u2ro)
275 u2imm = uri.from_string(uri.ALLEGED_IMMUTABLE_PREFIX + u.to_string())
276 self.failUnless(isinstance(u2imm, uri.UnknownURI), u2imm)
278 u3 = u2.get_readonly()
279 readkey = hashutil.ssk_readkey_hash(writekey)
280 self.failUnlessEqual(u3.fingerprint, fingerprint)
281 self.failUnlessEqual(u3.readkey, readkey)
282 self.failUnless(u3.is_readonly())
283 self.failUnless(u3.is_mutable())
284 self.failUnless(IURI.providedBy(u3))
285 self.failUnless(IMutableFileURI.providedBy(u3))
286 self.failIf(IDirnodeURI.providedBy(u3))
288 u3i = uri.from_string(u3.to_string(), deep_immutable=True)
289 self.failUnless(isinstance(u3i, uri.UnknownURI), u3i)
290 u3ro = uri.from_string(uri.ALLEGED_READONLY_PREFIX + u3.to_string())
291 self.failUnlessEqual(u3.to_string(), u3ro.to_string())
292 u3imm = uri.from_string(uri.ALLEGED_IMMUTABLE_PREFIX + u3.to_string())
293 self.failUnless(isinstance(u3imm, uri.UnknownURI), u3imm)
295 he = u3.to_human_encoding()
296 u3_h = uri.ReadonlySSKFileURI.init_from_human_encoding(he)
297 self.failUnlessEqual(u3, u3_h)
299 u4 = uri.ReadonlySSKFileURI(readkey, fingerprint)
300 self.failUnlessEqual(u4.fingerprint, fingerprint)
301 self.failUnlessEqual(u4.readkey, readkey)
302 self.failUnless(u4.is_readonly())
303 self.failUnless(u4.is_mutable())
304 self.failUnless(IURI.providedBy(u4))
305 self.failUnless(IMutableFileURI.providedBy(u4))
306 self.failIf(IDirnodeURI.providedBy(u4))
308 u4i = uri.from_string(u4.to_string(), deep_immutable=True)
309 self.failUnless(isinstance(u4i, uri.UnknownURI), u4i)
310 u4ro = uri.from_string(uri.ALLEGED_READONLY_PREFIX + u4.to_string())
311 self.failUnlessEqual(u4.to_string(), u4ro.to_string())
312 u4imm = uri.from_string(uri.ALLEGED_IMMUTABLE_PREFIX + u4.to_string())
313 self.failUnless(isinstance(u4imm, uri.UnknownURI), u4imm)
315 u4a = uri.from_string(u4.to_string())
316 self.failUnlessEqual(u4a, u4)
317 self.failUnless("ReadonlySSKFileURI" in str(u4a))
318 self.failUnlessIdentical(u4a.get_readonly(), u4a)
320 u5 = u4.get_verify_cap()
321 self.failUnless(IVerifierURI.providedBy(u5))
322 self.failUnlessEqual(u5.get_storage_index(), u.get_storage_index())
323 u7 = u.get_verify_cap()
324 self.failUnless(IVerifierURI.providedBy(u7))
325 self.failUnlessEqual(u7.get_storage_index(), u.get_storage_index())
327 he = u5.to_human_encoding()
328 u5_h = uri.SSKVerifierURI.init_from_human_encoding(he)
329 self.failUnlessEqual(u5, u5_h)
332 class Dirnode(unittest.TestCase):
334 writekey = "\x01" * 16
335 fingerprint = "\x02" * 32
337 n = uri.WriteableSSKFileURI(writekey, fingerprint)
338 u1 = uri.DirectoryURI(n)
339 self.failIf(u1.is_readonly())
340 self.failUnless(u1.is_mutable())
341 self.failUnless(IURI.providedBy(u1))
342 self.failIf(IFileURI.providedBy(u1))
343 self.failUnless(IDirnodeURI.providedBy(u1))
344 self.failUnless("DirectoryURI" in str(u1))
345 u1_filenode = u1.get_filenode_cap()
346 self.failUnless(u1_filenode.is_mutable())
347 self.failIf(u1_filenode.is_readonly())
349 u2 = uri.from_string(u1.to_string())
350 self.failUnlessEqual(u1.to_string(), u2.to_string())
351 self.failIf(u2.is_readonly())
352 self.failUnless(u2.is_mutable())
353 self.failUnless(IURI.providedBy(u2))
354 self.failIf(IFileURI.providedBy(u2))
355 self.failUnless(IDirnodeURI.providedBy(u2))
357 u2i = uri.from_string(u1.to_string(), deep_immutable=True)
358 self.failUnless(isinstance(u2i, uri.UnknownURI))
360 u3 = u2.get_readonly()
361 self.failUnless(u3.is_readonly())
362 self.failUnless(u3.is_mutable())
363 self.failUnless(IURI.providedBy(u3))
364 self.failIf(IFileURI.providedBy(u3))
365 self.failUnless(IDirnodeURI.providedBy(u3))
367 u3i = uri.from_string(u2.to_string(), deep_immutable=True)
368 self.failUnless(isinstance(u3i, uri.UnknownURI))
370 u3n = u3._filenode_uri
371 self.failUnless(u3n.is_readonly())
372 self.failUnless(u3n.is_mutable())
373 u3_filenode = u3.get_filenode_cap()
374 self.failUnless(u3_filenode.is_mutable())
375 self.failUnless(u3_filenode.is_readonly())
377 u3a = uri.from_string(u3.to_string())
378 self.failUnlessIdentical(u3a, u3a.get_readonly())
380 u4 = uri.ReadonlyDirectoryURI(u2._filenode_uri.get_readonly())
381 self.failUnlessEqual(u4.to_string(), u3.to_string())
382 self.failUnless(u4.is_readonly())
383 self.failUnless(u4.is_mutable())
384 self.failUnless(IURI.providedBy(u4))
385 self.failIf(IFileURI.providedBy(u4))
386 self.failUnless(IDirnodeURI.providedBy(u4))
388 u4_verifier = u4.get_verify_cap()
389 u4_verifier_filenode = u4_verifier.get_filenode_cap()
390 self.failUnless(isinstance(u4_verifier_filenode, uri.SSKVerifierURI))
392 verifiers = [u1.get_verify_cap(), u2.get_verify_cap(),
393 u3.get_verify_cap(), u4.get_verify_cap(),
394 uri.DirectoryURIVerifier(n.get_verify_cap()),
397 self.failUnless(IVerifierURI.providedBy(v))
398 self.failUnlessEqual(v._filenode_uri,
399 u1.get_verify_cap()._filenode_uri)
401 def test_immutable(self):
402 readkey = "\x01" * 16
403 uri_extension_hash = hashutil.uri_extension_hash("stuff")
408 fnuri = uri.CHKFileURI(key=readkey,
409 uri_extension_hash=uri_extension_hash,
410 needed_shares=needed_shares,
411 total_shares=total_shares,
413 fncap = fnuri.to_string()
414 self.failUnlessEqual(fncap, "URI:CHK:aeaqcaibaeaqcaibaeaqcaibae:nf3nimquen7aeqm36ekgxomalstenpkvsdmf6fplj7swdatbv5oa:3:10:1234")
415 u1 = uri.ImmutableDirectoryURI(fnuri)
416 self.failUnless(u1.is_readonly())
417 self.failIf(u1.is_mutable())
418 self.failUnless(IURI.providedBy(u1))
419 self.failIf(IFileURI.providedBy(u1))
420 self.failUnless(IDirnodeURI.providedBy(u1))
421 self.failUnless("DirectoryURI" in str(u1))
422 u1_filenode = u1.get_filenode_cap()
423 self.failIf(u1_filenode.is_mutable())
424 self.failUnless(u1_filenode.is_readonly())
425 self.failUnlessEqual(u1_filenode.to_string(), fncap)
426 self.failUnless(str(u1))
428 u2 = uri.from_string(u1.to_string())
429 self.failUnlessEqual(u1.to_string(), u2.to_string())
430 self.failUnless(u2.is_readonly())
431 self.failIf(u2.is_mutable())
432 self.failUnless(IURI.providedBy(u2))
433 self.failIf(IFileURI.providedBy(u2))
434 self.failUnless(IDirnodeURI.providedBy(u2))
436 u2i = uri.from_string(u1.to_string(), deep_immutable=True)
437 self.failUnlessEqual(u1.to_string(), u2i.to_string())
439 u3 = u2.get_readonly()
440 self.failUnlessEqual(u3.to_string(), u2.to_string())
441 self.failUnless(str(u3))
443 u3i = uri.from_string(u2.to_string(), deep_immutable=True)
444 self.failUnlessEqual(u2.to_string(), u3i.to_string())
446 u2_verifier = u2.get_verify_cap()
447 self.failUnless(isinstance(u2_verifier,
448 uri.ImmutableDirectoryURIVerifier),
450 self.failUnless(IVerifierURI.providedBy(u2_verifier))
451 u2vs = u2_verifier.to_string()
452 # URI:DIR2-CHK-Verifier:$key:$ueb:$k:$n:$size
453 self.failUnless(u2vs.startswith("URI:DIR2-CHK-Verifier:"), u2vs)
454 u2_verifier_fileuri = u2_verifier.get_filenode_cap()
455 self.failUnless(IVerifierURI.providedBy(u2_verifier_fileuri))
456 u2vfs = u2_verifier_fileuri.to_string()
457 # URI:CHK-Verifier:$key:$ueb:$k:$n:$size
458 self.failUnlessEqual(u2vfs, fnuri.get_verify_cap().to_string())
459 self.failUnlessEqual(u2vs[len("URI:DIR2-"):], u2vfs[len("URI:"):])
460 self.failUnless(str(u2_verifier))
462 def test_literal(self):
463 u0 = uri.LiteralFileURI("data")
464 u1 = uri.LiteralDirectoryURI(u0)
465 self.failUnless(str(u1))
466 self.failUnlessEqual(u1.to_string(), "URI:DIR2-LIT:mrqxiyi")
467 self.failUnless(u1.is_readonly())
468 self.failIf(u1.is_mutable())
469 self.failUnless(IURI.providedBy(u1))
470 self.failIf(IFileURI.providedBy(u1))
471 self.failUnless(IDirnodeURI.providedBy(u1))
472 self.failUnlessEqual(u1.get_verify_cap(), None)