summaryrefslogtreecommitdiff
path: root/morphlib/fsutils_tests.py
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@codethink.co.uk>2013-08-13 11:08:17 +0100
committerRichard Maw <richard.maw@codethink.co.uk>2013-08-15 15:25:04 +0000
commite59ade699e91764ae02d63b853ae7f3bc6c1c3d4 (patch)
tree75ee80beaa36dcc41b58f549095480096bd359f6 /morphlib/fsutils_tests.py
parent2d11c3d82fb869197da5ffa12635e125a380e48f (diff)
downloadmorph-e59ade699e91764ae02d63b853ae7f3bc6c1c3d4.tar.gz
fsutils: add invert_paths function
This will list all the paths generated by the walker generator function that aren't in the specified set. It removes directories from those returned by the walker, since with os.walk(topdown=True) this culls the search space. In the set of provided paths and the set of returned paths, if a directory is given, then its contents are virtually part of the set. This oddly specific behaviour is because invert_paths is to be used with linux-user-chroot to mark subtrees as read-only, when it only has a set of paths it wants to keep writable. It takes a walker, rather than being given a path and using os.walk, so that it is a pure function, so is easier to unit test.
Diffstat (limited to 'morphlib/fsutils_tests.py')
-rw-r--r--morphlib/fsutils_tests.py74
1 files changed, 74 insertions, 0 deletions
diff --git a/morphlib/fsutils_tests.py b/morphlib/fsutils_tests.py
new file mode 100644
index 00000000..f49e6f89
--- /dev/null
+++ b/morphlib/fsutils_tests.py
@@ -0,0 +1,74 @@
+# Copyright (C) 2013 Codethink Limited
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+
+import os
+import unittest
+
+import morphlib
+
+
+def dummy_top_down_walker(root, treedict):
+ '''Something that imitates os.walk, but with a dict'''
+
+ subdirs = [k for k in treedict if isinstance(treedict[k], dict)]
+ files = [k for k in treedict if not isinstance(treedict[k], dict)]
+ yield root, subdirs, files
+ for subdir in subdirs:
+ subwalker = dummy_top_down_walker(os.path.join(root, subdir),
+ treedict[subdir])
+ for result in subwalker:
+ yield result
+
+
+class InvertPathsTests(unittest.TestCase):
+
+ def setUp(self):
+ self.flat_tree = {"foo": None, "bar": None, "baz": None}
+ self.nested_tree = {
+ "foo": {
+ "bar": None,
+ "baz": None,
+ },
+ "fs": {
+ "btrfs": None,
+ "ext2": None,
+ "ext3": None,
+ "ext4": None,
+ "nfs": None,
+ },
+ }
+
+ def test_flat_lists_single_files(self):
+ walker = dummy_top_down_walker('.', self.flat_tree)
+ self.assertEqual(sorted(["./foo", "./bar", "./baz"]),
+ sorted(morphlib.fsutils.invert_paths(walker, [])))
+
+ def test_flat_excludes_listed_files(self):
+ walker = dummy_top_down_walker('.', self.flat_tree)
+ self.assertTrue(
+ "./bar" not in morphlib.fsutils.invert_paths(walker, ["./bar"]))
+
+ def test_nested_excludes_listed_files(self):
+ walker = dummy_top_down_walker('.', self.nested_tree)
+ excludes = ["./foo/bar", "./fs/nfs"]
+ found = frozenset(morphlib.fsutils.invert_paths(walker, excludes))
+ self.assertTrue(all(path not in found for path in excludes))
+
+ def test_nested_excludes_whole_dir(self):
+ walker = dummy_top_down_walker('.', self.nested_tree)
+ found = frozenset(morphlib.fsutils.invert_paths(walker, ["./foo"]))
+ unexpected = ("./foo", "./foo/bar", "./foo/baz")
+ self.assertTrue(all(path not in found for path in unexpected))