Source code

Revision control

Copy as Markdown

Other Tools

# 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
try:
# Python2
from cStringIO import StringIO
except ImportError:
# Python3
from io import StringIO
import mozinfo
import pytest
from manifestparser import expression
from moztest.selftest.fixtures import binary_fixture, setup_test_harness # noqa
here = os.path.abspath(os.path.dirname(__file__))
setup_args = [False, "reftest", "reftest"]
@pytest.fixture(scope="module")
def normalize():
"""A function that can take a relative path and append it to the 'files'
directory which contains the data necessary to run these tests.
"""
def inner(path):
if os.path.isabs(path):
return path
return os.path.join(here, "files", path)
return inner
@pytest.fixture
def parser(setup_test_harness):
setup_test_harness(*setup_args)
cmdline = pytest.importorskip("reftestcommandline")
return cmdline.DesktopArgumentsParser()
@pytest.fixture
def get_reftest(setup_test_harness, binary, parser):
setup_test_harness(*setup_args)
runreftest = pytest.importorskip("runreftest")
harness_root = runreftest.SCRIPT_DIRECTORY
build = parser.build_obj
options = vars(parser.parse_args([]))
options.update(
{
"app": binary,
"focusFilterMode": "non-needs-focus",
"suite": "reftest",
}
)
if not os.path.isdir(build.bindir):
package_root = os.path.dirname(harness_root)
options.update(
{
"extraProfileFiles": [os.path.join(package_root, "bin", "plugins")],
"reftestExtensionPath": os.path.join(harness_root, "reftest"),
"sandboxReadWhitelist": [here, os.environ["PYTHON_TEST_TMP"]],
"utilityPath": os.path.join(package_root, "bin"),
"specialPowersExtensionPath": os.path.join(
harness_root, "specialpowers"
),
}
)
if "MOZ_FETCHES_DIR" in os.environ:
options["sandboxReadWhitelist"].append(os.environ["MOZ_FETCHES_DIR"])
else:
options.update(
{
"extraProfileFiles": [os.path.join(build.topobjdir, "dist", "plugins")],
"sandboxReadWhitelist": [build.topobjdir, build.topsrcdir],
"specialPowersExtensionPath": os.path.join(
build.distdir, "xpi-stage", "specialpowers"
),
}
)
def inner(**opts):
options.update(opts)
config = Namespace(**options)
# This is pulled from `runreftest.run_test_harness` minus some error
# checking that isn't necessary in this context. It should stay roughly
# in sync.
reftest = runreftest.RefTest(config.suite)
parser.validate(config, reftest)
config.app = reftest.getFullPath(config.app)
assert os.path.exists(config.app)
if config.xrePath is None:
config.xrePath = os.path.dirname(config.app)
return reftest, config
return inner
@pytest.fixture # noqa: F811
def runtests(get_reftest, normalize):
def inner(*tests, **opts):
assert len(tests) > 0
opts["tests"] = map(normalize, tests)
buf = StringIO()
opts["log_raw"] = [buf]
reftest, options = get_reftest(**opts)
result = reftest.runTests(options.tests, options)
out = json.loads("[" + ",".join(buf.getvalue().splitlines()) + "]")
buf.close()
return result, out
return inner
@pytest.fixture(autouse=True) # noqa: F811
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)
runreftest = pytest.importorskip("runreftest")
runreftest.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))