Upgrade wptrunner (tests/wpt/harness) to latest version

This commit is contained in:
Corey Farwell 2015-08-09 15:30:02 -04:00
parent 5478c7c24b
commit 759c52d7eb
28 changed files with 164 additions and 146 deletions

View file

@ -154,11 +154,11 @@ metadata files in a subdirectory of the current directory named ``meta``.
Output Output
------ ------
wptrunner uses the :py:mod:`mozlog.structured` package for output. This wptrunner uses the :py:mod:`mozlog` package for output. This
structures events such as test results or log messages as JSON objects structures events such as test results or log messages as JSON objects
that can then be fed to other tools for interpretation. More details that can then be fed to other tools for interpretation. More details
about the message format are given in the about the message format are given in the
:py:mod:`mozlog.structured` documentation. :py:mod:`mozlog` documentation.
By default the raw JSON messages are dumped to stdout. This is By default the raw JSON messages are dumped to stdout. This is
convenient for piping into other tools, but not ideal for humans convenient for piping into other tools, but not ideal for humans

View file

@ -1,4 +1,4 @@
html5lib >= 0.99 html5lib >= 0.99
mozinfo >= 0.7 mozinfo >= 0.7
mozlog >= 2.8 mozlog >= 3.0
mozdebug >= 0.1 mozdebug >= 0.1

View file

@ -8,7 +8,11 @@ ssl-type=none
# prefs-root=/path/to/gecko-src/testing/profiles/ # prefs-root=/path/to/gecko-src/testing/profiles/
# [servo] # [servo]
# binary=/path/to/servo-src/components/servo/target/servo # binary=/path/to/servo-src/target/release/servo
# exclude=testharness # Because it needs a special testharness.js
# [servodriver]
# binary=/path/to/servo-src/target/release/servo
# exclude=testharness # Because it needs a special testharness.js # exclude=testharness # Because it needs a special testharness.js
# [chrome] # [chrome]

View file

@ -8,9 +8,9 @@ import threading
import time import time
from StringIO import StringIO from StringIO import StringIO
from mozlog.structured import structuredlog, reader from mozlog import structuredlog, reader
from mozlog.structured.handlers import BaseHandler, StreamHandler, StatusHandler from mozlog.handlers import BaseHandler, StreamHandler, StatusHandler
from mozlog.structured.formatters import MachFormatter from mozlog.formatters import MachFormatter
from wptrunner import wptcommandline, wptrunner from wptrunner import wptcommandline, wptrunner
here = os.path.abspath(os.path.dirname(__file__)) here = os.path.abspath(os.path.dirname(__file__))

View file

@ -27,7 +27,8 @@ __wptrunner__ = {"product": "firefox",
"reftest": "MarionetteRefTestExecutor"}, "reftest": "MarionetteRefTestExecutor"},
"browser_kwargs": "browser_kwargs", "browser_kwargs": "browser_kwargs",
"executor_kwargs": "executor_kwargs", "executor_kwargs": "executor_kwargs",
"env_options": "env_options"} "env_options": "env_options",
"run_info_extras": "run_info_extras"}
def check_args(**kwargs): def check_args(**kwargs):
@ -43,7 +44,8 @@ def browser_kwargs(**kwargs):
"symbols_path": kwargs["symbols_path"], "symbols_path": kwargs["symbols_path"],
"stackwalk_binary": kwargs["stackwalk_binary"], "stackwalk_binary": kwargs["stackwalk_binary"],
"certutil_binary": kwargs["certutil_binary"], "certutil_binary": kwargs["certutil_binary"],
"ca_certificate_path": kwargs["ssl_env"].ca_cert_path()} "ca_certificate_path": kwargs["ssl_env"].ca_cert_path(),
"e10s": kwargs["gecko_e10s"]}
def executor_kwargs(test_type, server_config, cache_manager, run_info_data, def executor_kwargs(test_type, server_config, cache_manager, run_info_data,
@ -63,13 +65,15 @@ def env_options():
"certificate_domain": "web-platform.test", "certificate_domain": "web-platform.test",
"supports_debugger": True} "supports_debugger": True}
def run_info_extras(**kwargs):
return {"e10s": kwargs["gecko_e10s"]}
class FirefoxBrowser(Browser): class FirefoxBrowser(Browser):
used_ports = set() used_ports = set()
def __init__(self, logger, binary, prefs_root, debug_info=None, def __init__(self, logger, binary, prefs_root, debug_info=None,
symbols_path=None, stackwalk_binary=None, certutil_binary=None, symbols_path=None, stackwalk_binary=None, certutil_binary=None,
ca_certificate_path=None): ca_certificate_path=None, e10s=False):
Browser.__init__(self, logger) Browser.__init__(self, logger)
self.binary = binary self.binary = binary
self.prefs_root = prefs_root self.prefs_root = prefs_root
@ -81,6 +85,7 @@ class FirefoxBrowser(Browser):
self.stackwalk_binary = stackwalk_binary self.stackwalk_binary = stackwalk_binary
self.ca_certificate_path = ca_certificate_path self.ca_certificate_path = ca_certificate_path
self.certutil_binary = certutil_binary self.certutil_binary = certutil_binary
self.e10s = e10s
def start(self): def start(self):
self.marionette_port = get_free_port(2828, exclude=self.used_ports) self.marionette_port = get_free_port(2828, exclude=self.used_ports)
@ -99,6 +104,8 @@ class FirefoxBrowser(Browser):
"marionette.defaultPrefs.port": self.marionette_port, "marionette.defaultPrefs.port": self.marionette_port,
"dom.disable_open_during_load": False, "dom.disable_open_during_load": False,
"network.dns.localDomains": ",".join(hostnames)}) "network.dns.localDomains": ",".join(hostnames)})
if self.e10s:
self.profile.set_preferences({"browser.tabs.remote.autostart": True})
if self.ca_certificate_path is not None: if self.ca_certificate_path is not None:
self.setup_ssl() self.setup_ssl()

View file

@ -10,7 +10,7 @@ import socket
import sys import sys
import time import time
from mozlog.structured import get_default_logger, handlers from mozlog import get_default_logger, handlers
from wptlogging import LogLevelRewriter from wptlogging import LogLevelRewriter
@ -80,25 +80,6 @@ class TestEnvironmentError(Exception):
pass pass
class StaticHandler(object):
def __init__(self, path, format_args, content_type, **headers):
with open(path) as f:
self.data = f.read() % format_args
self.resp_headers = [("Content-Type", content_type)]
for k, v in headers.iteritems():
resp_headers.append((k.replace("_", "-"), v))
self.handler = serve.handlers.handler(self.handle_request)
def handle_request(self, request, response):
return self.resp_headers, self.data
def __call__(self, request, response):
rv = self.handler(request, response)
return rv
class TestEnvironment(object): class TestEnvironment(object):
def __init__(self, test_paths, ssl_env, pause_after_test, debug_info, options): def __init__(self, test_paths, ssl_env, pause_after_test, debug_info, options):
"""Context manager that owns the test environment i.e. the http and """Context manager that owns the test environment i.e. the http and
@ -114,29 +95,30 @@ class TestEnvironment(object):
self.options = options if options is not None else {} self.options = options if options is not None else {}
self.cache_manager = multiprocessing.Manager() self.cache_manager = multiprocessing.Manager()
self.routes = self.get_routes() self.stash = serve.stash.StashServer()
def __enter__(self): def __enter__(self):
self.stash.__enter__()
self.ssl_env.__enter__() self.ssl_env.__enter__()
self.cache_manager.__enter__() self.cache_manager.__enter__()
self.setup_server_logging() self.setup_server_logging()
self.config = self.load_config() self.config = self.load_config()
serve.set_computed_defaults(self.config) serve.set_computed_defaults(self.config)
self.external_config, self.servers = serve.start(self.config, self.ssl_env, self.external_config, self.servers = serve.start(self.config, self.ssl_env,
self.routes) self.get_routes())
if self.options.get("supports_debugger") and self.debug_info and self.debug_info.interactive: if self.options.get("supports_debugger") and self.debug_info and self.debug_info.interactive:
self.ignore_interrupts() self.ignore_interrupts()
return self return self
def __exit__(self, exc_type, exc_val, exc_tb): def __exit__(self, exc_type, exc_val, exc_tb):
self.process_interrupts() self.process_interrupts()
self.cache_manager.__exit__(exc_type, exc_val, exc_tb)
self.ssl_env.__exit__(exc_type, exc_val, exc_tb)
for scheme, servers in self.servers.iteritems(): for scheme, servers in self.servers.iteritems():
for port, server in servers: for port, server in servers:
server.kill() server.kill()
self.cache_manager.__exit__(exc_type, exc_val, exc_tb)
self.ssl_env.__exit__(exc_type, exc_val, exc_tb)
self.stash.__exit__()
def ignore_interrupts(self): def ignore_interrupts(self):
signal.signal(signal.SIGINT, signal.SIG_IGN) signal.signal(signal.SIGINT, signal.SIG_IGN)
@ -193,40 +175,25 @@ class TestEnvironment(object):
pass pass
def get_routes(self): def get_routes(self):
routes = serve.default_routes() route_builder = serve.RoutesBuilder()
for path, format_args, content_type, route in [ for path, format_args, content_type, route in [
("testharness_runner.html", {}, "text/html", "/testharness_runner.html"), ("testharness_runner.html", {}, "text/html", "/testharness_runner.html"),
(self.options.get("testharnessreport", "testharnessreport.js"), (self.options.get("testharnessreport", "testharnessreport.js"),
{"output": self.pause_after_test}, "text/javascript", {"output": self.pause_after_test}, "text/javascript",
"/resources/testharnessreport.js")]: "/resources/testharnessreport.js")]:
handler = StaticHandler(os.path.join(here, path), format_args, content_type) path = os.path.normpath(os.path.join(here, path))
routes.insert(0, (b"GET", str(route), handler)) route_builder.add_static(path, format_args, content_type, route)
for url, paths in self.test_paths.iteritems(): for url_base, paths in self.test_paths.iteritems():
if url == "/": if url_base == "/":
continue continue
route_builder.add_mount_point(url_base, paths["tests_path"])
path = paths["tests_path"]
url = "/%s/" % url.strip("/")
for (method,
suffix,
handler_cls) in [(b"*",
b"*.py",
serve.handlers.PythonScriptHandler),
(b"GET",
"*.asis",
serve.handlers.AsIsHandler),
(b"GET",
"*",
serve.handlers.FileHandler)]:
route = (method, b"%s%s" % (str(url), str(suffix)), handler_cls(path, url_base=url))
routes.insert(-3, route)
if "/" not in self.test_paths: if "/" not in self.test_paths:
routes = routes[:-3] del route_builder.mountpoint_routes["/"]
return routes return route_builder.get_routes()
def ensure_started(self): def ensure_started(self):
# Pause for a while to ensure that the server has a chance to start # Pause for a while to ensure that the server has a chance to start

View file

@ -55,12 +55,14 @@ class TestharnessResultConverter(object):
def __call__(self, test, result): def __call__(self, test, result):
"""Convert a JSON result into a (TestResult, [SubtestResult]) tuple""" """Convert a JSON result into a (TestResult, [SubtestResult]) tuple"""
assert result["test"] == test.url, ("Got results from %s, expected %s" % result_url, status, message, stack, subtest_results = result
(result["test"], test.url)) assert result_url == test.url, ("Got results from %s, expected %s" %
harness_result = test.result_cls(self.harness_codes[result["status"]], result["message"]) (result_url, test.url))
harness_result = test.result_cls(self.harness_codes[status], message)
return (harness_result, return (harness_result,
[test.subtest_result_cls(subtest["name"], self.test_codes[subtest["status"]], [test.subtest_result_cls(name, self.test_codes[status], message, stack)
subtest["message"], subtest.get("stack", None)) for subtest in result["tests"]]) for name, status, message, stack in subtest_results])
testharness_result_converter = TestharnessResultConverter() testharness_result_converter = TestharnessResultConverter()

View file

@ -107,6 +107,12 @@ class MarionetteProtocol(Protocol):
return True return True
def after_connect(self): def after_connect(self):
# Turn off debug-level logging by default since this is so verbose
with self.marionette.using_context("chrome"):
self.marionette.execute_script("""
Components.utils.import("resource://gre/modules/Log.jsm");
Log.repository.getLogger("Marionette").level = Log.Level.Info;
""")
self.load_runner("http") self.load_runner("http")
def load_runner(self, protocol): def load_runner(self, protocol):

View file

@ -65,6 +65,8 @@ class ServoTestharnessExecutor(ProcessTestExecutor):
args = ["--cpu", "--hard-fail", "-u", "Servo/wptrunner", "-z", self.test_url(test)] args = ["--cpu", "--hard-fail", "-u", "Servo/wptrunner", "-z", self.test_url(test)]
for stylesheet in self.browser.user_stylesheets: for stylesheet in self.browser.user_stylesheets:
args += ["--user-stylesheet", stylesheet] args += ["--user-stylesheet", stylesheet]
for pref in test.environment.get('prefs', {}):
args += ["--pref", pref]
debug_args, command = browser_command(self.binary, args, self.debug_info) debug_args, command = browser_command(self.binary, args, self.debug_info)
self.command = command self.command = command
@ -104,7 +106,6 @@ class ServoTestharnessExecutor(ProcessTestExecutor):
if self.result_flag.is_set(): if self.result_flag.is_set():
if self.result_data is not None: if self.result_data is not None:
self.result_data["test"] = test.url
result = self.convert_result(test, self.result_data) result = self.convert_result(test, self.result_data)
else: else:
self.proc.wait() self.proc.wait()
@ -190,19 +191,29 @@ class ServoRefTestExecutor(ProcessTestExecutor):
full_url = self.test_url(test) full_url = self.test_url(test)
with TempFilename(self.tempdir) as output_path: with TempFilename(self.tempdir) as output_path:
self.command = [self.binary, "--cpu", "--hard-fail", "--exit", debug_args, command = browser_command(
"-u", "Servo/wptrunner", "-Z", "disable-text-aa", self.binary,
"--output=%s" % output_path, full_url] ["--cpu", "--hard-fail", "--exit", "-u", "Servo/wptrunner",
"-Z", "disable-text-aa", "--output=%s" % output_path, full_url],
self.debug_info)
for stylesheet in self.browser.user_stylesheets: for stylesheet in self.browser.user_stylesheets:
self.command += ["--user-stylesheet", stylesheet] command += ["--user-stylesheet", stylesheet]
for pref in test.environment.get('prefs', {}):
command += ["--pref", pref]
self.command = debug_args + command
env = os.environ.copy() env = os.environ.copy()
env["HOST_FILE"] = self.hosts_path env["HOST_FILE"] = self.hosts_path
if not self.interactive:
self.proc = ProcessHandler(self.command, self.proc = ProcessHandler(self.command,
processOutputLine=[self.on_output], processOutputLine=[self.on_output],
env=env) env=env)
try: try:
self.proc.run() self.proc.run()
timeout = test.timeout * self.timeout_multiplier + 5 timeout = test.timeout * self.timeout_multiplier + 5
@ -210,6 +221,14 @@ class ServoRefTestExecutor(ProcessTestExecutor):
except KeyboardInterrupt: except KeyboardInterrupt:
self.proc.kill() self.proc.kill()
raise raise
else:
self.proc = subprocess.Popen(self.command,
env=env)
try:
rv = self.proc.wait()
except KeyboardInterrupt:
self.proc.kill()
raise
if rv is None: if rv is None:
self.proc.kill() self.proc.kill()

View file

@ -13,11 +13,16 @@ window.wrappedJSObject.addEventListener("message", function listener(event) {
clearTimeout(timer); clearTimeout(timer);
var tests = event.data.tests; var tests = event.data.tests;
var status = event.data.status; var status = event.data.status;
marionetteScriptFinished({test:"%(url)s",
tests: tests, var subtest_results = tests.map(function(x) {
status: status.status, return [x.name, x.status, x.message, x.stack]
message: status.message, });
stack: status.stack});
marionetteScriptFinished(["%(url)s",
status.status,
status.message,
status.stack,
subtest_results]);
}, false); }, false);
window.wrappedJSObject.win = window.open("%(abs_url)s", "%(window_id)s"); window.wrappedJSObject.win = window.open("%(abs_url)s", "%(window_id)s");

View file

@ -8,12 +8,17 @@ window.timeout_multiplier = %(timeout_multiplier)d;
window.addEventListener("message", function(event) { window.addEventListener("message", function(event) {
var tests = event.data[0]; var tests = event.data[0];
var status = event.data[1]; var status = event.data[1];
var subtest_results = tests.map(function(x) {
return [x.name, x.status, x.message, x.stack]
});
clearTimeout(timer); clearTimeout(timer);
callback({test:"%(url)s", callback(["%(url)s",
tests: tests, status.status,
status: status.status, status.message,
message: status.message, status.stack,
stack: status.stack}); subtest_results]);
}, false); }, false);
window.win = window.open("%(abs_url)s", "%(window_id)s"); window.win = window.open("%(abs_url)s", "%(window_id)s");

View file

@ -57,7 +57,7 @@ class IncludeManifest(ManifestItem):
try: try:
skip_value = self.get("skip", {"test_type": test.item_type}).lower() skip_value = self.get("skip", {"test_type": test.item_type}).lower()
assert skip_value in ("true", "false") assert skip_value in ("true", "false")
return False if skip_value == "true" else True return skip_value != "true"
except KeyError: except KeyError:
if node.parent is not None: if node.parent is not None:
node = node.parent node = node.parent
@ -107,6 +107,7 @@ class IncludeManifest(ManifestItem):
if component not in node.child_map: if component not in node.child_map:
new_node = IncludeManifest(DataNode(component)) new_node = IncludeManifest(DataNode(component))
node.append(new_node) node.append(new_node)
new_node.set("skip", node.get("skip", {}))
node = node.child_map[component] node = node.child_map[component]

View file

@ -329,7 +329,7 @@ def group_conditionals(values):
properties = set(item[0] for item in by_property.iterkeys()) properties = set(item[0] for item in by_property.iterkeys())
prop_order = ["debug", "os", "version", "processor", "bits"] prop_order = ["debug", "e10s", "os", "version", "processor", "bits"]
include_props = [] include_props = []
for prop in prop_order: for prop in prop_order:
@ -356,7 +356,7 @@ def make_expr(prop_set, status):
assert len(prop_set) > 0 assert len(prop_set) > 0
no_value_props = set(["debug"]) no_value_props = set(["debug", "e10s"])
expressions = [] expressions = []
for prop, value in prop_set: for prop, value in prop_set:

View file

@ -10,8 +10,8 @@ import types
import uuid import uuid
from collections import defaultdict from collections import defaultdict
from mozlog.structured import reader from mozlog import reader
from mozlog.structured import structuredlog from mozlog import structuredlog
import expected import expected
import manifestupdate import manifestupdate

View file

@ -43,6 +43,8 @@ def load_product(config, product):
browser_kwargs = getattr(module, data["browser_kwargs"]) browser_kwargs = getattr(module, data["browser_kwargs"])
executor_kwargs = getattr(module, data["executor_kwargs"]) executor_kwargs = getattr(module, data["executor_kwargs"])
env_options = getattr(module, data["env_options"])() env_options = getattr(module, data["env_options"])()
run_info_extras = (getattr(module, data["run_info_extras"])
if "run_info_extras" in data else lambda **kwargs:{})
executor_classes = {} executor_classes = {}
for test_type, cls_name in data["executor"].iteritems(): for test_type, cls_name in data["executor"].iteritems():
@ -52,4 +54,4 @@ def load_product(config, product):
return (check_args, return (check_args,
browser_cls, browser_kwargs, browser_cls, browser_kwargs,
executor_classes, executor_kwargs, executor_classes, executor_kwargs,
env_options) env_options, run_info_extras)

View file

@ -10,7 +10,7 @@ from collections import defaultdict
import wptrunner import wptrunner
import wpttest import wpttest
from mozlog.structured import commandline, reader from mozlog import commandline, reader
logger = None logger = None

View file

@ -7,12 +7,14 @@ var props = {output:%(output)d};
setup(props); setup(props);
add_completion_callback(function (tests, harness_status) { add_completion_callback(function (tests, harness_status) {
alert("RESULT: " + JSON.stringify({ var id = location.pathname + location.search + location.hash;
tests: tests.map(function(t) { alert("RESULT: " + JSON.stringify([
return { name: t.name, status: t.status, message: t.message, stack: t.stack} id,
harness_status.status,
harness_status.message,
harness_status.stack,
tests.map(function(t) {
return [t.name, t.status, t.message, t.stack]
}), }),
status: harness_status.status, ]));
message: harness_status.message,
stack: harness_status.stack,
}));
}); });

View file

@ -6,15 +6,15 @@ setup({output:%(output)d});
add_completion_callback(function() { add_completion_callback(function() {
add_completion_callback(function (tests, status) { add_completion_callback(function (tests, status) {
var test_results = tests.map(function(x) { var subtest_results = tests.map(function(x) {
return {name:x.name, status:x.status, message:x.message, stack:x.stack} return [x.name, x.status, x.message, x.stack]
}); });
var id = location.pathname + location.search + location.hash; var id = location.pathname + location.search + location.hash;
var results = JSON.stringify({test: id, var results = JSON.stringify([id,
tests:test_results, status.status,
status: status.status, status.message,
message: status.message, status.stack,
stack: status.stack}); subtest_results]);
(function done() { (function done() {
if (window.__wd_results_callback__) { if (window.__wd_results_callback__) {
clearTimeout(__wd_results_timer__); clearTimeout(__wd_results_timer__);

View file

@ -15,16 +15,3 @@ if (window.opener && window.opener.explicit_timeout) {
} }
setup(props); setup(props);
add_completion_callback(function() {
add_completion_callback(function(tests, status) {
var harness_status = {
"status": status.status,
"message": status.message,
"stack": status.stack
};
var test_results = tests.map(function(x) {
return {name:x.name, status:x.status, message:x.message, stack:x.stack}
});
window.opener.postMessage([test_results, harness_status], "*");
})
});

View file

@ -496,7 +496,7 @@ class TestLoader(object):
def iter_tests(self): def iter_tests(self):
manifest_items = [] manifest_items = []
for manifest in self.manifests.keys(): for manifest in sorted(self.manifests.keys(), key=lambda x:x.url_base):
manifest_iter = iterfilter(self.manifest_filters, manifest_iter = iterfilter(self.manifest_filters,
manifest.itertypes(*self.test_types)) manifest.itertypes(*self.test_types))
manifest_items.extend(manifest_iter) manifest_items.extend(manifest_iter)

View file

@ -11,7 +11,7 @@ import traceback
from Queue import Empty from Queue import Empty
from multiprocessing import Process, current_process, Queue from multiprocessing import Process, current_process, Queue
from mozlog.structured import structuredlog from mozlog import structuredlog
# Special value used as a sentinal in various commands # Special value used as a sentinal in various commands
Stop = object() Stop = object()

View file

@ -6,7 +6,7 @@ import unittest
import StringIO import StringIO
from .. import metadata, manifestupdate from .. import metadata, manifestupdate
from mozlog.structured import structuredlog, handlers, formatters from mozlog import structuredlog, handlers, formatters
class TestExpectedUpdater(unittest.TestCase): class TestExpectedUpdater(unittest.TestCase):

View file

@ -124,24 +124,23 @@ class GetSyncTargetCommit(Step):
class LoadManifest(Step): class LoadManifest(Step):
"""Load the test manifest""" """Load the test manifest"""
provides = ["test_manifest"] provides = ["manifest_path", "test_manifest", "old_manifest"]
def create(self, state): def create(self, state):
state.test_manifest = testloader.ManifestLoader(state.tests_path).load_manifest( from manifest import manifest
state.tests_path, state.metadata_path, state.manifest_path = os.path.join(state.metadata_path, "MANIFEST.json")
) # Conservatively always rebuild the manifest when doing a sync
state.old_manifest = manifest.load(state.tests_path, state.manifest_path)
state.test_manifest = manifest.Manifest(None, "/")
class UpdateManifest(Step): class UpdateManifest(Step):
"""Update the manifest to match the tests in the sync tree checkout""" """Update the manifest to match the tests in the sync tree checkout"""
provides = ["initial_rev"]
def create(self, state): def create(self, state):
from manifest import manifest, update from manifest import manifest, update
test_manifest = state.test_manifest update.update(state.sync["path"], "/", state.test_manifest)
state.initial_rev = test_manifest.rev manifest.write(state.test_manifest, state.manifest_path)
update.update(state.sync["path"], "/", test_manifest)
manifest.write(test_manifest, os.path.join(state.metadata_path, "MANIFEST.json"))
class CopyWorkTree(Step): class CopyWorkTree(Step):

View file

@ -5,7 +5,7 @@
import subprocess import subprocess
from functools import partial from functools import partial
from mozlog.structured import get_default_logger from mozlog import get_default_logger
logger = None logger = None

View file

@ -35,7 +35,7 @@ def require_arg(kwargs, name, value_func=None):
def create_parser(product_choices=None): def create_parser(product_choices=None):
from mozlog.structured import commandline from mozlog import commandline
import products import products
@ -154,6 +154,8 @@ def create_parser(product_choices=None):
gecko_group = parser.add_argument_group("Gecko-specific") gecko_group = parser.add_argument_group("Gecko-specific")
gecko_group.add_argument("--prefs-root", dest="prefs_root", action="store", type=abs_path, gecko_group.add_argument("--prefs-root", dest="prefs_root", action="store", type=abs_path,
help="Path to the folder containing browser prefs") help="Path to the folder containing browser prefs")
gecko_group.add_argument("--e10s", dest="gecko_e10s", action="store_true",
help="Path to the folder containing browser prefs")
b2g_group = parser.add_argument_group("B2G-specific") b2g_group = parser.add_argument_group("B2G-specific")
b2g_group.add_argument("--b2g-no-backup", action="store_true", default=False, b2g_group.add_argument("--b2g-no-backup", action="store_true", default=False,
@ -290,7 +292,7 @@ def check_args(kwargs):
kwargs["debugger"] = mozdebug.get_default_debugger_name() kwargs["debugger"] = mozdebug.get_default_debugger_name()
debug_info = mozdebug.get_debugger_info(kwargs["debugger"], debug_info = mozdebug.get_debugger_info(kwargs["debugger"],
kwargs["debugger_args"]) kwargs["debugger_args"])
if debug_info.interactive: if debug_info and debug_info.interactive:
if kwargs["processes"] != 1: if kwargs["processes"] != 1:
kwargs["processes"] = 1 kwargs["processes"] = 1
kwargs["no_capture_stdio"] = True kwargs["no_capture_stdio"] = True

View file

@ -8,7 +8,7 @@ import threading
from StringIO import StringIO from StringIO import StringIO
from multiprocessing import Queue from multiprocessing import Queue
from mozlog.structured import commandline, stdadapter from mozlog import commandline, stdadapter
def setup(args, defaults): def setup(args, defaults):
logger = commandline.setup_logging("web-platform-tests", args, defaults) logger = commandline.setup_logging("web-platform-tests", args, defaults)

View file

@ -40,8 +40,12 @@ def setup_logging(*args, **kwargs):
global logger global logger
logger = wptlogging.setup(*args, **kwargs) logger = wptlogging.setup(*args, **kwargs)
def get_loader(test_paths, product, ssl_env, debug=None, **kwargs): def get_loader(test_paths, product, ssl_env, debug=None, run_info_extras=None, **kwargs):
run_info = wpttest.get_run_info(kwargs["run_info"], product, debug=debug) if run_info_extras is None:
run_info_extras = {}
run_info = wpttest.get_run_info(kwargs["run_info"], product, debug=debug,
extras=run_info_extras)
test_manifests = testloader.ManifestLoader(test_paths, force_manifest_update=kwargs["manifest_update"]).load() test_manifests = testloader.ManifestLoader(test_paths, force_manifest_update=kwargs["manifest_update"]).load()
@ -111,17 +115,21 @@ def run_tests(config, test_paths, product, **kwargs):
(check_args, (check_args,
browser_cls, get_browser_kwargs, browser_cls, get_browser_kwargs,
executor_classes, get_executor_kwargs, executor_classes, get_executor_kwargs,
env_options) = products.load_product(config, product) env_options, run_info_extras) = products.load_product(config, product)
ssl_env = env.ssl_env(logger, **kwargs) ssl_env = env.ssl_env(logger, **kwargs)
check_args(**kwargs) check_args(**kwargs)
if "test_loader" in kwargs: if "test_loader" in kwargs:
run_info = wpttest.get_run_info(kwargs["run_info"], product, debug=None) run_info = wpttest.get_run_info(kwargs["run_info"], product, debug=None,
extras=run_info_extras(**kwargs))
test_loader = kwargs["test_loader"] test_loader = kwargs["test_loader"]
else: else:
run_info, test_loader = get_loader(test_paths, product, ssl_env, run_info, test_loader = get_loader(test_paths,
product,
ssl_env,
run_info_extras=run_info_extras(**kwargs),
**kwargs) **kwargs)
if kwargs["run_by_dir"] is False: if kwargs["run_by_dir"] is False:

View file

@ -57,7 +57,7 @@ def get_run_info(metadata_root, product, **kwargs):
class RunInfo(dict): class RunInfo(dict):
def __init__(self, metadata_root, product, debug): def __init__(self, metadata_root, product, debug, extras=None):
self._update_mozinfo(metadata_root) self._update_mozinfo(metadata_root)
self.update(mozinfo.info) self.update(mozinfo.info)
self["product"] = product self["product"] = product
@ -66,6 +66,8 @@ class RunInfo(dict):
elif "debug" not in self: elif "debug" not in self:
# Default to release # Default to release
self["debug"] = False self["debug"] = False
if extras is not None:
self.update(extras)
def _update_mozinfo(self, metadata_root): def _update_mozinfo(self, metadata_root):
"""Add extra build information from a mozinfo.json file in a parent """Add extra build information from a mozinfo.json file in a parent