Bug 1253382 - Add a new tabpaint talos test. r=jmaher

tabpaint measures how long it takes to open a new tab and show its content.

MozReview-Commit-ID: IIVprFdvH1Z

--HG--
extra : rebase_source : dbe899be09b01df5219e7d29b291a6c1455cfe3b
This commit is contained in:
Mike Conley 2016-03-01 17:29:09 -05:00
Родитель 0ab3965084
Коммит e8ffd9aa80
9 изменённых файлов: 355 добавлений и 6 удалений

Просмотреть файл

@ -22,24 +22,24 @@
"talos_options": ["--e10s"]
},
"other": {
"tests": ["a11yr", "ts_paint", "tpaint", "sessionrestore", "sessionrestore_no_auto_restore"]
"tests": ["a11yr", "ts_paint", "tpaint", "sessionrestore", "sessionrestore_no_auto_restore", "tabpaint"]
},
"other-e10s": {
"tests": ["a11yr", "ts_paint", "tpaint", "sessionrestore", "sessionrestore_no_auto_restore"],
"tests": ["a11yr", "ts_paint", "tpaint", "sessionrestore", "sessionrestore_no_auto_restore", "tabpaint"],
"talos_options": ["--e10s"]
},
"other_nol64": {
"tests": ["a11yr", "ts_paint", "tpaint", "sessionrestore", "sessionrestore_no_auto_restore"]
"tests": ["a11yr", "ts_paint", "tpaint", "sessionrestore", "sessionrestore_no_auto_restore", "tabpaint"]
},
"other-e10s_nol64": {
"tests": ["a11yr", "ts_paint", "tpaint", "sessionrestore", "sessionrestore_no_auto_restore"],
"tests": ["a11yr", "ts_paint", "tpaint", "sessionrestore", "sessionrestore_no_auto_restore", "tabpaint"],
"talos_options": ["--e10s"]
},
"other_l64": {
"tests": ["a11yr", "ts_paint", "tpaint", "sessionrestore", "sessionrestore_no_auto_restore"]
"tests": ["a11yr", "ts_paint", "tpaint", "sessionrestore", "sessionrestore_no_auto_restore", "tabpaint"]
},
"other-e10s_l64": {
"tests": ["a11yr", "ts_paint", "tpaint", "sessionrestore", "sessionrestore_no_auto_restore"],
"tests": ["a11yr", "ts_paint", "tpaint", "sessionrestore", "sessionrestore_no_auto_restore", "tabpaint"],
"talos_options": ["--e10s"]
},
"g1": {

Просмотреть файл

@ -238,6 +238,29 @@ class PageloaderTest(Test):
'test_name_extension', 'lower_is_better', 'unit']
@register_test()
class tabpaint(PageloaderTest):
"""
Tests the amount of time it takes to open new tabs, triggered from
both the parent process and the content process.
"""
extensions = '${talos}/tests/tabpaint/tabpaint-signed.xpi'
tpmanifest = '${talos}/tests/tabpaint/tabpaint.manifest'
tppagecycles = 20
sps_profile_entries = 1000000
tploadnocache = True
unit = 'ms'
preferences = {
# 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.
# See http://kb.mozillazine.org/Browser.link.open_newwindow
# and http://kb.mozillazine.org/Browser.link.open_newwindow.restriction
'browser.link.open_newwindow': 3,
'browser.link.open_newwindow.restriction': 2,
}
@register_test()
class tps(PageloaderTest):
"""

259
testing/talos/talos/tests/tabpaint/bootstrap.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,259 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
/**
* This test will measure the performance of opening a tab and displaying
* the simplest content (a blank page). This test is concerned primarily
* with the time it takes to show the content area to the user, rather than
* the performance of the tab opening or closing animations (which are
* measured in the TART test). This is why this test disables tab animations.
*
* When opening tabs and showing content, there are two cases to consider:
*
* 1) The tab has been opened via a command from the parent process. For example,
* the user has clicked on a link in a separate application which is opening
* in this browser, so the message to open the tab and display the content
* comes from the operating system, to the parent.
*
* 2) The tab has been opened by clicking on a link in content. It is possible
* for certain types of links (_blank links for example) to open new tabs.
*/
var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource:///modules/RecentWindow.jsm");
const TAB_ANIMATION_PREF = "browser.tabs.animate";
const TARGET_URI = "chrome://tabpaint/content/target.html";
var TabPaint = {
MESSAGES: [
"TabPaint:Go",
"TabPaint:Painted",
],
/**
* We'll hold the original tab animation preference here so
* we can restore it once the test is done.
*/
originalTabsAnimate: null,
/**
* We'll store a callback here to be fired once the TARGET_URI
* reports that it has painted.
*/
paintCallback: null,
/**
* Shortcut to getting at the TalosParentProfiler.
*/
get Profiler() {
delete this.Profiler;
let context = {};
Services.scriptloader.loadSubScript("chrome://talos-powers-content/content/TalosParentProfiler.js", context);
return this.Profiler = context.TalosParentProfiler;
},
init() {
// We don't have a window in this scope, and in fact, there might
// not be any browser windows around. Since pageloader is loading
// this add-on, along with the tabpaint.html content, what we'll do
// is wait for the tabpaint.html content to send us a message to
// get us moving.
for (let msgName of this.MESSAGES) {
Services.mm.addMessageListener(msgName, this);
}
this.originalTabsAnimate = Services.prefs.getBoolPref(TAB_ANIMATION_PREF);
Services.prefs.setBoolPref(TAB_ANIMATION_PREF, false);
},
uninit() {
for (let msgName of this.MESSAGES) {
Services.mm.removeMessageListener(msgName, this);
}
Services.prefs.setBoolPref(TAB_ANIMATION_PREF, this.originalTabsAnimate);
},
receiveMessage(msg) {
let browser = msg.target;
let gBrowser = browser.ownerGlobal.gBrowser;
switch(msg.name) {
case "TabPaint:Go": {
// Our document has loaded, and we're off to the races!
this.go(gBrowser).then((results) => {
this.reportResults(results);
});
break;
}
case "TabPaint:Painted": {
// Content has reported that it has painted.
if (!this.paintCallback) {
throw new Error("TabPaint:Painted fired without a paintCallback set");
}
let tab = gBrowser.getTabForBrowser(browser);
let delta = msg.data.delta;
this.paintCallback({tab, delta});
break;
}
}
},
/**
* Start a single run of the test. This will measure the time
* to open a new tab from the parent, and then measure the time
* to open a new tab from content.
*
* @param gBrowser (<xul:tabbrowser>)
* The tabbrowser of the window to use.
*
* @return Promise
* Resolves with an object with two properties:
*
* fromParent (int):
* The time (ms) it took to present a tab that
* was opened from the parent.
*
* fromContent (int):
* The time (ms) it took to present a tab that
* was opened from content.
*/
go: Task.async(function*(gBrowser) {
let fromParent = yield this.openTabFromParent(gBrowser);
let fromContent = yield this.openTabFromContent(gBrowser);
return { fromParent, fromContent };
}),
/**
* Opens a tab from the parent, waits until it is displayed, then
* removes the tab.
*
* @param gBrowser (<xul:tabbrowser>)
* The tabbrowser of the window to use.
*
* @return Promise
* Resolves once the tab has been fully removed. Resolves
* with the time (in ms) it took to open the tab from the parent.
*/
openTabFromParent(gBrowser) {
let win = gBrowser.ownerGlobal;
return new Promise((resolve) => {
this.Profiler.resume("tabpaint parent start");
gBrowser.selectedTab = gBrowser.addTab(TARGET_URI + "?" + Date.now());
this.whenTabShown().then(({tab, delta}) => {
this.Profiler.pause("tabpaint parent end");
this.removeTab(tab).then(() => {
resolve(delta);
});
});
});
},
/**
* Opens a tab from content, waits until it is displayed, then
* removes the tab.
*
* @param gBrowser (<xul:tabbrowser>)
* The tabbrowser of the window to use.
*
* @return Promise
* Resolves once the tab has been fully removed. Resolves
* with the time (in ms) it took to open the tab from content.
*/
openTabFromContent(gBrowser) {
let win = gBrowser.ownerGlobal;
return new Promise((resolve) => {
this.Profiler.resume("tabpaint content start");
Services.mm.broadcastAsyncMessage("TabPaint:OpenFromContent");
this.whenTabShown().then(({tab, delta}) => {
this.Profiler.pause("tabpaint content end");
this.removeTab(tab).then(() => {
resolve(delta);
});
});
});
},
/**
* Returns a Promise that will resolve once the next tab reports
* it has shown.
*
* @return Promise
*/
whenTabShown() {
return new Promise((resolve) => {
this.paintCallback = resolve;
});
},
/**
* Returns a Promise that removes a tab, and resolves once the final
* message from that tab has come up.
*
* @param tab (<xul:tab>)
* The tab to remove.
*
* @return Promise
*/
removeTab(tab) {
return new Promise((resolve) => {
let {messageManager: mm, frameLoader} = tab.linkedBrowser;
mm.addMessageListener("SessionStore:update", function onMessage(msg) {
if (msg.targetFrameLoader == frameLoader && msg.data.isFinal) {
mm.removeMessageListener("SessionStore:update", onMessage);
resolve();
}
}, true);
tab.ownerDocument.defaultView.gBrowser.removeTab(tab);
});
},
/**
* Sends the results down to the tabpaint-test.html page, which will
* pipe them out to the console.
*
* @param results (Object)
* An object with the following properties:
*
* fromParent (int):
* The time (ms) it took to present a tab that
* was opened from the parent.
*
* fromContent (int):
* The time (ms) it took to present a tab that
* was opened from content.
*/
reportResults(results) {
Services.mm.broadcastAsyncMessage("TabPaint:FinalResults", results);
},
};
// Bootstrap functions below
function install(aData, aReason) {}
function startup(aData, aReason) {
TabPaint.init();
}
function shutdown(aData, aReason) {
TabPaint.uninit();
}
function uninstall(aData, aReason) {}

Просмотреть файл

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

Просмотреть файл

@ -0,0 +1,40 @@
<html>
<head>
<script>
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
function init() {
if (document.location.hash.indexOf("#auto") == 0) {
let mm = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
mm.addMessageListener("TabPaint:FinalResults", function onResults(msg) {
mm.removeMessageListener("TabPaint:FinalResults", onResults);
let { fromParent, fromContent } = msg.data;
tpRecordTime([fromParent, fromContent].join(','), 0, "tabpaint-from-parent, tabpaint-from-content");
});
mm.addMessageListener("TabPaint:OpenFromContent", function openFromContent() {
let target = document.getElementById("target");
let now = Date.now();
let href = "target.html?" + now;
target.href = href;
target.click();
});
mm.sendAsyncMessage("TabPaint:Go");
}
}
</script>
</head>
<body onload="init();">
Hello, Talos!
<a href="#" id="target" target="_blank">I'll open a new tab</a>
</body>
</html>

Просмотреть файл

@ -0,0 +1,24 @@
<?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>tabpaint-test@mozilla.org</em:id>
<em:type>2</em:type>
<em:name>tabpaint test</em:name>
<em:version>1.0.0</em:version>
<em:bootstrap>true</em:bootstrap>
<em:description>Measures the performance of opening tabs</em:description>
<em:creator>Mike Conley</em:creator>
<em:multiprocessCompatible>true</em:multiprocessCompatible>
<!-- Desktop -->
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>38.0</em:minVersion>
<em:maxVersion>*</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
<em:description>https://wiki.mozilla.org/Buildbot/Talos/Tests</em:description>
<em:homepageURL>https://wiki.mozilla.org/Buildbot/Talos/Tests</em:homepageURL>
</RDF>

Двоичные данные
testing/talos/talos/tests/tabpaint/tabpaint-signed.xpi Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1 @@
% chrome://tabpaint/content/tabpaint.html#auto

Просмотреть файл

@ -0,0 +1 @@
% chrome://tabpaint/content/tabpaint.html#auto