From f0b727eac28244e0fa24a6107dee44e83ad0f561 Mon Sep 17 00:00:00 2001 From: Tom Ritter Date: Tue, 20 Feb 2018 13:30:16 -0600 Subject: Bug 1430173 - Add Timer Rounding tests backported from -central to -esr. r=baku, a=RyanVM MozReview-Commit-ID: Jl4WZAamgrI --HG-- extra : transplant_source : E%DC%91lU%1C%A4l%2C%C8%23PCz%EB%F2%81%25%1F%90 --- dom/tests/browser/browser.ini | 2 + dom/tests/browser/browser_performanceAPI.js | 139 ++++++++++++++++++++ dom/tests/browser/file_workerPerformance.js | 65 ++++++++++ dom/tests/mochitest/general/mochitest.ini | 3 + .../general/test_reduce_time_precision.html | 143 +++++++++++++++++++++ dom/tests/mochitest/general/worker_child.js | 28 ++++ dom/tests/mochitest/general/worker_grandchild.js | 10 ++ 7 files changed, 390 insertions(+) mode change 100644 => 100755 dom/tests/browser/browser.ini create mode 100755 dom/tests/browser/browser_performanceAPI.js create mode 100755 dom/tests/browser/file_workerPerformance.js mode change 100644 => 100755 dom/tests/mochitest/general/mochitest.ini create mode 100755 dom/tests/mochitest/general/test_reduce_time_precision.html create mode 100755 dom/tests/mochitest/general/worker_child.js create mode 100755 dom/tests/mochitest/general/worker_grandchild.js diff --git a/dom/tests/browser/browser.ini b/dom/tests/browser/browser.ini old mode 100644 new mode 100755 index 35ebd56c6..4d3a60a2c --- a/dom/tests/browser/browser.ini +++ b/dom/tests/browser/browser.ini @@ -8,6 +8,7 @@ support-files = worker_bug1004814.js geo_leak_test.html dummy.html + file_workerPerformance.js test_largeAllocation.html test_largeAllocation.html^headers^ !/dom/tests/mochitest/geolocation/network_geolocation.sjs @@ -44,3 +45,4 @@ support-files = support-files = test_new_window_from_content_child.html [browser_xhr_sandbox.js] +[browser_performanceAPI.js] diff --git a/dom/tests/browser/browser_performanceAPI.js b/dom/tests/browser/browser_performanceAPI.js new file mode 100755 index 000000000..2c28fe3d1 --- /dev/null +++ b/dom/tests/browser/browser_performanceAPI.js @@ -0,0 +1,139 @@ +/** + * 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); +}); diff --git a/dom/tests/browser/file_workerPerformance.js b/dom/tests/browser/file_workerPerformance.js new file mode 100755 index 000000000..c77ba4377 --- /dev/null +++ b/dom/tests/browser/file_workerPerformance.js @@ -0,0 +1,65 @@ +function ok(a, msg) { + postMessage({type: "status", status: !!a, msg}); +} + +function is(a, b, msg) { + ok(a === b, msg); +} + +function finish() { + postMessage({type: "finish"}); +} + +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; +}; + +function runRTPTests(expectedPrecision) { + // Try to add some entries. + performance.mark("Test"); + performance.mark("Test-End"); + performance.measure("Test-Measure", "Test", "Test-End"); + + // Check the entries in performance.getEntries/getEntriesByType/getEntriesByName. + is(performance.getEntries().length, 3, "In a worker, for reduceTimerPrecision: Incorrect number of entries for performance.getEntries() for workers: " + performance.getEntries().length); + for (var i = 0; i < 3; i++) { + let startTime = performance.getEntries()[i].startTime; + let duration = performance.getEntries()[i].duration; + ok(isRounded(startTime, expectedPrecision), "In a worker, for reduceTimerPrecision(" + expectedPrecision + "), performance.getEntries(" + i.toString() + ").startTime is not rounded: " + startTime.toString()); + ok(isRounded(duration, expectedPrecision), "In a worker, for reduceTimerPrecision(" + expectedPrecision + "), performance.getEntries(" + i.toString() + ").duration is not rounded: " + duration.toString()); + } + is(performance.getEntriesByType("mark").length, 2, "In a worker, for reduceTimerPrecision: Incorrect number of entries for performance.getEntriesByType() for workers: " + performance.getEntriesByType("resource").length); + is(performance.getEntriesByName("Test", "mark").length, 1, "In a worker, for reduceTimerPrecision: Incorrect number of entries for performance.getEntriesByName() for workers: " + performance.getEntriesByName("Test", "mark").length); + + finish(); +} + +self.onmessage = function(e) { + runRTPTests(e.data.precision); +}; diff --git a/dom/tests/mochitest/general/mochitest.ini b/dom/tests/mochitest/general/mochitest.ini old mode 100644 new mode 100755 index d59527801..d00ea1d4b --- a/dom/tests/mochitest/general/mochitest.ini +++ b/dom/tests/mochitest/general/mochitest.ini @@ -43,6 +43,8 @@ support-files = frameStoragePrevented.html frameStorageChrome.html frameStorageNullprincipal.sjs + worker_child.js + worker_grandchild.js workerStorageAllowed.js workerStoragePrevented.js storagePermissionsUtils.js @@ -108,6 +110,7 @@ support-files = test_offsets.js [test_picture_mutations.html] [test_pointerPreserves3D.html] [test_pointerPreserves3DClip.html] +[test_reduce_time_precision.html] [test_resource_timing.html] [test_resource_timing_cross_origin.html] [test_resource_timing_frameset.html] diff --git a/dom/tests/mochitest/general/test_reduce_time_precision.html b/dom/tests/mochitest/general/test_reduce_time_precision.html new file mode 100755 index 000000000..6f149f28d --- /dev/null +++ b/dom/tests/mochitest/general/test_reduce_time_precision.html @@ -0,0 +1,143 @@ + + + + + + Test for Tor Bug 1517 and Mozilla Bug 1424341 + + + + + +Tor Bug 1517 +Mozilla Bug 1424341 + + + + + + + + + + diff --git a/dom/tests/mochitest/general/worker_child.js b/dom/tests/mochitest/general/worker_child.js new file mode 100755 index 000000000..fa340fc65 --- /dev/null +++ b/dom/tests/mochitest/general/worker_child.js @@ -0,0 +1,28 @@ +let timeStampCodes; +let worker = new Worker("worker_grandchild.js"); + +function listenToParent(event) { + self.removeEventListener("message", listenToParent); + timeStampCodes = event.data; + + let timeStamps = []; + for (let timeStampCode of timeStampCodes) { + timeStamps.push(eval(timeStampCode)); + } + // Send the timeStamps to the parent. + postMessage(timeStamps); + + // Tell the grandchild to start. + worker.postMessage(timeStampCodes); +} + +// The worker grandchild will send results back. +function listenToChild(event) { + worker.removeEventListener("message", listenToChild); + // Pass the results to the parent. + postMessage(event.data); + worker.terminate(); +} + +worker.addEventListener("message", listenToChild); +self.addEventListener("message", listenToParent); diff --git a/dom/tests/mochitest/general/worker_grandchild.js b/dom/tests/mochitest/general/worker_grandchild.js new file mode 100755 index 000000000..cd21508b2 --- /dev/null +++ b/dom/tests/mochitest/general/worker_grandchild.js @@ -0,0 +1,10 @@ +self.addEventListener("message", function(event) { + let timeStampCodes = event.data; + + let timeStamps = []; + for (let timeStampCode of timeStampCodes) { + timeStamps.push(eval(timeStampCode)); + } + // Send the timeStamps to the parent. + postMessage(timeStamps); +}); -- cgit v1.2.3