Bug 1435296 Address test failures caused by bumping timer precision to 2 ms r?baku draft
authorTom Ritter <tom@mozilla.com>
Mon, 12 Feb 2018 11:39:41 -0600
changeset 753920 403cd7bb8f8dd6d5731237f528a3c925afe79c24
parent 753919 633ea4d87b1d277a6bd58ad1ed71f656d806927e
child 753921 a3c8d0bec6d60e232680a4aaa18311a419f66ba5
push id98722
push userbmo:tom@mozilla.com
push dateMon, 12 Feb 2018 17:42:43 +0000
reviewersbaku
bugs1435296, 1429648
milestone60.0a1
Bug 1435296 Address test failures caused by bumping timer precision to 2 ms r?baku There are a few different reasons why tests needed updating (not an exhaustive list): - Tests assume that successive operations take place at different times. - Tests assume that an operation took a minimum amount of time. - Tests hardcodes a specific delay. In most cases we hardcode the preference off. In some cases this is the best approach, in others, we would like to improve. The bug for tracking those improvements is Bug 1429648 An improvement that is present in some tests is to hardcode a specific precision reduction that is acceptable based on the confides of the test. (Obviously this needs to be a fix for the test framework and not a requirement on the feature being tested.) In a few places, the test itself can be fixed, for example to no longer require the end time of an operation to be strictly greater than the start time, and allows it to be equal to it. MozReview-Commit-ID: J59c7xQtZZJ
browser/base/content/test/general/browser_lastAccessedTab.js
browser/base/content/test/general/browser_storagePressure_notification.js
browser/base/content/test/urlbar/browser_autocomplete_enter_race.js
browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed_tabs.js
browser/extensions/formautofill/test/browser/browser_manageCreditCardsDialog.js
browser/extensions/formautofill/test/mochitest/test_on_address_submission.html
browser/extensions/shield-recipe-client/test/browser/browser_ClientEnvironment.js
devtools/client/animationinspector/test/browser_animation_timeline_pause_button_02.js
devtools/client/canvasdebugger/test/browser_profiling-canvas.js
devtools/client/canvasdebugger/test/browser_profiling-webgl.js
devtools/client/inspector/markup/test/browser_markup_mutation_02.js
devtools/client/netmonitor/src/har/test/browser_net_har_copy_all_as_har.js
devtools/client/netmonitor/test/browser_net_status-bar.js
devtools/client/sourceeditor/test/browser_codemirror.js
devtools/server/tests/browser/browser_perf-samples-01.js
devtools/server/tests/mochitest/memory-helpers.js
docshell/test/chrome/test_bug453650.xul
dom/animation/test/css-animations/test_event-dispatch.html
dom/animation/test/css-transitions/test_animation-starttime.html
dom/animation/test/document-timeline/test_document-timeline.html
dom/animation/test/mozilla/test_transition_finish_on_compositor.html
dom/base/test/test_bug403852.html
dom/events/test/test_eventTimeStamp.html
dom/media/test/test_background_video_suspend.html
dom/media/tests/mochitest/test_peerConnection_audioContributingSources.html
dom/performance/tests/test_performance_user_timing.html
dom/performance/tests/test_sharedWorker_performance_user_timing.html
dom/performance/tests/test_timeOrigin.html
dom/performance/tests/test_worker_performance_entries.html
dom/performance/tests/test_worker_performance_now.html
dom/performance/tests/test_worker_user_timing.html
dom/smil/test/test_smilTimeEvents.xhtml
dom/tests/mochitest/ajax/jquery/test_jQuery.html
dom/tests/mochitest/general/test_performance_now.html
dom/tests/mochitest/general/test_resource_timing.html
dom/tests/mochitest/general/test_resource_timing_cross_origin.html
layout/reftests/svg/smil/reftest.list
security/manager/ssl/tests/unit/test_baseline_requirements_subject_common_name.js
security/manager/ssl/tests/unit/test_cert_eku.js
testing/web-platform/meta/hr-time/__dir__.ini
testing/web-platform/meta/intersection-observer/timestamp.html.ini
testing/web-platform/meta/media-source/mediasource-getvideoplaybackquality.html.ini
testing/web-platform/meta/navigation-timing/nav2_test_redirect_server.html.ini
testing/web-platform/meta/requestidlecallback/basic.html.ini
testing/web-platform/meta/resource-timing/__dir__.ini
testing/web-platform/meta/service-workers/service-worker/performance-timeline.https.html.ini
testing/web-platform/meta/service-workers/service-worker/resource-timing.https.html.ini
testing/web-platform/meta/user-timing/__dir__.ini
testing/web-platform/meta/workers/WorkerPerformanceNow.html.ini
testing/web-platform/meta/workers/semantics/navigation/002.html.ini
testing/web-platform/meta/workers/worker-performance.worker.js.ini
--- a/browser/base/content/test/general/browser_lastAccessedTab.js
+++ b/browser/base/content/test/general/browser_lastAccessedTab.js
@@ -15,19 +15,24 @@ function nextStep(fn) {
   setTimeout(fn, CURRENT_TIME_TOLERANCE_MS + 10);
 }
 
 var originalTab;
 var newTab;
 
 function test() {
   waitForExplicitFinish();
-
-  originalTab = gBrowser.selectedTab;
-  nextStep(step2);
+  // This test assumes that time passes between operations. But if the precision
+  // is low enough, and the test fast enough, an operation, and a successive call
+  // to Date.now() will have the same time value.
+  SpecialPowers.pushPrefEnv({"set": [["privacy.reduceTimerPrecision", false]]},
+    function() {
+      originalTab = gBrowser.selectedTab;
+      nextStep(step2);
+    });
 }
 
 function step2() {
   isCurrent(originalTab, "selected tab has the current timestamp");
   newTab = BrowserTestUtils.addTab(gBrowser, "about:blank", {skipAnimation: true});
   nextStep(step3);
 }
 
--- a/browser/base/content/test/general/browser_storagePressure_notification.js
+++ b/browser/base/content/test/general/browser_storagePressure_notification.js
@@ -20,16 +20,18 @@ function openAboutPrefPromise() {
   return Promise.all(promises);
 }
 
 // Test only displaying notification once within the given interval
 add_task(async function() {
   const TEST_NOTIFICATION_INTERVAL_MS = 2000;
   await SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]});
   await SpecialPowers.pushPrefEnv({set: [["browser.storageManager.pressureNotification.minIntervalMS", TEST_NOTIFICATION_INTERVAL_MS]]});
+  // Commenting this to see if we really need it
+  // await SpecialPowers.pushPrefEnv({set: [["privacy.reduceTimerPrecision", false]]});
 
   await notifyStoragePressure();
   let notificationbox = document.getElementById("high-priority-global-notificationbox");
   let notification = notificationbox.getNotificationWithValue("storage-pressure-notification");
   ok(notification instanceof XULElement, "Should display storage pressure notification");
   notification.close();
 
   await notifyStoragePressure();
--- a/browser/base/content/test/urlbar/browser_autocomplete_enter_race.js
+++ b/browser/base/content/test/urlbar/browser_autocomplete_enter_race.js
@@ -13,16 +13,24 @@ add_task(async function setup() {
   });
   await PlacesUtils.keywords.insert({ keyword: "keyword",
                                       url: "http://example.com/?q=%s" });
   // Needs at least one success.
   ok(true, "Setup complete");
 });
 
 add_task(async function test_keyword() {
+  // This is set because we see (undiagnosed) test timeouts without it
+  let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
+  Preferences.set("privacy.reduceTimerPrecision", false);
+
+  registerCleanupFunction(function() {
+    Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
+  });
+
   await promiseAutocompleteResultPopup("keyword bear");
   gURLBar.focus();
   EventUtils.synthesizeKey("d", {});
   EventUtils.synthesizeKey("VK_RETURN", {});
   info("wait for the page to load");
   await BrowserTestUtils.browserLoaded(gBrowser.selectedTab.linkedBrowser,
                                       false, "http://example.com/?q=beard");
 });
@@ -95,19 +103,27 @@ add_task(async function test_disabled_ac
   await cleanup();
 });
 
 add_task(async function test_delay() {
   const TIMEOUT = 10000;
   // Set a large delay.
   let delay = Preferences.get("browser.urlbar.delay");
   Preferences.set("browser.urlbar.delay", TIMEOUT);
+  // This may be a real test regression on Bug 1283329, if we can get it to
+  // fail at a realistic 2ms.
+  let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
+  Preferences.set("privacy.reduceTimerPrecision", true);
+  let timerPrecisionUSec = Preferences.get("privacy.resistFingerprinting.reduceTimerPrecision.microseconds");
+  Preferences.set("privacy.resistFingerprinting.reduceTimerPrecision.microseconds", 2000);
 
   registerCleanupFunction(function() {
     Preferences.set("browser.urlbar.delay", delay);
+    Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
+    Preferences.set("privacy.resistFingerprinting.reduceTimerPrecision.microseconds", timerPrecisionUSec);
   });
 
   // This is needed to clear the current value, otherwise autocomplete may think
   // the user removed text from the end.
   let start = Date.now();
   await promiseAutocompleteResultPopup("");
   Assert.ok((Date.now() - start) < TIMEOUT);
 
--- a/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed_tabs.js
+++ b/browser/components/extensions/test/browser/browser_ext_sessions_getRecentlyClosed_tabs.js
@@ -16,16 +16,20 @@ function expectedTabInfo(tab, window) {
 
 function checkTabInfo(expected, actual) {
   for (let prop in expected) {
     is(actual[prop], expected[prop], `Expected value found for ${prop} of tab object.`);
   }
 }
 
 add_task(async function test_sessions_get_recently_closed_tabs() {
+  // Below, the test makes assumptions about the last accessed time of tabs that are
+  // not true is we execute fast and reduce the timer precision enough
+  await SpecialPowers.pushPrefEnv({set: [["privacy.reduceTimerPrecision", false]]});
+
   async function background() {
     browser.test.onMessage.addListener(async msg => {
       if (msg == "check-sessions") {
         let recentlyClosed = await browser.sessions.getRecentlyClosed();
         browser.test.sendMessage("recentlyClosed", recentlyClosed);
       }
     });
   }
--- a/browser/extensions/formautofill/test/browser/browser_manageCreditCardsDialog.js
+++ b/browser/extensions/formautofill/test/browser/browser_manageCreditCardsDialog.js
@@ -33,16 +33,17 @@ add_task(async function test_cancelManag
   await waitForFocusAndFormReady(win);
   let unloadPromise = BrowserTestUtils.waitForEvent(win, "unload");
   EventUtils.synthesizeKey("VK_ESCAPE", {}, win);
   await unloadPromise;
   ok(true, "Manage credit cards dialog is closed with ESC key");
 });
 
 add_task(async function test_removingSingleAndMultipleCreditCards() {
+  await SpecialPowers.pushPrefEnv({"set": [["privacy.reduceTimerPrecision", false]]});
   await saveCreditCard(TEST_CREDIT_CARD_1);
   await saveCreditCard(TEST_CREDIT_CARD_2);
   await saveCreditCard(TEST_CREDIT_CARD_3);
 
   let win = window.openDialog(MANAGE_CREDIT_CARDS_DIALOG_URL, null, DIALOG_SIZE);
   await waitForFocusAndFormReady(win);
 
   let selRecords = win.document.querySelector(TEST_SELECTORS.selRecords);
@@ -85,16 +86,17 @@ add_task(async function test_creditCards
 
   await removeCreditCards([selRecords.options[0].value]);
   await BrowserTestUtils.waitForEvent(selRecords, "RecordsLoaded");
   is(selRecords.length, 0, "Credit card is removed");
   win.close();
 });
 
 add_task(async function test_showCreditCards() {
+  await SpecialPowers.pushPrefEnv({"set": [["privacy.reduceTimerPrecision", false]]});
   await saveCreditCard(TEST_CREDIT_CARD_1);
   await saveCreditCard(TEST_CREDIT_CARD_2);
   await saveCreditCard(TEST_CREDIT_CARD_3);
 
   let win = window.openDialog(MANAGE_CREDIT_CARDS_DIALOG_URL, null, DIALOG_SIZE);
   await waitForFocusAndFormReady(win);
 
   let selRecords = win.document.querySelector(TEST_SELECTORS.selRecords);
--- a/browser/extensions/formautofill/test/mochitest/test_on_address_submission.html
+++ b/browser/extensions/formautofill/test/mochitest/test_on_address_submission.html
@@ -31,17 +31,17 @@ let TEST_ADDRESSES = [{
 }];
 
 initPopupListener();
 
 // Submit first address for saving.
 add_task(async function check_storage_after_form_submitted() {
   // We already verified the first time use case in browser test
   await SpecialPowers.pushPrefEnv({
-    set: [["extensions.formautofill.firstTimeUse", false]],
+    "set": [["extensions.formautofill.firstTimeUse", false]],
   });
 
   for (let key in TEST_ADDRESSES[0]) {
     await setInput("#" + key, TEST_ADDRESSES[0][key]);
   }
 
   clickOnElement("input[type=submit]");
 
@@ -51,16 +51,18 @@ add_task(async function check_storage_af
   expectedAddresses[0].timesUsed = 1;
   let matching = await checkAddresses(expectedAddresses);
   ok(matching, "Address saved as expected");
   delete expectedAddresses[0].timesUsed;
 });
 
 // Submit another new address.
 add_task(async function check_storage_after_another_address_submitted() {
+  await SpecialPowers.pushPrefEnv({"set": [["privacy.reduceTimerPrecision", false]]});
+
   document.querySelector("form").reset();
   for (let key in TEST_ADDRESSES[1]) {
     await setInput("#" + key, TEST_ADDRESSES[1][key]);
   }
 
   clickOnElement("input[type=submit]");
 
   // The 2nd test address should be on the top since it's the last used one.
--- a/browser/extensions/shield-recipe-client/test/browser/browser_ClientEnvironment.js
+++ b/browser/extensions/shield-recipe-client/test/browser/browser_ClientEnvironment.js
@@ -5,16 +5,18 @@ ChromeUtils.import("resource://gre/modul
 ChromeUtils.import("resource://gre/modules/AddonManager.jsm", this);
 ChromeUtils.import("resource://testing-common/AddonTestUtils.jsm", this);
 ChromeUtils.import("resource://shield-recipe-client/lib/ClientEnvironment.jsm", this);
 ChromeUtils.import("resource://shield-recipe-client/lib/PreferenceExperiments.jsm", this);
 
 
 add_task(async function testTelemetry() {
   // setup
+  await SpecialPowers.pushPrefEnv({set: [["privacy.reduceTimerPrecision", true]]});
+
   await TelemetryController.submitExternalPing("testfoo", {foo: 1});
   await TelemetryController.submitExternalPing("testbar", {bar: 2});
   await TelemetryController.submitExternalPing("testfoo", {foo: 3});
   const environment = ClientEnvironment.getEnvironment();
 
   // Test it can access telemetry
   const telemetry = await environment.telemetry;
   is(typeof telemetry, "object", "Telemetry is accesible");
--- a/devtools/client/animationinspector/test/browser_animation_timeline_pause_button_02.js
+++ b/devtools/client/animationinspector/test/browser_animation_timeline_pause_button_02.js
@@ -1,21 +1,31 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  http://creativecommons.org/publicdomain/zero/1.0/ */
 /* eslint-disable mozilla/no-arbitrary-setTimeout */
 
 "use strict";
 
 requestLongerTimeout(2);
+ChromeUtils.defineModuleGetter(this, "Preferences",
+  "resource://gre/modules/Preferences.jsm");
 
 // Checks that the play/pause button goes to the right state when the scrubber has reached
 // the end of the timeline but there are infinite animations playing.
 
 add_task(function* () {
+  // TODO see if this is needed?
+  // let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
+  // Preferences.set("privacy.reduceTimerPrecision", false);
+
+  // registerCleanupFunction(function () {
+  //   Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
+  // });
+
   yield addTab(URL_ROOT + "doc_simple_animation.html");
 
   let {panel, inspector} = yield openAnimationInspector();
   let timeline = panel.animationsTimelineComponent;
   let btn = panel.playTimelineButtonEl;
 
   info("Select an infinite animation and wait for the scrubber to reach the end");
   yield selectNodeAndWaitForAnimations(".multi", inspector);
--- a/devtools/client/canvasdebugger/test/browser_profiling-canvas.js
+++ b/devtools/client/canvasdebugger/test/browser_profiling-canvas.js
@@ -32,14 +32,14 @@ function* ifTestingSupported() {
   is(functionCalls.length, 8,
     "The number of function call actors is correct.");
 
   info("Check the timestamps of function calls");
 
   for (let i = 0; i < functionCalls.length - 1; i += 2) {
     ok(functionCalls[i].timestamp > 0, "The timestamp of the called function is larger than 0.");
     ok(functionCalls[i].timestamp < currentTime, "The timestamp has been minus the frame start time.");
-    ok(functionCalls[i + 1].timestamp > functionCalls[i].timestamp, "The timestamp of the called function is correct.");
+    ok(functionCalls[i + 1].timestamp >= functionCalls[i].timestamp, "The timestamp of the called function is correct.");
   }
 
   yield removeTab(target.tab);
   finish();
 }
--- a/devtools/client/canvasdebugger/test/browser_profiling-webgl.js
+++ b/devtools/client/canvasdebugger/test/browser_profiling-webgl.js
@@ -77,11 +77,11 @@ function* ifTestingSupported() {
 }
 
 function testFunctionCallTimestamp(functionCalls, currentTime) {
   info("Check the timestamps of function calls");
 
   for ( let i = 0; i < functionCalls.length-1; i += 2 ) {
     ok( functionCalls[i].timestamp > 0, "The timestamp of the called function is larger than 0." );
     ok( functionCalls[i].timestamp < currentTime, "The timestamp has been minus the frame start time." );
-    ok( functionCalls[i+1].timestamp > functionCalls[i].timestamp, "The timestamp of the called function is correct." );
+    ok( functionCalls[i+1].timestamp >= functionCalls[i].timestamp, "The timestamp of the called function is correct." );
   }
 }
--- a/devtools/client/inspector/markup/test/browser_markup_mutation_02.js
+++ b/devtools/client/inspector/markup/test/browser_markup_mutation_02.js
@@ -4,16 +4,18 @@
 
 "use strict";
 
 // Test that markup-containers in the markup-view do flash when their
 // corresponding DOM nodes mutate
 
 // Have to use the same timer functions used by the inspector.
 const {clearTimeout} = ChromeUtils.import("resource://gre/modules/Timer.jsm", {});
+ChromeUtils.defineModuleGetter(this, "Preferences",
+  "resource://gre/modules/Preferences.jsm");
 
 const TEST_URL = URL_ROOT + "doc_markup_flashing.html";
 
 // The test data contains a list of mutations to test.
 // Each item is an object:
 // - desc: a description of the test step, for better logging
 // - mutate: a generator function that should make changes to the content DOM
 // - attribute: if set, the test will expect the corresponding attribute to
@@ -87,16 +89,23 @@ const TEST_DATA = [{
     yield testActor.eval(`
       let root = document.querySelector(".list");
       root.removeAttribute("class");
     `);
   }
 }];
 
 add_task(function* () {
+  let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
+  Preferences.set("privacy.reduceTimerPrecision", false);
+
+  registerCleanupFunction(function () {
+    Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
+  });
+
   let {inspector, testActor} = yield openInspectorForURL(TEST_URL);
 
   // Make sure mutated nodes flash for a very long time so we can more easily
   // assert they do
   inspector.markup.CONTAINER_FLASHING_DURATION = 1000 * 60 * 60;
 
   info("Getting the <ul.list> root node to test mutations on");
   let rootNodeFront = yield getNodeFront(".list", inspector);
--- a/devtools/client/netmonitor/src/har/test/browser_net_har_copy_all_as_har.js
+++ b/devtools/client/netmonitor/src/har/test/browser_net_har_copy_all_as_har.js
@@ -38,18 +38,18 @@ add_task(function* () {
   // Check out HAR log
   isnot(har.log, null, "The HAR log must exist");
   is(har.log.creator.name, "Firefox", "The creator field must be set");
   is(har.log.browser.name, "Firefox", "The browser field must be set");
   is(har.log.pages.length, 1, "There must be one page");
   is(har.log.entries.length, 1, "There must be one request");
 
   let page = har.log.pages[0];
-  ok(page.pageTimings.onContentLoad > 0, "There must be onContentLoad time");
-  ok(page.pageTimings.onLoad > 0, "There must be onLoad time");
+  ok("onContentLoad" in page.pageTimings, "There must be onContentLoad time");
+  ok("onLoad" in page.pageTimings, "There must be onLoad time");
 
   let entry = har.log.entries[0];
   is(entry.request.method, "GET", "Check the method");
   is(entry.request.url, SIMPLE_URL, "Check the URL");
   is(entry.request.headers.length, 9, "Check number of request headers");
   is(entry.response.status, 200, "Check response status");
   is(entry.response.statusText, "OK", "Check response status text");
   is(entry.response.headers.length, 6, "Check number of response headers");
--- a/devtools/client/netmonitor/test/browser_net_status-bar.js
+++ b/devtools/client/netmonitor/test/browser_net_status-bar.js
@@ -10,16 +10,18 @@ add_task(async () => {
   let { tab, monitor } = await initNetMonitor(SIMPLE_URL);
   info("Starting test... ");
 
   let { document, store, windowRequire } = monitor.panelWin;
   let Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
 
   store.dispatch(Actions.batchEnable(false));
 
+  await SpecialPowers.pushPrefEnv({ "set": [["privacy.reduceTimerPrecision", false]]});
+
   let requestsDone = waitForAllRequestsFinished(monitor);
   let markersDone = waitForTimelineMarkers(monitor);
   tab.linkedBrowser.reload();
   await Promise.all([requestsDone, markersDone]);
 
   let statusBar = document.querySelector(".devtools-toolbar-bottom");
   let requestCount = statusBar.querySelector(".requests-list-network-summary-count");
   let size = statusBar.querySelector(".requests-list-network-summary-transfer");
--- a/devtools/client/sourceeditor/test/browser_codemirror.js
+++ b/devtools/client/sourceeditor/test/browser_codemirror.js
@@ -7,12 +7,29 @@
 const URI = "chrome://mochitests/content/browser/devtools/client/" +
             "sourceeditor/test/codemirror/codemirror.html";
 loadHelperScript("helper_codemirror_runner.js");
 
 function test() {
   requestLongerTimeout(3);
   waitForExplicitFinish();
 
-  addTab(URI).then(function (tab) {
-    runCodeMirrorTest(tab.linkedBrowser);
-  });
+  /*
+   * In devtools/client/sourceeditor/test/codemirror/search_test.js there is a test
+   * multilineInsensitiveSlow which assumes an operation takes less than 100ms.
+   * With a precision of 100ms, if we get unlikely and begin execution towards the
+   * end of one spot (e.g. at 95 ms) we will clamp down, take (e.g.) 10ms to execute
+   * and it will appear to take 100ms.
+   *
+   * To avoid this, we hardcode to 2ms of precision.
+   *
+   * In theory we don't need to set the pref for all of CodeMirror, in practice
+   * it seems very difficult to set a pref for just one of the tests.
+   */
+  SpecialPowers.pushPrefEnv(
+    { set: [["privacy.reduceTimerPrecision", true],
+            ["privacy.resistFingerprinting.reduceTimerPrecision.microseconds", 2000]]},
+    function () {
+      addTab(URI).then(function (tab) {
+        runCodeMirrorTest(tab.linkedBrowser);
+      });
+    });
 }
--- a/devtools/server/tests/browser/browser_perf-samples-01.js
+++ b/devtools/server/tests/browser/browser_perf-samples-01.js
@@ -9,16 +9,17 @@
 "use strict";
 
 // time in ms
 const WAIT_TIME = 1000;
 
 const { PerformanceFront } = require("devtools/shared/fronts/performance");
 
 add_task(function* () {
+  yield SpecialPowers.pushPrefEnv({"set": [["privacy.reduceTimerPrecision", false]]});
   yield addTab(MAIN_DOMAIN + "doc_perf.html");
 
   initDebuggerServer();
   let client = new DebuggerClient(DebuggerServer.connectPipe());
   let form = yield connectDebuggerClient(client);
   let front = PerformanceFront(client, form);
   yield front.connect();
 
--- a/devtools/server/tests/mochitest/memory-helpers.js
+++ b/devtools/server/tests/mochitest/memory-helpers.js
@@ -7,18 +7,21 @@ const Services = require("Services");
 const { Task } = require("devtools/shared/task");
 const { DebuggerClient } = require("devtools/shared/client/debugger-client");
 const { DebuggerServer } = require("devtools/server/main");
 
 const { MemoryFront } = require("devtools/shared/fronts/memory");
 
 // Always log packets when running tests.
 Services.prefs.setBoolPref("devtools.debugger.log", true);
+var gReduceTimePrecision = Services.prefs.getBoolPref("privacy.reduceTimerPrecision");
+Services.prefs.setBoolPref("privacy.reduceTimerPrecision", false);
 SimpleTest.registerCleanupFunction(function () {
   Services.prefs.clearUserPref("devtools.debugger.log");
+  Services.prefs.setBoolPref("privacy.reduceTimerPrecision", gReduceTimePrecision);
 });
 
 function startServerAndGetSelectedTabMemory() {
   DebuggerServer.init();
   DebuggerServer.registerAllActors();
   let client = new DebuggerClient(DebuggerServer.connectPipe());
 
   return client.connect()
--- a/docshell/test/chrome/test_bug453650.xul
+++ b/docshell/test/chrome/test_bug453650.xul
@@ -55,29 +55,29 @@ https://bugzilla.mozilla.org/show_bug.cg
       reflow: function (start, end) {
         if (interruptible) {
           ok(false, "expected interruptible reflow");
         } else {
           ok(true, "observed uninterruptible reflow");
         }
 
         info("times: " + start + ", " + end);
-        ok(start < end, "reflow start time lower than end time");
+        ok(start <= end, "reflow start time lower than end time");
         done();
       },
 
       reflowInterruptible: function (start, end) {
         if (!interruptible) {
           ok(false, "expected uninterruptible reflow");
         } else {
           ok(true, "observed interruptible reflow");
         }
 
         info("times: " + start + ", " + end);
-        ok(start < end, "reflow start time lower than end time");
+        ok(start <= end, "reflow start time lower than end time");
         done();
       },
 
       QueryInterface: function (iid) {
         if (Ci.nsIReflowObserver.equals(iid) ||
             Ci.nsISupportsWeakReference.equals(iid) ||
             Ci.nsISupports.equals(iid))
           return this;
--- a/dom/animation/test/css-animations/test_event-dispatch.html
+++ b/dom/animation/test/css-animations/test_event-dispatch.html
@@ -2,14 +2,16 @@
 <meta charset=utf-8>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <div id="log"></div>
 <script>
 'use strict';
 setup({explicit_done: true});
 SpecialPowers.pushPrefEnv(
-  { "set": [["dom.animations-api.core.enabled", true]]},
+  { "set":
+  	  [["dom.animations-api.core.enabled", true],
+       ["privacy.reduceTimerPrecision", false]]},
   function() {
     window.open("file_event-dispatch.html");
   });
 </script>
 </html>
--- a/dom/animation/test/css-transitions/test_animation-starttime.html
+++ b/dom/animation/test/css-transitions/test_animation-starttime.html
@@ -2,15 +2,13 @@
 <meta charset=utf-8>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <div id="log"></div>
 <script>
 'use strict';
 setup({explicit_done: true});
 SpecialPowers.pushPrefEnv(
-  { "set":
-      [["dom.animations-api.core.enabled", true],
-       ["privacy.reduceTimerPrecision", false]]},
+  { "set": [["dom.animations-api.core.enabled", true]]},
   function() {
     window.open("file_animation-starttime.html");
   });
 </script>
--- a/dom/animation/test/document-timeline/test_document-timeline.html
+++ b/dom/animation/test/document-timeline/test_document-timeline.html
@@ -2,15 +2,13 @@
 <meta charset=utf-8>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <div id="log"></div>
 <script>
 'use strict';
 setup({explicit_done: true});
 SpecialPowers.pushPrefEnv(
-  { "set":
-      [["dom.animations-api.core.enabled", true],
-       ["privacy.reduceTimerPrecision", false]]},
+  { "set": [["dom.animations-api.core.enabled", true]]},
   function() {
     window.open("file_document-timeline.html");
   });
 </script>
--- a/dom/animation/test/mozilla/test_transition_finish_on_compositor.html
+++ b/dom/animation/test/mozilla/test_transition_finish_on_compositor.html
@@ -1,14 +1,19 @@
 <!doctype html>
 <meta charset=utf-8>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <div id="log"></div>
 <script>
 'use strict';
 setup({explicit_done: true});
+// This test appears like it might get racey and cause a timeout with too low of a
+// precision, so we hardcode it to something reasonable.
 SpecialPowers.pushPrefEnv(
-  { "set": [["dom.animations-api.core.enabled", true]]},
+  { "set":
+      [["dom.animations-api.core.enabled", true],
+       ["privacy.reduceTimerPrecision", true],
+       ["privacy.resistFingerprinting.reduceTimerPrecision.microseconds", 2000]]},
   function() {
     window.open("file_transition_finish_on_compositor.html");
   });
 </script>
--- a/dom/base/test/test_bug403852.html
+++ b/dom/base/test/test_bug403852.html
@@ -16,20 +16,25 @@ https://bugzilla.mozilla.org/show_bug.cg
 </p>
 <div id="content" style="display: none">
 </div>
 
 <pre id="test">
 <script class="testbody" type="text/javascript">
 SimpleTest.waitForExplicitFinish();
 
-var url = SimpleTest.getTestFileURL("bug403852_fileOpener.js");
-var script = SpecialPowers.loadChromeScript(url);
-script.addMessageListener("file.opened", onOpened);
-script.sendAsyncMessage("file.open");
+var script = '';
+SpecialPowers.pushPrefEnv({ "set":
+      [["privacy.reduceTimerPrecision", false]]},
+  function() {
+    var url = SimpleTest.getTestFileURL("bug403852_fileOpener.js");
+    script = SpecialPowers.loadChromeScript(url);
+    script.addMessageListener("file.opened", onOpened);
+    script.sendAsyncMessage("file.open");
+});
 
 function onOpened(message) {
   var fileList = document.getElementById('fileList');
   SpecialPowers.wrap(fileList).mozSetFileArray([message.file]);
 
   // Make sure the file is accessible with indexed notation
   var domFile = fileList.files[0];
 
--- a/dom/events/test/test_eventTimeStamp.html
+++ b/dom/events/test/test_eventTimeStamp.html
@@ -33,19 +33,26 @@ https://bugzilla.mozilla.org/show_bug.cg
 "use strict";
 
 SimpleTest.waitForExplicitFinish();
 SimpleTest.requestFlakyTimeout("untriaged");
 
 // We don't use SpecialPowers.pushPrefEnv since it can delay the test
 // function until after the load event has fired which means we can't
 // test the timestamp of the load event.
-const kPrefName = "dom.event.highrestimestamp.enabled";
-var prevPrefValue = SpecialPowers.getBoolPref(kPrefName);
-SpecialPowers.setBoolPref(kPrefName, true);
+const kHighResTimestampsPrefName = "dom.event.highrestimestamp.enabled";
+var highRestimerPrevPrefValue = SpecialPowers.getBoolPref(kHighResTimestampsPrefName);
+SpecialPowers.setBoolPref(kHighResTimestampsPrefName, true);
+
+// This file performs tests that normalize the timeOrigin within a worker
+// and compare it to the page. When this occurs, time can appear to go backwards.
+// This is a known (and accepted) regression.
+const kReduceTimePrecisionPrefName = "privacy.reduceTimerPrecision";
+var reduceTimePrecisionPrevPrefValue = SpecialPowers.getBoolPref(kReduceTimePrecisionPrefName);
+SpecialPowers.setBoolPref(kReduceTimePrecisionPrefName, false);
 testRegularEvents();
 
 // Event.timeStamp should be relative to the time origin which is:
 //
 //   Non-worker context: navigation start
 //   Dedicated worker: navigation start of the document that created the worker
 //   Shared worker: creation time of the shared worker
 //
@@ -106,16 +113,17 @@ function testSharedWorkerEvents() {
       finishTests();
     };
     worker.port.start();
     worker.port.postMessage("");
   }, 500);
 }
 
 var finishTests = function() {
-  SpecialPowers.setBoolPref(kPrefName, prevPrefValue);
+  SpecialPowers.setBoolPref(kHighResTimestampsPrefName, highRestimerPrevPrefValue);
+  SpecialPowers.setBoolPref(kReduceTimePrecisionPrefName, reduceTimePrecisionPrevPrefValue);
   SimpleTest.finish();
 };
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/test/test_background_video_suspend.html
+++ b/dom/media/test/test_background_video_suspend.html
@@ -18,19 +18,20 @@ function testDelay(v, start, min) {
   ok(delay > min, `${v.token} suspended with a delay of ${delay} ms`);
 }
 
 startTest({
   desc: 'Test Background Video Suspends',
   prefs: [
     [ "media.test.video-suspend", true ],
     [ "media.suspend-bkgnd-video.enabled", true ],
-    // User a short delay to ensure video decode suspend happens before end
+    // Use a short delay to ensure video decode suspend happens before end
     // of video.
-    [ "media.suspend-bkgnd-video.delay-ms", MIN_DELAY ]
+    [ "media.suspend-bkgnd-video.delay-ms", MIN_DELAY ],
+    [ "privacy.reduceTimerPrecision", false ]
   ],
   tests: gDecodeSuspendTests,
   runTest: (test, token) => {
     let v = appendVideoToDoc(test.name, token);
     manager.started(token);
 
     let start;
     waitUntilPlaying(v)
--- a/dom/media/tests/mochitest/test_peerConnection_audioContributingSources.html
+++ b/dom/media/tests/mochitest/test_peerConnection_audioContributingSources.html
@@ -115,14 +115,17 @@
 
   var test;
   runNetworkTest(function(options) {
     test = new PeerConnectionTest(options);
     test.chain.insertAfter("PC_REMOTE_WAIT_FOR_MEDIA_FLOW",
       [testGetContributingSources]);
     test.setMediaConstraints([{audio: true}], [{audio: true}]);
     test.pcLocal.audioElementsOnly = true;
-    test.run();
+    SpecialPowers.pushPrefEnv(
+    { "set": [["privacy.reduceTimerPrecision", false]]}, function() {
+      test.run();
+    });
   });
 </script>
 </pre>
 </body>
 </html>
--- a/dom/performance/tests/test_performance_user_timing.html
+++ b/dom/performance/tests/test_performance_user_timing.html
@@ -29,17 +29,21 @@
                          is(performance.getEntriesByType("mark").length, 0, "clearing performance mark entries");
                          is(performance.getEntriesByType("measure").length, 0, "clearing performance measure entries");
                          steps[i]();
                      } catch(ex) {
                          ok(false, "Caught exception", ex);
                      }
                  }
 
+                SpecialPowers.setBoolPref("privacy.reduceTimerPrecision", reduceTimePrecisionPrevPrefValue);
                 SimpleTest.finish();
              }
 
+             var reduceTimePrecisionPrevPrefValue = SpecialPowers.getBoolPref("privacy.reduceTimerPrecision");
+             SpecialPowers.setBoolPref("privacy.reduceTimerPrecision", false);
+
              SimpleTest.waitForExplicitFinish();
              addLoadEvent(next);
             </script>
         </pre>
     </body>
 </html>
--- a/dom/performance/tests/test_sharedWorker_performance_user_timing.html
+++ b/dom/performance/tests/test_sharedWorker_performance_user_timing.html
@@ -10,18 +10,21 @@
     <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   </head>
   <body>
     <script class="testbody" type="text/javascript">
 
 var sw = new SharedWorker('sharedworker_performance_user_timing.js');
 sw.port.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);
   }
 }
 
+var reduceTimePrecisionPrevPrefValue = SpecialPowers.getBoolPref("privacy.reduceTimerPrecision");
+SpecialPowers.setBoolPref("privacy.reduceTimerPrecision", false);
 SimpleTest.waitForExplicitFinish();
     </script>
   </body>
 </html>
--- a/dom/performance/tests/test_timeOrigin.html
+++ b/dom/performance/tests/test_timeOrigin.html
@@ -47,22 +47,31 @@ function testSharedWorker() {
     ok (e.data.now + e.data.timeOrigin > now + performance.timeOrigin, "Comparing worker.now and window.now");
     next();
   }
 }
 
 var tests = [ testBasic, testWorker, testSharedWorker ];
 function next() {
   if (!tests.length) {
+    SpecialPowers.setBoolPref("privacy.reduceTimerPrecision", reduceTimePrecisionPrevPrefValue);
     SimpleTest.finish();
     return;
   }
 
   var test = tests.shift();
   test();
 }
 
 SimpleTest.waitForExplicitFinish();
+
+// It is a known issue that comparing time between a worker and a window
+// when timer clamping is in effect may cause time to go backwards.
+// Do not run this test with this preference set. For large values of
+// clamping you will see failures. For small values, it is intermitant.
+var reduceTimePrecisionPrevPrefValue = SpecialPowers.getBoolPref("privacy.reduceTimerPrecision");
+SpecialPowers.setBoolPref("privacy.reduceTimerPrecision", false);
+
 addLoadEvent(next);
       </script>
     </pre>
   </body>
 </html>
--- a/dom/performance/tests/test_worker_performance_entries.html
+++ b/dom/performance/tests/test_worker_performance_entries.html
@@ -6,24 +6,32 @@
   <title>PerformanceResouceTiming in workers</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
+
+// The worker assumes it will take some amount of time to load a resource.
+// With a low enough precision, the duration to load a resource may clamp
+// down to zero.
+var reduceTimePrecisionPrevPrefValue = SpecialPowers.getBoolPref("privacy.reduceTimerPrecision");
+SpecialPowers.setBoolPref("privacy.reduceTimerPrecision", false);
+
 var worker = new Worker('test_worker_performance_entries.js');
 worker.onmessage = function(event) {
   if (event.data.type == "check") {
     ok(event.data.status, event.data.msg);
     return;
   }
 
   if (event.data.type == "finish") {
+    SpecialPowers.setBoolPref("privacy.reduceTimerPrecision", reduceTimePrecisionPrevPrefValue);
     SimpleTest.finish();
     return;
   }
 
   ok(false, "?!?");
 }
 
 </script>
--- a/dom/performance/tests/test_worker_performance_now.html
+++ b/dom/performance/tests/test_worker_performance_now.html
@@ -6,19 +6,24 @@
   <title>Validate Interfaces Exposed to Workers</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <script class="testbody" type="text/javascript">
 
 SimpleTest.waitForExplicitFinish();
+
+var reduceTimePrecisionPrevPrefValue = SpecialPowers.getBoolPref("privacy.reduceTimerPrecision");
+SpecialPowers.setBoolPref("privacy.reduceTimerPrecision", false);
+
 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',
--- a/dom/performance/tests/test_worker_user_timing.html
+++ b/dom/performance/tests/test_worker_user_timing.html
@@ -10,18 +10,21 @@
     <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   </head>
   <body>
     <script class="testbody" type="text/javascript">
 
 var worker = new Worker('worker_performance_user_timing.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);
   }
 }
 
+var reduceTimePrecisionPrevPrefValue = SpecialPowers.getBoolPref("privacy.reduceTimerPrecision");
+SpecialPowers.setBoolPref("privacy.reduceTimerPrecision", false);
 SimpleTest.waitForExplicitFinish();
     </script>
   </body>
 </html>
--- a/dom/smil/test/test_smilTimeEvents.xhtml
+++ b/dom/smil/test/test_smilTimeEvents.xhtml
@@ -232,18 +232,23 @@ function handleOnEnd(evt)
 function sanityCheckEvent(evt)
 {
   is(evt.target, gAnim, "Unexpected event target");
   is(evt.currentTarget, gAnim, "Unexpected event current target");
   is(evt.eventPhase, evt.AT_TARGET);
   is(evt.bubbles, false, "Event should not bubble");
   is(evt.cancelable, false, "Event should not be cancelable");
   if (SpecialPowers.getBoolPref("dom.event.highrestimestamp.enabled")) {
+    var lessThanOrEqualsAllowed = SpecialPowers.getBoolPref("privacy.reduceTimerPrecision");
     var now = window.performance.now();
-    ok(evt.timeStamp > 0 && evt.timeStamp < now,
+    ok(evt.timeStamp > 0 &&
+       (
+        (evt.timeStamp < now && !lessThanOrEqualsAllowed) ||
+        (evt.timeStamp <= now && lessThanOrEqualsAllowed)
+       ),
        "Event timeStamp (" + evt.timeStamp + ") should be > 0 but " +
        "before the current time (" + now + ")");
   } else {
     is(evt.timeStamp, 0, "Event timeStamp should be 0");
   }
   ok(evt.view !== null, "Event view not set");
 }
 
--- a/dom/tests/mochitest/ajax/jquery/test_jQuery.html
+++ b/dom/tests/mochitest/ajax/jquery/test_jQuery.html
@@ -1,15 +1,24 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <title>Test for jQuery</title>
   <script src="/MochiKit/Base.js"></script>
   <script src="/MochiKit/Async.js"></script>
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript">
+    // On Linux 64 Stylo Disabled, we observed a failure in the
+    // test 'stop() - several in queue' in fx.js with a low precision value.
+    // We specify a value that seems safe. The root cause of this issue is
+    // believed to be jQuery's use of new Date as a mechanism to advance animations.
+  	SpecialPowers.pushPrefEnv({set:
+      [["privacy.reduceTimerPrecision", true],
+       ["privacy.resistFingerprinting.reduceTimerPrecision.microseconds", 2000]]});
+  </script>
   <script type="text/javascript" src="../lib/AJAX_setup.js"></script>         
   <link rel="stylesheet" type="text/css" href="../lib/test.css" />
 </head>
 <body>
   <iframe width="100%" height="500" id="testframe" src=""></iframe>
 </body>
 </html>
 
--- a/dom/tests/mochitest/general/test_performance_now.html
+++ b/dom/tests/mochitest/general/test_performance_now.html
@@ -9,16 +9,18 @@
 <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");
 
     // 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
@@ -53,14 +55,15 @@
 
       // 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);
       SimpleTest.finish();
     };
     setTimeout(checkAfterTimeout, 1);
   </script>
 </body>
 </html>
--- a/dom/tests/mochitest/general/test_resource_timing.html
+++ b/dom/tests/mochitest/general/test_resource_timing.html
@@ -15,17 +15,19 @@ https://bugzilla.mozilla.org/show_bug.cg
 <body>
 
 <pre id="test">
 <script type="application/javascript">
 
 SimpleTest.waitForExplicitFinish();
 
 // Resource timing is prefed off by default, so we had to use this workaround
-SpecialPowers.pushPrefEnv({"set": [["dom.enable_resource_timing", true]]}, start);
+SpecialPowers.pushPrefEnv({"set": [
+	["dom.enable_resource_timing", true],
+	["privacy.reduceTimerPrecision", false]]}, start);
 var subwindow = null;
 
 function start() {
   subwindow = window.open("resource_timing_main_test.html");
 }
 
 function finishTests() {
   subwindow.close();
--- a/dom/tests/mochitest/general/test_resource_timing_cross_origin.html
+++ b/dom/tests/mochitest/general/test_resource_timing_cross_origin.html
@@ -16,17 +16,19 @@ https://bugzilla.mozilla.org/show_bug.cg
 
 <pre id="test">
 <script type="application/javascript">
 
 SimpleTest.waitForExplicitFinish();
 
 // Resource timing is prefed off by default, so we had to use this workaround
 var subwindow = null;
-SpecialPowers.pushPrefEnv({"set": [["dom.enable_resource_timing", true]]}, start);
+SpecialPowers.pushPrefEnv({"set": [
+  ["dom.enable_resource_timing", true],
+  ["privacy.reduceTimerPrecision", false]]}, start);
 
 function start() {
   subwindow = window.open("resource_timing_cross_origin.html");
 }
 
 function finishTests() {
   subwindow.close();
   SpecialPowers.pushPrefEnv({"clear":[["dom.enable_resource_timing"]]}, SimpleTest.finish);
--- a/layout/reftests/svg/smil/reftest.list
+++ b/layout/reftests/svg/smil/reftest.list
@@ -263,25 +263,29 @@ fuzzy-if(cocoaWidget&&layersGPUAccelerat
 == smil-transitions-interaction-3a.svg lime.svg
 == smil-transitions-interaction-3b.svg lime.svg
 == smil-transitions-interaction-4a.svg lime.svg
 == smil-transitions-interaction-4b.svg lime.svg
 
 # Test filtering of excessive times
 == filtered-instance-time-1.svg anim-standard-ref.svg
 
+# Animation tests disable reduceTimerPrecision because they use a screenshot
+# mechanism that relies on performance.now(), and on low precision that can be
+# finnicky.
+
 # Test animation using defs element
-== anim-defs-gradient-property.svg lime.svg
-== anim-defs-gradient-attribute.svg lime.svg
-== anim-defs-fill.svg lime.svg
-== anim-defs-width.svg lime.svg
+pref(privacy.reduceTimerPrecision,false) == anim-defs-gradient-property.svg lime.svg
+pref(privacy.reduceTimerPrecision,false) == anim-defs-gradient-attribute.svg lime.svg
+pref(privacy.reduceTimerPrecision,false) == anim-defs-fill.svg lime.svg
+pref(privacy.reduceTimerPrecision,false) == anim-defs-width.svg lime.svg
 
 # Test animation that changes 'display' attribute
-== anim-display.svg lime.svg
-== anim-display-in-g-element.svg lime.svg
+pref(privacy.reduceTimerPrecision,false) == anim-display.svg lime.svg
+pref(privacy.reduceTimerPrecision,false) == anim-display-in-g-element.svg lime.svg
 
 # Test animation that change 'display' style value to 'none'
 == anim-change-display-none-for-ancestor-elem.html lime.html
 == anim-change-display-none-for-target-elem.html lime.html
 == anim-change-display-none-for-dynamically-appended-elem.html lime.html
 == anim-change-display-block-for-dynamically-appended-elem.html anim-standard-ref.html
 
 fuzzy(63,146) == anim-clipPath-viewBox.svg anim-clipPath-viewBox-ref.svg
--- a/security/manager/ssl/tests/unit/test_baseline_requirements_subject_common_name.js
+++ b/security/manager/ssl/tests/unit/test_baseline_requirements_subject_common_name.js
@@ -35,18 +35,21 @@ function checkCertOn25August2016(cert, e
                               certificateUsageSSLServer, VALIDATION_TIME, {},
                               "example.com");
 }
 
 function run_test() {
   registerCleanupFunction(() => {
     Services.prefs.clearUserPref("security.pki.name_matching_mode");
     Services.prefs.clearUserPref("security.test.built_in_root_hash");
+    Services.prefs.clearUserPref("privacy.reduceTimerPrecision");
   });
 
+  Services.prefs.setBoolPref("privacy.reduceTimerPrecision", false);
+
   loadCertWithTrust("ca", "CTu,,");
 
   // When verifying a certificate, if the trust anchor is not a built-in root,
   // name matching will fall back to using the subject common name if necessary
   // (i.e. if there is no subject alternative name extension or it does not
   // contain any dNSName or iPAddress entries). Thus, since imported roots are
   // not in general treated as built-ins, these should all successfully verify
   // regardless of the value of the pref.
--- a/security/manager/ssl/tests/unit/test_cert_eku.js
+++ b/security/manager/ssl/tests/unit/test_cert_eku.js
@@ -28,17 +28,23 @@ function checkEndEntity(cert, expectedRe
 
 function checkCertOn25August2016(cert, expectedResult) {
   // (new Date("2016-08-25T00:00:00Z")).getTime() / 1000
   const VALIDATION_TIME = 1472083200;
   checkCertErrorGenericAtTime(certdb, cert, expectedResult,
                               certificateUsageSSLServer, VALIDATION_TIME);
 }
 
+
 function run_test() {
+  registerCleanupFunction(() => {
+    Services.prefs.clearUserPref("privacy.reduceTimerPrecision");
+  });
+  Services.prefs.setBoolPref("privacy.reduceTimerPrecision", false);
+
   loadCertWithTrust("ca", "CTu,,");
   // end-entity has id-kp-serverAuth => success
   checkEndEntity(certFromFile("ee-SA"), PRErrorCodeSuccess);
   // end-entity has id-kp-serverAuth => success
   checkEndEntity(certFromFile("ee-SA-CA"), PRErrorCodeSuccess);
   // end-entity has extended key usage, but id-kp-serverAuth is not present =>
   // failure
   checkEndEntity(certFromFile("ee-CA"), SEC_ERROR_INADEQUATE_CERT_TYPE);
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/hr-time/__dir__.ini
@@ -0,0 +1,1 @@
+prefs: [privacy.reduceTimerPrecision:false]
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/intersection-observer/timestamp.html.ini
@@ -0,0 +1,1 @@
+prefs: [privacy.reduceTimerPrecision:false]
--- a/testing/web-platform/meta/media-source/mediasource-getvideoplaybackquality.html.ini
+++ b/testing/web-platform/meta/media-source/mediasource-getvideoplaybackquality.html.ini
@@ -1,4 +1,5 @@
+prefs: [privacy.reduceTimerPrecision:false]
 [mediasource-getvideoplaybackquality.html]
   [Test the totalFrameDelay attribute of HTMLVideoElement.getVideoPlaybackQuality() with MediaSource API]
     expected: FAIL
 
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/navigation-timing/nav2_test_redirect_server.html.ini
@@ -0,0 +1,1 @@
+prefs: [privacy.reduceTimerPrecision:false]
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/requestidlecallback/basic.html.ini
@@ -0,0 +1,1 @@
+prefs: [privacy.reduceTimerPrecision:false]
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/resource-timing/__dir__.ini
@@ -0,0 +1,1 @@
+prefs: [privacy.reduceTimerPrecision:false]
\ No newline at end of file
--- a/testing/web-platform/meta/service-workers/service-worker/performance-timeline.https.html.ini
+++ b/testing/web-platform/meta/service-workers/service-worker/performance-timeline.https.html.ini
@@ -1,5 +1,6 @@
+prefs: [privacy.reduceTimerPrecision:false]
 [performance-timeline.https.html]
   expected: TIMEOUT
   [Resource Timing]
     expected: TIMEOUT
 
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/service-workers/service-worker/resource-timing.https.html.ini
@@ -0,0 +1,1 @@
+prefs: [privacy.reduceTimerPrecision:false]
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/user-timing/__dir__.ini
@@ -0,0 +1,1 @@
+prefs: [privacy.reduceTimerPrecision:false]
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/workers/WorkerPerformanceNow.html.ini
@@ -0,0 +1,1 @@
+prefs: [privacy.reduceTimerPrecision:false]
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/workers/semantics/navigation/002.html.ini
@@ -0,0 +1,1 @@
+prefs: [privacy.reduceTimerPrecision:false]
--- a/testing/web-platform/meta/workers/worker-performance.worker.js.ini
+++ b/testing/web-platform/meta/workers/worker-performance.worker.js.ini
@@ -1,4 +1,5 @@
+prefs: [privacy.reduceTimerPrecision:false]
 [worker-performance.worker.html]
   [performance.toJSON is available in workers]
     expected: FAIL