Bug 1354232 - Allow wpt manifest files to specify LSAN errors to ignore, r=maja_zf
This adds a property lsan-allowed to the expectation manifest files
that takes a list of strings. Any entry in the list that matches a
frame in an LSAN stack will cause that stack to be regarded as an
expected failure.
MozReview-Commit-ID: 2oUw0joThha
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/firefox.py
+++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/firefox.py
@@ -182,16 +182,18 @@ class FirefoxBrowser(Browser):
self.leak_report_file = None
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):
+ if self.asan:
+ self.lsan_handler.set_allowed(test.lsan_allowed)
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 = test_environment(xrePath=os.path.dirname(self.binary),
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/manifestexpected.py
+++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/manifestexpected.py
@@ -56,22 +56,37 @@ def prefs(node):
def value(ini_value):
if isinstance(ini_value, (str, unicode)):
return tuple(ini_value.split(":", 1))
else:
return (ini_value, None)
try:
node_prefs = node.get("prefs")
- rv = dict(value(item) for item in node_prefs)
+ if type(node_prefs) in (str, unicode):
+ rv = dict(value(node_prefs))
+ else:
+ rv = dict(value(item) for item in node_prefs)
except KeyError:
rv = {}
return rv
+def lsan_allowed(node):
+ try:
+ node_items = node.get("lsan-allowed")
+ if isinstance(node_items, (str, unicode)):
+ rv = {node_items}
+ else:
+ rv = set(node_items)
+ except KeyError:
+ rv = set()
+ return rv
+
+
class ExpectedManifest(ManifestItem):
def __init__(self, name, test_path, url_base):
"""Object representing all the tests in a particular manifest
:param name: Name of the AST Node associated with this object.
Should always be None since this should always be associated with
the root node of the AST.
:param test_path: Path of the test file associated with this manifest.
@@ -132,16 +147,20 @@ class ExpectedManifest(ManifestItem):
@property
def tags(self):
return tags(self)
@property
def prefs(self):
return prefs(self)
+ @property
+ def lsan_allowed(self):
+ return lsan_allowed(self)
+
class DirectoryManifest(ManifestItem):
@property
def disabled(self):
return bool_prop("disabled", self)
@property
def restart_after(self):
@@ -162,16 +181,20 @@ class DirectoryManifest(ManifestItem):
@property
def tags(self):
return tags(self)
@property
def prefs(self):
return prefs(self)
+ @property
+ def lsan_allowed(self):
+ return lsan_allowed(self)
+
class TestNode(ManifestItem):
def __init__(self, name):
"""Tree node associated with a particular test in a manifest
:param name: name of the test"""
assert name is not None
ManifestItem.__init__(self, name)
@@ -219,16 +242,20 @@ class TestNode(ManifestItem):
@property
def tags(self):
return tags(self)
@property
def prefs(self):
return prefs(self)
+ @property
+ def lsan_allowed(self):
+ return lsan_allowed(self)
+
def append(self, node):
"""Add a subtest to the current test
:param node: AST Node associated with the subtest"""
child = ManifestItem.append(self, node)
self.subtests[child.name] = child
def get_subtest(self, name):
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/wpttest.py
+++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/wpttest.py
@@ -210,16 +210,26 @@ class Test(object):
def max_assertion_count(self):
for meta in self.itermeta(None):
count = meta.max_assertion_count
if count is not None:
return count
return 0
@property
+ def lsan_allowed(self):
+ lsan_allowed = set()
+ for meta in self.itermeta():
+ lsan_allowed |= meta.lsan_allowed
+ if atom_reset in lsan_allowed:
+ lsan_allowed.remove(atom_reset)
+ break
+ return lsan_allowed
+
+ @property
def tags(self):
tags = set()
for meta in self.itermeta():
meta_tags = meta.tags
tags |= meta_tags
if atom_reset in meta_tags:
tags.remove(atom_reset)
break