mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-24 07:06:41 +00:00
vdrive: add get_node_at_path(pathlist)
This commit is contained in:
parent
13400e24ac
commit
d6e732b65f
@ -679,6 +679,19 @@ class IVirtualDrive(Interface):
|
|||||||
This returns a Deferred that fires with an IDirectoryNode instance
|
This returns a Deferred that fires with an IDirectoryNode instance
|
||||||
corresponding to this client's private root directory."""
|
corresponding to this client's private root directory."""
|
||||||
|
|
||||||
|
def get_node_at_path(self, path):
|
||||||
|
"""Transform a path into an IDirectoryNode or IFileNode.
|
||||||
|
|
||||||
|
The path is a list of path-name elements, typically constructed by
|
||||||
|
doing userpath.split('/') . If the first element of this list is '~',
|
||||||
|
the rest will be interpreted relative to the local user's private
|
||||||
|
root directory. Otherwse it will be interpreted relative to the
|
||||||
|
global public root directory.
|
||||||
|
|
||||||
|
This method returns a Deferred that fires with the node in question,
|
||||||
|
or errbacks with an IndexError if the target node could not be found.
|
||||||
|
"""
|
||||||
|
|
||||||
def get_node(self, uri):
|
def get_node(self, uri):
|
||||||
"""Transform a URI into an IDirectoryNode or IFileNode.
|
"""Transform a URI into an IDirectoryNode or IFileNode.
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ from allmydata import client, uri, download, upload
|
|||||||
from allmydata.introducer_and_vdrive import IntroducerAndVdrive
|
from allmydata.introducer_and_vdrive import IntroducerAndVdrive
|
||||||
from allmydata.util import idlib, fileutil, testutil
|
from allmydata.util import idlib, fileutil, testutil
|
||||||
from allmydata.scripts import runner
|
from allmydata.scripts import runner
|
||||||
|
from allmydata.interfaces import IDirectoryNode
|
||||||
from foolscap.eventual import flushEventualQueue
|
from foolscap.eventual import flushEventualQueue
|
||||||
from twisted.python import log
|
from twisted.python import log
|
||||||
from twisted.python.failure import Failure
|
from twisted.python.failure import Failure
|
||||||
@ -104,7 +105,7 @@ class SystemTest(testutil.SignalMixin, unittest.TestCase):
|
|||||||
return defer.succeed(None)
|
return defer.succeed(None)
|
||||||
|
|
||||||
def test_connections(self):
|
def test_connections(self):
|
||||||
self.basedir = "test_system/SystemTest/test_connections"
|
self.basedir = "system/SystemTest/test_connections"
|
||||||
d = self.set_up_nodes()
|
d = self.set_up_nodes()
|
||||||
self.extra_node = None
|
self.extra_node = None
|
||||||
d.addCallback(lambda res: self.add_extra_node(5))
|
d.addCallback(lambda res: self.add_extra_node(5))
|
||||||
@ -128,7 +129,7 @@ class SystemTest(testutil.SignalMixin, unittest.TestCase):
|
|||||||
del test_connections
|
del test_connections
|
||||||
|
|
||||||
def test_upload_and_download(self):
|
def test_upload_and_download(self):
|
||||||
self.basedir = "test_system/SystemTest/test_upload_and_download"
|
self.basedir = "system/SystemTest/test_upload_and_download"
|
||||||
# we use 4000 bytes of data, which will result in about 400k written
|
# we use 4000 bytes of data, which will result in about 400k written
|
||||||
# to disk among all our simulated nodes
|
# to disk among all our simulated nodes
|
||||||
DATA = "Some data to upload\n" * 200
|
DATA = "Some data to upload\n" * 200
|
||||||
@ -231,42 +232,131 @@ class SystemTest(testutil.SignalMixin, unittest.TestCase):
|
|||||||
# plaintext_hash check.
|
# plaintext_hash check.
|
||||||
|
|
||||||
def test_vdrive(self):
|
def test_vdrive(self):
|
||||||
self.basedir = "test_system/SystemTest/test_vdrive"
|
self.basedir = "system/SystemTest/test_vdrive"
|
||||||
self.data = DATA = "Some data to publish to the virtual drive\n"
|
self.data = DATA = "Some data to publish to the virtual drive\n"
|
||||||
d = self.set_up_nodes()
|
d = self.set_up_nodes()
|
||||||
def _do_publish(res):
|
d.addCallback(self.log, "starting publish")
|
||||||
log.msg("PUBLISHING")
|
d.addCallback(self._do_publish)
|
||||||
ut = upload.Data(DATA)
|
# at this point, we have the following global filesystem:
|
||||||
c0 = self.clients[0]
|
# /
|
||||||
d1 = c0.getServiceNamed("vdrive").get_public_root()
|
# /subdir1
|
||||||
d1.addCallback(lambda root: root.create_empty_directory("subdir1"))
|
# /subdir1/mydata567
|
||||||
d1.addCallback(lambda subdir1_node:
|
|
||||||
subdir1_node.add_file("mydata567", ut))
|
|
||||||
def _stash_uri(filenode):
|
|
||||||
self.uri = filenode.get_uri()
|
|
||||||
return filenode
|
|
||||||
d1.addCallback(_stash_uri)
|
|
||||||
return d1
|
|
||||||
d.addCallback(_do_publish)
|
|
||||||
def _publish_done(filenode):
|
|
||||||
log.msg("publish finished")
|
|
||||||
|
|
||||||
c1 = self.clients[1]
|
d.addCallback(self._bounce_client0)
|
||||||
d1 = c1.getServiceNamed("vdrive").get_public_root()
|
d.addCallback(self.log, "bounced client0")
|
||||||
d1.addCallback(lambda root: root.get("subdir1"))
|
|
||||||
d1.addCallback(lambda subdir1: subdir1.get("mydata567"))
|
d.addCallback(self._check_publish1)
|
||||||
d1.addCallback(lambda filenode: filenode.download_to_data())
|
d.addCallback(self.log, "did _check_publish1")
|
||||||
return d1
|
d.addCallback(self._check_publish2)
|
||||||
d.addCallback(_publish_done)
|
d.addCallback(self.log, "did _check_publish2")
|
||||||
def _get_done(data):
|
d.addCallback(self._do_publish_private)
|
||||||
log.msg("get finished")
|
d.addCallback(self.log, "did _do_publish_private")
|
||||||
self.failUnlessEqual(data, DATA)
|
# now we also have:
|
||||||
d.addCallback(_get_done)
|
# ~client0/personal/sekrit data
|
||||||
|
d.addCallback(self._check_publish_private)
|
||||||
|
d.addCallback(self.log, "did _check_publish_private")
|
||||||
d.addCallback(self._test_web)
|
d.addCallback(self._test_web)
|
||||||
d.addCallback(self._test_runner)
|
d.addCallback(self._test_runner)
|
||||||
return d
|
return d
|
||||||
test_vdrive.timeout = 1100
|
test_vdrive.timeout = 1100
|
||||||
|
|
||||||
|
def _do_publish(self, res):
|
||||||
|
ut = upload.Data(self.data)
|
||||||
|
c0 = self.clients[0]
|
||||||
|
d = c0.getServiceNamed("vdrive").get_public_root()
|
||||||
|
d.addCallback(lambda root: root.create_empty_directory("subdir1"))
|
||||||
|
d.addCallback(lambda subdir1_node:
|
||||||
|
subdir1_node.add_file("mydata567", ut))
|
||||||
|
d.addCallback(self.log, "publish finished")
|
||||||
|
def _stash_uri(filenode):
|
||||||
|
self.uri = filenode.get_uri()
|
||||||
|
return filenode
|
||||||
|
d.addCallback(_stash_uri)
|
||||||
|
return d
|
||||||
|
|
||||||
|
def _bounce_client0(self, res):
|
||||||
|
old_client0 = self.clients[0]
|
||||||
|
d = old_client0.disownServiceParent()
|
||||||
|
assert isinstance(d, defer.Deferred)
|
||||||
|
d.addCallback(self.log, "STOPPED")
|
||||||
|
def _stopped(res):
|
||||||
|
new_client0 = client.Client(basedir=self.getdir("client0"))
|
||||||
|
self.add_service(new_client0)
|
||||||
|
self.clients[0] = new_client0
|
||||||
|
return self.wait_for_connections()
|
||||||
|
d.addCallback(_stopped)
|
||||||
|
d.addCallback(self.log, "CONNECTED")
|
||||||
|
def _connected(res):
|
||||||
|
# now find out where the web port was
|
||||||
|
l = self.clients[0].getServiceNamed("webish").listener
|
||||||
|
port = l._port.getHost().port
|
||||||
|
self.webish_url = "http://localhost:%d/" % port
|
||||||
|
d.addCallback(_connected)
|
||||||
|
d.addCallback(self.log, "GOT WEB LISTENER")
|
||||||
|
return d
|
||||||
|
|
||||||
|
def log(self, res, msg):
|
||||||
|
#print msg
|
||||||
|
log.msg(msg)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _do_publish_private(self, res):
|
||||||
|
ut = upload.Data(self.data)
|
||||||
|
vdrive0 = self.clients[0].getServiceNamed("vdrive")
|
||||||
|
d = vdrive0.get_node_at_path(["~"])
|
||||||
|
d.addCallback(self.log, "GOT ~")
|
||||||
|
d.addCallback(lambda node: node.create_empty_directory("personal"))
|
||||||
|
d.addCallback(self.log, "made ~/personal")
|
||||||
|
d.addCallback(lambda node: node.add_file("sekrit data", ut))
|
||||||
|
return d
|
||||||
|
|
||||||
|
def _check_publish1(self, res):
|
||||||
|
# this one uses the iterative API
|
||||||
|
c1 = self.clients[1]
|
||||||
|
d = c1.getServiceNamed("vdrive").get_public_root()
|
||||||
|
d.addCallback(self.log, "check_publish1 got /")
|
||||||
|
d.addCallback(lambda root: root.get("subdir1"))
|
||||||
|
d.addCallback(lambda subdir1: subdir1.get("mydata567"))
|
||||||
|
d.addCallback(lambda filenode: filenode.download_to_data())
|
||||||
|
d.addCallback(self.log, "get finished")
|
||||||
|
def _get_done(data):
|
||||||
|
self.failUnlessEqual(data, self.data)
|
||||||
|
d.addCallback(_get_done)
|
||||||
|
return d
|
||||||
|
|
||||||
|
def _check_publish2(self, res):
|
||||||
|
# this one uses the path-based API
|
||||||
|
vdrive1 = self.clients[1].getServiceNamed("vdrive")
|
||||||
|
def get_path(path):
|
||||||
|
return vdrive1.get_node_at_path(path.split("/"))
|
||||||
|
d = get_path("subdir1")
|
||||||
|
d.addCallback(lambda dirnode:
|
||||||
|
self.failUnless(IDirectoryNode.providedBy(dirnode)))
|
||||||
|
d.addCallback(lambda res: get_path("subdir1/mydata567"))
|
||||||
|
d.addCallback(lambda filenode: filenode.download_to_data())
|
||||||
|
d.addCallback(lambda data: self.failUnlessEqual(data, self.data))
|
||||||
|
|
||||||
|
d.addCallback(lambda res: get_path("subdir1/mydata567"))
|
||||||
|
def _got_filenode(filenode):
|
||||||
|
d1 = vdrive1.get_node(filenode.get_uri())
|
||||||
|
d1.addCallback(self.failUnlessEqual, filenode)
|
||||||
|
return d1
|
||||||
|
d.addCallback(_got_filenode)
|
||||||
|
return d
|
||||||
|
|
||||||
|
def _check_publish_private(self, res):
|
||||||
|
# this one uses the path-based API
|
||||||
|
def get_path(path):
|
||||||
|
vdrive0 = self.clients[0].getServiceNamed("vdrive")
|
||||||
|
return vdrive0.get_node_at_path(path.split("/"))
|
||||||
|
d = get_path("~/personal")
|
||||||
|
d.addCallback(lambda dirnode:
|
||||||
|
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))
|
||||||
|
return d
|
||||||
|
|
||||||
def _test_web(self, res):
|
def _test_web(self, res):
|
||||||
base = self.webish_url
|
base = self.webish_url
|
||||||
d = getPage(base)
|
d = getPage(base)
|
||||||
|
@ -71,12 +71,6 @@ class VirtualDrive(service.MultiService):
|
|||||||
d.addCallback(_got_directory)
|
d.addCallback(_got_directory)
|
||||||
|
|
||||||
|
|
||||||
def get_node(self, node_uri):
|
|
||||||
if uri.is_dirnode_uri(node_uri):
|
|
||||||
return dirnode.create_directory_node(self.parent, node_uri)
|
|
||||||
else:
|
|
||||||
return defer.succeed(dirnode.FileNode(node_uri, self.parent))
|
|
||||||
|
|
||||||
def have_public_root(self):
|
def have_public_root(self):
|
||||||
return bool(self._global_uri)
|
return bool(self._global_uri)
|
||||||
def get_public_root(self):
|
def get_public_root(self):
|
||||||
@ -91,3 +85,30 @@ class VirtualDrive(service.MultiService):
|
|||||||
return defer.fail(NoPrivateVirtualDriveError())
|
return defer.fail(NoPrivateVirtualDriveError())
|
||||||
return self.get_node(self._private_uri)
|
return self.get_node(self._private_uri)
|
||||||
|
|
||||||
|
def get_node(self, node_uri):
|
||||||
|
if uri.is_dirnode_uri(node_uri):
|
||||||
|
return dirnode.create_directory_node(self.parent, node_uri)
|
||||||
|
else:
|
||||||
|
return defer.succeed(dirnode.FileNode(node_uri, self.parent))
|
||||||
|
|
||||||
|
|
||||||
|
def get_node_at_path(self, path, root=None):
|
||||||
|
assert isinstance(path, (list, tuple))
|
||||||
|
|
||||||
|
if root is None:
|
||||||
|
if path and path[0] == "~":
|
||||||
|
d = self.get_private_root()
|
||||||
|
d.addCallback(lambda node:
|
||||||
|
self.get_node_at_path(path[1:], node))
|
||||||
|
return d
|
||||||
|
d = self.get_public_root()
|
||||||
|
d.addCallback(lambda node: self.get_node_at_path(path, node))
|
||||||
|
return d
|
||||||
|
|
||||||
|
if path:
|
||||||
|
assert path[0] != ""
|
||||||
|
d = root.get(path[0])
|
||||||
|
d.addCallback(lambda node: self.get_node_at_path(path[1:], node))
|
||||||
|
return d
|
||||||
|
|
||||||
|
return root
|
||||||
|
Loading…
Reference in New Issue
Block a user