Bug 1499609 Convert cpstartup to a webextension r=mconley

Differential Revision: https://phabricator.services.mozilla.com/D9411

--HG--
rename : testing/talos/talos/tests/cpstartup/content/cpstartup.html => testing/talos/talos/tests/cpstartup/cpstartup.html
rename : testing/talos/talos/tests/cpstartup/bootstrap.js => testing/talos/talos/tests/cpstartup/extension/api.js
rename : testing/talos/talos/tests/cpstartup/install.rdf => testing/talos/talos/tests/cpstartup/extension/manifest.json
rename : testing/talos/talos/tests/cpstartup/content/target.html => testing/talos/talos/tests/cpstartup/target.html
extra : moz-landing-system : lando
This commit is contained in:
Andrew Swan 2018-10-23 21:39:17 +00:00
parent 002bf06b3f
commit fc154a3b91
11 changed files with 141 additions and 126 deletions

View File

@ -285,14 +285,13 @@ class cpstartup(PageloaderTest):
initialize it to the point where it can start processing incoming URLs
to load.
"""
extensions = ['${talos}/tests/cpstartup', '${talos}/pageloader']
extensions = ['${talos}/pageloader', '${talos}/tests/cpstartup/extension']
tpmanifest = '${talos}/tests/cpstartup/cpstartup.manifest'
tppagecycles = 20
gecko_profile_entries = 1000000
tploadnocache = True
unit = 'ms'
preferences = {
'addon.test.cpstartup.webserver': '${webserver}',
# By default, Talos is configured to open links from
# content in new windows. We're overriding them so that
# they open in new tabs instead.

View File

@ -1 +0,0 @@
content cpstartup content/ remoteenabled=yes contentaccessible=yes

View File

@ -1,27 +0,0 @@
<html>
<head>
<script>
function init() {
if (document.location.hash.indexOf("#auto") == 0) {
let mm = window.docShell.messageManager;
mm.addMessageListener("CPStartup:FinalResults", function onResults(msg) {
mm.removeMessageListener("CPStartup:FinalResults", onResults);
let results = msg.data;
tpRecordTime(results, 0, "content-process-startup");
});
mm.sendAsyncMessage("CPStartup:Go");
}
}
</script>
</head>
<body onload="init();">
Hello, Talos!
<a href="#" id="target" target="_blank">I'll open a new tab</a>
</body>
</html>

View File

@ -0,0 +1,43 @@
<html>
<head>
<script>
function init() {
window.addEventListener("CPStartup:FinalResults", function onResults(event) {
let results = event.detail;
tpRecordTime(results, 0, "content-process-startup");
}, {once: true});
async function tryPing() {
let pingPromise = new Promise(resolve => {
window.addEventListener("CPStartup:Pong", resolve, {once: true});
dispatchEvent(new CustomEvent("CPStartup:Ping", {bubbles: true}));
});
let timeoutPromise = new Promise((resolve, reject) => setTimeout(reject, 500));
try {
await Promise.race([pingPromise, timeoutPromise]);
} catch (e) {
return tryPing();
}
return null;
}
let target = document.location.href.replace(/cpstartup.html$/, "target.html");
tryPing().then(() => {
dispatchEvent(new CustomEvent("CPStartup:Go", {
bubbles: true,
detail: {target},
}));
});
}
</script>
</head>
<body onload="init();">
Hello, Talos!
<a href="#" id="target" target="_blank">I'll open a new tab</a>
</body>
</html>

View File

@ -1 +1 @@
% chrome://cpstartup/content/cpstartup.html#auto
% http://localhost/tests/cpstartup/cpstartup.html

View File

@ -2,61 +2,61 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
const PREALLOCATED_PREF = "dom.ipc.processPrelaunch.enabled";
const TARGET_PATH = "tests/cpstartup/content/target.html";
const WEBSERVER = Services.prefs.getCharPref("addon.test.cpstartup.webserver");
const TARGET_URI = `${WEBSERVER}/${TARGET_PATH}`;
/**
* The purpose of this test it to measure the performance of a content process startup.
* The purpose of this test it to measure the performance of a
* content process startup.
*
* In practice it measures a bit more than the content process startup. First the parent
* process starts the clock and requests a new tab with a simple page and then the child
* stops the clock in the frame script that will be able to process the URL to handle.
* So it does measure a few things pre process creation (browser element and tab creation
* on parent side) but does not measure the part where we actually parse and render the
* page on the content side, just the overhead of spawning a new content process.
* In practice it measures a bit more than the content process startup. First
* the parent process starts the clock and requests a new tab with a simple
* page and then the child stops the clock in the frame script that will be
* able to process the URL to handle. So it does measure a few things
* pre process creation (browser element and tab creation on parent side) but
* does not measure the part where we actually parse and render the page on
* the content side, just the overhead of spawning a new content process.
*/
var CPStartup = {
MESSAGES: [
"CPStartup:Go",
"Content:BrowserChildReady",
],
readyCallback: null,
XPCOMUtils.defineLazyScriptGetter(this, "TalosParentProfiler",
"resource://talos-powers/TalosParentProfiler.js");
startStamp: null,
ChromeUtils.defineModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
tab: null,
/**
* Shortcut to getting at the TalosParentProfiler.
*/
get Profiler() {
delete this.Profiler;
let context = {};
Services.scriptloader.loadSubScript("resource://talos-powers/TalosParentProfiler.js", context);
return this.Profiler = context.TalosParentProfiler;
},
const PREALLOCATED_PREF = "dom.ipc.processPrelaunch.enabled";
const MESSAGES = [
"CPStartup:Go",
"Content:BrowserChildReady",
];
init() {
for (let msgName of this.MESSAGES) {
/* global ExtensionAPI */
this.cpstartup = class extends ExtensionAPI {
onStartup() {
for (let msgName of MESSAGES) {
Services.mm.addMessageListener(msgName, this);
}
this.framescriptURL = this.extension.baseURI.resolve("/framescript.js");
Services.mm.loadFrameScript(this.framescriptURL, true);
this.originalPreallocatedEnabled = Services.prefs.getBoolPref(PREALLOCATED_PREF);
Services.prefs.setBoolPref(PREALLOCATED_PREF, false);
},
uninit() {
for (let msgName of this.MESSAGES) {
this.readyCallback = null;
this.startStamp = null;
this.tab = null;
}
onShutdown() {
Services.prefs.setBoolPref(PREALLOCATED_PREF, this.originalPreallocatedEnabled);
Services.mm.removeDelayedFrameScript(this.framescriptURL);
for (let msgName of MESSAGES) {
Services.mm.removeMessageListener(msgName, this);
}
Services.prefs.setBoolPref(PREALLOCATED_PREF, this.originalPreallocatedEnabled);
},
}
receiveMessage(msg) {
let browser = msg.target;
@ -64,7 +64,7 @@ var CPStartup = {
switch (msg.name) {
case "CPStartup:Go": {
this.openTab(gBrowser).then(results =>
this.openTab(gBrowser, msg.data.target).then(results =>
this.reportResults(results));
break;
}
@ -86,31 +86,25 @@ var CPStartup = {
break;
}
}
},
}
openTab(gBrowser) {
return new Promise((resolve) => {
// Start the timer and the profiler right before the tab open on the parent side.
this.Profiler.resume("tab opening starts");
this.startStamp = Services.telemetry.msSystemNow();
this.tab = gBrowser.selectedTab = gBrowser.addTab(TARGET_URI, {
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
async openTab(gBrowser, url) {
// Start the timer and the profiler right before the tab open on the parent side.
TalosParentProfiler.resume("tab opening starts");
this.startStamp = Services.telemetry.msSystemNow();
this.tab = gBrowser.selectedTab = gBrowser.addTrustedTab(url);
this.whenTabReady().then(({tab, delta}) => {
this.Profiler.pause("tab opening end");
this.removeTab(tab).then(() => {
resolve(delta);
});
});
});
},
let {tab, delta} = await this.whenTabReady();
TalosParentProfiler.pause("tab opening end");
await this.removeTab(tab);
return delta;
}
whenTabReady() {
return new Promise((resolve) => {
this.readyCallback = resolve;
});
},
}
removeTab(tab) {
return new Promise((resolve) => {
@ -124,21 +118,9 @@ var CPStartup = {
tab.ownerGlobal.gBrowser.removeTab(tab);
});
},
}
reportResults(results) {
Services.mm.broadcastAsyncMessage("CPStartup:FinalResults", results);
},
}
};
function install(aData, aReason) {}
function startup(aData, aReason) {
CPStartup.init();
}
function shutdown(aData, aReason) {
CPStartup.uninit();
}
function uninstall(aData, aReason) {}

View File

@ -0,0 +1,19 @@
(function() {
addEventListener("CPStartup:Ping", e => {
let evt = new content.CustomEvent("CPStartup:Pong", {bubbles: true});
content.dispatchEvent(evt);
}, false, true);
addEventListener("CPStartup:Go", e => {
sendAsyncMessage("CPStartup:Go", e.detail);
}, false, true);
addMessageListener("CPStartup:FinalResults", msg => {
let evt = Cu.cloneInto({
bubbles: true,
detail: msg.data,
}, content);
content.dispatchEvent(new content.CustomEvent("CPStartup:FinalResults", evt));
});
})();

View File

@ -0,0 +1,23 @@
{
"manifest_version": 2,
"name": "cpstartup test",
"description": "Measures the performance of starting and initializing new content processes",
"version": "1.1",
"applications": {
"gecko": {
"id": "cpstartup-test@mozilla.org"
}
},
"experiment_apis": {
"cpstartup": {
"schema": "schema.json",
"parent": {
"scopes": ["addon_parent"],
"script": "api.js",
"events": ["startup"]
}
}
}
}

View File

@ -0,0 +1 @@
[]

View File

@ -1,24 +0,0 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>cpstartup-test@mozilla.org</em:id>
<em:type>2</em:type>
<em:name>cpstartup test</em:name>
<em:version>1.0.0</em:version>
<em:bootstrap>true</em:bootstrap>
<em:description>Measures the performance of starting and initializing new content processes</em:description>
<em:creator>Gabor Krizsanits</em:creator>
<em:multiprocessCompatible>true</em:multiprocessCompatible>
<!-- Desktop -->
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>55.0</em:minVersion>
<em:maxVersion>*</em:maxVersion>
</Description>
</em:targetApplication>
<em:description>https://wiki.mozilla.org/Buildbot/Talos/Tests</em:description>
<em:homepageURL>https://wiki.mozilla.org/Buildbot/Talos/Tests</em:homepageURL>
</Description>
</RDF>