summaryrefslogtreecommitdiffstats
path: root/testing/mozbase/manifestparser/tests/test_manifestparser.py
diff options
context:
space:
mode:
Diffstat (limited to 'testing/mozbase/manifestparser/tests/test_manifestparser.py')
-rwxr-xr-xtesting/mozbase/manifestparser/tests/test_manifestparser.py453
1 files changed, 453 insertions, 0 deletions
diff --git a/testing/mozbase/manifestparser/tests/test_manifestparser.py b/testing/mozbase/manifestparser/tests/test_manifestparser.py
new file mode 100755
index 0000000000..8168fe15a4
--- /dev/null
+++ b/testing/mozbase/manifestparser/tests/test_manifestparser.py
@@ -0,0 +1,453 @@
+#!/usr/bin/env python
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+import shutil
+import tempfile
+import unittest
+
+import mozunit
+from manifestparser import ManifestParser
+from six import StringIO
+
+here = os.path.dirname(os.path.abspath(__file__))
+
+
+class TestManifestParser(unittest.TestCase):
+ """
+ Test the manifest parser
+
+ You must have manifestparser installed before running these tests.
+ Run ``python manifestparser.py setup develop`` with setuptools installed.
+ """
+
+ def test_sanity(self):
+ """Ensure basic parser is sane"""
+
+ parser = ManifestParser()
+ mozmill_example = os.path.join(here, "mozmill-example.ini")
+ parser.read(mozmill_example)
+ tests = parser.tests
+ self.assertEqual(
+ len(tests), len(open(mozmill_example).read().strip().splitlines())
+ )
+
+ # Ensure that capitalization and order aren't an issue:
+ lines = ["[%s]" % test["name"] for test in tests]
+ self.assertEqual(lines, open(mozmill_example).read().strip().splitlines())
+
+ # Show how you select subsets of tests:
+ mozmill_restart_example = os.path.join(here, "mozmill-restart-example.ini")
+ parser.read(mozmill_restart_example)
+ restart_tests = parser.get(type="restart")
+ self.assertTrue(len(restart_tests) < len(parser.tests))
+ self.assertEqual(
+ len(restart_tests), len(parser.get(manifest=mozmill_restart_example))
+ )
+ self.assertFalse(
+ [
+ test
+ for test in restart_tests
+ if test["manifest"] != os.path.join(here, "mozmill-restart-example.ini")
+ ]
+ )
+ self.assertEqual(
+ parser.get("name", tags=["foo"]),
+ [
+ "restartTests/testExtensionInstallUninstall/test2.js",
+ "restartTests/testExtensionInstallUninstall/test1.js",
+ ],
+ )
+ self.assertEqual(
+ parser.get("name", foo="bar"),
+ ["restartTests/testExtensionInstallUninstall/test2.js"],
+ )
+
+ def test_include(self):
+ """Illustrate how include works"""
+
+ include_example = os.path.join(here, "include-example.ini")
+ parser = ManifestParser(manifests=(include_example,))
+
+ # All of the tests should be included, in order:
+ self.assertEqual(parser.get("name"), ["crash-handling", "fleem", "flowers"])
+ self.assertEqual(
+ [
+ (test["name"], os.path.basename(test["manifest"]))
+ for test in parser.tests
+ ],
+ [
+ ("crash-handling", "bar.ini"),
+ ("fleem", "include-example.ini"),
+ ("flowers", "foo.ini"),
+ ],
+ )
+
+ # The including manifest is always reported as a part of the generated test object.
+ self.assertTrue(
+ all(
+ [
+ t["ancestor_manifest"] == "include-example.ini"
+ for t in parser.tests
+ if t["name"] != "fleem"
+ ]
+ )
+ )
+
+ # The manifests should be there too:
+ self.assertEqual(len(parser.manifests()), 3)
+
+ # We already have the root directory:
+ self.assertEqual(here, parser.rootdir)
+
+ # DEFAULT values should persist across includes, unless they're
+ # overwritten. In this example, include-example.ini sets foo=bar, but
+ # it's overridden to fleem in bar.ini
+ self.assertEqual(parser.get("name", foo="bar"), ["fleem", "flowers"])
+ self.assertEqual(parser.get("name", foo="fleem"), ["crash-handling"])
+
+ # Passing parameters in the include section allows defining variables in
+ # the submodule scope:
+ self.assertEqual(parser.get("name", tags=["red"]), ["flowers"])
+
+ # However, this should be overridable from the DEFAULT section in the
+ # included file and that overridable via the key directly connected to
+ # the test:
+ self.assertEqual(parser.get(name="flowers")[0]["blue"], "ocean")
+ self.assertEqual(parser.get(name="flowers")[0]["yellow"], "submarine")
+
+ # You can query multiple times if you need to:
+ flowers = parser.get(foo="bar")
+ self.assertEqual(len(flowers), 2)
+
+ # Using the inverse flag should invert the set of tests returned:
+ self.assertEqual(
+ parser.get("name", inverse=True, tags=["red"]), ["crash-handling", "fleem"]
+ )
+
+ # All of the included tests actually exist:
+ self.assertEqual([i["name"] for i in parser.missing()], [])
+
+ # Write the output to a manifest:
+ buffer = StringIO()
+ parser.write(fp=buffer, global_kwargs={"foo": "bar"})
+ expected_output = """[DEFAULT]
+foo = bar
+
+[fleem]
+
+[include/flowers]
+blue = ocean
+red = roses
+yellow = submarine""" # noqa
+
+ self.assertEqual(buffer.getvalue().strip(), expected_output)
+
+ def test_include_manifest_defaults(self):
+ """
+ Test that manifest_defaults and manifests() are correctly populated
+ when includes are used.
+ """
+
+ include_example = os.path.join(here, "include-example.ini")
+ noinclude_example = os.path.join(here, "just-defaults.ini")
+ bar_path = os.path.join(here, "include", "bar.ini")
+ foo_path = os.path.join(here, "include", "foo.ini")
+
+ parser = ManifestParser(
+ manifests=(include_example, noinclude_example), rootdir=here
+ )
+
+ # Standalone manifests must be appear as-is.
+ self.assertTrue(include_example in parser.manifest_defaults)
+ self.assertTrue(noinclude_example in parser.manifest_defaults)
+
+ # Included manifests must only appear together with the parent manifest
+ # that included the manifest.
+ self.assertFalse(bar_path in parser.manifest_defaults)
+ self.assertFalse(foo_path in parser.manifest_defaults)
+ ancestor_ini = os.path.relpath(include_example, parser.rootdir)
+ self.assertTrue((ancestor_ini, bar_path) in parser.manifest_defaults)
+ self.assertTrue((ancestor_ini, foo_path) in parser.manifest_defaults)
+
+ # manifests() must only return file paths (strings).
+ manifests = parser.manifests()
+ self.assertEqual(len(manifests), 4)
+ self.assertIn(foo_path, manifests)
+ self.assertIn(bar_path, manifests)
+ self.assertIn(include_example, manifests)
+ self.assertIn(noinclude_example, manifests)
+
+ def test_include_handle_defaults_False(self):
+ """
+ Test that manifest_defaults and manifests() are correct even when
+ handle_defaults is set to False.
+ """
+ manifest = os.path.join(here, "include-example.ini")
+ foo_path = os.path.join(here, "include", "foo.ini")
+
+ parser = ManifestParser(
+ manifests=(manifest,), handle_defaults=False, rootdir=here
+ )
+ ancestor_ini = os.path.relpath(manifest, parser.rootdir)
+
+ self.assertIn(manifest, parser.manifest_defaults)
+ self.assertNotIn(foo_path, parser.manifest_defaults)
+ self.assertIn((ancestor_ini, foo_path), parser.manifest_defaults)
+ self.assertEqual(
+ parser.manifest_defaults[manifest],
+ {
+ "foo": "bar",
+ "here": here,
+ },
+ )
+ self.assertEqual(
+ parser.manifest_defaults[(ancestor_ini, foo_path)],
+ {
+ "here": os.path.join(here, "include"),
+ "red": "roses",
+ "blue": "ocean",
+ "yellow": "daffodils",
+ },
+ )
+
+ def test_include_repeated(self):
+ """
+ Test that repeatedly included manifests are independent of each other.
+ """
+ include_example = os.path.join(here, "include-example.ini")
+ included_foo = os.path.join(here, "include", "foo.ini")
+
+ # In the expected output, blue and yellow have the values from foo.ini
+ # (ocean, submarine) instead of the ones from include-example.ini
+ # (violets, daffodils), because the defaults in the included file take
+ # precedence over the values from the parent.
+ include_output = """[include/crash-handling]
+foo = fleem
+
+[fleem]
+foo = bar
+
+[include/flowers]
+blue = ocean
+foo = bar
+red = roses
+yellow = submarine
+
+"""
+ included_output = """[include/flowers]
+blue = ocean
+yellow = submarine
+
+"""
+
+ parser = ManifestParser(manifests=(include_example, included_foo), rootdir=here)
+ self.assertEqual(
+ parser.get("name"), ["crash-handling", "fleem", "flowers", "flowers"]
+ )
+ self.assertEqual(
+ [
+ (test["name"], os.path.basename(test["manifest"]))
+ for test in parser.tests
+ ],
+ [
+ ("crash-handling", "bar.ini"),
+ ("fleem", "include-example.ini"),
+ ("flowers", "foo.ini"),
+ ("flowers", "foo.ini"),
+ ],
+ )
+ self.check_included_repeat(
+ parser,
+ parser.tests[3],
+ parser.tests[2],
+ "%s%s" % (include_output, included_output),
+ )
+
+ # Same tests, but with the load order of the manifests swapped.
+ parser = ManifestParser(manifests=(included_foo, include_example), rootdir=here)
+ self.assertEqual(
+ parser.get("name"), ["flowers", "crash-handling", "fleem", "flowers"]
+ )
+ self.assertEqual(
+ [
+ (test["name"], os.path.basename(test["manifest"]))
+ for test in parser.tests
+ ],
+ [
+ ("flowers", "foo.ini"),
+ ("crash-handling", "bar.ini"),
+ ("fleem", "include-example.ini"),
+ ("flowers", "foo.ini"),
+ ],
+ )
+ self.check_included_repeat(
+ parser,
+ parser.tests[0],
+ parser.tests[3],
+ "%s%s" % (included_output, include_output),
+ )
+
+ def check_included_repeat(
+ self, parser, isolated_test, included_test, expected_output
+ ):
+ include_example = os.path.join(here, "include-example.ini")
+ included_foo = os.path.join(here, "include", "foo.ini")
+ ancestor_ini = os.path.relpath(include_example, parser.rootdir)
+ manifest_default_key = (ancestor_ini, included_foo)
+
+ self.assertFalse("ancestor_manifest" in isolated_test)
+ self.assertEqual(included_test["ancestor_manifest"], "include-example.ini")
+
+ self.assertTrue(include_example in parser.manifest_defaults)
+ self.assertTrue(included_foo in parser.manifest_defaults)
+ self.assertTrue(manifest_default_key in parser.manifest_defaults)
+ self.assertEqual(
+ parser.manifest_defaults[manifest_default_key],
+ {
+ "foo": "bar",
+ "here": os.path.join(here, "include"),
+ "red": "roses",
+ "blue": "ocean",
+ "yellow": "daffodils",
+ },
+ )
+
+ buffer = StringIO()
+ parser.write(fp=buffer)
+ self.assertEqual(buffer.getvalue(), expected_output)
+
+ def test_invalid_path(self):
+ """
+ Test invalid path should not throw when not strict
+ """
+ manifest = os.path.join(here, "include-invalid.ini")
+ ManifestParser(manifests=(manifest,), strict=False)
+
+ def test_copy(self):
+ """Test our ability to copy a set of manifests"""
+
+ tempdir = tempfile.mkdtemp()
+ include_example = os.path.join(here, "include-example.ini")
+ manifest = ManifestParser(manifests=(include_example,))
+ manifest.copy(tempdir)
+ self.assertEqual(
+ sorted(os.listdir(tempdir)), ["fleem", "include", "include-example.ini"]
+ )
+ self.assertEqual(
+ sorted(os.listdir(os.path.join(tempdir, "include"))),
+ ["bar.ini", "crash-handling", "flowers", "foo.ini"],
+ )
+ from_manifest = ManifestParser(manifests=(include_example,))
+ to_manifest = os.path.join(tempdir, "include-example.ini")
+ to_manifest = ManifestParser(manifests=(to_manifest,))
+ self.assertEqual(to_manifest.get("name"), from_manifest.get("name"))
+ shutil.rmtree(tempdir)
+
+ def test_path_override(self):
+ """You can override the path in the section too.
+ This shows that you can use a relative path"""
+ path_example = os.path.join(here, "path-example.ini")
+ manifest = ManifestParser(manifests=(path_example,))
+ self.assertEqual(manifest.tests[0]["path"], os.path.join(here, "fleem"))
+
+ def test_relative_path(self):
+ """
+ Relative test paths are correctly calculated.
+ """
+ relative_path = os.path.join(here, "relative-path.ini")
+ manifest = ManifestParser(manifests=(relative_path,))
+ self.assertEqual(
+ manifest.tests[0]["path"], os.path.join(os.path.dirname(here), "fleem")
+ )
+ self.assertEqual(manifest.tests[0]["relpath"], os.path.join("..", "fleem"))
+ self.assertEqual(
+ manifest.tests[1]["relpath"], os.path.join("..", "testsSIBLING", "example")
+ )
+
+ def test_path_from_fd(self):
+ """
+ Test paths are left untouched when manifest is a file-like object.
+ """
+ fp = StringIO("[section]\npath=fleem")
+ manifest = ManifestParser(manifests=(fp,))
+ self.assertEqual(manifest.tests[0]["path"], "fleem")
+ self.assertEqual(manifest.tests[0]["relpath"], "fleem")
+ self.assertEqual(manifest.tests[0]["manifest"], None)
+
+ def test_comments(self):
+ """
+ ensure comments work, see
+ https://bugzilla.mozilla.org/show_bug.cgi?id=813674
+ """
+ comment_example = os.path.join(here, "comment-example.ini")
+ manifest = ManifestParser(manifests=(comment_example,))
+ self.assertEqual(len(manifest.tests), 8)
+ names = [i["name"] for i in manifest.tests]
+ self.assertFalse("test_0202_app_launch_apply_update_dirlocked.js" in names)
+
+ def test_verifyDirectory(self):
+
+ directory = os.path.join(here, "verifyDirectory")
+
+ # correct manifest
+ manifest_path = os.path.join(directory, "verifyDirectory.ini")
+ manifest = ManifestParser(manifests=(manifest_path,))
+ missing = manifest.verifyDirectory(directory, extensions=(".js",))
+ self.assertEqual(missing, (set(), set()))
+
+ # manifest is missing test_1.js
+ test_1 = os.path.join(directory, "test_1.js")
+ manifest_path = os.path.join(directory, "verifyDirectory_incomplete.ini")
+ manifest = ManifestParser(manifests=(manifest_path,))
+ missing = manifest.verifyDirectory(directory, extensions=(".js",))
+ self.assertEqual(missing, (set(), set([test_1])))
+
+ # filesystem is missing test_notappearinginthisfilm.js
+ missing_test = os.path.join(directory, "test_notappearinginthisfilm.js")
+ manifest_path = os.path.join(directory, "verifyDirectory_toocomplete.ini")
+ manifest = ManifestParser(manifests=(manifest_path,))
+ missing = manifest.verifyDirectory(directory, extensions=(".js",))
+ self.assertEqual(missing, (set([missing_test]), set()))
+
+ def test_just_defaults(self):
+ """Ensure a manifest with just a DEFAULT section exposes that data."""
+
+ parser = ManifestParser()
+ manifest = os.path.join(here, "just-defaults.ini")
+ parser.read(manifest)
+ self.assertEqual(len(parser.tests), 0)
+ self.assertTrue(manifest in parser.manifest_defaults)
+ self.assertEqual(parser.manifest_defaults[manifest]["foo"], "bar")
+
+ def test_manifest_list(self):
+ """
+ Ensure a manifest with just a DEFAULT section still returns
+ itself from the manifests() method.
+ """
+
+ parser = ManifestParser()
+ manifest = os.path.join(here, "no-tests.ini")
+ parser.read(manifest)
+ self.assertEqual(len(parser.tests), 0)
+ self.assertTrue(len(parser.manifests()) == 1)
+
+ def test_manifest_with_invalid_condition(self):
+ """
+ Ensure a skip-if or similar condition with an assignment in it
+ causes errors.
+ """
+
+ parser = ManifestParser()
+ manifest = os.path.join(here, "broken-skip-if.ini")
+ with self.assertRaisesRegex(
+ Exception, "Should not assign in skip-if condition for DEFAULT"
+ ):
+ parser.read(manifest)
+
+
+if __name__ == "__main__":
+ mozunit.main()