conftest.py (4260B)
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 json 6 import os 7 from argparse import Namespace 8 9 try: 10 # Python2 11 from cStringIO import StringIO 12 except ImportError: 13 # Python3 14 from io import StringIO 15 16 import mozinfo 17 import pytest 18 from manifestparser import expression 19 from moztest.selftest.fixtures import binary_fixture, setup_test_harness # noqa 20 21 here = os.path.abspath(os.path.dirname(__file__)) 22 setup_args = [False, "reftest", "reftest"] 23 24 25 @pytest.fixture(scope="module") 26 def normalize(): 27 """A function that can take a relative path and append it to the 'files' 28 directory which contains the data necessary to run these tests. 29 """ 30 31 def inner(path): 32 if os.path.isabs(path): 33 return path 34 return os.path.join(here, "files", path) 35 36 return inner 37 38 39 @pytest.fixture 40 def parser(setup_test_harness): 41 setup_test_harness(*setup_args) 42 cmdline = pytest.importorskip("reftestcommandline") 43 return cmdline.DesktopArgumentsParser() 44 45 46 @pytest.fixture 47 def get_reftest(setup_test_harness, binary, parser): 48 setup_test_harness(*setup_args) 49 runreftest = pytest.importorskip("runreftest") 50 harness_root = runreftest.SCRIPT_DIRECTORY 51 52 build = parser.build_obj 53 options = vars(parser.parse_args([])) 54 options.update({ 55 "app": binary, 56 "focusFilterMode": "non-needs-focus", 57 "suite": "reftest", 58 }) 59 60 if not os.path.isdir(build.bindir): 61 package_root = os.path.dirname(harness_root) 62 options.update({ 63 "extraProfileFiles": [os.path.join(package_root, "bin", "plugins")], 64 "reftestExtensionPath": os.path.join(harness_root, "reftest"), 65 "sandboxReadWhitelist": [here, os.environ["PYTHON_TEST_TMP"]], 66 "utilityPath": os.path.join(package_root, "bin"), 67 "specialPowersExtensionPath": os.path.join(harness_root, "specialpowers"), 68 }) 69 70 if "MOZ_FETCHES_DIR" in os.environ: 71 options["sandboxReadWhitelist"].append(os.environ["MOZ_FETCHES_DIR"]) 72 else: 73 options.update({ 74 "extraProfileFiles": [os.path.join(build.topobjdir, "dist", "plugins")], 75 "sandboxReadWhitelist": [build.topobjdir, build.topsrcdir], 76 "specialPowersExtensionPath": os.path.join( 77 build.distdir, "xpi-stage", "specialpowers" 78 ), 79 }) 80 81 def inner(**opts): 82 options.update(opts) 83 config = Namespace(**options) 84 85 # This is pulled from `runreftest.run_test_harness` minus some error 86 # checking that isn't necessary in this context. It should stay roughly 87 # in sync. 88 reftest = runreftest.RefTest(config.suite) 89 parser.validate(config, reftest) 90 91 config.app = reftest.getFullPath(config.app) 92 assert os.path.exists(config.app) 93 94 if config.xrePath is None: 95 config.xrePath = os.path.dirname(config.app) 96 97 return reftest, config 98 99 return inner 100 101 102 @pytest.fixture # noqa: F811 103 def runtests(get_reftest, normalize): 104 def inner(*tests, **opts): 105 assert len(tests) > 0 106 opts["tests"] = map(normalize, tests) 107 108 buf = StringIO() 109 opts["log_raw"] = [buf] 110 111 reftest, options = get_reftest(**opts) 112 result = reftest.runTests(options.tests, options) 113 114 out = json.loads("[" + ",".join(buf.getvalue().splitlines()) + "]") 115 buf.close() 116 return result, out 117 118 return inner 119 120 121 @pytest.fixture(autouse=True) # noqa: F811 122 def skip_using_mozinfo(request, setup_test_harness): 123 """Gives tests the ability to skip based on values from mozinfo. 124 125 Example: 126 @pytest.mark.skip_mozinfo("!e10s || os == 'linux'") 127 def test_foo(): 128 pass 129 """ 130 131 setup_test_harness(*setup_args) 132 runreftest = pytest.importorskip("runreftest") 133 runreftest.update_mozinfo() 134 135 skip_mozinfo = request.node.get_closest_marker("skip_mozinfo") 136 if skip_mozinfo: 137 value = skip_mozinfo.args[0] 138 if expression.parse(value, **mozinfo.info): 139 pytest.skip(f"skipped due to mozinfo match: \n{value}")