]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/commitdiff
vdrive: add get_node_at_path(pathlist)
authorBrian Warner <warner@allmydata.com>
Thu, 28 Jun 2007 18:00:03 +0000 (11:00 -0700)
committerBrian Warner <warner@allmydata.com>
Thu, 28 Jun 2007 18:00:03 +0000 (11:00 -0700)
src/allmydata/interfaces.py
src/allmydata/test/test_system.py
src/allmydata/vdrive.py

index 20d3ca9344721a1fe6e1909c4edab10a09069989..af99b727ce01a089e41811ceae9720ecf1d74447 100644 (file)
@@ -679,6 +679,19 @@ class IVirtualDrive(Interface):
         This returns a Deferred that fires with an IDirectoryNode instance
         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):
         """Transform a URI into an IDirectoryNode or IFileNode.
 
index 651dfc1f74208bc6e0bdd0952c8ae20a5345245f..5e6a248c0ea14b3e012cc22048a98a4e092caca9 100644 (file)
@@ -8,6 +8,7 @@ from allmydata import client, uri, download, upload
 from allmydata.introducer_and_vdrive import IntroducerAndVdrive
 from allmydata.util import idlib, fileutil, testutil
 from allmydata.scripts import runner
+from allmydata.interfaces import IDirectoryNode
 from foolscap.eventual import flushEventualQueue
 from twisted.python import log
 from twisted.python.failure import Failure
@@ -104,7 +105,7 @@ class SystemTest(testutil.SignalMixin, unittest.TestCase):
         return defer.succeed(None)
 
     def test_connections(self):
-        self.basedir = "test_system/SystemTest/test_connections"
+        self.basedir = "system/SystemTest/test_connections"
         d = self.set_up_nodes()
         self.extra_node = None
         d.addCallback(lambda res: self.add_extra_node(5))
@@ -128,7 +129,7 @@ class SystemTest(testutil.SignalMixin, unittest.TestCase):
     del test_connections
 
     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
         # to disk among all our simulated nodes
         DATA = "Some data to upload\n" * 200
@@ -231,42 +232,131 @@ class SystemTest(testutil.SignalMixin, unittest.TestCase):
     # plaintext_hash check.
 
     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"
         d = self.set_up_nodes()
-        def _do_publish(res):
-            log.msg("PUBLISHING")
-            ut = upload.Data(DATA)
-            c0 = self.clients[0]
-            d1 = c0.getServiceNamed("vdrive").get_public_root()
-            d1.addCallback(lambda root: root.create_empty_directory("subdir1"))
-            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]
-            d1 = c1.getServiceNamed("vdrive").get_public_root()
-            d1.addCallback(lambda root: root.get("subdir1"))
-            d1.addCallback(lambda subdir1: subdir1.get("mydata567"))
-            d1.addCallback(lambda filenode: filenode.download_to_data())
-            return d1
-        d.addCallback(_publish_done)
-        def _get_done(data):
-            log.msg("get finished")
-            self.failUnlessEqual(data, DATA)
-        d.addCallback(_get_done)
+        d.addCallback(self.log, "starting publish")
+        d.addCallback(self._do_publish)
+        # at this point, we have the following global filesystem:
+        # /
+        # /subdir1
+        # /subdir1/mydata567
+
+        d.addCallback(self._bounce_client0)
+        d.addCallback(self.log, "bounced client0")
+
+        d.addCallback(self._check_publish1)
+        d.addCallback(self.log, "did _check_publish1")
+        d.addCallback(self._check_publish2)
+        d.addCallback(self.log, "did _check_publish2")
+        d.addCallback(self._do_publish_private)
+        d.addCallback(self.log, "did _do_publish_private")
+        # now we also have:
+        #  ~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_runner)
         return d
     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):
         base = self.webish_url
         d = getPage(base)
index aa22aaada6b288ea9228b2aa662ff4b8b1a47b52..cb44d36f10327e7df668f00119afd8b2500dcc26 100644 (file)
@@ -71,12 +71,6 @@ class VirtualDrive(service.MultiService):
             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):
         return bool(self._global_uri)
     def get_public_root(self):
@@ -91,3 +85,30 @@ class VirtualDrive(service.MultiService):
             return defer.fail(NoPrivateVirtualDriveError())
         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