tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

conftest.py (5324B)


      1 # This Source Code Form is subject to the terms of the Mozilla Public
      2 # License, v. 2.0. If a copy of the MPL was not distributed with this
      3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
      4 
      5 import io
      6 import json
      7 import os
      8 from argparse import Namespace
      9 
     10 import mozinfo
     11 import pytest
     12 from manifestparser import TestManifest, expression
     13 from moztest.selftest.fixtures import binary_fixture, setup_test_harness  # noqa
     14 
     15 here = os.path.abspath(os.path.dirname(__file__))
     16 setup_args = [os.path.join(here, "files"), "mochitest", "testing/mochitest"]
     17 
     18 
     19 @pytest.fixture
     20 def create_manifest(tmpdir, build_obj):
     21    def inner(string, name="manifest.ini"):
     22        manifest = tmpdir.join(name)
     23        manifest.write(string, ensure=True)
     24        path = str(manifest)
     25        return TestManifest(manifests=(path,), strict=False, rootdir=tmpdir.strpath)
     26 
     27    return inner
     28 
     29 
     30 @pytest.fixture(scope="function")
     31 def parser(request):
     32    parser = pytest.importorskip("mochitest_options")
     33 
     34    app = getattr(request.module, "APP", "generic")
     35    return parser.MochitestArgumentParser(app=app)
     36 
     37 
     38 @pytest.fixture(scope="function")
     39 def runtests(setup_test_harness, binary, parser, request):
     40    """Creates an easy to use entry point into the mochitest harness.
     41 
     42    :returns: A function with the signature `*tests, **opts`. Each test is a file name
     43              (relative to the `files` dir). At least one is required. The opts are
     44              used to override the default mochitest options, they are optional.
     45    """
     46    flavor = "plain"
     47    if "flavor" in request.fixturenames:
     48        flavor = request.getfixturevalue("flavor")
     49 
     50    runFailures = ""
     51    if "runFailures" in request.fixturenames:
     52        runFailures = request.getfixturevalue("runFailures")
     53 
     54    restartAfterFailure = False
     55    if "restartAfterFailure" in request.fixturenames:
     56        restartAfterFailure = request.getfixturevalue("restartAfterFailure")
     57 
     58    setup_test_harness(*setup_args, flavor=flavor)
     59 
     60    runtests = pytest.importorskip("runtests")
     61 
     62    mochitest_root = runtests.SCRIPT_DIR
     63    if flavor == "plain":
     64        test_root = os.path.join(mochitest_root, "tests", "selftests")
     65        manifest_name = "mochitest.ini"
     66    elif flavor == "browser-chrome":
     67        test_root = os.path.join(mochitest_root, "browser", "tests", "selftests")
     68        manifest_name = "browser.ini"
     69    else:
     70        raise Exception(f"Invalid flavor {flavor}!")
     71 
     72    buf = io.StringIO()
     73    options = vars(parser.parse_args([]))
     74    options.update({
     75        "app": binary,
     76        "flavor": flavor,
     77        "runFailures": runFailures,
     78        "restartAfterFailure": restartAfterFailure,
     79        "keep_open": False,
     80        "log_raw": [buf],
     81    })
     82 
     83    if runFailures == "selftest":
     84        options["crashAsPass"] = True
     85        options["timeoutAsPass"] = True
     86        runtests.mozinfo.update({"selftest": True})
     87 
     88    if not os.path.isdir(runtests.build_obj.bindir):
     89        package_root = os.path.dirname(mochitest_root)
     90        options.update({
     91            "certPath": os.path.join(package_root, "certs"),
     92            "utilityPath": os.path.join(package_root, "bin"),
     93        })
     94        options["extraProfileFiles"].append(
     95            os.path.join(package_root, "bin", "plugins")
     96        )
     97 
     98    options.update(getattr(request.module, "OPTIONS", {}))
     99 
    100    def normalize(test):
    101        if isinstance(test, str):
    102            test = [test]
    103        return [
    104            {
    105                "name": t,
    106                "relpath": t,
    107                "path": os.path.join(test_root, t),
    108                # add a dummy manifest file because mochitest expects it
    109                "manifest": os.path.join(test_root, manifest_name),
    110                "manifest_relpath": manifest_name,
    111                "skip-if": runFailures,
    112            }
    113            for t in test
    114        ]
    115 
    116    def inner(*tests, **opts):
    117        assert len(tests) > 0
    118 
    119        # Inject a TestManifest in the runtests option if one
    120        # has not been already included by the caller.
    121        if not isinstance(options["manifestFile"], TestManifest):
    122            manifest = TestManifest()
    123            options["manifestFile"] = manifest
    124            # pylint --py3k: W1636
    125            manifest.tests.extend(list(map(normalize, tests))[0])
    126            options.update(opts)
    127 
    128        result = runtests.run_test_harness(parser, Namespace(**options))
    129        out = json.loads("[" + ",".join(buf.getvalue().splitlines()) + "]")
    130        buf.close()
    131        return result, out
    132 
    133    return inner
    134 
    135 
    136 @pytest.fixture
    137 def build_obj(setup_test_harness):
    138    setup_test_harness(*setup_args)
    139    mochitest_options = pytest.importorskip("mochitest_options")
    140    return mochitest_options.build_obj
    141 
    142 
    143 @pytest.fixture(autouse=True)
    144 def skip_using_mozinfo(request, setup_test_harness):
    145    """Gives tests the ability to skip based on values from mozinfo.
    146 
    147    Example:
    148        @pytest.mark.skip_mozinfo("!e10s || os == 'linux'")
    149        def test_foo():
    150            pass
    151    """
    152 
    153    setup_test_harness(*setup_args)
    154    runtests = pytest.importorskip("runtests")
    155    runtests.update_mozinfo()
    156 
    157    skip_mozinfo = request.node.get_closest_marker("skip_mozinfo")
    158    if skip_mozinfo:
    159        value = skip_mozinfo.args[0]
    160        if expression.parse(value, **mozinfo.info):
    161            pytest.skip(f"skipped due to mozinfo match: \n{value}")