140 lines
5.3 KiB
JavaScript
140 lines
5.3 KiB
JavaScript
/**
|
|
* Bug 1369303 - A test for making sure that performance APIs have been correctly
|
|
* spoofed or disabled.
|
|
*/
|
|
|
|
const TEST_PATH = "http://example.net/browser/" +
|
|
"dom/tests/browser/";
|
|
|
|
const PERFORMANCE_TIMINGS = [
|
|
"navigationStart",
|
|
"unloadEventStart",
|
|
"unloadEventEnd",
|
|
"redirectStart",
|
|
"redirectEnd",
|
|
"fetchStart",
|
|
"domainLookupStart",
|
|
"domainLookupEnd",
|
|
"connectStart",
|
|
"connectEnd",
|
|
"requestStart",
|
|
"responseStart",
|
|
"responseEnd",
|
|
"domLoading",
|
|
"domInteractive",
|
|
"domContentLoadedEventStart",
|
|
"domContentLoadedEventEnd",
|
|
"domComplete",
|
|
"loadEventStart",
|
|
"loadEventEnd",
|
|
];
|
|
|
|
let isRounded = (x, expectedPrecision) => {
|
|
let rounded = (Math.floor(x / expectedPrecision) * expectedPrecision);
|
|
// First we do the perfectly normal check that should work just fine
|
|
if (rounded === x || x === 0)
|
|
return true;
|
|
|
|
// When we're diving by non-whole numbers, we may not get perfect
|
|
// multiplication/division because of floating points
|
|
if (Math.abs(rounded - x + expectedPrecision) < .0000001) {
|
|
return true;
|
|
} else if (Math.abs(rounded - x) < .0000001) {
|
|
return true;
|
|
}
|
|
|
|
// Then we handle the case where you're sub-millisecond and the timer is not
|
|
// We check that the timer is not sub-millisecond by assuming it is not if it
|
|
// returns an even number of milliseconds
|
|
if (expectedPrecision < 1 && Math.round(x) == x) {
|
|
if (Math.round(rounded) == x) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
ok(false, "Looming Test Failure, Additional Debugging Info: Expected Precision: " + expectedPrecision + " Measured Value: " + x +
|
|
" Rounded Vaue: " + rounded + " Fuzzy1: " + Math.abs(rounded - x + expectedPrecision) +
|
|
" Fuzzy 2: " + Math.abs(rounded - x));
|
|
|
|
return false;
|
|
};
|
|
|
|
// ================================================================================================
|
|
// ================================================================================================
|
|
add_task(function* () {
|
|
let tab = yield BrowserTestUtils.openNewForegroundTab(
|
|
gBrowser, TEST_PATH + "dummy.html");
|
|
|
|
yield ContentTask.spawn(tab.linkedBrowser, {
|
|
list: PERFORMANCE_TIMINGS,
|
|
precision: 2,
|
|
isRoundedFunc: isRounded.toString()
|
|
}, (data) => {
|
|
let timerlist = data.list;
|
|
let expectedPrecision = data.precision;
|
|
// eslint beleives that isrounded is available in this scope, but if you
|
|
// remove the assignment, you will see it is not
|
|
// eslint-disable-next-line
|
|
let isRounded = eval(data.isRoundedFunc);
|
|
|
|
// Check that whether the performance timing API is correctly spoofed.
|
|
for (let time of timerlist) {
|
|
ok(isRounded(content.performance.timing[time], expectedPrecision), `For reduceTimerPrecision(` + expectedPrecision + `), the timing(${time}) is not correctly rounded: ` + content.performance.timing[time]);
|
|
}
|
|
|
|
// Try to add some entries.
|
|
content.performance.mark("Test");
|
|
content.performance.mark("Test-End");
|
|
content.performance.measure("Test-Measure", "Test", "Test-End");
|
|
|
|
// Check the entries for performance.getEntries/getEntriesByType/getEntriesByName.
|
|
is(content.performance.getEntries().length, 3, "For reduceTimerPrecision, there should be 3 entries for performance.getEntries()");
|
|
for (var i = 0; i < 3; i++) {
|
|
let startTime = content.performance.getEntries()[i].startTime;
|
|
let duration = content.performance.getEntries()[i].duration;
|
|
ok(isRounded(startTime, expectedPrecision), "For reduceTimerPrecision(" + expectedPrecision + "), performance.getEntries(" + i + ").startTime is not rounded: " + startTime);
|
|
ok(isRounded(duration, expectedPrecision), "For reduceTimerPrecision(" + expectedPrecision + "), performance.getEntries(" + i + ").duration is not rounded: " + duration);
|
|
}
|
|
is(content.performance.getEntriesByType("mark").length, 2, "For reduceTimerPrecision, there should be 2 entries for performance.getEntriesByType()");
|
|
is(content.performance.getEntriesByName("Test", "mark").length, 1, "For reduceTimerPrecision, there should be 1 entry for performance.getEntriesByName()");
|
|
content.performance.clearMarks();
|
|
content.performance.clearMeasures();
|
|
content.performance.clearResourceTimings();
|
|
});
|
|
gBrowser.removeTab(tab);
|
|
});
|
|
|
|
// ================================================================================================
|
|
// ================================================================================================
|
|
add_task(function*() {
|
|
let tab = yield BrowserTestUtils.openNewForegroundTab(
|
|
gBrowser, TEST_PATH + "dummy.html");
|
|
|
|
yield ContentTask.spawn(tab.linkedBrowser, {
|
|
list: PERFORMANCE_TIMINGS,
|
|
precision: 2,
|
|
isRoundedFunc: isRounded.toString()
|
|
}, (data) => {
|
|
let expectedPrecision = data.precision;
|
|
let workerCall = data.workerCall;
|
|
return new Promise(resolve => {
|
|
let worker = new content.Worker("file_workerPerformance.js");
|
|
worker.onmessage = function(e) {
|
|
if (e.data.type == "status") {
|
|
ok(e.data.status, e.data.msg);
|
|
} else if (e.data.type == "finish") {
|
|
worker.terminate();
|
|
resolve();
|
|
} else {
|
|
ok(false, "Unknown message type");
|
|
worker.terminate();
|
|
resolve();
|
|
}
|
|
};
|
|
worker.postMessage({precision: expectedPrecision});
|
|
});
|
|
});
|
|
|
|
gBrowser.removeTab(tab);
|
|
});
|