Skip to content

Commit

Permalink
Bug 1644778 - add a mozperftest to measure browser.xhtml DOM size, r=…
Browse files Browse the repository at this point in the history
…tarek,dhouse,sparky

Differential Revision: https://phabricator.services.mozilla.com/D79152
  • Loading branch information
billrest committed Jul 13, 2020
1 parent bddb48e commit 7dfca9d
Show file tree
Hide file tree
Showing 14 changed files with 549 additions and 233 deletions.
85 changes: 85 additions & 0 deletions browser/base/content/test/perftest_browser_xhtml_dom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/* Any copyright is dedicated to the Public Domain.
* https://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint-env node */
"use strict";

/* global module */
async function test(context, commands) {
await context.selenium.driver.setContext("chrome");
let elementData = await context.selenium.driver.executeAsyncScript(
function() {
let callback = arguments[arguments.length - 1];
(async function() {
let lightDOM = document.querySelectorAll("*");
let elementsWithoutIDs = {};
let idElements = [];
let lightDOMDetails = { idElements, elementsWithoutIDs };
lightDOM.forEach(n => {
if (n.id) {
idElements.push(n.id);
} else {
if (!elementsWithoutIDs.hasOwnProperty(n.localName)) {
elementsWithoutIDs[n.localName] = 0;
}
elementsWithoutIDs[n.localName]++;
}
});
let lightDOMCount = lightDOM.length;

// Recursively explore shadow DOM:
function getShadowElements(root) {
let allElems = Array.from(root.querySelectorAll("*"));
let shadowRoots = allElems.map(n => n.openOrClosedShadowRoot);
for (let innerRoot of shadowRoots) {
if (innerRoot) {
allElems.push(getShadowElements(innerRoot));
}
}
return allElems;
}
let totalDOMCount = Array.from(lightDOM, node => {
if (node.openOrClosedShadowRoot) {
return [node].concat(
getShadowElements(node.openOrClosedShadowRoot)
);
}
return node;
}).flat().length;
let panelMenuCount = document.querySelectorAll(
"panel,menupopup,popup,popupnotification"
).length;
return {
panelMenuCount,
lightDOMCount,
totalDOMCount,
lightDOMDetails,
};
})().then(callback);
}
);
let { lightDOMDetails } = elementData;
delete elementData.lightDOMDetails;
lightDOMDetails.idElements.sort();
for (let id of lightDOMDetails.idElements) {
console.log(id);
}
console.log("Elements without ids:");
for (let [localName, count] of Object.entries(
lightDOMDetails.elementsWithoutIDs
)) {
console.log(count.toString().padStart(4) + " " + localName);
}
console.log(elementData);
await context.selenium.driver.setContext("content");
await commands.measure.start("data:text/html,BrowserDOM");
commands.measure.addObject(elementData);
}

module.exports = {
test,
owner: "Browser Front-end team",
name: "Dom-size",
description: "Measures the size of the DOM",
supportedBrowsers: ["Desktop"],
supportedPlatforms: ["Windows", "Linux", "macOS"],
};
2 changes: 2 additions & 0 deletions build/gen_test_packages_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
'gtest',
'updater-dep',
'jsreftest',
'perftests',
]

PACKAGE_SPECIFIED_HARNESSES = [
Expand All @@ -39,6 +40,7 @@
'updater-dep',
'jittest',
'jsreftest',
'perftests',
]

# These packages are not present for every build configuration.
Expand Down
3 changes: 3 additions & 0 deletions build/sparse-profiles/perftest
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@
[include]
path:tools/lint/eslint/
path:testing/performance
glob:**/perftest_*.js


55 changes: 55 additions & 0 deletions python/mozbuild/mozbuild/action/test_archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
'jsreftest/**',
'jit-test/**',
'jittest/**', # To make the ignore checker happy
'perftests/**',
],
},
{
Expand Down Expand Up @@ -465,6 +466,60 @@
'dest': 'talos/talos/tests/webkit/PerformanceTests/',
},
],
'perftests': [
{
'source': buildconfig.topsrcdir,
'pattern': 'testing/mozbase/**',
},
{
'source': buildconfig.topsrcdir,
'pattern': 'third_party/python/**',
},
{
'source': buildconfig.topsrcdir,
'pattern': 'tools/lint/eslint/**',
},
{
'source': buildconfig.topsrcdir,
'pattern': '**/perftest_*.js'
},
{
'source': buildconfig.topsrcdir,
'pattern': '**/hooks_*py'
},
{
'source': buildconfig.topsrcdir,
'pattern': 'build/autoconf/**'
},
{
'source': buildconfig.topsrcdir,
'pattern': 'build/moz.configure/**'
},
{
'source': buildconfig.topsrcdir,
'pattern': 'python/**'
},
{
'source': buildconfig.topsrcdir,
'pattern': 'build/mach_bootstrap.py'
},
{
'source': buildconfig.topsrcdir,
'pattern': 'build/virtualenv_packages.txt'
},
{
'source': buildconfig.topsrcdir,
'pattern': 'mach/**'
},
{
'source': buildconfig.topsrcdir,
'pattern': 'testing/web-platform/tests/tools/third_party/certifi/**'
},
{
'source': buildconfig.topsrcdir,
'pattern': 'testing/mozharness/**'
}
],
'condprof': [
{
'source': buildconfig.topsrcdir,
Expand Down
1 change: 1 addition & 0 deletions python/mozperftest/mozperftest/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"testing/mozbase/mozprofile",
"testing/mozbase/mozproxy",
"third_party/python/attrs/src",
"third_party/python/distro",
"third_party/python/dlmanager",
"third_party/python/esprima",
"third_party/python/importlib_metadata",
Expand Down
43 changes: 26 additions & 17 deletions python/mozperftest/mozperftest/test/browsertime/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


BROWSERTIME_SRC_ROOT = Path(__file__).parent
PILLOW_VERSION = "6.0.0"
PILLOW_VERSION = "6.2.1"
PYSSIM_VERSION = "0.4"


Expand Down Expand Up @@ -60,6 +60,7 @@ class BrowsertimeRunner(NodeRunner):
arguments = {
"cycles": {"type": int, "default": 1, "help": "Number of full cycles"},
"iterations": {"type": int, "default": 1, "help": "Number of iterations"},
"node": {"type": str, "default": None, "help": "Path to Node.js"},
"geckodriver": {"type": str, "default": None, "help": "Path to geckodriver"},
"binary": {
"type": str,
Expand Down Expand Up @@ -125,6 +126,10 @@ def browsertime_js(self):
def setup(self):
"""Install browsertime and visualmetrics.py prerequisites and the Node.js package.
"""
node = self.get_arg("node")
if node is not None:
os.environ["NODEJS"] = node

super(BrowsertimeRunner, self).setup()
install_url = self.get_arg("install-url")

Expand All @@ -138,7 +143,7 @@ def setup(self):

# installing Python deps on the fly
for dep in ("Pillow==%s" % PILLOW_VERSION, "pyssim==%s" % PYSSIM_VERSION):
install_package(self.virtualenv_manager, dep)
install_package(self.virtualenv_manager, dep, ignore_failure=True)

# check if the browsertime package has been deployed correctly
# for this we just check for the browsertime directory presence
Expand Down Expand Up @@ -236,21 +241,25 @@ def extra_default_args(self, args=[]):
extra_args.append("--skipHar")

if not matches(args, "--android"):
# If --firefox.binaryPath is not specified, default to the objdir binary
# Note: --firefox.release is not a real browsertime option, but it will
# silently ignore it instead and default to a release installation.
if (
not matches(
args,
"--firefox.binaryPath",
"--firefox.release",
"--firefox.nightly",
"--firefox.beta",
"--firefox.developer",
)
and extract_browser_name(args) != "chrome"
):
extra_args.extend(("--firefox.binaryPath", self.get_binary_path()))
binary = self.get_arg("binary")
if binary is not None:
extra_args.extend(("--firefox.binaryPath", binary))
else:
# If --firefox.binaryPath is not specified, default to the objdir binary
# Note: --firefox.release is not a real browsertime option, but it will
# silently ignore it instead and default to a release installation.
if (
not matches(
args,
"--firefox.binaryPath",
"--firefox.release",
"--firefox.nightly",
"--firefox.beta",
"--firefox.developer",
)
and extract_browser_name(args) != "chrome"
):
extra_args.extend(("--firefox.binaryPath", self.get_binary_path()))

geckodriver = self.get_arg("geckodriver")
if geckodriver is not None:
Expand Down
19 changes: 18 additions & 1 deletion python/mozperftest/mozperftest/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,27 @@ def check_if_exists(self, **kw):
def test_install_package():
vem = mock.Mock()
vem.bin_path = "someplace"
install_package(vem, "foo")
assert install_package(vem, "foo")
vem._run_pip.assert_called()


@mock.patch("pip._internal.req.constructors.install_req_from_line", new=_req)
def test_install_package_failures():
vem = mock.Mock()
vem.bin_path = "someplace"

def run_pip(*args):
raise Exception()

vem._run_pip = run_pip

with pytest.raises(Exception):
install_package(vem, "foo")

# we can also absorb the error, and just return False
assert not install_package(vem, "foo", ignore_failure=True)


@mock.patch("mozperftest.utils.requests.get", requests_content())
def test_build_test_list():
tests = [EXAMPLE_TESTS_DIR, "https://some/location/perftest_one.js"]
Expand Down
20 changes: 17 additions & 3 deletions python/mozperftest/mozperftest/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,15 @@ def error(self, msg, name="mozperftest", **kwargs):
self._logger(logging.ERROR, name, kwargs, msg)


def install_package(virtualenv_manager, package):
def install_package(virtualenv_manager, package, ignore_failure=False):
"""Installs a package using the virtualenv manager.
Makes sure the package is really installed when the user already has it
in their local installation.
Returns True on success, or re-raise the error. If ignore_failure
is set to True, ignore the error and return False
"""
from pip._internal.req.constructors import install_req_from_line

req = install_req_from_line(package)
Expand All @@ -108,9 +116,15 @@ def install_package(virtualenv_manager, package):
site_packages = os.path.abspath(req.satisfied_by.location)
if site_packages.startswith(venv_site_lib):
# already installed in this venv, we can skip
return
return True
with silence():
virtualenv_manager._run_pip(["install", package])
try:
virtualenv_manager._run_pip(["install", package])
return True
except Exception:
if not ignore_failure:
raise
return False


def build_test_list(tests, randomized=False):
Expand Down
Loading

0 comments on commit 7dfca9d

Please sign in to comment.