]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/commitdiff
dirnode.set_uri/set_children: change signature to take writecap+readcap
authorBrian Warner <warner@lothar.com>
Mon, 12 Oct 2009 23:51:26 +0000 (16:51 -0700)
committerBrian Warner <warner@lothar.com>
Mon, 12 Oct 2009 23:51:26 +0000 (16:51 -0700)
instead of a single cap. The webapi t=set_children call benefits too.

src/allmydata/dirnode.py
src/allmydata/interfaces.py
src/allmydata/test/test_deepcheck.py
src/allmydata/test/test_dirnode.py
src/allmydata/test/test_system.py
src/allmydata/test/test_web.py
src/allmydata/web/directory.py

index cacb0ade10f749d89a373e437298331c57a399fb..20faef2eccd0f7c3495ae6342bde18a0f1d65261 100644 (file)
@@ -380,19 +380,11 @@ class DirectoryNode:
         d = self.get_child_and_metadata(childname)
         return d
 
-    def set_uri(self, name, child_uri, metadata=None, overwrite=True):
-        """I add a child (by URI) at the specific name. I return a Deferred
-        that fires with the child node when the operation finishes. I will
-        replace any existing child of the same name.
-
-        The child_uri could be for a file, or for a directory (either
-        read-write or read-only, using a URI that came from get_uri() ).
-
-        If this directory node is read-only, the Deferred will errback with a
-        NotMutableError."""
+    def set_uri(self, name, writecap, readcap, metadata=None, overwrite=True):
         precondition(isinstance(name, unicode), name)
-        precondition(isinstance(child_uri, str), child_uri)
-        child_node = self._create_node(child_uri, None)
+        precondition(isinstance(writecap, (str,type(None))), writecap)
+        precondition(isinstance(readcap, (str,type(None))), readcap)
+        child_node = self._create_node(writecap, readcap)
         if isinstance(child_node, UnknownNode):
             # don't be willing to pack unknown nodes: we might accidentally
             # put some write-authority into the rocap slot because we don't
@@ -409,15 +401,16 @@ class DirectoryNode:
         a = Adder(self, overwrite=overwrite)
         node_entries = []
         for e in entries:
-            if len(e) == 2:
-                name, child_uri = e
+            if len(e) == 3:
+                name, writecap, readcap = e
                 metadata = None
             else:
-                assert len(e) == 3
-                name, child_uri, metadata = e
+                assert len(e) == 4
+                name, writecap, readcap, metadata = e
             assert isinstance(name, unicode)
-            assert isinstance(child_uri, str)
-            child_node = self._create_node(child_uri, None)
+            precondition(isinstance(writecap, (str,type(None))), writecap)
+            precondition(isinstance(readcap, (str,type(None))), readcap)
+            child_node = self._create_node(writecap, readcap)
             if isinstance(child_node, UnknownNode):
                 msg = "cannot pack unknown node as child %s" % str(name)
                 raise CannotPackUnknownNodeError(msg)
index e582ee20358d692f2930d4ff8467eb410b748348..ce6bc5b2e267b7aca94a836d0c4e0392335d666f 100644 (file)
@@ -873,15 +873,19 @@ class IDirectoryNode(IMutableFilesystemNode):
         is empty, the metadata will be an empty dictionary.
         """
 
-    def set_uri(name, child_uri, metadata=None, overwrite=True):
-        """I add a child (by URI) at the specific name. I return a Deferred
-        that fires when the operation finishes. If overwrite= is True, I will
-        replace any existing child of the same name, otherwise an existing
-        child will cause me to return ExistingChildError. The child name must
-        be a unicode string.
-
-        The child_uri could be for a file, or for a directory (either
-        read-write or read-only, using a URI that came from get_uri() ).
+    def set_uri(name, writecap, readcap=None, metadata=None, overwrite=True):
+        """I add a child (by writecap+readcap) at the specific name. I return
+        a Deferred that fires when the operation finishes. If overwrite= is
+        True, I will replace any existing child of the same name, otherwise
+        an existing child will cause me to return ExistingChildError. The
+        child name must be a unicode string.
+
+        The child caps could be for a file, or for a directory. If the new
+        child is read/write, you will provide both writecap and readcap. If
+        the child is read-only, you will provide the readcap write (i.e. the
+        writecap= and readcap= arguments will both be the child's readcap).
+        The filecaps are typically obtained from an IFilesystemNode with
+        get_uri() and get_readonly_uri().
 
         If metadata= is provided, I will use it as the metadata for the named
         edge. This will replace any existing metadata. If metadata= is left
@@ -894,11 +898,11 @@ class IDirectoryNode(IMutableFilesystemNode):
         NotMutableError."""
 
     def set_children(entries, overwrite=True):
-        """Add multiple (name, child_uri) pairs (or (name, child_uri,
-        metadata) triples) to a directory node. Returns a Deferred that fires
-        (with None) when the operation finishes. This is equivalent to
-        calling set_uri() multiple times, but is much more efficient. All
-        child names must be unicode strings.
+        """Add multiple (name, writecap, readcap) triples (or (name,
+        writecap, readcap, metadata) 4-tuples) to a directory node. Returns a
+        Deferred that fires (with None) when the operation finishes. This is
+        equivalent to calling set_uri() multiple times, but is much more
+        efficient. All child names must be unicode strings.
         """
 
     def set_node(name, child, metadata=None, overwrite=True):
index e1cb38717273bfc527f24f3d5e7b0d2ea6e2a2fd..be3f35a698f7d9b186377e5c119db9d426f71651 100644 (file)
@@ -1186,8 +1186,8 @@ class Large(DeepCheckBase, unittest.TestCase):
             self.subdir_node = subdir_node
             kids = []
             for i in range(1, COUNT):
-                litnode = LiteralFileURI("%03d-data" % i).to_string()
-                kids.append( (u"%03d-small" % i, litnode) )
+                litcap = LiteralFileURI("%03d-data" % i).to_string()
+                kids.append( (u"%03d-small" % i, litcap, litcap) )
             return subdir_node.set_children(kids)
         d.addCallback(_add_children)
         up = upload.Data("large enough for CHK" * 100, "")
index fcd53702b632173daf0f4fc67d364884a826c7ce..aee125bf25f3be9a55c8e96b40396a9cdbbaee17 100644 (file)
@@ -67,6 +67,7 @@ class Dirnode(GridTestMixin, unittest.TestCase,
             d.addCallback(lambda res: c.create_dirnode())
             d.addCallback(lambda dn:
                           self._rootnode.set_uri(u"rodir",
+                                                 dn.get_uri(),
                                                  dn.get_readonly_uri()))
             return d
         d.addCallback(_created_subdir)
@@ -159,7 +160,7 @@ class Dirnode(GridTestMixin, unittest.TestCase,
 
         d = c.create_dirnode()
         def _created(rw_dn):
-            d2 = rw_dn.set_uri(u"child", filecap)
+            d2 = rw_dn.set_uri(u"child", filecap, filecap)
             d2.addCallback(lambda res: rw_dn)
             return d2
         d.addCallback(_created)
@@ -171,7 +172,7 @@ class Dirnode(GridTestMixin, unittest.TestCase,
             self.failUnless(ro_dn.is_mutable())
 
             self.shouldFail(dirnode.NotMutableError, "set_uri ro", None,
-                            ro_dn.set_uri, u"newchild", filecap)
+                            ro_dn.set_uri, u"newchild", filecap, filecap)
             self.shouldFail(dirnode.NotMutableError, "set_uri ro", None,
                             ro_dn.set_node, u"newchild", filenode)
             self.shouldFail(dirnode.NotMutableError, "set_nodes ro", None,
@@ -243,11 +244,13 @@ class Dirnode(GridTestMixin, unittest.TestCase,
             self.expected_manifest.append( ((u"child",) , m.get_uri()) )
             self.expected_verifycaps.add(ffu_v)
             self.expected_storage_indexes.add(base32.b2a(m.get_storage_index()))
-            d.addCallback(lambda res: n.set_uri(u"child", fake_file_uri))
+            d.addCallback(lambda res: n.set_uri(u"child",
+                                                fake_file_uri, fake_file_uri))
             d.addCallback(lambda res:
                           self.shouldFail(ExistingChildError, "set_uri-no",
                                           "child 'child' already exists",
-                                          n.set_uri, u"child", other_file_uri,
+                                          n.set_uri, u"child",
+                                          other_file_uri, other_file_uri,
                                           overwrite=False))
             # /
             # /child = mutable
@@ -373,12 +376,16 @@ class Dirnode(GridTestMixin, unittest.TestCase,
 
             # set_uri + metadata
             # it should be possible to add a child without any metadata
-            d.addCallback(lambda res: n.set_uri(u"c2", fake_file_uri, {}))
+            d.addCallback(lambda res: n.set_uri(u"c2",
+                                                fake_file_uri, fake_file_uri,
+                                                {}))
             d.addCallback(lambda res: n.get_metadata_for(u"c2"))
             d.addCallback(lambda metadata: self.failUnlessEqual(metadata.keys(), ['tahoe']))
 
             # You can't override the link timestamps.
-            d.addCallback(lambda res: n.set_uri(u"c2", fake_file_uri, { 'tahoe': {'linkcrtime': "bogus"}}))
+            d.addCallback(lambda res: n.set_uri(u"c2",
+                                                fake_file_uri, fake_file_uri,
+                                                { 'tahoe': {'linkcrtime': "bogus"}}))
             d.addCallback(lambda res: n.get_metadata_for(u"c2"))
             def _has_good_linkcrtime(metadata):
                 self.failUnless(metadata.has_key('tahoe'))
@@ -387,7 +394,8 @@ class Dirnode(GridTestMixin, unittest.TestCase,
             d.addCallback(_has_good_linkcrtime)
 
             # if we don't set any defaults, the child should get timestamps
-            d.addCallback(lambda res: n.set_uri(u"c3", fake_file_uri))
+            d.addCallback(lambda res: n.set_uri(u"c3",
+                                                fake_file_uri, fake_file_uri))
             d.addCallback(lambda res: n.get_metadata_for(u"c3"))
             d.addCallback(lambda metadata:
                           self.failUnlessEqual(set(metadata.keys()),
@@ -395,7 +403,8 @@ class Dirnode(GridTestMixin, unittest.TestCase,
 
             # or we can add specific metadata at set_uri() time, which
             # overrides the timestamps
-            d.addCallback(lambda res: n.set_uri(u"c4", fake_file_uri,
+            d.addCallback(lambda res: n.set_uri(u"c4",
+                                                fake_file_uri, fake_file_uri,
                                                 {"key": "value"}))
             d.addCallback(lambda res: n.get_metadata_for(u"c4"))
             d.addCallback(lambda metadata:
@@ -439,17 +448,19 @@ class Dirnode(GridTestMixin, unittest.TestCase,
             d.addCallback(lambda res: n.delete(u"d4"))
 
             # metadata through set_children()
-            d.addCallback(lambda res: n.set_children([ (u"e1", fake_file_uri),
-                                                   (u"e2", fake_file_uri, {}),
-                                                   (u"e3", fake_file_uri,
-                                                    {"key": "value"}),
-                                                   ]))
+            d.addCallback(lambda res:
+                          n.set_children([
+                              (u"e1", fake_file_uri, fake_file_uri),
+                              (u"e2", fake_file_uri, fake_file_uri, {}),
+                              (u"e3", fake_file_uri, fake_file_uri,
+                               {"key": "value"}),
+                              ]))
             d.addCallback(lambda res:
                           self.shouldFail(ExistingChildError, "set_children-no",
                                           "child 'e1' already exists",
                                           n.set_children,
-                                          [ (u"e1", other_file_uri),
-                                            (u"new", other_file_uri), ],
+                                          [ (u"e1", other_file_uri, other_file_uri),
+                                            (u"new", other_file_uri, other_file_uri), ],
                                           overwrite=False))
             # and 'new' should not have been created
             d.addCallback(lambda res: n.list())
@@ -645,7 +656,8 @@ class Dirnode(GridTestMixin, unittest.TestCase,
 
             # now make sure that we honor overwrite=False
             d.addCallback(lambda res:
-                          self.subdir2.set_uri(u"newchild", other_file_uri))
+                          self.subdir2.set_uri(u"newchild",
+                                               other_file_uri, other_file_uri))
 
             d.addCallback(lambda res:
                           self.shouldFail(ExistingChildError, "move_child_to-no",
@@ -804,7 +816,8 @@ class Dirnode2(unittest.TestCase, testutil.ShouldFailMixin):
              self.shouldFail(CannotPackUnknownNodeError,
                              "copy unknown",
                              "cannot pack unknown node as child add",
-                             self._node.set_uri, u"add", future_writecap))
+                             self._node.set_uri, u"add",
+                             future_writecap, future_readcap))
         d.addCallback(lambda ign: self._node.list())
         def _check(children):
             self.failUnlessEqual(len(children), 1)
index 166a72f7a23e73eba7a025b7fa08207fcc69a2af..ed99d7955e110993dc9fdeb1595b983a4e133891 100644 (file)
@@ -862,8 +862,12 @@ class SystemTest(SystemTestMixin, unittest.TestCase):
             d1.addCallback(self.log, "made P/personal/sekrit data")
             d1.addCallback(lambda res: rootnode.get_child_at_path([u"subdir1", u"subdir2"]))
             def _got_s2(s2node):
-                d2 = privnode.set_uri(u"s2-rw", s2node.get_uri())
-                d2.addCallback(lambda node: privnode.set_uri(u"s2-ro", s2node.get_readonly_uri()))
+                d2 = privnode.set_uri(u"s2-rw", s2node.get_uri(),
+                                      s2node.get_readonly_uri())
+                d2.addCallback(lambda node:
+                               privnode.set_uri(u"s2-ro",
+                                                s2node.get_readonly_uri(),
+                                                s2node.get_readonly_uri()))
                 return d2
             d1.addCallback(_got_s2)
             d1.addCallback(lambda res: privnode)
@@ -944,7 +948,7 @@ class SystemTest(SystemTestMixin, unittest.TestCase):
             d1.addCallback(self.log, "doing delete(ro)")
             d1.addCallback(lambda res: self.shouldFail2(NotMutableError, "delete(nope)", None, dirnode.delete, u"mydata992"))
 
-            d1.addCallback(lambda res: self.shouldFail2(NotMutableError, "set_uri(nope)", None, dirnode.set_uri, u"hopeless", self.uri))
+            d1.addCallback(lambda res: self.shouldFail2(NotMutableError, "set_uri(nope)", None, dirnode.set_uri, u"hopeless", self.uri, self.uri))
 
             d1.addCallback(lambda res: self.shouldFail2(NoSuchChildError, "get(missing)", "missing", dirnode.get, u"missing"))
 
index f829abaf2d9da6aba164d06ce23985aa91229616..b3573dc4c7adaee328d931ac8c1b77a2898f3281 100644 (file)
@@ -136,37 +136,40 @@ class WebMixin(object):
             self._foo_verifycap = foo.get_verify_cap().to_string()
             # NOTE: we ignore the deferred on all set_uri() calls, because we
             # know the fake nodes do these synchronously
-            self.public_root.set_uri(u"foo", foo.get_uri())
+            self.public_root.set_uri(u"foo", foo.get_uri(),
+                                     foo.get_readonly_uri())
 
             self.BAR_CONTENTS, n, self._bar_txt_uri = self.makefile(0)
-            foo.set_uri(u"bar.txt", self._bar_txt_uri)
+            foo.set_uri(u"bar.txt", self._bar_txt_uri, self._bar_txt_uri)
             self._bar_txt_verifycap = n.get_verify_cap().to_string()
 
-            foo.set_uri(u"empty", res[3][1].get_uri())
+            foo.set_uri(u"empty", res[3][1].get_uri(),
+                        res[3][1].get_readonly_uri())
             sub_uri = res[4][1].get_uri()
             self._sub_uri = sub_uri
-            foo.set_uri(u"sub", sub_uri)
+            foo.set_uri(u"sub", sub_uri, sub_uri)
             sub = self.s.create_node_from_uri(sub_uri)
 
             _ign, n, blocking_uri = self.makefile(1)
-            foo.set_uri(u"blockingfile", blocking_uri)
+            foo.set_uri(u"blockingfile", blocking_uri, blocking_uri)
 
             unicode_filename = u"n\u00fc.txt" # n u-umlaut . t x t
             # ok, unicode calls it LATIN SMALL LETTER U WITH DIAERESIS but I
             # still think of it as an umlaut
-            foo.set_uri(unicode_filename, self._bar_txt_uri)
+            foo.set_uri(unicode_filename, self._bar_txt_uri, self._bar_txt_uri)
 
             _ign, n, baz_file = self.makefile(2)
             self._baz_file_uri = baz_file
-            sub.set_uri(u"baz.txt", baz_file)
+            sub.set_uri(u"baz.txt", baz_file, baz_file)
 
             _ign, n, self._bad_file_uri = self.makefile(3)
             # this uri should not be downloadable
             del FakeCHKFileNode.all_contents[self._bad_file_uri]
 
             rodir = res[5][1]
-            self.public_root.set_uri(u"reedownlee", rodir.get_readonly_uri())
-            rodir.set_uri(u"nor", baz_file)
+            self.public_root.set_uri(u"reedownlee", rodir.get_readonly_uri(),
+                                     rodir.get_readonly_uri())
+            rodir.set_uri(u"nor", baz_file, baz_file)
 
             # public/
             # public/foo/
index d1d9faad49bb1667e38eef77336038906ffe1db5..89b0872533ca05fe121a96c94dd7ec80b62c6a59 100644 (file)
@@ -204,7 +204,6 @@ class DirectoryNodeHandler(RenderMixin, rend.Page, ReplaceMeMixin):
         elif t == "stream-manifest":
             d = self._POST_stream_manifest(ctx)
         elif t == "set_children":
-            # TODO: docs
             d = self._POST_set_children(req)
         else:
             raise WebError("POST to a directory with bad t=%s" % t)
@@ -303,7 +302,7 @@ class DirectoryNodeHandler(RenderMixin, rend.Page, ReplaceMeMixin):
         charset = get_arg(req, "_charset", "utf-8")
         name = name.decode(charset)
         replace = boolean_of_arg(get_arg(req, "replace", "true"))
-        d = self.node.set_uri(name, childcap, overwrite=replace)
+        d = self.node.set_uri(name, childcap, childcap, overwrite=replace)
         d.addCallback(lambda res: childcap)
         return d
 
@@ -471,8 +470,13 @@ class DirectoryNodeHandler(RenderMixin, rend.Page, ReplaceMeMixin):
         cs = []
         for name, (file_or_dir, mddict) in children.iteritems():
             name = unicode(name) # simplejson-2.0.1 returns str *or* unicode
-            cap = str(mddict.get('rw_uri') or mddict.get('ro_uri'))
-            cs.append((name, cap, mddict.get('metadata')))
+            writecap = mddict.get('rw_uri')
+            if writecap is not None:
+                writecap = str(writecap)
+            readcap = mddict.get('ro_uri')
+            if readcap is not None:
+                readcap = str(readcap)
+            cs.append((name, writecap, readcap, mddict.get('metadata')))
         d = self.node.set_children(cs, replace)
         d.addCallback(lambda res: "Okay so I did it.")
         # TODO: results