add parser for immutable directory caps: DIR2-CHK, DIR2-LIT, DIR2-CHK-Verifier
authorBrian Warner <warner@lothar.com>
Wed, 4 Nov 2009 17:24:53 +0000 (09:24 -0800)
committerBrian Warner <warner@lothar.com>
Wed, 4 Nov 2009 18:13:51 +0000 (10:13 -0800)
src/allmydata/test/test_uri.py
src/allmydata/uri.py

index 6dd95a29c11da8fbe49df6947a672a0341b3caab..1ee39ff171ac480db6540b97c4e3899a26ed57f8 100644 (file)
@@ -331,3 +331,64 @@ class NewDirnode(unittest.TestCase):
             self.failUnless(IVerifierURI.providedBy(v))
             self.failUnlessEqual(v._filenode_uri,
                                  u1.get_verify_cap()._filenode_uri)
+
+    def test_immutable(self):
+        readkey = "\x01" * 16
+        uri_extension_hash = hashutil.uri_extension_hash("stuff")
+        needed_shares = 3
+        total_shares = 10
+        size = 1234
+
+        fnuri = uri.CHKFileURI(key=readkey,
+                               uri_extension_hash=uri_extension_hash,
+                               needed_shares=needed_shares,
+                               total_shares=total_shares,
+                               size=size)
+        fncap = fnuri.to_string()
+        self.failUnlessEqual(fncap, "URI:CHK:aeaqcaibaeaqcaibaeaqcaibae:nf3nimquen7aeqm36ekgxomalstenpkvsdmf6fplj7swdatbv5oa:3:10:1234")
+        u1 = uri.ImmutableDirectoryURI(fnuri)
+        self.failUnless(u1.is_readonly())
+        self.failIf(u1.is_mutable())
+        self.failUnless(IURI.providedBy(u1))
+        self.failIf(IFileURI.providedBy(u1))
+        self.failUnless(IDirnodeURI.providedBy(u1))
+        self.failUnless("DirectoryURI" in str(u1))
+        u1_filenode = u1.get_filenode_uri()
+        self.failIf(u1_filenode.is_mutable())
+        self.failUnless(u1_filenode.is_readonly())
+        self.failUnlessEqual(u1_filenode.to_string(), fncap)
+        self.failUnless(str(u1))
+
+        u2 = uri.from_string(u1.to_string())
+        self.failUnlessEqual(u1.to_string(), u2.to_string())
+        self.failUnless(u2.is_readonly())
+        self.failIf(u2.is_mutable())
+        self.failUnless(IURI.providedBy(u2))
+        self.failIf(IFileURI.providedBy(u2))
+        self.failUnless(IDirnodeURI.providedBy(u2))
+
+        u3 = u2.get_readonly()
+        self.failUnlessEqual(u3.to_string(), u2.to_string())
+        self.failUnless(str(u3))
+
+        u2_verifier = u2.get_verify_cap()
+        self.failUnless(isinstance(u2_verifier,
+                                   uri.ImmutableDirectoryURIVerifier), u2_verifier)
+        self.failUnless(IVerifierURI.providedBy(u2_verifier))
+        u2_verifier_fileuri = u2_verifier.get_filenode_uri()
+        self.failUnless(IVerifierURI.providedBy(u2_verifier_fileuri))
+        self.failUnlessEqual(u2_verifier_fileuri.to_string(),
+                             fnuri.get_verify_cap().to_string())
+        self.failUnless(str(u2_verifier))
+
+    def test_literal(self):
+        u1 = uri.LiteralDirectoryURI("data")
+        self.failUnless(str(u1))
+        u1s = u1.to_string()
+        self.failUnlessEqual(u1.to_string(), "URI:DIR2-LIT:mrqxiyi")
+        self.failUnless(u1.is_readonly())
+        self.failIf(u1.is_mutable())
+        self.failUnless(IURI.providedBy(u1))
+        self.failIf(IFileURI.providedBy(u1))
+        self.failUnless(IDirnodeURI.providedBy(u1))
+        self.failUnlessEqual(u1.get_verify_cap(), None)
index 0fba6164482a16f687d92909edd94401cbd5822f..44a3b963fa25e1b52971d5c400f2f0bd1fee3cf2 100644 (file)
@@ -48,6 +48,7 @@ class _BaseURI:
 class CHKFileURI(_BaseURI):
     implements(IURI, IImmutableFileURI)
 
+    BASE_STRING='URI:CHK:'
     STRING_RE=re.compile('^URI:CHK:'+BASE32STR_128bits+':'+
                          BASE32STR_256bits+':'+NUMBER+':'+NUMBER+':'+NUMBER+
                          '$')
@@ -159,6 +160,7 @@ class CHKFileVerifierURI(_BaseURI):
 class LiteralFileURI(_BaseURI):
     implements(IURI, IImmutableFileURI)
 
+    BASE_STRING='URI:LIT:'
     STRING_RE=re.compile('^URI:LIT:'+base32.BASE32STR_anybytes+'$')
     HUMAN_RE=re.compile('^'+OPTIONALHTTPLEAD+'URI'+SEP+'LIT'+SEP+base32.BASE32STR_anybytes+'$')
 
@@ -422,6 +424,44 @@ class ReadonlyDirectoryURI(_DirectoryBaseURI):
     def get_readonly(self):
         return self
 
+class _ImmutableDirectoryBaseURI(_DirectoryBaseURI):
+    def __init__(self, filenode_uri=None):
+        if filenode_uri:
+            assert isinstance(filenode_uri, self.INNER_URI_CLASS), filenode_uri
+        _DirectoryBaseURI.__init__(self, filenode_uri)
+
+    def is_mutable(self):
+        return False
+
+    def is_readonly(self):
+        return True
+
+    def get_readonly(self):
+        return self
+
+class ImmutableDirectoryURI(_ImmutableDirectoryBaseURI):
+    BASE_STRING='URI:DIR2-CHK:'
+    BASE_STRING_RE=re.compile('^'+BASE_STRING)
+    BASE_HUMAN_RE=re.compile('^'+OPTIONALHTTPLEAD+'URI'+SEP+'DIR2-CHK'+SEP)
+    INNER_URI_CLASS=CHKFileURI
+    def get_verify_cap(self):
+        vcap = self._filenode_uri.get_verify_cap()
+        return ImmutableDirectoryURIVerifier(vcap)
+
+
+class LiteralDirectoryURI(_ImmutableDirectoryBaseURI):
+    BASE_STRING='URI:DIR2-LIT:'
+    BASE_STRING_RE=re.compile('^'+BASE_STRING)
+    BASE_HUMAN_RE=re.compile('^'+OPTIONALHTTPLEAD+'URI'+SEP+'DIR2-LIT'+SEP)
+    INNER_URI_CLASS=LiteralFileURI
+    def __init__(self, data=None):
+        filenode_uri = LiteralFileURI(data)
+        _ImmutableDirectoryBaseURI.__init__(self, filenode_uri)
+    def get_verify_cap(self):
+        # LIT caps have no verifier, since they aren't distributed
+        return None
+
+
 class DirectoryURIVerifier(_DirectoryBaseURI):
     implements(IVerifierURI)
 
@@ -438,6 +478,13 @@ class DirectoryURIVerifier(_DirectoryBaseURI):
     def get_filenode_uri(self):
         return self._filenode_uri
 
+class ImmutableDirectoryURIVerifier(DirectoryURIVerifier):
+    implements(IVerifierURI)
+    BASE_STRING='URI:DIR2-CHK-Verifier:'
+    BASE_STRING_RE=re.compile('^'+BASE_STRING)
+    BASE_HUMAN_RE=re.compile('^'+OPTIONALHTTPLEAD+'URI'+SEP+'DIR2-CHK-VERIFIER'+SEP)
+    INNER_URI_CLASS=CHKFileVerifierURI
+
 class UnknownURI:
     def __init__(self, uri):
         self._uri = uri
@@ -465,6 +512,10 @@ def from_string(s):
         return ReadonlyDirectoryURI.init_from_string(s)
     elif s.startswith('URI:DIR2-Verifier:'):
         return DirectoryURIVerifier.init_from_string(s)
+    elif s.startswith('URI:DIR2-CHK:'):
+        return ImmutableDirectoryURI.init_from_string(s)
+    elif s.startswith('URI:DIR2-LIT:'):
+        return LiteralDirectoryURI.init_from_string(s)
     return UnknownURI(s)
 
 def is_uri(s):