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)
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_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}"])