Bug 1336712 - dom: Remove performance.now() test checks for Windows XP. r=bzbarsky
authorChris Peterson <cpeterson@mozilla.com>
Thu, 13 Sep 2018 23:39:41 -0700
changeset 438917 a902caa5f3209f558a58b11ce44cc4cce77a5b6a
parent 438916 787f0f511af260a998fc83951cc0cd738001c098
child 438918 87f643635a1260fd357572a3797e9e5e7daedde9
push id34742
push userccoroiu@mozilla.com
push dateSun, 30 Sep 2018 09:46:37 +0000
treeherdermozilla-central@7e9ab0e7b608 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs1336712
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1336712 - dom: Remove performance.now() test checks for Windows XP. r=bzbarsky Firefox no longer supports Windows XP, so these test checks that allow for timeouts with 25 ms resolution can be removed. Also, rewrite some test logic and comments to make the test's intention clearer. The 'getOSCPU' message handler can be removed from test_worker_performance_now.html because test_worker_performance_now.js no longer needs to check for Windows XP. Stop setting the pref "privacy.reduceTimerPrecision" = false in test_performance_now.html. That pref removes performance.now()'s 1 ms resolution limit so the performance timer will run at full speed. By leaving the pref's default value, the test can assert that performance.now() is actually honoring the 1 ms limit. I didn't remove "privacy.reduceTimerPrecision" = false for the worker test. The worker tests run an accelerated setTimeout() clock, so setTimeout(1) can time out in less than 1 ms. Leaving the pref "privacy.reduceTimerPrecision" = true causes hundreds of worker tests to run more slowly (in real time), which would increase test automation time. Differential Revision: https://phabricator.services.mozilla.com/D6581
dom/performance/tests/test_worker_performance_now.html
dom/performance/tests/test_worker_performance_now.js
dom/tests/mochitest/general/test_performance_now.html
--- a/dom/performance/tests/test_worker_performance_now.html
+++ b/dom/performance/tests/test_worker_performance_now.html
@@ -18,20 +18,14 @@ SpecialPowers.setBoolPref("privacy.reduc
 var worker = new Worker('test_worker_performance_now.js');
 worker.onmessage = function(event) {
   if (event.data.type == 'finish') {
     SpecialPowers.setBoolPref("privacy.reduceTimerPrecision", reduceTimePrecisionPrevPrefValue);
     SimpleTest.finish();
 
   } else if (event.data.type == 'status') {
     ok(event.data.status, event.data.msg);
-
-  } else if (event.data.type == 'getOSCPU') {
-    worker.postMessage({
-      type: 'returnOSCPU',
-      result: navigator.oscpu
-    });
   }
 }
 
 </script>
 </body>
 </html>
--- a/dom/performance/tests/test_worker_performance_now.js
+++ b/dom/performance/tests/test_worker_performance_now.js
@@ -2,75 +2,56 @@ function ok(a, msg) {
   dump("OK: " + !!a + "  =>  " + a + ": " + msg + "\n");
   postMessage({type: 'status', status: !!a, msg: a + ": " + msg });
 }
 
 function workerTestDone() {
   postMessage({ type: 'finish' });
 }
 
-function workerTestGetOSCPU(cb) {
-  addEventListener('message', function workerTestGetOSCPUCB(e) {
-    if (e.data.type !== 'returnOSCPU') {
-      return;
-    }
-    removeEventListener('message', workerTestGetOSCPUCB);
-    cb(e.data.result);
-  });
-  postMessage({
-    type: 'getOSCPU'
-  });
-}
-
 ok(self.performance, "Performance object should exist.");
 ok(typeof self.performance.now == 'function', "Performance object should have a 'now' method.");
 var n = self.performance.now(), d = Date.now();
 ok(n >= 0, "The value of now() should be equal to or greater than 0.");
 ok(self.performance.now() >= n, "The value of now() should monotonically increase.");
 
-// The spec says performance.now() should have micro-second resolution, but allows 1ms if the platform doesn't support it.
-// Our implementation does provide micro-second resolution, except for windows XP combined with some HW properties
-// where we can't use QueryPerformanceCounters (see comments at mozilla-central/xpcom/ds/TimeStamp_windows.cpp).
-// This XP-low-res case results in about 15ms resolutions, and can be identified when perf.now() returns only integers.
-//
-// Since setTimeout might return too early/late, our goal is that perf.now() changed within 2ms
-// (or 25ms for XP-low-res), rather than specific number of setTimeout(N) invocations.
+// Spin on setTimeout() until performance.now() increases. Due to recent
+// security developments, the hr-time working group has not yet reached
+// consensus on what the recommend minimum clock resolution should be:
+// https://w3c.github.io/hr-time/#clock-resolution
+// Since setTimeout might return too early/late, our goal is for
+// performance.now() to increase before a 2 ms deadline rather than specific
+// number of setTimeout(N) invocations.
 // See bug 749894 (intermittent failures of this test)
-var platformPossiblyLowRes;
-workerTestGetOSCPU(function(oscpu) {
-    platformPossiblyLowRes = oscpu.indexOf("Windows NT 5.1") == 0; // XP only
-    setTimeout(checkAfterTimeout, 1);
-});
-var allInts = (n % 1) == 0; // Indicator of limited HW resolution.
+setTimeout(checkAfterTimeout, 1);
+
 var checks = 0;
 
 function checkAfterTimeout() {
   checks++;
   var d2 = Date.now();
   var n2 = self.performance.now();
 
-  allInts = allInts && (n2 % 1) == 0;
-  var lowResCounter = platformPossiblyLowRes && allInts;
-
-  if ( n2 == n && checks < 50 && // 50 is just a failsafe. Our real goals are 2ms or 25ms.
-       ( (d2 - d) < 2 // The spec allows 1ms resolution. We allow up to measured 2ms to ellapse.
-         ||
-         lowResCounter &&
-         (d2 - d) < 25
-       )
-     ) {
+  // Spin on setTimeout() until performance.now() increases. Abort the test
+  // if it runs for more than 2 ms or 50 timeouts.
+  let elapsedTime = d2 - d;
+  let elapsedPerf = n2 - n;
+  if (elapsedPerf == 0 && elapsedTime < 2 && checks < 50) {
     setTimeout(checkAfterTimeout, 1);
     return;
   }
 
-  // Loose spec: 1ms resolution, or 15ms resolution for the XP-low-res case.
-  // We shouldn't test that dt is actually within 2/25ms since the iterations break if it isn't, and timeout could be late.
-  ok(n2 > n, "Loose - the value of now() should increase within 2ms (or 25ms if low-res counter) (delta now(): " + (n2 - n) + " ms).");
+  // Our implementation provides 1 ms resolution (bug 1451790), but we
+  // can't assert that elapsedPerf >= 1 ms because this worker test runs with
+  // "privacy.reduceTimerPrecision" == false so performance.now() is not
+  // limited to 1 ms resolution.
+  ok(elapsedPerf > 0,
+     `Loose - the value of now() should increase after 2ms. ` +
+     `delta now(): ${elapsedPerf} ms`);
 
-  // Strict spec: if it's not the XP-low-res case, while the spec allows 1ms resolution, it prefers microseconds, which we provide.
-  // Since the fastest setTimeout return which I observed was ~500 microseconds, a microseconds counter should change in 1 iteretion.
-  ok(n2 > n && (lowResCounter || checks == 1),
-     "Strict - [if high-res counter] the value of now() should increase after one setTimeout (hi-res: " + (!lowResCounter) +
-                                                                                              ", iters: " + checks +
-                                                                                              ", dt: " + (d2 - d) +
-                                                                                              ", now(): " + n2 + ").");
+  // If we need more than 1 iteration, then either performance.now() resolution
+  // is shorter than 1 ms or setTimeout() is returning too early.
+  ok(checks == 1,
+     `Strict - the value of now() should increase after one setTimeout. ` +
+     `iters: ${checks}, dt: ${elapsedTime}, now(): ${n2}`);
+
   workerTestDone();
 };
--- a/dom/tests/mochitest/general/test_performance_now.html
+++ b/dom/tests/mochitest/general/test_performance_now.html
@@ -8,62 +8,53 @@
 </head>
 <body>
   <script>
     ok(window.performance, "Performance object should exist.");
     ok(typeof window.performance.now == 'function', "Performance object should have a 'now' method.");
     var n = window.performance.now(), d = Date.now();
     ok(n >= 0, "The value of now() should be equal to or greater than 0.");
     ok(window.performance.now() >= n, "The value of now() should monotonically increase.");
+
     SimpleTest.waitForExplicitFinish();
-    var reduceTimePrecisionPrevPrefValue = SpecialPowers.getBoolPref("privacy.reduceTimerPrecision");
-    SpecialPowers.setBoolPref("privacy.reduceTimerPrecision", false);
-    SimpleTest.requestFlakyTimeout("untriaged");
+    SimpleTest.requestFlakyTimeout("using setTimeout() to measure performance.now()");
 
-    // The spec says performance.now() should have micro-second resolution, but allows 1ms if the platform doesn't support it.
-    // Our implementation does provide micro-second resolution, except for windows XP combined with some HW properties
-    // where we can't use QueryPerformanceCounters (see comments at mozilla-central/xpcom/ds/TimeStamp_windows.cpp).
-    // This XP-low-res case results in about 15ms resolutions, and can be identified when perf.now() returns only integers.
-    //
-    // Since setTimeout might return too early/late, our goal is that perf.now() changed within 2ms
-    // (or 25ms for XP-low-res), rather than specific number of setTimeout(N) invocations.
+    // Spin on setTimeout() until performance.now() increases. Due to recent
+    // security developments, the hr-time working group has not yet reached
+    // consensus on what the recommend minimum clock resolution should be:
+    // https://w3c.github.io/hr-time/#clock-resolution
+    // Since setTimeout might return too early/late, our goal is for
+    // performance.now() to increase before a 2 ms deadline rather than specific
+    // number of setTimeout(N) invocations.
     // See bug 749894 (intermittent failures of this test)
-    var platformPossiblyLowRes = navigator.oscpu.indexOf("Windows NT 5.1") == 0; // XP only
-    var allInts = (n % 1) == 0; // Indicator of limited HW resolution.
     var checks = 0;
 
     function checkAfterTimeout() {
       checks++;
       var d2 = Date.now();
       var n2 = window.performance.now();
 
-      allInts = allInts && (n2 % 1) == 0;
-      var lowResCounter = platformPossiblyLowRes && allInts;
-
-      if ( n2 == n && checks < 50 && // 50 is just a failsafe. Our real goals are 2ms or 25ms.
-           ( (d2 - d) < 2 // The spec allows 1ms resolution. We allow up to measured 2ms to ellapse.
-             ||
-             lowResCounter &&
-             (d2 - d) < 25
-           )
-         ) {
+      // Spin on setTimeout() until performance.now() increases. Abort the
+      // test if it runs for more than 2 ms or 50 timeouts.
+      let elapsedTime = d2 - d;
+      let elapsedPerf = n2 - n;
+      if (elapsedPerf == 0 && elapsedTime < 2 && checks < 50) {
         setTimeout(checkAfterTimeout, 1);
         return;
       }
 
-      // Loose spec: 1ms resolution, or 15ms resolution for the XP-low-res case.
-      // We shouldn't test that dt is actually within 2/25ms since the iterations break if it isn't, and timeout could be late.
-      ok(n2 > n, "Loose - the value of now() should increase within 2ms (or 25ms if low-res counter) (delta now(): " + (n2 - n) + " ms).");
+      // Our implementation provides 1 ms resolution (bug 1451790).
+      ok(elapsedPerf >= 1,
+         `Loose - the value of now() should increase by no less than 1 ms ` +
+         `after 2 ms. delta now(): ${elapsedPerf} ms`);
 
-      // Strict spec: if it's not the XP-low-res case, while the spec allows 1ms resolution, it prefers microseconds, which we provide.
-      // Since the fastest setTimeout return which I observed was ~500 microseconds, a microseconds counter should change in 1 iteretion.
-      ok(n2 > n && (lowResCounter || checks == 1),
-         "Strict - [if high-res counter] the value of now() should increase after one setTimeout (hi-res: " + (!lowResCounter) +
-                                                                                                  ", iters: " + checks +
-                                                                                                  ", dt: " + (d2 - d) +
-                                                                                                  ", now(): " + n2 + ").");
-      SpecialPowers.setBoolPref("privacy.reduceTimerPrecision", reduceTimePrecisionPrevPrefValue);
+      // If we need more than 1 iteration, then either performance.now()
+      // resolution is shorter than 1 ms or setTimeout() is returning too early.
+      ok(checks == 1,
+         `Strict - the value of now() should increase after one setTimeout. ` +
+         `iters: ${checks}, dt: ${elapsedTime}, now(): ${n2}`);
+
       SimpleTest.finish();
     };
     setTimeout(checkAfterTimeout, 1);
   </script>
 </body>
 </html>