From 131e05b1552826f4be246657540b59c73a47c89e Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Wed, 11 Nov 2009 14:25:42 -0800 Subject: [PATCH] clean up uri-vs-cap terminology, emphasize cap instances instead of URI strings * "cap" means a python instance which encapsulates a filecap/dircap (uri.py) * "uri" means a string with a "URI:" prefix * FileNode instances are created with (and retain) a cap instance, and generate uri strings on demand * .get_cap/get_readcap/get_verifycap/get_repaircap return cap instances * .get_uri/get_readonly_uri return uri strings * add filenode.download_to_filename() for control.py, should find a better way * use MutableFileNode.init_from_cap, not .init_from_uri * directory URI instances: use get_filenode_cap, not get_filenode_uri * update/cleanup bench_dirnode.py to match, add Makefile target to run it --- Makefile | 3 + src/allmydata/control.py | 3 +- src/allmydata/dirnode.py | 7 ++- src/allmydata/immutable/download.py | 6 +- src/allmydata/immutable/filenode.py | 38 +++++++----- src/allmydata/interfaces.py | 42 ++++++++----- src/allmydata/mutable/filenode.py | 45 +++++++------- src/allmydata/nodemaker.py | 47 +++++++-------- src/allmydata/test/bench_dirnode.py | 91 ++++++++++++++--------------- src/allmydata/test/common.py | 45 +++++++------- src/allmydata/test/test_dirnode.py | 2 +- src/allmydata/test/test_filenode.py | 22 ++++--- src/allmydata/test/test_system.py | 23 ++++---- src/allmydata/test/test_uri.py | 10 ++-- src/allmydata/test/test_web.py | 2 +- src/allmydata/uri.py | 4 +- 16 files changed, 214 insertions(+), 176 deletions(-) diff --git a/Makefile b/Makefile index 4cb82b1be..1bd8e84b1 100644 --- a/Makefile +++ b/Makefile @@ -223,6 +223,9 @@ check-grid: .built if [ -z '$(TESTCLIENTDIR)' ]; then exit 1; fi $(PYTHON) src/allmydata/test/check_grid.py $(TESTCLIENTDIR) bin/tahoe +bench-dirnode: .built + $(RUNPP) -p -c src/allmydata/test/bench_dirnode.py + # 'make repl' is a simple-to-type command to get a Python interpreter loop # from which you can type 'import allmydata' repl: diff --git a/src/allmydata/control.py b/src/allmydata/control.py index d629c1366..09d10d617 100644 --- a/src/allmydata/control.py +++ b/src/allmydata/control.py @@ -50,7 +50,8 @@ class ControlServer(Referenceable, service.Service): return d def remote_download_from_uri_to_file(self, uri, filename): - d = self.parent.downloader.download_to_filename(uri, filename) + filenode = self.parent.create_node_from_uri(uri) + d = filenode.download_to_filename(filename) d.addCallback(lambda res: filename) return d diff --git a/src/allmydata/dirnode.py b/src/allmydata/dirnode.py index de271551a..ad5a35d79 100644 --- a/src/allmydata/dirnode.py +++ b/src/allmydata/dirnode.py @@ -271,12 +271,15 @@ class DirectoryNode: def get_readonly_uri(self): return self._uri.get_readonly().to_string() + def get_cap(self): + return self._uri + def get_readcap(self): + return self._uri.get_readonly() def get_verify_cap(self): return self._uri.get_verify_cap() - def get_repair_cap(self): if self._node.is_readonly(): - return None + return None # readonly (mutable) dirnodes are not yet repairable return self._uri def get_storage_index(self): diff --git a/src/allmydata/immutable/download.py b/src/allmydata/immutable/download.py index 3dde40f1f..f6356caf3 100644 --- a/src/allmydata/immutable/download.py +++ b/src/allmydata/immutable/download.py @@ -7,8 +7,7 @@ from foolscap.api import DeadReferenceError, RemoteException, eventually from allmydata.util import base32, deferredutil, hashutil, log, mathutil, idlib from allmydata.util.assertutil import _assert, precondition from allmydata import codec, hashtree, uri -from allmydata.interfaces import IDownloadTarget, IDownloader, \ - IFileURI, IVerifierURI, \ +from allmydata.interfaces import IDownloadTarget, IDownloader, IVerifierURI, \ IDownloadStatus, IDownloadResults, IValidatedThingProxy, \ IStorageBroker, NotEnoughSharesError, NoSharesError, NoServersError, \ UnableToFetchCriticalDownloadDataError @@ -1330,12 +1329,11 @@ class Downloader: self._all_downloads = weakref.WeakKeyDictionary() # for debugging def download(self, u, t, _log_msg_id=None, monitor=None, history=None): - u = IFileURI(u) + assert isinstance(u, uri.CHKFileURI) t = IDownloadTarget(t) assert t.write assert t.close - assert isinstance(u, uri.CHKFileURI) if self.stats_provider: # these counters are meant for network traffic, and don't # include LIT files diff --git a/src/allmydata/immutable/filenode.py b/src/allmydata/immutable/filenode.py index f7e955aa9..0e8aabd1a 100644 --- a/src/allmydata/immutable/filenode.py +++ b/src/allmydata/immutable/filenode.py @@ -8,7 +8,7 @@ from foolscap.api import eventually from allmydata.interfaces import IFileNode, ICheckable, \ IDownloadTarget, IUploadResults from allmydata.util import dictutil, log, base32 -from allmydata import uri as urimodule +from allmydata.uri import CHKFileURI, LiteralFileURI from allmydata.immutable.checker import Checker from allmydata.check_results import CheckResults, CheckAndRepairResults from allmydata.immutable.repairer import Repairer @@ -181,8 +181,8 @@ class DownloadCache: class FileNode(_ImmutableFileNodeBase, log.PrefixingLogMixin): def __init__(self, filecap, storage_broker, secret_holder, downloader, history, cachedirectorymanager): - assert isinstance(filecap, str) - self.u = urimodule.CHKFileURI.init_from_string(filecap) + assert isinstance(filecap, CHKFileURI) + self.u = filecap self._storage_broker = storage_broker self._secret_holder = secret_holder self._downloader = downloader @@ -194,19 +194,22 @@ class FileNode(_ImmutableFileNodeBase, log.PrefixingLogMixin): log.PrefixingLogMixin.__init__(self, "allmydata.immutable.filenode", prefix=prefix) self.log("starting", level=log.OPERATIONAL) - def get_uri(self): - return self.u.to_string() - def get_size(self): return self.u.get_size() + def get_cap(self): + return self.u + def get_readcap(self): + return self.u.get_readonly() def get_verify_cap(self): return self.u.get_verify_cap() - def get_repair_cap(self): # CHK files can be repaired with just the verifycap return self.u.get_verify_cap() + def get_uri(self): + return self.u.to_string() + def get_storage_index(self): return self.u.storage_index @@ -294,13 +297,15 @@ class FileNode(_ImmutableFileNodeBase, log.PrefixingLogMixin): return d def download(self, target): - return self._downloader.download(self.get_uri(), target, + return self._downloader.download(self.get_cap(), target, self._parentmsgid, history=self._history) def download_to_data(self): - return self._downloader.download_to_data(self.get_uri(), + return self._downloader.download_to_data(self.get_cap(), history=self._history) + def download_to_filename(self, filename): + return self._downloader.download_to_filename(self.get_cap(), filename) class LiteralProducer: implements(IPushProducer) @@ -313,21 +318,24 @@ class LiteralProducer: class LiteralFileNode(_ImmutableFileNodeBase): def __init__(self, filecap): - assert isinstance(filecap, str) - self.u = urimodule.LiteralFileURI.init_from_string(filecap) - - def get_uri(self): - return self.u.to_string() + assert isinstance(filecap, LiteralFileURI) + self.u = filecap def get_size(self): return len(self.u.data) + def get_cap(self): + return self.u + def get_readcap(self): + return self.u def get_verify_cap(self): return None - def get_repair_cap(self): return None + def get_uri(self): + return self.u.to_string() + def get_storage_index(self): return None diff --git a/src/allmydata/interfaces.py b/src/allmydata/interfaces.py index 74ebcde4f..8546d9441 100644 --- a/src/allmydata/interfaces.py +++ b/src/allmydata/interfaces.py @@ -481,6 +481,32 @@ class UnhandledCapTypeError(Exception): it.""" class IFilesystemNode(Interface): + def get_cap(): + """Return the strongest 'cap instance' associated with this node. + (writecap for writeable-mutable files/directories, readcap for + immutable or readonly-mutable files/directories). To convert this + into a string, call .to_string() on the result.""" + + def get_readcap(): + """Return a readonly cap instance for this node. For immutable or + readonly nodes, get_cap() and get_readcap() return the same thing.""" + + def get_repair_cap(): + """Return an IURI instance that can be used to repair the file, or + None if this node cannot be repaired (either because it is not + distributed, like a LIT file, or because the node does not represent + sufficient authority to create a repair-cap, like a read-only RSA + mutable file node [which cannot create the correct write-enablers]). + """ + + def get_verify_cap(): + """Return an IVerifierURI instance that represents the + 'verifiy/refresh capability' for this node. The holder of this + capability will be able to renew the lease for this node, protecting + it from garbage-collection. They will also be able to ask a server if + it holds a share for the file or directory. + """ + def get_uri(): """ Return the URI string that can be used by others to get access to @@ -501,22 +527,6 @@ class IFilesystemNode(Interface): will return the same thing as get_uri(). """ - def get_repair_cap(): - """Return an IURI instance that can be used to repair the file, or - None if this node cannot be repaired (either because it is not - distributed, like a LIT file, or because the node does not represent - sufficient authority to create a repair-cap, like a read-only RSA - mutable file node [which cannot create the correct write-enablers]). - """ - - def get_verify_cap(): - """Return an IVerifierURI instance that represents the - 'verifiy/refresh capability' for this node. The holder of this - capability will be able to renew the lease for this node, protecting - it from garbage-collection. They will also be able to ask a server if - it holds a share for the file or directory. - """ - def get_storage_index(): """Return a string with the (binary) storage index in use on this download. This may be None if there is no storage index (i.e. LIT diff --git a/src/allmydata/mutable/filenode.py b/src/allmydata/mutable/filenode.py index afd71ffd0..5f7f40073 100644 --- a/src/allmydata/mutable/filenode.py +++ b/src/allmydata/mutable/filenode.py @@ -76,19 +76,16 @@ class MutableFileNode: else: return "<%s %x %s %s>" % (self.__class__.__name__, id(self), None, None) - def init_from_uri(self, filecap): + def init_from_cap(self, filecap): # we have the URI, but we have not yet retrieved the public # verification key, nor things like 'k' or 'N'. If and when someone # wants to get our contents, we'll pull from shares and fill those # in. - assert isinstance(filecap, str) - if filecap.startswith("URI:SSK:"): - self._uri = WriteableSSKFileURI.init_from_string(filecap) + assert isinstance(filecap, (ReadonlySSKFileURI, WriteableSSKFileURI)) + self._uri = filecap + self._writekey = None + if isinstance(filecap, WriteableSSKFileURI): self._writekey = self._uri.writekey - else: - assert filecap.startswith("URI:SSK-RO:") - self._uri = ReadonlySSKFileURI.init_from_string(filecap) - self._writekey = None self._readkey = self._uri.readkey self._storage_index = self._uri.storage_index self._fingerprint = self._uri.fingerprint @@ -188,21 +185,33 @@ class MutableFileNode: #################################### # IFilesystemNode - def get_uri(self): - return self._uri.to_string() def get_size(self): return "?" # TODO: this is likely to cause problems, not being an int + + def get_cap(self): + return self._uri + def get_readcap(self): + return self._uri.get_readonly() + def get_verify_cap(self): + return IMutableFileURI(self._uri).get_verify_cap() + def get_repair_cap(self): + if self._uri.is_readonly(): + return None + return self._uri + + def get_uri(self): + return self._uri.to_string() + def get_readonly_uri(self): + return self._uri.get_readonly().to_string() + def get_readonly(self): if self.is_readonly(): return self ro = MutableFileNode(self._storage_broker, self._secret_holder, self._default_encoding_parameters, self._history) - ro.init_from_uri(self.get_readonly_uri()) + ro.init_from_cap(self._uri.get_readonly()) return ro - def get_readonly_uri(self): - return self._uri.get_readonly().to_string() - def is_mutable(self): return self._uri.is_mutable() def is_readonly(self): @@ -217,14 +226,6 @@ class MutableFileNode: return cmp(self.__class__, them.__class__) return cmp(self._uri, them._uri) - def get_verify_cap(self): - return IMutableFileURI(self._uri).get_verify_cap() - - def get_repair_cap(self): - if self._uri.is_readonly(): - return None - return self._uri - def _do_serialized(self, cb, *args, **kwargs): # note: to avoid deadlock, this callable is *not* allowed to invoke # other serialized methods within this (or any other) diff --git a/src/allmydata/nodemaker.py b/src/allmydata/nodemaker.py index bf65e5c72..cb00394a8 100644 --- a/src/allmydata/nodemaker.py +++ b/src/allmydata/nodemaker.py @@ -6,7 +6,7 @@ from allmydata.immutable.filenode import FileNode, LiteralFileNode from allmydata.mutable.filenode import MutableFileNode from allmydata.dirnode import DirectoryNode, pack_children from allmydata.unknown import UnknownNode -from allmydata.uri import DirectoryURI, ReadonlyDirectoryURI +from allmydata import uri class NodeMaker: implements(INodeMaker) @@ -35,41 +35,42 @@ class NodeMaker: n = MutableFileNode(self.storage_broker, self.secret_holder, self.default_encoding_parameters, self.history) - return n.init_from_uri(cap) + return n.init_from_cap(cap) def _create_dirnode(self, filenode): return DirectoryNode(filenode, self, self.uploader) def create_from_cap(self, writecap, readcap=None): - # this returns synchronously. + # this returns synchronously. It starts with a "cap string". assert isinstance(writecap, (str, type(None))), type(writecap) assert isinstance(readcap, (str, type(None))), type(readcap) - cap = writecap or readcap - if not cap: + bigcap = writecap or readcap + if not bigcap: # maybe the writecap was hidden because we're in a readonly # directory, and the future cap format doesn't have a readcap, or # something. return UnknownNode(writecap, readcap) - if cap in self._node_cache: - return self._node_cache[cap] - elif cap.startswith("URI:LIT:"): - node = self._create_lit(cap) - elif cap.startswith("URI:CHK:"): - node = self._create_immutable(cap) - elif cap.startswith("URI:SSK-RO:") or cap.startswith("URI:SSK:"): - node = self._create_mutable(cap) - elif cap.startswith("URI:DIR2-RO:") or cap.startswith("URI:DIR2:"): - if cap.startswith("URI:DIR2-RO:"): - dircap = ReadonlyDirectoryURI.init_from_string(cap) - elif cap.startswith("URI:DIR2:"): - dircap = DirectoryURI.init_from_string(cap) - filecap = dircap.get_filenode_uri().to_string() - filenode = self.create_from_cap(filecap) - node = self._create_dirnode(filenode) + if bigcap in self._node_cache: + return self._node_cache[bigcap] + cap = uri.from_string(bigcap) + node = self._create_from_cap(cap) + if node: + self._node_cache[bigcap] = node # note: WeakValueDictionary else: - return UnknownNode(writecap, readcap) # don't cache UnknownNode - self._node_cache[cap] = node # note: WeakValueDictionary + node = UnknownNode(writecap, readcap) # don't cache UnknownNode return node + def _create_from_cap(self, cap): + # This starts with a "cap instance" + if isinstance(cap, uri.LiteralFileURI): + return self._create_lit(cap) + if isinstance(cap, uri.CHKFileURI): + return self._create_immutable(cap) + if isinstance(cap, (uri.ReadonlySSKFileURI, uri.WriteableSSKFileURI)): + return self._create_mutable(cap) + if isinstance(cap, (uri.ReadonlyDirectoryURI, uri.DirectoryURI)): + filenode = self._create_from_cap(cap.get_filenode_cap()) + return self._create_dirnode(filenode) + return None def create_mutable_file(self, contents=None, keysize=None): n = MutableFileNode(self.storage_broker, self.secret_holder, diff --git a/src/allmydata/test/bench_dirnode.py b/src/allmydata/test/bench_dirnode.py index e29dd86a2..06928c43c 100644 --- a/src/allmydata/test/bench_dirnode.py +++ b/src/allmydata/test/bench_dirnode.py @@ -2,49 +2,32 @@ import hotshot.stats, os, random, sys from pyutil import benchutil, randutil # http://allmydata.org/trac/pyutil -from allmydata import client, dirnode, uri +from allmydata import dirnode, uri from allmydata.mutable import filenode as mut_filenode from allmydata.immutable import filenode as immut_filenode -from allmydata.util import cachedir, fileutil - -class FakeClient(client.Client): - # just enough - def __init__(self): - self._node_cache = {} - download_cachedir = fileutil.NamedTemporaryDirectory() - self.download_cache_dirman = cachedir.CacheDirectoryManager(download_cachedir.name) - def getServiceNamed(self, name): - return None - def get_storage_broker(self): - return None - _secret_holder=None - def get_history(self): - return None - def get_encoding_parameters(self): - return {"k": 3, "n": 10} - def get_writekey(self): - return os.urandom(16) - def create_node_from_uri(self, writecap, readcap): - return None - -class FakeMutableFileNode(mut_filenode.MutableFileNode): - def __init__(self, *args, **kwargs): - mut_filenode.MutableFileNode.__init__(self, *args, **kwargs) - self._uri = uri.WriteableSSKFileURI(randutil.insecurerandstr(16), randutil.insecurerandstr(32)) - -class FakeDirectoryNode(dirnode.DirectoryNode): - def __init__(self, client): - dirnode.DirectoryNode.__init__(self, client) - mutfileuri = uri.WriteableSSKFileURI(randutil.insecurerandstr(16), randutil.insecurerandstr(32)) - myuri = uri.DirectoryURI(mutfileuri).to_string() - self.init_from_uri(myuri) - children = [] # tuples of (k, v) (suitable for passing to dict()) packstr = None -fakeclient = FakeClient() -testdirnode = dirnode.DirectoryNode(fakeclient) -testdirnode.init_from_uri(uri.DirectoryURI(uri.WriteableSSKFileURI(randutil.insecurerandstr(16), randutil.insecurerandstr(32))).to_string()) + +class ContainerNode: + # dirnodes sit on top of a "container" filenode, from which it extracts a + # writekey + def __init__(self): + self._writekey = randutil.insecurerandstr(16) + self._fingerprint = randutil.insecurerandstr(32) + self._cap = uri.WriteableSSKFileURI(self._writekey, self._fingerprint) + def get_writekey(self): + return self._writekey + def get_uri(self): + return self._cap.to_string() + def is_readonly(self): + return False +class FakeNodeMaker: + def create_from_cap(self, writecap, readcap=None): + return None + +nodemaker = FakeNodeMaker() +testdirnode = dirnode.DirectoryNode(ContainerNode(), nodemaker, uploader=None) def random_unicode(l): while True: @@ -53,16 +36,28 @@ def random_unicode(l): except UnicodeDecodeError: pass +encoding_parameters = {"k": 3, "n": 10} def random_fsnode(): coin = random.randrange(0, 3) if coin == 0: - return immut_filenode.FileNode(uri.CHKFileURI(randutil.insecurerandstr(16), randutil.insecurerandstr(32), random.randrange(1, 5), random.randrange(6, 15), random.randrange(99, 1000000000000)).to_string(), None, None, None, None, None) + cap = uri.CHKFileURI(randutil.insecurerandstr(16), + randutil.insecurerandstr(32), + random.randrange(1, 5), + random.randrange(6, 15), + random.randrange(99, 1000000000000)) + return immut_filenode.FileNode(cap, None, None, None, None, None) elif coin == 1: - encoding_parameters = {"k": 3, "n": 10} - return FakeMutableFileNode(None, None, encoding_parameters, None) + cap = uri.WriteableSSKFileURI(randutil.insecurerandstr(16), + randutil.insecurerandstr(32)) + n = mut_filenode.MutableFileNode(None, None, encoding_parameters, None) + return n.init_from_cap(cap) else: assert coin == 2 - return FakeDirectoryNode(fakeclient) + cap = uri.WriteableSSKFileURI(randutil.insecurerandstr(16), + randutil.insecurerandstr(32)) + n = mut_filenode.MutableFileNode(None, None, encoding_parameters, None) + n.init_from_cap(cap) + return dirnode.DirectoryNode(n, nodemaker, uploader=None) def random_metadata(): d = {} @@ -78,7 +73,8 @@ def random_child(): def init_for_pack(N): for i in xrange(len(children), N): - children.append((random_unicode(random.randrange(1, 9)), random_child())) + name = random_unicode(random.randrange(1, 9)) + children.append( (name, random_child()) ) def init_for_unpack(N): global packstr @@ -86,7 +82,7 @@ def init_for_unpack(N): packstr = pack(N) def pack(N): - return testdirnode._pack_contents(dirnode.CachingDict(children[:N])) + return testdirnode._pack_contents(dict(children[:N])) def unpack(N): return testdirnode._unpack_contents(packstr) @@ -97,9 +93,12 @@ def unpack_and_repack(N): PROF_FILE_NAME="bench_dirnode.prof" def run_benchmarks(profile=False): - for (func, initfunc) in [(unpack, init_for_unpack), (pack, init_for_pack), (unpack_and_repack, init_for_unpack)]: + for (initfunc, func) in [(init_for_unpack, unpack), + (init_for_pack, pack), + (init_for_unpack, unpack_and_repack)]: print "benchmarking %s" % (func,) - benchutil.bench(unpack_and_repack, initfunc=init_for_unpack, TOPXP=12)#, profile=profile, profresults=PROF_FILE_NAME) + benchutil.bench(unpack_and_repack, initfunc=init_for_unpack, + TOPXP=12)#, profile=profile, profresults=PROF_FILE_NAME) def print_stats(): s = hotshot.stats.load(PROF_FILE_NAME) diff --git a/src/allmydata/test/common.py b/src/allmydata/test/common.py index 5bc2f141a..5d31e5f93 100644 --- a/src/allmydata/test/common.py +++ b/src/allmydata/test/common.py @@ -39,8 +39,8 @@ class FakeCHKFileNode: bad_shares = {} def __init__(self, filecap): - precondition(isinstance(filecap, str), filecap) - self.my_uri = uri.CHKFileURI.init_from_string(filecap) + precondition(isinstance(filecap, uri.CHKFileURI), filecap) + self.my_uri = filecap self.storage_index = self.my_uri.storage_index def get_uri(self): @@ -130,18 +130,19 @@ class FakeCHKFileNode: d.addCallback(_got) return d +def make_chk_file_cap(size): + return uri.CHKFileURI(key=os.urandom(16), + uri_extension_hash=os.urandom(32), + needed_shares=3, + total_shares=10, + size=size) def make_chk_file_uri(size): - u = uri.CHKFileURI(key=os.urandom(16), - uri_extension_hash=os.urandom(32), - needed_shares=3, - total_shares=10, - size=size) - return u.to_string() + return make_chk_file_cap(size).to_string() def create_chk_filenode(contents): - filecap = make_chk_file_uri(len(contents)) + filecap = make_chk_file_cap(len(contents)) n = FakeCHKFileNode(filecap) - FakeCHKFileNode.all_contents[filecap] = contents + FakeCHKFileNode.all_contents[filecap.to_string()] = contents return n @@ -156,7 +157,7 @@ class FakeMutableFileNode: def __init__(self, storage_broker, secret_holder, default_encoding_parameters, history): - self.init_from_uri(make_mutable_file_uri()) + self.init_from_cap(make_mutable_file_cap()) def create(self, contents, key_generator=None, keysize=None): initial_contents = self._get_initial_contents(contents) if len(initial_contents) > self.MUTABLE_SIZELIMIT: @@ -173,15 +174,16 @@ class FakeMutableFileNode: assert callable(contents), "%s should be callable, not %s" % \ (contents, type(contents)) return contents(self) - def init_from_uri(self, filecap): - assert isinstance(filecap, str) - if filecap.startswith("URI:SSK:"): - self.my_uri = uri.WriteableSSKFileURI.init_from_string(filecap) - else: - assert filecap.startswith("URI:SSK-RO:") - self.my_uri = uri.ReadonlySSKFileURI.init_from_string(filecap) + def init_from_cap(self, filecap): + assert isinstance(filecap, (uri.WriteableSSKFileURI, + uri.ReadonlySSKFileURI)) + self.my_uri = filecap self.storage_index = self.my_uri.storage_index return self + def get_cap(self): + return self.my_uri + def get_readcap(self): + return self.my_uri.get_readonly() def get_uri(self): return self.my_uri.to_string() def get_readonly(self): @@ -296,9 +298,12 @@ class FakeMutableFileNode: data = self.all_contents[self.storage_index] return defer.succeed(data) -def make_mutable_file_uri(): +def make_mutable_file_cap(): return uri.WriteableSSKFileURI(writekey=os.urandom(16), - fingerprint=os.urandom(32)).to_string() + fingerprint=os.urandom(32)) +def make_mutable_file_uri(): + return make_mutable_file_cap().to_string() + def make_verifier_uri(): return uri.SSKVerifierURI(storage_index=os.urandom(16), fingerprint=os.urandom(32)).to_string() diff --git a/src/allmydata/test/test_dirnode.py b/src/allmydata/test/test_dirnode.py index 13e7ac47c..bfffd4ffb 100644 --- a/src/allmydata/test/test_dirnode.py +++ b/src/allmydata/test/test_dirnode.py @@ -1032,7 +1032,7 @@ class UCWEingNodeMaker(NodeMaker): n = UCWEingMutableFileNode(self.storage_broker, self.secret_holder, self.default_encoding_parameters, self.history) - return n.init_from_uri(cap) + return n.init_from_cap(cap) class Deleter(GridTestMixin, unittest.TestCase): diff --git a/src/allmydata/test/test_filenode.py b/src/allmydata/test/test_filenode.py index f9b75bc5e..1639c3337 100644 --- a/src/allmydata/test/test_filenode.py +++ b/src/allmydata/test/test_filenode.py @@ -32,12 +32,14 @@ class Node(unittest.TestCase): size=1000) c = FakeClient() cf = cachedir.CacheFile("none") - fn1 = filenode.FileNode(u.to_string(), None, None, None, None, cf) - fn2 = filenode.FileNode(u.to_string(), None, None, None, None, cf) + fn1 = filenode.FileNode(u, None, None, None, None, cf) + fn2 = filenode.FileNode(u, None, None, None, None, cf) self.failUnlessEqual(fn1, fn2) self.failIfEqual(fn1, "I am not a filenode") self.failIfEqual(fn1, NotANode()) self.failUnlessEqual(fn1.get_uri(), u.to_string()) + self.failUnlessEqual(fn1.get_cap(), u) + self.failUnlessEqual(fn1.get_readcap(), u) self.failUnlessEqual(fn1.is_readonly(), True) self.failUnlessEqual(fn1.is_mutable(), False) self.failUnlessEqual(fn1.get_readonly_uri(), u.to_string()) @@ -54,12 +56,14 @@ class Node(unittest.TestCase): DATA = "I am a short file." u = uri.LiteralFileURI(data=DATA) c = None - fn1 = filenode.LiteralFileNode(u.to_string()) - fn2 = filenode.LiteralFileNode(u.to_string()) + fn1 = filenode.LiteralFileNode(u) + fn2 = filenode.LiteralFileNode(u) self.failUnlessEqual(fn1, fn2) self.failIfEqual(fn1, "I am not a filenode") self.failIfEqual(fn1, NotANode()) self.failUnlessEqual(fn1.get_uri(), u.to_string()) + self.failUnlessEqual(fn1.get_cap(), u) + self.failUnlessEqual(fn1.get_readcap(), u) self.failUnlessEqual(fn1.is_readonly(), True) self.failUnlessEqual(fn1.is_mutable(), False) self.failUnlessEqual(fn1.get_readonly_uri(), u.to_string()) @@ -99,7 +103,7 @@ class Node(unittest.TestCase): u = uri.WriteableSSKFileURI("\x00"*16, "\x00"*32) n = MutableFileNode(None, None, client.get_encoding_parameters(), - None).init_from_uri(u.to_string()) + None).init_from_cap(u) self.failUnlessEqual(n.get_writekey(), wk) self.failUnlessEqual(n.get_readkey(), rk) @@ -112,11 +116,13 @@ class Node(unittest.TestCase): self.failUnlessEqual(n.get_uri(), u.to_string()) self.failUnlessEqual(n.get_readonly_uri(), u.get_readonly().to_string()) + self.failUnlessEqual(n.get_cap(), u) + self.failUnlessEqual(n.get_readcap(), u.get_readonly()) self.failUnlessEqual(n.is_mutable(), True) self.failUnlessEqual(n.is_readonly(), False) n2 = MutableFileNode(None, None, client.get_encoding_parameters(), - None).init_from_uri(u.to_string()) + None).init_from_cap(u) self.failUnlessEqual(n, n2) self.failIfEqual(n, "not even the right type") self.failIfEqual(n, u) # not the right class @@ -128,6 +134,8 @@ class Node(unittest.TestCase): self.failUnless(isinstance(nro, MutableFileNode)) self.failUnlessEqual(nro.get_readonly(), nro) + self.failUnlessEqual(nro.get_cap(), u.get_readonly()) + self.failUnlessEqual(nro.get_readcap(), u.get_readonly()) nro_u = nro.get_uri() self.failUnlessEqual(nro_u, nro.get_readonly_uri()) self.failUnlessEqual(nro_u, u.get_readonly().to_string()) @@ -143,7 +151,7 @@ class LiteralChecker(unittest.TestCase): def test_literal_filenode(self): DATA = "I am a short file." u = uri.LiteralFileURI(data=DATA) - fn1 = filenode.LiteralFileNode(u.to_string()) + fn1 = filenode.LiteralFileNode(u) d = fn1.check(Monitor()) def _check_checker_results(cr): diff --git a/src/allmydata/test/test_system.py b/src/allmydata/test/test_system.py index f419d243e..0a563309e 100644 --- a/src/allmydata/test/test_system.py +++ b/src/allmydata/test/test_system.py @@ -135,6 +135,7 @@ class SystemTest(SystemTestMixin, unittest.TestCase): log.msg("upload finished: uri is %s" % (theuri,)) self.uri = theuri assert isinstance(self.uri, str), self.uri + self.cap = uri.from_string(self.uri) self.downloader = self.clients[1].downloader d.addCallback(_upload_done) @@ -151,7 +152,7 @@ class SystemTest(SystemTestMixin, unittest.TestCase): def _download_to_data(res): log.msg("DOWNLOADING") - return self.downloader.download_to_data(self.uri) + return self.downloader.download_to_data(self.cap) d.addCallback(_download_to_data) def _download_to_data_done(data): log.msg("download finished") @@ -160,7 +161,7 @@ class SystemTest(SystemTestMixin, unittest.TestCase): target_filename = os.path.join(self.basedir, "download.target") def _download_to_filename(res): - return self.downloader.download_to_filename(self.uri, + return self.downloader.download_to_filename(self.cap, target_filename) d.addCallback(_download_to_filename) def _download_to_filename_done(res): @@ -171,7 +172,7 @@ class SystemTest(SystemTestMixin, unittest.TestCase): target_filename2 = os.path.join(self.basedir, "download.target2") def _download_to_filehandle(res): fh = open(target_filename2, "wb") - return self.downloader.download_to_filehandle(self.uri, fh) + return self.downloader.download_to_filehandle(self.cap, fh) d.addCallback(_download_to_filehandle) def _download_to_filehandle_done(fh): fh.close() @@ -182,7 +183,7 @@ class SystemTest(SystemTestMixin, unittest.TestCase): consumer = GrabEverythingConsumer() ct = download.ConsumerAdapter(consumer) d.addCallback(lambda res: - self.downloader.download(self.uri, ct)) + self.downloader.download(self.cap, ct)) def _download_to_consumer_done(ign): self.failUnlessEqual(consumer.contents, DATA) d.addCallback(_download_to_consumer_done) @@ -228,7 +229,7 @@ class SystemTest(SystemTestMixin, unittest.TestCase): baduri = self.mangle_uri(self.uri) log.msg("about to download non-existent URI", level=log.UNUSUAL, facility="tahoe.tests") - d1 = self.downloader.download_to_data(baduri) + d1 = self.downloader.download_to_data(uri.from_string(baduri)) def _baduri_should_fail(res): log.msg("finished downloading non-existend URI", level=log.UNUSUAL, facility="tahoe.tests") @@ -253,8 +254,8 @@ class SystemTest(SystemTestMixin, unittest.TestCase): u = upload.Data(HELPER_DATA, convergence=convergence) d = self.extra_node.upload(u) def _uploaded(results): - uri = results.uri - return self.downloader.download_to_data(uri) + cap = uri.from_string(results.uri) + return self.downloader.download_to_data(cap) d.addCallback(_uploaded) def _check(newdata): self.failUnlessEqual(newdata, HELPER_DATA) @@ -267,8 +268,8 @@ class SystemTest(SystemTestMixin, unittest.TestCase): u.debug_stash_RemoteEncryptedUploadable = True d = self.extra_node.upload(u) def _uploaded(results): - uri = results.uri - return self.downloader.download_to_data(uri) + cap = uri.from_string(results.uri) + return self.downloader.download_to_data(cap) d.addCallback(_uploaded) def _check(newdata): self.failUnlessEqual(newdata, HELPER_DATA) @@ -355,7 +356,7 @@ class SystemTest(SystemTestMixin, unittest.TestCase): d.addCallback(lambda res: self.extra_node.upload(u2)) def _uploaded(results): - uri = results.uri + cap = uri.from_string(results.uri) log.msg("Second upload complete", level=log.NOISY, facility="tahoe.test.test_system") @@ -383,7 +384,7 @@ class SystemTest(SystemTestMixin, unittest.TestCase): "resumption saved us some work even though we were using random keys:" " read %d bytes out of %d total" % (bytes_sent, len(DATA))) - return self.downloader.download_to_data(uri) + return self.downloader.download_to_data(cap) d.addCallback(_uploaded) def _check(newdata): diff --git a/src/allmydata/test/test_uri.py b/src/allmydata/test/test_uri.py index 1ee39ff17..744bd3a66 100644 --- a/src/allmydata/test/test_uri.py +++ b/src/allmydata/test/test_uri.py @@ -279,7 +279,7 @@ class NewDirnode(unittest.TestCase): self.failIf(IFileURI.providedBy(u1)) self.failUnless(IDirnodeURI.providedBy(u1)) self.failUnless("DirectoryURI" in str(u1)) - u1_filenode = u1.get_filenode_uri() + u1_filenode = u1.get_filenode_cap() self.failUnless(u1_filenode.is_mutable()) self.failIf(u1_filenode.is_readonly()) u1a = IDirnodeURI(u1.to_string()) @@ -302,7 +302,7 @@ class NewDirnode(unittest.TestCase): u3n = u3._filenode_uri self.failUnless(u3n.is_readonly()) self.failUnless(u3n.is_mutable()) - u3_filenode = u3.get_filenode_uri() + u3_filenode = u3.get_filenode_cap() self.failUnless(u3_filenode.is_mutable()) self.failUnless(u3_filenode.is_readonly()) @@ -318,7 +318,7 @@ class NewDirnode(unittest.TestCase): self.failUnless(IDirnodeURI.providedBy(u4)) u4_verifier = u4.get_verify_cap() - u4_verifier_filenode = u4_verifier.get_filenode_uri() + u4_verifier_filenode = u4_verifier.get_filenode_cap() self.failUnless(isinstance(u4_verifier_filenode, uri.SSKVerifierURI)) verifiers = [u1.get_verify_cap(), u2.get_verify_cap(), @@ -353,7 +353,7 @@ class NewDirnode(unittest.TestCase): self.failIf(IFileURI.providedBy(u1)) self.failUnless(IDirnodeURI.providedBy(u1)) self.failUnless("DirectoryURI" in str(u1)) - u1_filenode = u1.get_filenode_uri() + u1_filenode = u1.get_filenode_cap() self.failIf(u1_filenode.is_mutable()) self.failUnless(u1_filenode.is_readonly()) self.failUnlessEqual(u1_filenode.to_string(), fncap) @@ -375,7 +375,7 @@ class NewDirnode(unittest.TestCase): self.failUnless(isinstance(u2_verifier, uri.ImmutableDirectoryURIVerifier), u2_verifier) self.failUnless(IVerifierURI.providedBy(u2_verifier)) - u2_verifier_fileuri = u2_verifier.get_filenode_uri() + u2_verifier_fileuri = u2_verifier.get_filenode_cap() self.failUnless(IVerifierURI.providedBy(u2_verifier_fileuri)) self.failUnlessEqual(u2_verifier_fileuri.to_string(), fnuri.get_verify_cap().to_string()) diff --git a/src/allmydata/test/test_web.py b/src/allmydata/test/test_web.py index 676cfb62e..2555d17ab 100644 --- a/src/allmydata/test/test_web.py +++ b/src/allmydata/test/test_web.py @@ -43,7 +43,7 @@ class FakeNodeMaker(NodeMaker): def _create_immutable(self, cap): return FakeCHKFileNode(cap) def _create_mutable(self, cap): - return FakeMutableFileNode(None, None, None, None).init_from_uri(cap) + return FakeMutableFileNode(None, None, None, None).init_from_cap(cap) def create_mutable_file(self, contents="", keysize=None): n = FakeMutableFileNode(None, None, None, None) return n.create(contents) diff --git a/src/allmydata/uri.py b/src/allmydata/uri.py index 44a3b963f..531b88cad 100644 --- a/src/allmydata/uri.py +++ b/src/allmydata/uri.py @@ -374,7 +374,7 @@ class _DirectoryBaseURI(_BaseURI): def abbrev_si(self): return base32.b2a(self._filenode_uri.storage_index)[:5] - def get_filenode_uri(self): + def get_filenode_cap(self): return self._filenode_uri def is_mutable(self): @@ -475,7 +475,7 @@ class DirectoryURIVerifier(_DirectoryBaseURI): filenode_uri = IVerifierURI(filenode_uri) self._filenode_uri = filenode_uri - def get_filenode_uri(self): + def get_filenode_cap(self): return self._filenode_uri class ImmutableDirectoryURIVerifier(DirectoryURIVerifier):