From: Brian Warner Date: Thu, 12 Jul 2007 23:17:49 +0000 (-0700) Subject: fix several methods to handle LIT URIs correctly, rather than assuming that all filen... X-Git-Url: https://git.rkrishnan.org/%5B/%5D%20/uri/flags/reliability?a=commitdiff_plain;h=ba7e14a870f1e6093a3a1304d7ed6b37e34888d3;p=tahoe-lafs%2Ftahoe-lafs.git fix several methods to handle LIT URIs correctly, rather than assuming that all filenodes are CHK URIs --- diff --git a/src/allmydata/dirnode.py b/src/allmydata/dirnode.py index f2743193..18b7999b 100644 --- a/src/allmydata/dirnode.py +++ b/src/allmydata/dirnode.py @@ -340,6 +340,11 @@ class ImmutableDirectoryNode: manifest.add(self.get_refresh_capability()) d = self._build_manifest_from_node(self, manifest) + # LIT nodes have no refresh-capability: their data is stored inside + # the URI itself, so there is no need to refresh anything. They + # indicate this by returning None from their get_refresh_capability + # method. We need to remove any such Nones from our set. + d.addCallback(lambda res: manifest.discard(None)) d.addCallback(lambda res: manifest) return d @@ -420,8 +425,11 @@ class FileNode: return cmp(self.uri, them.uri) def get_refresh_capability(self): - d = uri.unpack_uri(self.uri) - return "CHK-REFRESH:%s" % idlib.b2a(d['storage_index']) + t = uri.get_uri_type(self.uri) + if t == "CHK": + d = uri.unpack_uri(self.uri) + return "CHK-REFRESH:%s" % idlib.b2a(d['storage_index']) + return None def download(self, target): downloader = self._client.getServiceNamed("downloader") diff --git a/src/allmydata/test/test_system.py b/src/allmydata/test/test_system.py index 45bb9e6a..d899aa7a 100644 --- a/src/allmydata/test/test_system.py +++ b/src/allmydata/test/test_system.py @@ -326,7 +326,8 @@ class SystemTest(testutil.SignalMixin, unittest.TestCase): return d def _do_publish_private(self, res): - ut = upload.Data(self.data) + self.smalldata = "sssh, very secret stuff" + ut = upload.Data(self.smalldata) vdrive0 = self.clients[0].getServiceNamed("vdrive") d = vdrive0.get_node_at_path("~") d.addCallback(self.log, "GOT ~") @@ -395,7 +396,7 @@ class SystemTest(testutil.SignalMixin, unittest.TestCase): self.failUnless(IDirectoryNode.providedBy(dirnode))) d.addCallback(lambda res: get_path("~/personal/sekrit data")) d.addCallback(lambda filenode: filenode.download_to_data()) - d.addCallback(lambda data: self.failUnlessEqual(data, self.data)) + d.addCallback(lambda data: self.failUnlessEqual(data, self.smalldata)) d.addCallback(lambda res: get_path("~/s2-rw")) d.addCallback(lambda dirnode: self.failUnless(dirnode.is_mutable())) d.addCallback(lambda res: get_path("~/s2-ro")) diff --git a/src/allmydata/test/test_uri.py b/src/allmydata/test/test_uri.py index 6f2c64e9..815aa3e0 100644 --- a/src/allmydata/test/test_uri.py +++ b/src/allmydata/test/test_uri.py @@ -9,6 +9,8 @@ class LIT(unittest.TestCase): u = uri.pack_lit(data) self.failUnlessEqual(uri.get_uri_type(u), "LIT") self.failUnlessEqual(uri.unpack_lit(u), data) + self.failUnless(uri.is_filenode_uri(u)) + self.failUnlessEqual(uri.get_filenode_size(u), len(data)) def test_nonascii(self): data = "This contains \x00 and URI:LIT: and \n, oh my." @@ -39,6 +41,9 @@ class CHK(unittest.TestCase): self.failUnlessEqual(d['total_shares'], total_shares) self.failUnlessEqual(d['size'], size) + self.failUnless(uri.is_filenode_uri(u)) + self.failUnlessEqual(uri.get_filenode_size(u), size) + class Extension(unittest.TestCase): def test_pack(self): data = {"stuff": "value", diff --git a/src/allmydata/test/test_web.py b/src/allmydata/test/test_web.py index e5e531d3..c9ecfcb9 100644 --- a/src/allmydata/test/test_web.py +++ b/src/allmydata/test/test_web.py @@ -180,7 +180,7 @@ class Web(unittest.TestCase): sub_uri = foo.children["sub"] = self.makedir().get_uri() sub = self.nodes[sub_uri] - blocking_uri = self.makefile(1) + blocking_uri = self.make_smallfile(1) foo.children["blockingfile"] = blocking_uri baz_file = self.makefile(2) @@ -217,6 +217,18 @@ class Web(unittest.TestCase): self.files[newuri] = contents return newuri + def make_smallfile(self, number): + n = str(number) + assert len(n) == 1 + contents = "small data %s\n" % n + newuri = uri.pack_lit(contents) + assert newuri not in self.nodes + assert newuri not in self.files + node = MyFileNode(newuri, self.s) + self.nodes[newuri] = node + self.files[newuri] = contents + return newuri + def makedir(self): node = MyDirectoryNode(self.nodes, self.files, self.s) return node diff --git a/src/allmydata/uri.py b/src/allmydata/uri.py index 02a2725a..c9d3bf47 100644 --- a/src/allmydata/uri.py +++ b/src/allmydata/uri.py @@ -12,6 +12,17 @@ def get_uri_type(uri): return "LIT" return "CHK" +def is_filenode_uri(uri): + return get_uri_type(uri) in ("LIT", "CHK") + +def get_filenode_size(uri): + assert is_filenode_uri(uri) + t = get_uri_type(uri) + if t == "LIT": + return len(unpack_lit(uri)) + return unpack_uri(uri)['size'] + + # the URI shall be an ascii representation of the file. It shall contain # enough information to retrieve and validate the contents. It shall be # expressed in a limited character set (namely [TODO]). diff --git a/src/allmydata/webish.py b/src/allmydata/webish.py index 6d93d181..943c30b8 100644 --- a/src/allmydata/webish.py +++ b/src/allmydata/webish.py @@ -10,7 +10,7 @@ from allmydata.util import idlib, fileutil import simplejson from allmydata.uri import unpack_uri, is_dirnode_uri from allmydata.interfaces import IDownloadTarget, IDirectoryNode, IFileNode -from allmydata import upload, download +from allmydata import upload, download, uri from zope.interface import implements, Interface import urllib from formless import webform @@ -107,7 +107,7 @@ class Directory(rend.Page): #extract and display file size try: - size = unpack_uri(target.get_uri())['size'] + size = uri.get_filenode_size(target.get_uri()) except AssertionError: size = "?" ctx.fillSlots("size", size) @@ -302,11 +302,10 @@ class FileJSONMetadata(rend.Page): def renderNode(self, filenode): file_uri = filenode.get_uri() - pieces = unpack_uri(file_uri) data = ("filenode", {'mutable': False, 'uri': file_uri, - 'size': pieces['size'], + 'size': uri.get_filenode_size(file_uri), }) return simplejson.dumps(data, indent=1) @@ -393,11 +392,10 @@ class DirectoryJSONMetadata(rend.Page): for name, childnode in children.iteritems(): if IFileNode.providedBy(childnode): kiduri = childnode.get_uri() - pieces = unpack_uri(kiduri) kiddata = ("filenode", {'mutable': False, 'uri': kiduri, - 'size': pieces['size'], + 'size': uri.get_filenode_size(kiduri), }) else: assert IDirectoryNode.providedBy(childnode)