diff options
-rw-r--r-- | DEPS | 3 | ||||
-rw-r--r-- | tools/page_cycler/common/head.js | 136 | ||||
-rw-r--r-- | tools/page_cycler/common/report.html | 173 | ||||
-rw-r--r-- | tools/page_cycler/common/start.js | 90 |
4 files changed, 402 insertions, 0 deletions
@@ -51,6 +51,9 @@ deps = { "src/third_party/tcmalloc/tcmalloc": "http://google-perftools.googlecode.com/svn/trunk@74", + + "src/tools/page_cycler/acid3": + "/trunk/deps/page_cycler/acid3@19546", # TODO(jianli): Remove this once we do not need to run worker's layout tests # in ui test. diff --git a/tools/page_cycler/common/head.js b/tools/page_cycler/common/head.js new file mode 100644 index 0000000..1a4ddc84 --- /dev/null +++ b/tools/page_cycler/common/head.js @@ -0,0 +1,136 @@ +// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +var __c = ""; // that's good enough for me. +var __td; +var __tf; +var __tl; +var __iterations; +var __cycle; +var __results = false; +var __page; +var __TIMEOUT = 15; +function __get_cookie(name) { + var cookies = document.cookie.split("; "); + for (var i = 0; i < cookies.length; ++i) { + var t = cookies[i].split("="); + if (t[0] == name && t[1]) + return t[1]; + } + return ""; +} +function __pages() { // fetch lazily + if (!("data" in this)) + this.data = __get_cookie("__pc_pages").split(","); + return this.data; +} +function __get_timings() { + return __get_cookie("__pc_timings"); +} +function __set_timings(timings) { + document.cookie = "__pc_timings=" + timings + "; path=/"; +} +function __ontimeout() { + var doc; + + // Call GC twice to cleanup JS heap before starting a new test. + if (window.gc) { + window.gc(); + window.gc(); + } + + var ts = (new Date()).getTime(); + var tlag = (ts - __te) - __TIMEOUT; + if (tlag > 0) + __tf = __tf + tlag; + if (__cycle == (__pages().length * __iterations)) { + document.cookie = "__pc_done=1; path=/"; + doc = "../../common/report.html"; + } else { + doc = "../" + __pages()[__page] + "/index.html" + } + + var timings = __tl; + var oldTimings = __get_timings(); + if (oldTimings != "") { + timings = oldTimings + "," + timings; + } + __set_timings(timings); + + var url = doc + "?n=" + __iterations + "&i=" + __cycle + "&p=" + __page + "&ts=" + ts + "&td=" + __td + "&tf=" + __tf; + document.location.href = url; +} +function __onload() { + if (__results) + return; + var unused = document.body.offsetHeight; // force layout + + var ts = 0, td = 0, te = (new Date()).getTime(), tf = 0; + + var s = document.location.search; + if (s) { + var params = s.substring(1).split('&'); + for (var i = 0; i < params.length; ++i) { + var f = params[i].split('='); + switch (f[0]) { + case 'skip': + // No calculation, just viewing + return; + case 'n': + __iterations = f[1]; + break; + case 'i': + __cycle = (f[1] - 0) + 1; + break; + case 'p': + __page = ((f[1] - 0) + 1) % __pages().length; + break; + case 'ts': + ts = (f[1] - 0); + break; + case 'td': + td = (f[1] - 0); + break; + case 'tf': + tf = (f[1] - 0); + break; + } + } + } + __tl = (te - ts); + __td = td + __tl; + __te = te; + __tf = tf; // record t-fudge + + setTimeout("__ontimeout()", __TIMEOUT); +} + +if (window.attachEvent) + window.attachEvent("onload", __onload); +else + addEventListener("load", __onload, false); diff --git a/tools/page_cycler/common/report.html b/tools/page_cycler/common/report.html new file mode 100644 index 0000000..221d8ab --- /dev/null +++ b/tools/page_cycler/common/report.html @@ -0,0 +1,173 @@ +<html> +<head> +<style> +.discarded { + color: #C0C0C0; +} +</style> +<h2>Summary</h2> +<dl> +<script src="head.js"></script> +<script> +var __results = true; +var cycles = 0; +var s = document.location.search.substring(1); +var params = s.split('&'); +var iterations, pages, totalTime, fudgeTime; +for (var i = 0; i < params.length; ++i) { + var f = params[i].split('='); + switch (f[0]) { + case 'n': + iterations = (f[1] - 0); + break; + case 'i': + cycle = (f[1] - 0); + break; + case 'td': + totalTime = (f[1] - 0); + break; + case 'tf': + fudgeTime = (f[1] - 0); + break; + } +} +var pages = cycle / iterations; +document.write("<table border=1>"); +document.write("<tr><td>iterations</td><td>" + iterations + "</td></tr>"); +document.write("<tr><td>pages</td><td>" + pages + "</td></tr>"); +document.write("<tr><td>milliseconds</td><td>" + totalTime + "</td></tr>"); +document.write("<tr><td>mean per set</td><td>" + (totalTime / iterations).toFixed(2) + "</td></tr>"); +document.write("<tr><td>mean per page</td><td>" + (totalTime / iterations / pages).toFixed(2) + "</td></tr>"); +document.write("<tr><td>timer lag</td><td>" + (fudgeTime).toFixed(2) + "</td></tr>"); +document.write("<tr><td>timer lag per page</td><td>" + (fudgeTime / iterations / pages).toFixed(2) + "</td></tr>"); +document.write("</table>"); + + // returns an object with the following properties: + // min : min value of array elements + // max : max value of array elements + // mean : mean value of array elements + // vari : variance computation + // stdd : standard deviation, sqrt(vari) + // indexOfMax : index of max element (the element that is + // removed from the mean computation) + function getArrayStats(ary) { + var r = {}; + r.min = ary[0]; + r.max = ary[0]; + r.indexOfMax = 0; + var sum = 0; + for (var i = 0; i < ary.length; ++i) { + if (ary[i] < r.min) { + r.min = ary[i]; + } else if (ary[i] > r.max) { + r.max = ary[i]; + r.indexOfMax = i; + } + sum = sum + ary[i]; + } + + // ignore max value when computing mean and stddev + r.mean = (sum - r.max) / (ary.length - 1); + + r.vari = 0; + for (var i = 0; i < ary.length; ++i) { + if (i == r.indexOfMax) + continue; + var d = r.mean - ary[i]; + r.vari = r.vari + d * d; + } + + r.vari = r.vari / (ary.length - 1); + r.stdd = Math.sqrt(r.vari); + return r; + } + + function appendTableCol(tr, text, linkify) { + var doc = tr.ownerDocument; + var td = doc.createElement("TD"); + + if (linkify) { + var anchor = doc.createElement("A"); + anchor.href = text + "/index.html?skip=true"; + anchor.appendChild(doc.createTextNode(text)); + td.appendChild(anchor); + } + else + td.appendChild(doc.createTextNode(text)); + tr.appendChild(td); + return td; + } + + function getTimeVals() { + var rawData = __get_timings().split(","); + var timeVals = []; + for (var i = 0; i < iterations; ++i) { + for (var j = 0; j < pages; ++j) { + if (!timeVals[j]) + timeVals[j] = []; + timeVals[j].push(parseInt(rawData[j + i*pages])); + } + } + return timeVals; + } + + function showReport() { + var tbody = document.getElementById("tbody"); + var colsums = [0,0,0,0]; + var timeVals = getTimeVals(); + for (var i = 0; i < timeVals.length; ++i) { + var tr = document.createElement("TR"); + + appendTableCol(tr, __pages()[i], true); + + var r = getArrayStats(timeVals[i]); + appendTableCol(tr, r.min.toFixed(2)); + appendTableCol(tr, r.max.toFixed(2)); + appendTableCol(tr, r.mean.toFixed(2)); + appendTableCol(tr, r.stdd.toFixed(2)); + //appendTableCol(tr, r.chi2.toFixed(2)); + + for (var j = 0; j < timeVals[i].length; ++j) { + var tv = timeVals[i][j]; + var td = appendTableCol(tr, tv); + if (j == r.indexOfMax) + td.setAttribute("class", "discarded"); + } + + colsums[0] = colsums[0] + r.min; + colsums[1] = colsums[1] + r.max; + colsums[2] = colsums[2] + r.mean; + colsums[3] = colsums[3] + r.stdd; + + tbody.appendChild(tr); + } + + var tr = document.createElement("TR"); + appendTableCol(tr, "totals:"); + for (var k = 0; k < colsums.length; ++k) + appendTableCol(tr, colsums[k].toFixed(2)); + tbody.appendChild(tr); + } + window.onload = showReport; + +</script> +</dl> +</head> +<body> +<h2>Complete Statistics</h2> +<table border="1"> +<thead> +<tr> + <th>Site</th> + <th>Min</th> + <th>Max</th> + <th>Mean</th> + <th>Std.d</th> + <th colspan="10">Runs</th> +</tr> +</thead> +<tbody id="tbody"></tbody> +</table> +</body> +</html> + diff --git a/tools/page_cycler/common/start.js b/tools/page_cycler/common/start.js new file mode 100644 index 0000000..a5c6a0b --- /dev/null +++ b/tools/page_cycler/common/start.js @@ -0,0 +1,90 @@ +// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This script runs the page cycler. It assumes that __pages is an array +// containing the directories for various pages to exercise. + +document.title = "page cycler"; + +var initialPage = __pages[0]; + +document.cookie = "__pc_done=0; path=/"; +document.cookie = "__pc_pages=" + __pages + "; path=/"; +document.cookie = "__pc_timings=; path=/"; + +var options = location.search.substring(1).split('&'); + +function getopt(name) { + var r = new RegExp("^" + name + "="); + for (i = 0; i < options.length; ++i) { + if (options[i].match(r)) { + return options[i].substring(name.length + 1); + } + } + return null; +} + +function start() { + var iterations = document.getElementById("iterations").value; + window.resizeTo(800, 800); + var ts = (new Date()).getTime(); + var url = initialPage + "/index.html?n=" + iterations + "&i=0&p=0&ts=" + ts + "&td=0"; + window.location = url; +} + +function render_form() { + var form = document.createElement("FORM"); + form.setAttribute("action", "javascript:start()"); + + var label = document.createTextNode("Iterations: "); + form.appendChild(label); + + var input = document.createElement("INPUT"); + input.setAttribute("id", "iterations"); + var iterations = getopt("iterations"); + input.setAttribute("value", iterations ? iterations : "5"); + form.appendChild(input); + + input = document.createElement("INPUT"); + input.setAttribute("type", "submit"); + input.setAttribute("value", "Start"); + form.appendChild(input); + + document.body.appendChild(form); +} + +render_form(); + +// should we start automatically? +if (location.search.match("auto=1")) { + start(); +} else { + document.write("<h3>Note: You must have started chrome with <tt>--enable-file-cookies --js-flags=\"--expose_gc\"</tt> for this test to work manually.</h3>"); + if (!window.gc) + document.write("<h3 style='color:red'>WARNING: window.gc is not defined. Test results may be unreliable!</h3>"); +} |