--- a/testing/web-platform/moz.build
+++ b/testing/web-platform/moz.build
@@ -9,25 +9,29 @@ WEB_PLATFORM_TESTS_MANIFESTS += [
('mozilla/meta/MANIFEST.json', 'mozilla/tests/')
]
TEST_HARNESS_FILES['web-platform'] += [
'mach_commands_base.py',
'mach_test_package_commands.py',
'outbound/**',
'runtests.py',
- 'wptrunner.ini'
+ 'wptrunner.ini',
]
-TEST_HARNESS_FILES['web-platform'].certs = [
+TEST_HARNESS_FILES['web-platform'].certs += [
'certs/cacert.pem',
'certs/web-platform.test.key',
'certs/web-platform.test.pem',
]
+TEST_HARNESS_FILES['web-platform'].prefs += [
+ '/build/sanitizers/lsan_suppressions.txt',
+]
+
with Files("**"):
SCHEDULES.exclusive = [
'web-platform-tests',
'web-platform-tests-reftests',
'web-platform-tests-wdspec',
]
with Files("moz.build"):
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/firefox.py
+++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/firefox.py
@@ -6,17 +6,17 @@ import subprocess
import sys
import tempfile
import mozinfo
import mozleak
from mozprocess import ProcessHandler
from mozprofile import FirefoxProfile, Preferences
from mozrunner import FirefoxRunner
-from mozrunner.utils import get_stack_fixer_function
+from mozrunner.utils import test_environment, get_stack_fixer_function
from mozcrash import mozcrash
from .base import (get_free_port,
Browser,
ExecutorBrowser,
require_arg,
cmd_arg,
browser_command)
@@ -74,16 +74,17 @@ def browser_kwargs(test_type, run_info_d
"ca_certificate_path": kwargs["ssl_env"].ca_cert_path(),
"e10s": kwargs["gecko_e10s"],
"stackfix_dir": kwargs["stackfix_dir"],
"binary_args": kwargs["binary_args"],
"timeout_multiplier": get_timeout_multiplier(test_type,
run_info_data,
**kwargs),
"leak_check": kwargs["leak_check"],
+ "asan": run_info_data.get("asan"),
"stylo_threads": kwargs["stylo_threads"],
"chaos_mode_flags": kwargs["chaos_mode_flags"],
"config": kwargs["config"]}
def executor_kwargs(test_type, server_config, cache_manager, run_info_data,
**kwargs):
executor_kwargs = base_executor_kwargs(test_type, server_config,
@@ -144,18 +145,18 @@ def update_properties():
class FirefoxBrowser(Browser):
used_ports = set()
init_timeout = 60
shutdown_timeout = 60
def __init__(self, logger, binary, prefs_root, test_type, extra_prefs=None, debug_info=None,
symbols_path=None, stackwalk_binary=None, certutil_binary=None,
ca_certificate_path=None, e10s=False, stackfix_dir=None,
- binary_args=None, timeout_multiplier=None, leak_check=False, stylo_threads=1,
- chaos_mode_flags=None, config=None):
+ binary_args=None, timeout_multiplier=None, leak_check=False, asan=False,
+ stylo_threads=1, chaos_mode_flags=None, config=None):
Browser.__init__(self, logger)
self.binary = binary
self.prefs_root = prefs_root
self.test_type = test_type
self.extra_prefs = extra_prefs
self.marionette_port = None
self.runner = None
self.debug_info = debug_info
@@ -171,33 +172,38 @@ class FirefoxBrowser(Browser):
self.stack_fixer = get_stack_fixer_function(stackfix_dir,
self.symbols_path)
else:
self.stack_fixer = None
if timeout_multiplier:
self.init_timeout = self.init_timeout * timeout_multiplier
+ self.asan = asan
+ self.leak_check = leak_check
self.leak_report_file = None
- self.leak_check = leak_check
+ self.lsan_handler = None
+ if self.asan:
+ self.lsan_handler = mozleak.LSANLeaks(logger)
self.stylo_threads = stylo_threads
self.chaos_mode_flags = chaos_mode_flags
def settings(self, test):
return {"check_leaks": self.leak_check and not test.leaks}
def start(self, **kwargs):
if self.marionette_port is None:
self.marionette_port = get_free_port(2828, exclude=self.used_ports)
self.used_ports.add(self.marionette_port)
- env = os.environ.copy()
- env["MOZ_CRASHREPORTER"] = "1"
- env["MOZ_CRASHREPORTER_SHUTDOWN"] = "1"
- env["MOZ_DISABLE_NONLOCAL_CONNECTIONS"] = "1"
+ env = test_environment(xrePath=os.path.dirname(self.binary),
+ debugger=self.debug_info is not None,
+ log=self.logger,
+ lsanPath=self.prefs_root)
+
env["STYLO_THREADS"] = str(self.stylo_threads)
if self.chaos_mode_flags is not None:
env["MOZ_CHAOSMODE"] = str(self.chaos_mode_flags)
preferences = self.load_prefs()
self.profile = FirefoxProfile(preferences=preferences)
self.profile.set_preferences({"marionette.port": self.marionette_port,
@@ -287,30 +293,31 @@ class FirefoxBrowser(Browser):
break
except OSError:
# This can happen on Windows if the process is already dead
pass
self.logger.debug("stopped")
def process_leaks(self):
self.logger.debug("PROCESS LEAKS %s" % self.leak_report_file)
- if self.leak_report_file is None:
- return
- mozleak.process_leak_log(
- self.leak_report_file,
- leak_thresholds={
- "default": 0,
- "tab": 10000, # See dependencies of bug 1051230.
- # GMP rarely gets a log, but when it does, it leaks a little.
- "geckomediaplugin": 20000,
- },
- ignore_missing_leaks=["geckomediaplugin"],
- log=self.logger,
- stack_fixer=self.stack_fixer
- )
+ if self.lsan_handler:
+ self.lsan_handler.process()
+ if self.leak_report_file is not None:
+ mozleak.process_leak_log(
+ self.leak_report_file,
+ leak_thresholds={
+ "default": 0,
+ "tab": 10000, # See dependencies of bug 1051230.
+ # GMP rarely gets a log, but when it does, it leaks a little.
+ "geckomediaplugin": 20000,
+ },
+ ignore_missing_leaks=["geckomediaplugin"],
+ log=self.logger,
+ stack_fixer=self.stack_fixer
+ )
def pid(self):
if self.runner.process_handler is None:
return None
try:
return self.runner.process_handler.pid
except AttributeError:
@@ -319,16 +326,18 @@ class FirefoxBrowser(Browser):
def on_output(self, line):
"""Write a line of output from the firefox process to the log"""
if "GLib-GObject-CRITICAL" in line:
return
if line:
data = line.decode("utf8", "replace")
if self.stack_fixer:
data = self.stack_fixer(data)
+ if self.lsan_handler:
+ self.lsan_handler.log(data)
self.logger.process_output(self.pid(),
data,
command=" ".join(self.runner.command))
def is_alive(self):
if self.runner:
return self.runner.is_running()
return False