def test_nonrecursive(self): m = ManifestFileParser().build("""\ foo child1 child2 bar baz child3 """.split("\n")) self.assertEqual(list(m.paths(recursive = False)), ["bar", "baz", "foo"])
def test_nonrecursive(self): m = ManifestFileParser().build("""\ foo child1 child2 bar baz child3 """.split("\n")) result = [] for path, names, attrs in m.walk(): result.append("/".join(path)) del names[:] self.assertEqual(result, [""]) result = [] for path, names, attrs in m.walk(): result.append("/".join(path)) if path: del names[:] self.assertEqual(result, ["", "bar", "baz", "foo"])
def setUp(self): self.m = ManifestFileParser().build("""\ a a a b c b a b c c a b c b a a b c b a b c c a b c c a a b c b a b c c a b c """.split("\n")) self.all = ["", "a", "a/a", "a/a/a", "a/a/b", "a/a/c", "a/b", "a/b/a", "a/b/b", "a/b/c", "a/c", "a/c/a", "a/c/b", "a/c/c", "b", "b/a", "b/a/a", "b/a/b", "b/a/c", "b/b", "b/b/a", "b/b/b", "b/b/c", "b/c", "b/c/a", "b/c/b", "b/c/c", "c", "c/a", "c/a/a", "c/a/b", "c/a/c", "c/b", "c/b/a", "c/b/b", "c/b/c", "c/c", "c/c/a", "c/c/b", "c/c/c"]
class Test_Manifest_resolve(unittest.TestCase): def setUp(self): self.mfp = ManifestFileParser() def test_empty(self): m = Manifest() self.assertTrue(m.resolve("") is m) def test_single_entry(self): m = self.mfp.build(["foo"]) self.assertTrue(m.resolve("") is m) self.assertTrue(m.resolve("foo") is m["foo"]) def test_missing_is_None(self): m = self.mfp.build(["foo"]) self.assertTrue(m.resolve("bar") is None) def test_grandchild(self): m = self.mfp.build(["foo", "\tbar"]) self.assertTrue(m.resolve("") is m) self.assertTrue(m.resolve("foo") is m["foo"]) self.assertTrue(m.resolve("foo/bar") is m["foo"]["bar"]) def test_dot_path(self): m = self.mfp.build(["foo", "\tbar"]) self.assertTrue(m.resolve("./foo") is m["foo"]) self.assertTrue(m.resolve("foo/./") is m["foo"]) self.assertTrue(m.resolve("foo/./bar") is m["foo"]["bar"]) self.assertTrue(m.resolve("./foo/./bar/.") is m["foo"]["bar"]) self.assertTrue(m.resolve("./foo/./bar/./") is m["foo"]["bar"]) def test_dotdot_path(self): m = self.mfp.build(["foo", "\tbar"]) self.assertTrue(m.resolve("foo/..") is m) self.assertTrue(m.resolve("foo/../foo") is m["foo"]) self.assertTrue(m.resolve("foo/../foo/bar") is m["foo"]["bar"]) self.assertTrue(m.resolve("./foo/./bar/..") is m["foo"]) self.assertTrue(m.resolve("./foo/bar/../") is m["foo"]) self.assertTrue(m.resolve("./foo/bar/../..") is m) def test_excessive_dotdot_fails(self): m = self.mfp.build(["foo", "\tbar"]) self.assertTrue(m.resolve("..") is None) self.assertTrue(m.resolve("../") is None) self.assertTrue(m.resolve("foo/../..") is None) self.assertTrue(m.resolve("foo/bar/../../..") is None) self.assertTrue(m.resolve("foo/bar/../bar/../../..") is None)
def setUp(self): self.mfp = ManifestFileParser()
class Test_Manifest_walk_selective_recurse(unittest.TestCase): def setUp(self): self.m = ManifestFileParser().build("""\ a a a b c b a b c c a b c b a a b c b a b c c a b c c a a b c b a b c c a b c """.split("\n")) self.all = ["", "a", "a/a", "a/a/a", "a/a/b", "a/a/c", "a/b", "a/b/a", "a/b/b", "a/b/c", "a/c", "a/c/a", "a/c/b", "a/c/c", "b", "b/a", "b/a/a", "b/a/b", "b/a/c", "b/b", "b/b/a", "b/b/b", "b/b/c", "b/c", "b/c/a", "b/c/b", "b/c/c", "c", "c/a", "c/a/a", "c/a/b", "c/a/c", "c/b", "c/b/a", "c/b/b", "c/b/c", "c/c", "c/c/a", "c/c/b", "c/c/c"] def check_paths(self, pred, expect): actual = [] for path, names, attrs in self.m.walk(): if pred(path, names): actual.append("/".join(path)) self.assertEqual(actual, expect) def test_all(self): def modifier(path, names): return True self.check_paths(modifier, self.all) def test_none(self): def modifier(path, names): return False self.check_paths(modifier, []) def test_first(self): def modifier(path, names): del names[:] return True self.check_paths(modifier, [""]) def modifier(path, names): return not path self.check_paths(modifier, [""]) def test_not_first(self): def modifier(path, names): return path self.check_paths(modifier, self.all[1:]) def test_no_a(self): expect = [ "", "b", "b/b", "b/b/b", "b/b/c", "b/c", "b/c/b", "b/c/c", "c", "c/b", "c/b/b", "c/b/c", "c/c", "c/c/b", "c/c/c"] def modifier(path, names): try: del names[names.index("a")] except: pass return True self.check_paths(modifier, expect) def modifier(path, names): return "a" not in path self.check_paths(modifier, expect) def test_only_a(self): expect = ["", "a", "a/a", "a/a/a"] def modifier(path, names): names[:] = ["a"] if "a" in names else [] return True self.check_paths(modifier, expect) def modifier(path, names): return not any(True for p in path if p != "a") self.check_paths(modifier, expect) def test_starts_with_a(self): expect = [ "a", "a/a", "a/a/a", "a/a/b", "a/a/c", "a/b", "a/b/a", "a/b/b", "a/b/c", "a/c", "a/c/a", "a/c/b", "a/c/c"] def modifier(path, names): if not path: names[:] = ["a"] if "a" in names else [] return False else: return True self.check_paths(modifier, expect) def modifier(path, names): return path and path[0] == "a" self.check_paths(modifier, expect) def test_ends_with_a(self): expect = [ "a", "a/a", "a/a/a", "a/b/a", "a/c/a", "b/a", "b/a/a", "b/b/a", "b/c/a", "c/a", "c/a/a", "c/b/a", "c/c/a"] def modifier(path, names): return path and path[-1] == "a" self.check_paths(modifier, expect)
class Test_Manifest_merge(unittest.TestCase): def setUp(self): self.mfp = ManifestFileParser(Manifest) def test_nothing(self): self.assertEqual(list(Manifest.merge()), []) def test_one_empty(self): m = Manifest() self.assertEqual(list(Manifest.merge(m)), []) def test_two_empties(self): m1, m2 = Manifest(), Manifest_from_walking_unpacked_tar("empty.tar") self.assertEqual(list(Manifest.merge(m1, m2)), []) def test_one_single_file(self): m = Manifest_from_walking_unpacked_tar("single_file.tar") self.assertEqual(list(Manifest.merge(m)), [("foo",)]) def test_single_file_x2(self): m1 = Manifest_from_walking_unpacked_tar("single_file.tar") m2 = self.mfp.build(["foo"]) self.assertEqual(list(Manifest.merge(m1, m2)), [("foo", "foo")]) def test_three_different_singles(self): m1, m2, m3 = map(self.mfp.build, (["foo"], ["bar"], ["baz"])) self.assertEqual(list(Manifest.merge(m1, m2, m3)), [ (None, "bar", None), (None, None, "baz"), ("foo", None, None)]) def test_three_mixed_singles(self): m1, m2, m3 = map(self.mfp.build, (["foo"], ["bar"], ["foo"])) self.assertEqual(list(Manifest.merge(m1, m2, m3)), [ (None, "bar", None), ("foo", None, "foo")]) def test_three_with_overlap(self): ms = map(self.mfp.build, (["foo", "same"], ["bar", "same"], ["baz", "same"])) self.assertEqual(list(Manifest.merge(*ms)), [ (None, "bar", None), (None, None, "baz"), ("foo", None, None), ("same", "same", "same")]) def test_empty_subdir_vs_nonepty_subdir(self): m1 = Manifest_from_walking_unpacked_tar("file_and_empty_subdir.tar") m2 = Manifest_from_walking_unpacked_tar("file_and_subdir.tar") self.assertEqual(list(Manifest.merge(m1, m2)), [ ("file", "file"), ("subdir", "subdir"), (None, "subdir/foo")]) def test_custom_key(self): m1 = self.mfp.build(["1foo", "2bar", "3baz"]) m2 = self.mfp.build(["abc", "def", "ghi"]) m3 = self.mfp.build(["123", "456", "789"]) self.assertEqual( list(Manifest.merge(m1, m2, m3, key = lambda px: True)), [ ("1foo", "abc", "123"), ("2bar", "def", "456"), ("3baz", "ghi", "789")]) def test_nonrecursive(self): m1 = self.mfp.build(["bar", "foo", " bar", " foo"]) m2 = self.mfp.build(["foo", " foo", "xyzzy"]) m3 = self.mfp.build(["foo", " bar", " baz", " foo", " foo"]) self.assertEqual(list(Manifest.merge(m1, m2, m3)), [ ("bar", None, None), ("foo", "foo", "foo"), ("foo/bar", None, "foo/bar"), (None, None, "foo/bar/baz"), ("foo/foo", "foo/foo", "foo/foo"), (None, None, "foo/foo/foo"), (None, "xyzzy", None)]) # now without recursion self.assertEqual(list(Manifest.merge(m1, m2, m3, recursive = False)), [ ("bar", None, None), ("foo", "foo", "foo"), (None, "xyzzy", None)]) # and finally with selective recursion (only recurse into "foo"s) actual = [] gen = Manifest.merge(m1, m2, m3, recursive = False) try: t = next(gen) while True: actual.append(t) paths = [p for p in t if p is not None] self.assertTrue(paths) path = paths[0] self.assertEqual([path] * len(paths), paths) try: last_component = path.rsplit("/", 1)[1] except: last_component = path if last_component == "foo": t = gen.send(True) else: t = next(gen) except StopIteration: pass self.assertEqual(actual, [ ("bar", None, None), ("foo", "foo", "foo"), ("foo/bar", None, "foo/bar"), ("foo/foo", "foo/foo", "foo/foo"), (None, None, "foo/foo/foo"), (None, "xyzzy", None)])
class Test_ManifestFileParser_parse_lines(unittest.TestCase): def setUp(self): self.mfp = ManifestFileParser() def must_equal(self, input_string, expect): stream = self.mfp.parse_lines(StringIO(input_string)) self.assertEqual(list(stream), expect) def must_raise(self, input_string, exception): stream = self.mfp.parse_lines(StringIO(input_string)) self.assertRaises(exception, list, stream) def test_empty(self): self.must_equal("", []) def test_comment_line(self): self.must_equal(" # This is a comment", []) def test_single_word(self): self.must_equal("foo", [(0, "foo", {})]) def test_line_with_comment(self): self.must_equal("foo # comment", [(0, "foo", {})]) def test_two_entries(self): self.must_equal("foo\nbar", [(0, "foo", {}), (0, "bar", {})]) def test_simple_indent(self): self.must_equal("foo\n\tbar", [(0, "foo", {}), (1, "bar", {})]) def test_increasing_indent(self): self.must_equal("foo\n\tbar\n\t baz", [(0, "foo", {}), (1, "bar", {}), (2, "baz", {})]) def test_decreasing_indent(self): self.must_equal("foo\n\tbar\n\t baz\n\txyzzy", [(0, "foo", {}), (1, "bar", {}), (2, "baz", {}), (1, "xyzzy", {})]) def test_multidecreasing_indent(self): self.must_equal("foo\n\tbar\n\t baz\nxyzzy", [(0, "foo", {}), (1, "bar", {}), (2, "baz", {}), (0, "xyzzy", {})]) def test_broken_indent(self): self.must_raise("foo\n\tbar\n\t baz\n xyzzy", ValueError) def test_empty_lines(self): self.must_equal("\n \n foo \n #comment line\n\t\t\n", [(1, "foo", {})]) def test_empty_lines_and_comments_between_indents(self): self.must_equal("foo\n\tbar\n#comment line\n\n\t\t\t\n\nbaz\n\t\n#foo", [(0, "foo", {}), (1, "bar", {}), (0, "baz", {})]) def test_token_with_spaces(self): self.must_equal("This is a token with spaces", [(0, "This is a token with spaces", {})]) def test_token_with_spaces(self): self.must_equal("This is a token with spaces", [(0, "This is a token with spaces", {})]) def test_list_of_strings(self): stream = self.mfp.parse_lines(["foo", "bar", "\tbaz", "\t xyzzy"]) self.assertEqual(list(stream), [(0, "foo", {}), (0, "bar", {}), (1, "baz", {}), (2, "xyzzy", {})]) def test_empty_attrs(self): self.must_equal("foo {}", [(0, "foo", {})]) def test_size_attr(self): self.must_equal("foo {size: 1}", [(0, "foo", {"size": 1})]) def test_two_attrs(self): sha1 = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef" self.must_equal("foo {size: 1, sha1: %s}" % (sha1), [(0, "foo", {"size": 1, "sha1": sha1})]) def test_sha1_attr_lowered(self): sha1 = "deadbeefDEADBEEFdeadbeefdeadbeefdeadbeef" self.must_equal("foo {size: 1, sha1: %s}" % (sha1), [(0, "foo", {"size": 1, "sha1": sha1.lower()})]) def test_unknown_attr(self): self.must_equal("foo { bar : baz }", [(0, "foo", {"bar": "baz"})])
class Test_ManifestFileParser_build(unittest.TestCase): def setUp(self): self.mfp = ManifestFileParser() def test_empty(self): m = self.mfp.build(StringIO("")) self.assertEqual(m, {}) def test_single_word(self): m = self.mfp.build(StringIO("foo")) self.assertEqual(m, {"foo": {}}) def test_two_words(self): m = self.mfp.build(StringIO("foo\nbar")) self.assertEqual(m, {"foo": {}, "bar": {}}) def test_entry_with_child(self): m = self.mfp.build(StringIO("foo\n\tbar")) self.assertEqual(m, {"foo": {"bar": {}}}) def test_entry_with_children(self): m = self.mfp.build(StringIO("foo\n\tbar\n\tbaz")) self.assertEqual(m, {"foo": {"bar": {}, "baz": {}}}) def test_entry_with_child_and_sibling(self): m = self.mfp.build(StringIO("foo\n\tbar\nfooz")) self.assertEqual(m, {"foo": {"bar": {}}, "fooz": {}}) def test_entry_with_grandchild(self): m = self.mfp.build(StringIO("foo\n\tbar\n\t\tbaz")) self.assertEqual(m, {"foo": {"bar": {"baz": {}}}}) def test_entry_with_grandchild_and_sibling(self): m = self.mfp.build(StringIO("foo\n\tbar\n\t\tbaz\nxyzzy")) self.assertEqual(m, {"foo": {"bar": {"baz": {}}}, "xyzzy": {}}) def test_parent_refs(self): m = self.mfp.build(StringIO("foo\n\tbar")) self.assertEqual(m, {"foo": {"bar": {}}}) self.assertEqual(m.getparent(), None) self.assertEqual(m["foo"].getparent(), m) self.assertEqual(m["foo"]["bar"].getparent(), m["foo"]) def test_empty_attrs(self): m = self.mfp.build(["foo {}"]) self.assertEqual(m, {"foo": {}}) self.assertEqual(m["foo"].getattrs(), {}) def test_unknown_attr(self): m = self.mfp.build(["foo {bar: baz}"]) self.assertEqual(m, {"foo": {}}) self.assertEqual(m["foo"].getattrs(), { "bar": "baz"}) def test_size_attr(self): m = self.mfp.build(["foo {size: 1}"]) self.assertEqual(m, {"foo": {}}) self.assertEqual(m["foo"].getattrs(), {"size": 1}) def test_invalid_size_attr_raises(self): self.assertRaises(ValueError, self.mfp.build, ["foo {size: bar}"]) self.assertRaises(ValueError, self.mfp.build, ["foo {size: -1}"]) def test_two_attrs(self): sha1 = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef" m = self.mfp.build(["foo {size: 1, sha1: %s}" % (sha1)]) self.assertEqual(m, {"foo": {}}) self.assertEqual(m["foo"].getattrs(), {"size": 1, "sha1": sha1}) def test_sha1_attr_lowered(self): sha1 = "deadbeefDEADBEEFdeadbeefdeadbeefdeadbeef" m = self.mfp.build(["foo {size: 1, sha1: %s}" % (sha1)]) self.assertEqual(m, {"foo": {}}) self.assertEqual(m["foo"].getattrs(), {"size": 1, "sha1": sha1.lower()}) def test_invalid_sha1_attr_raises(self): self.assertRaises(ValueError, self.mfp.build, ["foo {sha1: not_hex}"]) self.assertRaises(ValueError, self.mfp.build, ["foo {sha1: 123}"]) # <40 def test_mode_Xid_attr(self): m = self.mfp.build(["foo { mode: 0o100644, uid: 1000, gid: 100 }"]) self.assertEqual(m, {"foo": {}}) self.assertEqual(m["foo"].getattrs(), {"mode": 0o100644, "uid": 1000, "gid": 100}) def test_invalid_mode_Xid_attr_raises(self): self.assertRaises(ValueError, self.mfp.build, ["foo {mode: not_int}"]) self.assertRaises(ValueError, self.mfp.build, ["foo {uid: -13}"]) self.assertRaises(ValueError, self.mfp.build, ["foo {gid: 0x123foo}"])