Bug 749894: performance.now() mochitest3: Better spec compliance, stricter test, better slack. r=bz

This commit is contained in:
Avi Halachmi 2013-03-05 07:17:11 +02:00
parent cfb9cd3f1d
commit 15cfd9ce65

View File

@ -15,22 +15,51 @@
ok(window.performance.now() >= n, "The value of now() should monotonically increase.");
SimpleTest.waitForExplicitFinish();
// 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.
// 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();
// Timeouts aren't extremely reliable and especially on Windows we are prone to fallback to
// millisecond timers, in which case this test might occasionally fail. This is a workaround:
if (navigator.platform.indexOf("Win") == 0 &&
window.performance.now() == n && d == d2 &&
checks < 5) {
setTimeout(checkAfterTimeout, 20);
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
)
) {
setTimeout(checkAfterTimeout, 1);
return;
}
ok(window.performance.now() > n, "After a timeout, the value of now() should be strictly greater than before.");
// 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).");
// 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 + ").");
SimpleTest.finish();
};
setTimeout(checkAfterTimeout, 20);
setTimeout(checkAfterTimeout, 1);
</script>
</body>
</html>