]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/test/test_uri.py
Change direct accesses to an_uri.storage_index to calls to .get_storage_index() ...
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / test / test_uri.py
1
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
7
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())
18
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())
27
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())
35
36         u3 = u.get_readonly()
37         self.failUnlessIdentical(u, u3)
38         self.failUnlessEqual(u.get_verify_cap(), None)
39
40         he = u.to_human_encoding()
41         u_h = uri.LiteralFileURI.init_from_human_encoding(he)
42         self.failUnlessEqual(u, u_h)
43
44     def test_empty(self):
45         data = "" # This data is some *very* small data!
46         return self._help_test(data)
47
48     def test_pack(self):
49         data = "This is some small data"
50         return self._help_test(data)
51
52     def test_nonascii(self):
53         data = "This contains \x00 and URI:LIT: and \n, oh my."
54         return self._help_test(data)
55
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
69
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))
74
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"))
84
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"))
91
92 class CHKFile(unittest.TestCase):
93     def test_pack(self):
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")
97         needed_shares = 25
98         total_shares = 100
99         size = 1234
100         u = uri.CHKFileURI(key=key,
101                            uri_extension_hash=uri_extension_hash,
102                            needed_shares=needed_shares,
103                            total_shares=total_shares,
104                            size=size)
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)
117
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)
123
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)
137
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())
144
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())
149
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)
155
156         v3 = uri.CHKFileVerifierURI(storage_index="\x00"*16,
157                                     uri_extension_hash="\x00"*32,
158                                     needed_shares=3,
159                                     total_shares=10,
160                                     size=1234)
161         self.failUnless(isinstance(v3.to_string(), str))
162         self.failUnless(v3.is_readonly())
163         self.failIf(v3.is_mutable())
164
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")
169         needed_shares = 25
170         total_shares = 100
171         size = 1234
172         self.failUnlessRaises(TypeError,
173                               uri.CHKFileURI,
174                               key=key,
175                               uri_extension_hash=uri_extension_hash,
176                               needed_shares=needed_shares,
177                               total_shares=total_shares,
178                               size=size,
179
180                               bogus_extra_argument="reject me",
181                               )
182         self.failUnlessRaises(TypeError,
183                               uri.CHKFileVerifierURI,
184                               bogus="bogus")
185         self.failUnlessRaises(TypeError,
186                               uri.CHKFileVerifierURI,
187                               storage_index=storage_index,
188                               uri_extension_hash=uri_extension_hash,
189                               needed_shares=3,
190                               total_shares=10,
191                               # leave size= missing
192                               )
193
194
195 class Extension(unittest.TestCase):
196     def test_pack(self):
197         data = {"stuff": "value",
198                 "size": 12,
199                 "needed_shares": 3,
200                 "big_hash": hashutil.tagged_hash("foo", "bar"),
201                 }
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"))
207
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)))
216
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)
226
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))
231
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)
237        bad = 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)
242
243 class Mutable(unittest.TestCase):
244     def test_pack(self):
245         writekey = "\x01" * 16
246         fingerprint = "\x02" * 32
247
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))
257
258         he = u.to_human_encoding()
259         u_h = uri.WriteableSSKFileURI.init_from_human_encoding(he)
260         self.failUnlessEqual(u, u_h)
261
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))
270
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)
277
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))
287
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)
294
295         he = u3.to_human_encoding()
296         u3_h = uri.ReadonlySSKFileURI.init_from_human_encoding(he)
297         self.failUnlessEqual(u3, u3_h)
298
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))
307
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)
314
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)
319
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())
326
327         he = u5.to_human_encoding()
328         u5_h = uri.SSKVerifierURI.init_from_human_encoding(he)
329         self.failUnlessEqual(u5, u5_h)
330
331
332 class Dirnode(unittest.TestCase):
333     def test_pack(self):
334         writekey = "\x01" * 16
335         fingerprint = "\x02" * 32
336
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())
348
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))
356
357         u2i = uri.from_string(u1.to_string(), deep_immutable=True)
358         self.failUnless(isinstance(u2i, uri.UnknownURI))
359
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))
366
367         u3i = uri.from_string(u2.to_string(), deep_immutable=True)
368         self.failUnless(isinstance(u3i, uri.UnknownURI))
369
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())
376
377         u3a = uri.from_string(u3.to_string())
378         self.failUnlessIdentical(u3a, u3a.get_readonly())
379
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))
387
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))
391
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()),
395                      ]
396         for v in verifiers:
397             self.failUnless(IVerifierURI.providedBy(v))
398             self.failUnlessEqual(v._filenode_uri,
399                                  u1.get_verify_cap()._filenode_uri)
400
401     def test_immutable(self):
402         readkey = "\x01" * 16
403         uri_extension_hash = hashutil.uri_extension_hash("stuff")
404         needed_shares = 3
405         total_shares = 10
406         size = 1234
407
408         fnuri = uri.CHKFileURI(key=readkey,
409                                uri_extension_hash=uri_extension_hash,
410                                needed_shares=needed_shares,
411                                total_shares=total_shares,
412                                size=size)
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))
427
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))
435
436         u2i = uri.from_string(u1.to_string(), deep_immutable=True)
437         self.failUnlessEqual(u1.to_string(), u2i.to_string())
438
439         u3 = u2.get_readonly()
440         self.failUnlessEqual(u3.to_string(), u2.to_string())
441         self.failUnless(str(u3))
442
443         u3i = uri.from_string(u2.to_string(), deep_immutable=True)
444         self.failUnlessEqual(u2.to_string(), u3i.to_string())
445
446         u2_verifier = u2.get_verify_cap()
447         self.failUnless(isinstance(u2_verifier,
448                                    uri.ImmutableDirectoryURIVerifier),
449                         u2_verifier)
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))
461
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)