Bug 1476574 - Support resetting/dumping code coverage counters before/after web-platform-tests. r=jgraham

--HG--
extra : source : ec37892ce390414a0349e16e7cdc5d07d2d158ff
extra : histedit_source : 3f3e267d2c2385b35393c2e08621dabd47c07be4%2C03271be81bfe9f7b0d0dec52037606a20699bc3e
This commit is contained in:
Marco Castelluccio 2018-07-19 11:57:54 +02:00
parent 3441526820
commit 87fbf2563c
4 changed files with 83 additions and 2 deletions

View File

@ -132,6 +132,7 @@ var whitelist = [
{file: "chrome://marionette/content/test_anonymous_content.xul"},
{file: "chrome://marionette/content/test_dialog.properties"},
{file: "chrome://marionette/content/test_dialog.xul"},
{file: "chrome://marionette/content/PerTestCoverageUtils.jsm"},
// Bug 1348533
{file: "chrome://mozapps/skin/downloads/buttons.png", platforms: ["macosx"]},
{file: "chrome://mozapps/skin/downloads/downloadButtons.png", platforms: ["linux", "win"]},

View File

@ -46,4 +46,5 @@ marionette.jar:
content/test_dialog.xul (chrome/test_dialog.xul)
content/test_nested_iframe.xul (chrome/test_nested_iframe.xul)
content/test.xul (chrome/test.xul)
content/PerTestCoverageUtils.jsm (../../tools/code-coverage/PerTestCoverageUtils.jsm)
#endif

View File

@ -29,7 +29,8 @@ from .protocol import (AssertsProtocolPart,
SelectorProtocolPart,
ClickProtocolPart,
SendKeysProtocolPart,
TestDriverProtocolPart)
TestDriverProtocolPart,
CoverageProtocolPart)
from ..testrunner import Stop
from ..webdriver_server import GeckoDriverServer
@ -371,6 +372,53 @@ class MarionetteTestDriverProtocolPart(TestDriverProtocolPart):
self.parent.base.execute_script("window.postMessage(%s, '*')" % json.dumps(obj))
class MarionetteCoverageProtocolPart(CoverageProtocolPart):
def setup(self):
self.marionette = self.parent.marionette
script = """
ChromeUtils.import("chrome://marionette/content/PerTestCoverageUtils.jsm");
return PerTestCoverageUtils.enabled;
"""
with self.marionette.using_context(self.marionette.CONTEXT_CHROME):
self.is_enabled = self.marionette.execute_script(script)
def reset(self):
script = """
var callback = arguments[arguments.length - 1];
ChromeUtils.import("chrome://marionette/content/PerTestCoverageUtils.jsm");
PerTestCoverageUtils.beforeTest().then(callback, callback);
"""
with self.marionette.using_context(self.marionette.CONTEXT_CHROME):
try:
error = self.marionette.execute_async_script(script)
if error is not None:
raise Exception('Failure while resetting counters: %s' % json.dumps(error))
except (errors.MarionetteException, socket.error):
# This usually happens if the process crashed
pass
def dump(self):
if len(self.marionette.window_handles):
handle = self.marionette.window_handles[0]
self.marionette.switch_to_window(handle)
script = """
var callback = arguments[arguments.length - 1];
ChromeUtils.import("chrome://marionette/content/PerTestCoverageUtils.jsm");
PerTestCoverageUtils.afterTest().then(callback, callback);
"""
with self.marionette.using_context(self.marionette.CONTEXT_CHROME):
try:
error = self.marionette.execute_async_script(script)
if error is not None:
raise Exception('Failure while dumping counters: %s' % json.dumps(error))
except (errors.MarionetteException, socket.error):
# This usually happens if the process crashed
pass
class MarionetteProtocol(Protocol):
implements = [MarionetteBaseProtocolPart,
MarionetteTestharnessProtocolPart,
@ -380,7 +428,8 @@ class MarionetteProtocol(Protocol):
MarionetteClickProtocolPart,
MarionetteSendKeysProtocolPart,
MarionetteTestDriverProtocolPart,
MarionetteAssertsProtocolPart]
MarionetteAssertsProtocolPart,
MarionetteCoverageProtocolPart]
def __init__(self, executor, browser, capabilities=None, timeout_multiplier=1, e10s=True):
do_delayed_imports()
@ -599,6 +648,9 @@ class MarionetteTestharnessExecutor(TestharnessExecutor):
else:
timeout_ms = "null"
if self.protocol.coverage.is_enabled:
self.protocol.coverage.reset()
format_map = {"abs_url": url,
"url": strip_server(url),
"window_id": self.window_id,
@ -621,6 +673,10 @@ class MarionetteTestharnessExecutor(TestharnessExecutor):
done, rv = handler(result)
if done:
break
if self.protocol.coverage.is_enabled:
self.protocol.coverage.dump()
return rv
@ -689,8 +745,14 @@ class MarionetteRefTestExecutor(RefTestExecutor):
self.protocol.base.set_window(self.protocol.marionette.window_handles[-1])
self.has_window = True
if self.protocol.coverage.is_enabled:
self.protocol.coverage.reset()
result = self.implementation.run_test(test)
if self.protocol.coverage.is_enabled:
self.protocol.coverage.dump()
if self.debug:
assertion_count = self.protocol.asserts.get()
if "extra" not in result:

View File

@ -303,3 +303,20 @@ class AssertsProtocolPart(ProtocolPart):
def get(self):
"""Get a count of assertions since the last browser start"""
pass
class CoverageProtocolPart(ProtocolPart):
"""Protocol part for collecting per-test coverage data."""
__metaclass__ = ABCMeta
name = "coverage"
@abstractmethod
def reset(self):
"""Reset coverage counters"""
pass
@abstractmethod
def dump(self):
"""Dump coverage counters"""
pass