From cf65cc2ae3cc10624479d0e52da6592610ab8899 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Mon, 12 Oct 2009 19:15:20 -0700 Subject: [PATCH] replace dirnode.create_empty_directory() with create_subdirectory(), which takes an initial_children= argument --- src/allmydata/dirnode.py | 7 ++--- src/allmydata/frontends/ftpd.py | 2 +- src/allmydata/frontends/sftpd.py | 2 +- src/allmydata/interfaces.py | 12 ++++--- src/allmydata/test/test_cli.py | 9 ++---- src/allmydata/test/test_deepcheck.py | 6 ++-- src/allmydata/test/test_dirnode.py | 47 +++++++++++++++++++++++----- src/allmydata/test/test_system.py | 8 ++--- src/allmydata/test/test_web.py | 2 +- src/allmydata/web/directory.py | 8 ++--- 10 files changed, 67 insertions(+), 36 deletions(-) diff --git a/src/allmydata/dirnode.py b/src/allmydata/dirnode.py index c7e6f56f..ba6d5528 100644 --- a/src/allmydata/dirnode.py +++ b/src/allmydata/dirnode.py @@ -475,14 +475,13 @@ class DirectoryNode: d.addCallback(lambda res: deleter.old_child) return d - def create_empty_directory(self, name, overwrite=True): - """I create and attach an empty directory at the given name. I return - a Deferred that fires (with the new directory node) when the - operation finishes.""" + def create_subdirectory(self, name, initial_children={}, overwrite=True): assert isinstance(name, unicode) if self.is_readonly(): return defer.fail(NotMutableError()) d = self._nodemaker.create_new_mutable_directory() + if initial_children: + d.addCallback(lambda n: n.set_children(initial_children)) def _created(child): entries = [(name, child, None)] a = Adder(self, entries, overwrite=overwrite) diff --git a/src/allmydata/frontends/ftpd.py b/src/allmydata/frontends/ftpd.py index e9447716..4d4256df 100644 --- a/src/allmydata/frontends/ftpd.py +++ b/src/allmydata/frontends/ftpd.py @@ -85,7 +85,7 @@ class Handler: d = node.get(path[0]) def _maybe_create(f): f.trap(NoSuchChildError) - return node.create_empty_directory(path[0]) + return node.create_subdirectory(path[0]) d.addErrback(_maybe_create) d.addCallback(self._get_or_create_directories, path[1:]) return d diff --git a/src/allmydata/frontends/sftpd.py b/src/allmydata/frontends/sftpd.py index aa15bbba..5a713e1c 100644 --- a/src/allmydata/frontends/sftpd.py +++ b/src/allmydata/frontends/sftpd.py @@ -242,7 +242,7 @@ class SFTPHandler: d = node.get(path[0]) def _maybe_create(f): f.trap(NoSuchChildError) - return node.create_empty_directory(path[0]) + return node.create_subdirectory(path[0]) d.addErrback(_maybe_create) d.addCallback(self._get_or_create_directories, path[1:]) return d diff --git a/src/allmydata/interfaces.py b/src/allmydata/interfaces.py index 42ec62c0..66d742ee 100644 --- a/src/allmydata/interfaces.py +++ b/src/allmydata/interfaces.py @@ -946,10 +946,14 @@ class IDirectoryNode(IMutableFilesystemNode): string. I raise NoSuchChildError if I do not have a child by that name.""" - def create_empty_directory(name, overwrite=True): - """I create and attach an empty directory at the given name. The - child name must be a unicode string. I return a Deferred that fires - when the operation finishes.""" + def create_subdirectory(name, initial_children={}, overwrite=True): + """I create and attach a directory at the given name. The new + directory can be empty, or it can be populated with children + according to 'initial_children', which takes a dictionary in the same + format as set_children (i.e. mapping unicode child name to (writecap, + readcap, metadata) triples). The child name must be a unicode string. + I return a Deferred that fires (with the new directory node) when the + operation finishes.""" def move_child_to(current_child_name, new_parent, new_child_name=None, overwrite=True): diff --git a/src/allmydata/test/test_cli.py b/src/allmydata/test/test_cli.py index 468f0fe7..56a83470 100644 --- a/src/allmydata/test/test_cli.py +++ b/src/allmydata/test/test_cli.py @@ -754,12 +754,10 @@ class List(GridTestMixin, CLITestMixin, unittest.TestCase): self.rooturi = n.get_uri() return n.add_file(u"good", upload.Data("small", convergence="")) d.addCallback(_stash_root_and_create_file) - d.addCallback(lambda ign: - self.rootnode.create_empty_directory(u"1share")) + d.addCallback(lambda ign: self.rootnode.create_subdirectory(u"1share")) d.addCallback(lambda n: self.delete_shares_numbered(n.get_uri(), range(1,10))) - d.addCallback(lambda ign: - self.rootnode.create_empty_directory(u"0share")) + d.addCallback(lambda ign: self.rootnode.create_subdirectory(u"0share")) d.addCallback(lambda n: self.delete_shares_numbered(n.get_uri(), range(0,10))) d.addCallback(lambda ign: @@ -1471,8 +1469,7 @@ class Check(GridTestMixin, CLITestMixin, unittest.TestCase): # now add a subdir, and a file below that, then make the subdir # unrecoverable - d.addCallback(lambda ign: - self.rootnode.create_empty_directory(u"subdir")) + d.addCallback(lambda ign: self.rootnode.create_subdirectory(u"subdir")) d.addCallback(_stash_uri, "subdir") d.addCallback(lambda fn: fn.add_file(u"subfile", upload.Data(DATA+"2", ""))) diff --git a/src/allmydata/test/test_deepcheck.py b/src/allmydata/test/test_deepcheck.py index 0ec2ef84..165013c5 100644 --- a/src/allmydata/test/test_deepcheck.py +++ b/src/allmydata/test/test_deepcheck.py @@ -887,11 +887,11 @@ class DeepCheckWebBad(DeepCheckBase, unittest.TestCase): d.addCallback(lambda ignored: self.nodes["broken"].add_file(u"large1", large1)) d.addCallback(lambda ignored: - self.nodes["broken"].create_empty_directory(u"subdir-good")) + self.nodes["broken"].create_subdirectory(u"subdir-good")) large2 = upload.Data("Lots of data\n" * 1000 + "large2" + "\n", None) d.addCallback(lambda subdir: subdir.add_file(u"large2-good", large2)) d.addCallback(lambda ignored: - self.nodes["broken"].create_empty_directory(u"subdir-unrecoverable")) + self.nodes["broken"].create_subdirectory(u"subdir-unrecoverable")) d.addCallback(self._stash_node, "subdir-unrecoverable") large3 = upload.Data("Lots of data\n" * 1000 + "large3" + "\n", None) d.addCallback(lambda subdir: subdir.add_file(u"large3-good", large3)) @@ -1181,7 +1181,7 @@ class Large(DeepCheckBase, unittest.TestCase): self.root = n return n d.addCallback(_created_root) - d.addCallback(lambda root: root.create_empty_directory(u"subdir")) + d.addCallback(lambda root: root.create_subdirectory(u"subdir")) def _add_children(subdir_node): self.subdir_node = subdir_node kids = {} diff --git a/src/allmydata/test/test_dirnode.py b/src/allmydata/test/test_dirnode.py index 097a9a15..4330ce9e 100644 --- a/src/allmydata/test/test_dirnode.py +++ b/src/allmydata/test/test_dirnode.py @@ -58,7 +58,7 @@ class Dirnode(GridTestMixin, unittest.TestCase, d = c.create_dirnode() def _created_root(rootnode): self._rootnode = rootnode - return rootnode.create_empty_directory(u"subdir") + return rootnode.create_subdirectory(u"subdir") d.addCallback(_created_root) def _created_subdir(subdir): self._subdir = subdir @@ -182,7 +182,7 @@ class Dirnode(GridTestMixin, unittest.TestCase, self.shouldFail(dirnode.NotMutableError, "set_uri ro", None, ro_dn.delete, u"child") self.shouldFail(dirnode.NotMutableError, "set_uri ro", None, - ro_dn.create_empty_directory, u"newchild") + ro_dn.create_subdirectory, u"newchild") self.shouldFail(dirnode.NotMutableError, "set_metadata_for ro", None, ro_dn.set_metadata_for, u"child", {}) self.shouldFail(dirnode.NotMutableError, "set_uri ro", None, @@ -255,7 +255,7 @@ class Dirnode(GridTestMixin, unittest.TestCase, # / # /child = mutable - d.addCallback(lambda res: n.create_empty_directory(u"subdir")) + d.addCallback(lambda res: n.create_subdirectory(u"subdir")) # / # /child = mutable @@ -274,7 +274,7 @@ class Dirnode(GridTestMixin, unittest.TestCase, d.addCallback(lambda res: self.shouldFail(ExistingChildError, "mkdir-no", "child 'subdir' already exists", - n.create_empty_directory, u"subdir", + n.create_subdirectory, u"subdir", overwrite=False)) d.addCallback(lambda res: n.list()) @@ -322,7 +322,7 @@ class Dirnode(GridTestMixin, unittest.TestCase, d.addCallback(_check_manifest) def _add_subsubdir(res): - return self.subdir.create_empty_directory(u"subsubdir") + return self.subdir.create_subdirectory(u"subsubdir") d.addCallback(_add_subsubdir) # / # /child = mutable @@ -624,7 +624,7 @@ class Dirnode(GridTestMixin, unittest.TestCase, (metadata['key'] == "value"), metadata)) d.addCallback(lambda res: n.delete(u"newfile-metadata")) - d.addCallback(lambda res: n.create_empty_directory(u"subdir2")) + d.addCallback(lambda res: n.create_subdirectory(u"subdir2")) def _created2(subdir2): self.subdir2 = subdir2 # put something in the way, to make sure it gets overwritten @@ -682,6 +682,37 @@ class Dirnode(GridTestMixin, unittest.TestCase, d.addErrback(self.explain_error) return d + def test_create_subdirectory(self): + self.basedir = "dirnode/Dirnode/test_create_subdirectory" + self.set_up_grid() + c = self.g.clients[0] + + d = c.create_dirnode() + def _then(n): + # / + self.rootnode = n + fake_file_uri = make_mutable_file_uri() + other_file_uri = make_mutable_file_uri() + md = {"metakey": "metavalue"} + kids = {u"kid1": (fake_file_uri, fake_file_uri), + u"kid2": (other_file_uri, other_file_uri, md), + } + d = n.create_subdirectory(u"subdir", kids) + def _check(sub): + d = n.get_child_at_path(u"subdir") + d.addCallback(lambda sub2: self.failUnlessEqual(sub2.get_uri(), + sub.get_uri())) + d.addCallback(lambda ign: sub.list()) + return d + d.addCallback(_check) + def _check_kids(kids2): + self.failUnlessEqual(sorted(kids.keys()), sorted(kids2.keys())) + self.failUnlessEqual(kids2[u"kid2"][1]["metakey"], "metavalue") + d.addCallback(_check_kids) + return d + d.addCallback(_then) + return d + class Packing(unittest.TestCase): # This is a base32-encoded representation of the directory tree # root/file1 @@ -974,7 +1005,7 @@ class Adder(GridTestMixin, unittest.TestCase, testutil.ShouldFailMixin): d.addCallback(lambda res: root_node.add_file(u'file2', upload.Data("Sekrit Codes", None))) d.addCallback(lambda res: - root_node.create_empty_directory(u"dir1")) + root_node.create_subdirectory(u"dir1")) d.addCallback(lambda res: root_node) return d @@ -984,7 +1015,7 @@ class Adder(GridTestMixin, unittest.TestCase, testutil.ShouldFailMixin): d = root_node.set_node(u'file1', filenode) # We've overwritten file1. Let's try it with a directory d.addCallback(lambda res: - root_node.create_empty_directory(u'dir2')) + root_node.create_subdirectory(u'dir2')) d.addCallback(lambda res: root_node.set_node(u'dir2', filenode)) # We try overwriting a file with a child while also specifying diff --git a/src/allmydata/test/test_system.py b/src/allmydata/test/test_system.py index ed99d795..f419d243 100644 --- a/src/allmydata/test/test_system.py +++ b/src/allmydata/test/test_system.py @@ -825,7 +825,7 @@ class SystemTest(SystemTestMixin, unittest.TestCase): self._root_directory_uri = new_dirnode.get_uri() return c0.create_node_from_uri(self._root_directory_uri) d.addCallback(_made_root) - d.addCallback(lambda root: root.create_empty_directory(u"subdir1")) + d.addCallback(lambda root: root.create_subdirectory(u"subdir1")) def _made_subdir1(subdir1_node): self._subdir1_node = subdir1_node d1 = subdir1_node.add_file(u"mydata567", ut) @@ -840,7 +840,7 @@ class SystemTest(SystemTestMixin, unittest.TestCase): def _do_publish2(self, res): ut = upload.Data(self.data, convergence=None) - d = self._subdir1_node.create_empty_directory(u"subdir2") + d = self._subdir1_node.create_subdirectory(u"subdir2") d.addCallback(lambda subdir2: subdir2.add_file(u"mydata992", ut)) return d @@ -856,7 +856,7 @@ class SystemTest(SystemTestMixin, unittest.TestCase): d.addCallback(self.log, "GOT private directory") def _got_new_dir(privnode): rootnode = self.clients[0].create_node_from_uri(self._root_directory_uri) - d1 = privnode.create_empty_directory(u"personal") + d1 = privnode.create_subdirectory(u"personal") d1.addCallback(self.log, "made P/personal") d1.addCallback(lambda node: node.add_file(u"sekrit data", ut)) d1.addCallback(self.log, "made P/personal/sekrit data") @@ -934,7 +934,7 @@ class SystemTest(SystemTestMixin, unittest.TestCase): d1.addCallback(lambda res: dirnode.list()) d1.addCallback(self.log, "dirnode.list") - d1.addCallback(lambda res: self.shouldFail2(NotMutableError, "mkdir(nope)", None, dirnode.create_empty_directory, u"nope")) + d1.addCallback(lambda res: self.shouldFail2(NotMutableError, "mkdir(nope)", None, dirnode.create_subdirectory, u"nope")) d1.addCallback(self.log, "doing add_file(ro)") ut = upload.Data("I will disappear, unrecorded and unobserved. The tragedy of my demise is made more poignant by its silence, but this beauty is not for you to ever know.", convergence="99i-p1x4-xd4-18yc-ywt-87uu-msu-zo -- completely and totally unguessable string (unless you read this)") diff --git a/src/allmydata/test/test_web.py b/src/allmydata/test/test_web.py index b3573dc4..3ac6c660 100644 --- a/src/allmydata/test/test_web.py +++ b/src/allmydata/test/test_web.py @@ -2972,7 +2972,7 @@ class Grid(GridTestMixin, WebErrorMixin, unittest.TestCase, ShouldFailMixin): # unrecoverable, then see what happens d.addCallback(lambda ign: - self.rootnode.create_empty_directory(u"subdir")) + self.rootnode.create_subdirectory(u"subdir")) d.addCallback(_stash_uri, "subdir") d.addCallback(lambda subdir_node: subdir_node.add_file(u"grandchild", diff --git a/src/allmydata/web/directory.py b/src/allmydata/web/directory.py index 37dc574b..034b1ac7 100644 --- a/src/allmydata/web/directory.py +++ b/src/allmydata/web/directory.py @@ -86,7 +86,7 @@ class DirectoryNodeHandler(RenderMixin, rend.Page, ReplaceMeMixin): if should_create_intermediate_directories(req): # create intermediate directories if DEBUG: print " making intermediate directory" - d = self.node.create_empty_directory(name) + d = self.node.create_subdirectory(name) d.addCallback(make_handler_for, self.client, self.node, name) return d @@ -96,7 +96,7 @@ class DirectoryNodeHandler(RenderMixin, rend.Page, ReplaceMeMixin): if (method,t) in [ ("POST","mkdir"), ("PUT","mkdir") ]: if DEBUG: print " making final directory" # final directory - d = self.node.create_empty_directory(name) + d = self.node.create_subdirectory(name) d.addCallback(make_handler_for, self.client, self.node, name) return d @@ -221,7 +221,7 @@ class DirectoryNodeHandler(RenderMixin, rend.Page, ReplaceMeMixin): return defer.succeed(self.node.get_uri()) # TODO: urlencode name = name.decode("utf-8") replace = boolean_of_arg(get_arg(req, "replace", "true")) - d = self.node.create_empty_directory(name, overwrite=replace) + d = self.node.create_subdirectory(name, overwrite=replace) d.addCallback(lambda child: child.get_uri()) # TODO: urlencode return d @@ -246,7 +246,7 @@ class DirectoryNodeHandler(RenderMixin, rend.Page, ReplaceMeMixin): d = node.get(path[0]) def _maybe_create(f): f.trap(NoSuchChildError) - return node.create_empty_directory(path[0]) + return node.create_subdirectory(path[0]) d.addErrback(_maybe_create) d.addCallback(self._get_or_create_directories, path[1:]) return d -- 2.45.2