summaryrefslogtreecommitdiffstats
path: root/testing/mochitest/tests/python/conftest.py
diff options
context:
space:
mode:
Diffstat (limited to 'testing/mochitest/tests/python/conftest.py')
-rw-r--r--testing/mochitest/tests/python/conftest.py157
1 files changed, 157 insertions, 0 deletions
diff --git a/testing/mochitest/tests/python/conftest.py b/testing/mochitest/tests/python/conftest.py
new file mode 100644
index 0000000000..e418dfb816
--- /dev/null
+++ b/testing/mochitest/tests/python/conftest.py
@@ -0,0 +1,157 @@
+# 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 json
+import os
+from argparse import Namespace
+
+import mozinfo
+import pytest
+import six
+from manifestparser import TestManifest, expression
+from moztest.selftest.fixtures import binary_fixture, setup_test_harness # noqa
+
+here = os.path.abspath(os.path.dirname(__file__))
+setup_args = [os.path.join(here, "files"), "mochitest", "testing/mochitest"]
+
+
+@pytest.fixture
+def create_manifest(tmpdir, build_obj):
+ def inner(string, name="manifest.ini"):
+ manifest = tmpdir.join(name)
+ manifest.write(string, ensure=True)
+ # pylint --py3k: W1612
+ path = six.text_type(manifest)
+ return TestManifest(manifests=(path,), strict=False, rootdir=tmpdir.strpath)
+
+ return inner
+
+
+@pytest.fixture(scope="function")
+def parser(request):
+ parser = pytest.importorskip("mochitest_options")
+
+ app = getattr(request.module, "APP", "generic")
+ return parser.MochitestArgumentParser(app=app)
+
+
+@pytest.fixture(scope="function")
+def runtests(setup_test_harness, binary, parser, request):
+ """Creates an easy to use entry point into the mochitest harness.
+
+ :returns: A function with the signature `*tests, **opts`. Each test is a file name
+ (relative to the `files` dir). At least one is required. The opts are
+ used to override the default mochitest options, they are optional.
+ """
+ flavor = "plain"
+ if "flavor" in request.fixturenames:
+ flavor = request.getfixturevalue("flavor")
+
+ runFailures = ""
+ if "runFailures" in request.fixturenames:
+ runFailures = request.getfixturevalue("runFailures")
+
+ setup_test_harness(*setup_args, flavor=flavor)
+
+ runtests = pytest.importorskip("runtests")
+
+ mochitest_root = runtests.SCRIPT_DIR
+ if flavor == "plain":
+ test_root = os.path.join(mochitest_root, "tests", "selftests")
+ manifest_name = "mochitest.ini"
+ elif flavor == "browser-chrome":
+ test_root = os.path.join(mochitest_root, "browser", "tests", "selftests")
+ manifest_name = "browser.ini"
+ else:
+ raise Exception(f"Invalid flavor {flavor}!")
+
+ # pylint --py3k: W1648
+ buf = six.StringIO()
+ options = vars(parser.parse_args([]))
+ options.update(
+ {
+ "app": binary,
+ "flavor": flavor,
+ "runFailures": runFailures,
+ "keep_open": False,
+ "log_raw": [buf],
+ }
+ )
+
+ if runFailures == "selftest":
+ options["crashAsPass"] = True
+ options["timeoutAsPass"] = True
+ runtests.mozinfo.update({"selftest": True})
+
+ if not os.path.isdir(runtests.build_obj.bindir):
+ package_root = os.path.dirname(mochitest_root)
+ options.update(
+ {
+ "certPath": os.path.join(package_root, "certs"),
+ "utilityPath": os.path.join(package_root, "bin"),
+ }
+ )
+ options["extraProfileFiles"].append(
+ os.path.join(package_root, "bin", "plugins")
+ )
+
+ options.update(getattr(request.module, "OPTIONS", {}))
+
+ def normalize(test):
+ return {
+ "name": test,
+ "relpath": test,
+ "path": os.path.join(test_root, test),
+ # add a dummy manifest file because mochitest expects it
+ "manifest": os.path.join(test_root, manifest_name),
+ "manifest_relpath": manifest_name,
+ "skip-if": runFailures,
+ }
+
+ def inner(*tests, **opts):
+ assert len(tests) > 0
+
+ # Inject a TestManifest in the runtests option if one
+ # has not been already included by the caller.
+ if not isinstance(options["manifestFile"], TestManifest):
+ manifest = TestManifest()
+ options["manifestFile"] = manifest
+ # pylint --py3k: W1636
+ manifest.tests.extend(list(map(normalize, tests)))
+ options.update(opts)
+
+ result = runtests.run_test_harness(parser, Namespace(**options))
+ out = json.loads("[" + ",".join(buf.getvalue().splitlines()) + "]")
+ buf.close()
+ return result, out
+
+ return inner
+
+
+@pytest.fixture
+def build_obj(setup_test_harness):
+ setup_test_harness(*setup_args)
+ mochitest_options = pytest.importorskip("mochitest_options")
+ return mochitest_options.build_obj
+
+
+@pytest.fixture(autouse=True)
+def skip_using_mozinfo(request, setup_test_harness):
+ """Gives tests the ability to skip based on values from mozinfo.
+
+ Example:
+ @pytest.mark.skip_mozinfo("!e10s || os == 'linux'")
+ def test_foo():
+ pass
+ """
+
+ setup_test_harness(*setup_args)
+ runtests = pytest.importorskip("runtests")
+ runtests.update_mozinfo()
+
+ skip_mozinfo = request.node.get_closest_marker("skip_mozinfo")
+ if skip_mozinfo:
+ value = skip_mozinfo.args[0]
+ if expression.parse(value, **mozinfo.info):
+ pytest.skip("skipped due to mozinfo match: \n{}".format(value))