browser/metro/base/tests/mochiperf/head.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 http://creativecommons.org/publicdomain/zero/1.0/ */
michael@0 3
michael@0 4 "use strict";
michael@0 5
michael@0 6 // Load common code from ../mochitest/head.js
michael@0 7 let mochitestDir = getRootDirectory(gTestPath).replace('/mochiperf', '/mochitest');
michael@0 8 Services.scriptloader.loadSubScript(mochitestDir + "head.js", this);
michael@0 9
michael@0 10 // Misc. constants
michael@0 11 const kInfoHeader = "PERF-TEST | ";
michael@0 12 const kDeclareId = "DECLARE ";
michael@0 13 const kResultsId = "RESULTS ";
michael@0 14
michael@0 15 // Mochitest log data format version
michael@0 16 const kDataSetVersion = "1";
michael@0 17
michael@0 18 /*
michael@0 19 * PerfTest - helper library for simple mochitest based performance tests.
michael@0 20 */
michael@0 21
michael@0 22 var PerfTest = {
michael@0 23 _userStartTime: 0,
michael@0 24 _userStopTime: 0,
michael@0 25
michael@0 26 /******************************************************
michael@0 27 * Declare and results
michael@0 28 */
michael@0 29
michael@0 30 /*
michael@0 31 * declareTest
michael@0 32 *
michael@0 33 * Declare a test which the graph server will pick up and track.
michael@0 34 * Must be called by every test on startup. Graph server will
michael@0 35 * search for result data between this declaration and the next.
michael@0 36 *
michael@0 37 * @param aUUID string for this particular test, case sensitive.
michael@0 38 * @param aName The name of the test.
michael@0 39 * @param aCategory Top level test calegory. For example 'General',
michael@0 40 * 'Graphics', 'Startup', 'Jim's Tests'.
michael@0 41 * @param aSubCategory (optional) sub category name with aCategory.
michael@0 42 * @param aDescription A detailed description (sentence or two) of
michael@0 43 * what the test does.
michael@0 44 */
michael@0 45 declareTest: function declareTest(aUUID, aName, aCategory, aSubCategory, aDescription) {
michael@0 46 this._uid = aUUID;
michael@0 47 this._print(kDeclareId, this._toJsonStr({
michael@0 48 id: aUUID,
michael@0 49 version: kDataSetVersion,
michael@0 50 name: aName,
michael@0 51 category: aCategory,
michael@0 52 subcategory: aSubCategory,
michael@0 53 description: aDescription,
michael@0 54 buildid: Services.appinfo.appBuildID,
michael@0 55 }));
michael@0 56 },
michael@0 57
michael@0 58 /*
michael@0 59 * declareNumericalResult
michael@0 60 *
michael@0 61 * Declare a simple numerical result.
michael@0 62 *
michael@0 63 * @param aValue numerical value to record
michael@0 64 * @param aDescription string describing the value to display on the y axis.
michael@0 65 */
michael@0 66 declareNumericalResult: function declareNumericalResult(aValue, aDescription) {
michael@0 67 this._print(kResultsId, this._toJsonStr({
michael@0 68 id: this._uid,
michael@0 69 version: kDataSetVersion,
michael@0 70 results: {
michael@0 71 r0: {
michael@0 72 value: aValue,
michael@0 73 desc: aDescription
michael@0 74 }
michael@0 75 },
michael@0 76 }));
michael@0 77 },
michael@0 78
michael@0 79 /*
michael@0 80 * declareFrameRateResult
michael@0 81 *
michael@0 82 * Declare a frame rate for a result.
michael@0 83 *
michael@0 84 * @param aFrameCount numerical frame count
michael@0 85 * @param aRunMs run time in miliseconds
michael@0 86 * @param aDescription string describing the value to display on the y axis.
michael@0 87 */
michael@0 88 declareFrameRateResult: function declareFrameRateResult(aFrameCount, aRunMs, aDescription) {
michael@0 89 this._print(kResultsId, this._toJsonStr({
michael@0 90 id: this._uid,
michael@0 91 version: kDataSetVersion,
michael@0 92 results: {
michael@0 93 r0: {
michael@0 94 value: (aFrameCount / (aRunMs / 1000.0)),
michael@0 95 desc: aDescription
michael@0 96 }
michael@0 97 },
michael@0 98 }));
michael@0 99 },
michael@0 100
michael@0 101 /*
michael@0 102 * declareNumericalResults
michael@0 103 *
michael@0 104 * Declare a set of numerical results.
michael@0 105 *
michael@0 106 * @param aArray an array of datapoint objects of the form:
michael@0 107 *
michael@0 108 * [ { value: (value), desc: "description/units" }, .. ]
michael@0 109 *
michael@0 110 * optional values:
michael@0 111 * shareAxis - the 0 based index of a previous data point this point
michael@0 112 * should share a y axis with.
michael@0 113 */
michael@0 114 declareNumericalResults: function declareNumericalResults(aArray) {
michael@0 115 let collection = new Object();
michael@0 116 for (let idx = 0; idx < aArray.length; idx++) {
michael@0 117 collection['r' + idx] = { value: aArray[idx].value, desc: aArray[idx].desc };
michael@0 118 if (aArray[idx].shareAxis != undefined) {
michael@0 119 collection['r' + idx].shareAxis = aArray[idx].shareAxis;
michael@0 120 }
michael@0 121 }
michael@0 122 let dataset = {
michael@0 123 id: this._uid,
michael@0 124 version: kDataSetVersion,
michael@0 125 results: collection
michael@0 126 };
michael@0 127 this._print(kResultsId, this._toJsonStr(dataset));
michael@0 128 },
michael@0 129
michael@0 130 /******************************************************
michael@0 131 * Perf tests
michael@0 132 */
michael@0 133
michael@0 134 perfBoundsCheck: function perfBoundsCheck(aLow, aHigh, aValue, aTestMessage) {
michael@0 135 ok(aValue < aLow || aValue > aHigh, aTestMessage);
michael@0 136 },
michael@0 137
michael@0 138 /******************************************************
michael@0 139 * Math utilities
michael@0 140 */
michael@0 141
michael@0 142 computeMedian: function computeMedian(aArray, aOptions) {
michael@0 143 aArray.sort(function (a, b) {
michael@0 144 return a - b;
michael@0 145 });
michael@0 146
michael@0 147 var idx = Math.floor(aArray.length / 2);
michael@0 148
michael@0 149 if(aArray.length % 2) {
michael@0 150 return aArray[idx];
michael@0 151 } else {
michael@0 152 return (aArray[idx-1] + aArray[idx]) / 2;
michael@0 153 }
michael@0 154 },
michael@0 155
michael@0 156 computeAverage: function computeAverage(aArray, aOptions) {
michael@0 157 let idx;
michael@0 158 let count = 0, total = 0;
michael@0 159 let highIdx = -1, lowIdx = -1;
michael@0 160 let high = 0, low = 0;
michael@0 161 if (aOptions.stripOutliers) {
michael@0 162 for (idx = 0; idx < aArray.length; idx++) {
michael@0 163 if (high < aArray[idx]) {
michael@0 164 highIdx = idx;
michael@0 165 high = aArray[idx];
michael@0 166 }
michael@0 167 if (low > aArray[idx]) {
michael@0 168 lowIdx = idx;
michael@0 169 low = aArray[idx];
michael@0 170 }
michael@0 171 }
michael@0 172 }
michael@0 173 for (idx = 0; idx < aArray.length; idx++) {
michael@0 174 if (idx != high && idx != low) {
michael@0 175 total += aArray[idx];
michael@0 176 count++;
michael@0 177 }
michael@0 178 }
michael@0 179 return total / count;
michael@0 180 },
michael@0 181
michael@0 182 computeHighLowBands: function computeHighLow(aArray, aPercentage) {
michael@0 183 let bandCount = Math.ceil(aArray.length * aPercentage);
michael@0 184 let lowGroup = 0, highGroup = 0;
michael@0 185 let idx;
michael@0 186
michael@0 187 function compareNumbers(a, b) {
michael@0 188 return a - b;
michael@0 189 }
michael@0 190 aArray.sort(compareNumbers);
michael@0 191 for (idx = 0; idx < bandCount; idx++) {
michael@0 192 lowGroup += aArray[idx];
michael@0 193 }
michael@0 194 let top = aArray.length - 1;
michael@0 195 for (idx = top; idx > (top - bandCount); idx--) {
michael@0 196 highGroup += aArray[idx];
michael@0 197 }
michael@0 198 return {
michael@0 199 low: lowGroup / bandCount,
michael@0 200 high: highGroup / bandCount,
michael@0 201 ave: this.computeAverage(aArray, {})
michael@0 202 };
michael@0 203 },
michael@0 204
michael@0 205 /******************************************************
michael@0 206 * Internal
michael@0 207 */
michael@0 208
michael@0 209 _print: function _print() {
michael@0 210 let str = kInfoHeader;
michael@0 211 for (let idx = 0; idx < arguments.length; idx++) {
michael@0 212 str += arguments[idx];
michael@0 213 }
michael@0 214 info(str);
michael@0 215 },
michael@0 216
michael@0 217 _toJsonStr: function _toJsonStr(aTable) {
michael@0 218 return window.JSON.stringify(aTable);
michael@0 219 },
michael@0 220 };
michael@0 221
michael@0 222 /*
michael@0 223 * StopWatch - timing helper
michael@0 224 */
michael@0 225
michael@0 226 function StopWatch(aStart) {
michael@0 227 if (aStart) {
michael@0 228 this.start();
michael@0 229 }
michael@0 230 }
michael@0 231
michael@0 232 StopWatch.prototype = {
michael@0 233 /*
michael@0 234 * Start timing. Resets existing clock.
michael@0 235 */
michael@0 236 start: function start() {
michael@0 237 this.reset();
michael@0 238 this._userStartTime = window.performance.now();
michael@0 239 },
michael@0 240
michael@0 241 /*
michael@0 242 * Stop timing.
michael@0 243 */
michael@0 244 stop: function stop() {
michael@0 245 this._userStopTime = window.performance.now();
michael@0 246 return this.time();
michael@0 247 },
michael@0 248
michael@0 249 /*
michael@0 250 * Resets both start and end time.
michael@0 251 */
michael@0 252 reset: function reset() {
michael@0 253 this._userStartTime = this._userStopTime = 0;
michael@0 254 },
michael@0 255
michael@0 256 /*
michael@0 257 * Returns the total time ellapsed in milliseconds. Returns zero if
michael@0 258 * no time has been accumulated.
michael@0 259 */
michael@0 260 time: function time() {
michael@0 261 if (!this._userStartTime) {
michael@0 262 return 0;
michael@0 263 }
michael@0 264 if (!this._userStopTime) {
michael@0 265 return (window.performance.now() - this._userStartTime);
michael@0 266 }
michael@0 267 return this._userStopTime - this._userStartTime;
michael@0 268 },
michael@0 269 };

mercurial