--- a/browser/components/extensions/test/xpcshell/test_ext_browsingData_cookies_cache.js
+++ b/browser/components/extensions/test/xpcshell/test_ext_browsingData_cookies_cache.js
@@ -78,16 +78,30 @@ add_task(async function testCache() {
await testRemovalMethod("removeCache");
await testRemovalMethod("remove");
await extension.unload();
});
add_task(async function testCookies() {
+ // Above in setUpCookies we create an 'old' cookies, wait 10ms, then log a timestamp.
+ // Here we ask the browser to delete all cookies after the timestamp, with the intention
+ // that the 'old' cookie is not removed. The issue arises when the timer precision is
+ // low enough such that the timestamp that gets logged is the same as the 'old' cookie.
+ // We hardcode a precision value to ensure that there is time between the 'old' cookie
+ // and the timestamp generation.
+ Services.prefs.setBoolPref("privacy.reduceTimerPrecision", true);
+ Services.prefs.setIntPref("privacy.resistFingerprinting.reduceTimerPrecision.microseconds", 2000);
+
+ registerCleanupFunction(function() {
+ Services.prefs.clearUserPref("privacy.reduceTimerPrecision");
+ Services.prefs.clearUserPref("privacy.resistFingerprinting.reduceTimerPrecision.microseconds");
+ });
+
function background() {
browser.test.onMessage.addListener(async (msg, options) => {
if (msg == "removeCookies") {
await browser.browsingData.removeCookies(options);
} else {
await browser.browsingData.remove(options, {cookies: true});
}
browser.test.sendMessage("cookiesRemoved");
--- a/browser/extensions/formautofill/test/unit/test_addressRecords.js
+++ b/browser/extensions/formautofill/test/unit/test_addressRecords.js
@@ -249,16 +249,19 @@ const MERGE_TESTCASES = [
"given-name": "Timothy",
"street-address": "331 E. Evelyn Avenue\nLine2\nLine3",
"tel": "+16509030800",
country: "US",
},
},
];
+ChromeUtils.defineModuleGetter(this, "Preferences",
+ "resource://gre/modules/Preferences.jsm");
+
let do_check_record_matches = (recordWithMeta, record) => {
for (let key in record) {
Assert.equal(recordWithMeta[key], record[key]);
}
};
add_task(async function test_initialize() {
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME);
@@ -364,16 +367,26 @@ add_task(async function test_add() {
Assert.throws(() => profileStorage.addresses.add({}),
/Record contains no valid field\./);
Assert.throws(() => profileStorage.addresses.add(TEST_ADDRESS_EMPTY_AFTER_NORMALIZE),
/Record contains no valid field\./);
});
add_task(async function test_update() {
+ // Test assumes that when an entry is saved a second time, it's last modified date will
+ // be different from the first. With high values of precision reduction, we execute too
+ // fast for that to be true.
+ let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
+ Preferences.set("privacy.reduceTimerPrecision", false);
+
+ registerCleanupFunction(function() {
+ Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
+ });
+
let profileStorage = await initProfileStorage(TEST_STORE_FILE_NAME,
[TEST_ADDRESS_1, TEST_ADDRESS_2]);
let addresses = profileStorage.addresses.getAll();
let guid = addresses[1].guid;
let timeLastModified = addresses[1].timeLastModified;
let onChanged = TestUtils.topicObserved(
--- a/browser/extensions/formautofill/test/unit/test_creditCardRecords.js
+++ b/browser/extensions/formautofill/test/unit/test_creditCardRecords.js
@@ -1,15 +1,17 @@
/**
* Tests FormAutofillStorage object with creditCards records.
*/
"use strict";
const {FormAutofillStorage} = ChromeUtils.import("resource://formautofill/FormAutofillStorage.jsm", {});
+ChromeUtils.defineModuleGetter(this, "Preferences",
+ "resource://gre/modules/Preferences.jsm");
const TEST_STORE_FILE_NAME = "test-credit-card.json";
const COLLECTION_NAME = "creditCards";
const TEST_CREDIT_CARD_1 = {
"cc-name": "John Doe",
"cc-number": "1234567812345678",
"cc-exp-month": 4,
@@ -285,16 +287,26 @@ add_task(async function test_add() {
Assert.throws(() => profileStorage.creditCards.add({}),
/Record contains no valid field\./);
Assert.throws(() => profileStorage.creditCards.add(TEST_CREDIT_CARD_EMPTY_AFTER_NORMALIZE),
/Record contains no valid field\./);
});
add_task(async function test_update() {
+ // Test assumes that when an entry is saved a second time, it's last modified date will
+ // be different from the first. With high values of precision reduction, we execute too
+ // fast for that to be true.
+ let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
+ Preferences.set("privacy.reduceTimerPrecision", false);
+
+ registerCleanupFunction(function() {
+ Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
+ });
+
let path = getTempFile(TEST_STORE_FILE_NAME).path;
await prepareTestCreditCards(path);
let profileStorage = new FormAutofillStorage(path);
await profileStorage.initialize();
let creditCards = profileStorage.creditCards.getAll();
let guid = creditCards[1].guid;
--- a/devtools/server/tests/unit/test_promises_object_creationtimestamp.js
+++ b/devtools/server/tests/unit/test_promises_object_creationtimestamp.js
@@ -6,17 +6,27 @@
*/
"use strict";
const { PromisesFront } = require("devtools/shared/fronts/promises");
var EventEmitter = require("devtools/shared/event-emitter");
+ChromeUtils.defineModuleGetter(this, "Preferences",
+ "resource://gre/modules/Preferences.jsm");
+
add_task(function* () {
+ let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
+ Preferences.set("privacy.reduceTimerPrecision", false);
+
+ registerCleanupFunction(function () {
+ Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
+ });
+
let client = yield startTestDebuggerServer("promises-object-test");
let chromeActors = yield getChromeActors(client);
ok(Promise.toString().includes("native code"), "Expect native DOM Promise.");
// We have to attach the chrome TabActor before playing with the PromiseActor
yield attachTab(client, chromeActors);
yield testPromiseCreationTimestamp(client, chromeActors, v => {
@@ -58,14 +68,15 @@ function* testPromiseCreationTimestamp(c
let end = Date.now();
let grip = yield onNewPromise;
ok(grip, "Found our new promise.");
let creationTimestamp = grip.promiseState.creationTimestamp;
ok(start - 1 <= creationTimestamp && creationTimestamp <= end + 1,
- "Expect promise creation timestamp to be within elapsed time range.");
+ "Expect promise creation timestamp to be within elapsed time range: " +
+ (start - 1) + " <= " + creationTimestamp + " <= " + (end + 1));
yield front.detach();
// Appease eslint
void promise;
}
--- a/netwerk/test/unit/test_race_cache_with_network.js
+++ b/netwerk/test/unit/test_race_cache_with_network.js
@@ -75,16 +75,31 @@ function run_test() {
httpserver.registerPathHandler("/rcwn", test_handler);
httpserver.registerPathHandler("/rcwn_cached", cached_handler);
testGenerator.next();
do_test_pending();
}
let testGenerator = testSteps();
function *testSteps() {
+ /*
+ * In this test, we have a relatively low timeout of 200ms and an assertion that
+ * the timer works properly by checking that the time was greater than 200ms.
+ * With a timer precision of 100ms (for example) we will clamp downwards to 200
+ * and cause the assertion to fail. To resolve this, we hardcode a precision of
+ * 20ms.
+ */
+ Services.prefs.setBoolPref("privacy.reduceTimerPrecision", true);
+ Services.prefs.setIntPref("privacy.resistFingerprinting.reduceTimerPrecision.microseconds", 20000);
+
+ registerCleanupFunction(function() {
+ Services.prefs.clearUserPref("privacy.reduceTimerPrecision");
+ Services.prefs.clearUserPref("privacy.resistFingerprinting.reduceTimerPrecision.microseconds");
+ });
+
// Initial request. Stores the response in the cache.
var channel = make_channel("http://localhost:" + PORT + "/rcwn");
channel.asyncOpen2(new ChannelListener(checkContent, null));
yield undefined;
equal(gResponseCounter, 1);
equal(g200Counter, 1, "check number of 200 responses");
equal(g304Counter, 0, "check number of 304 responses");
--- a/services/fxaccounts/tests/xpcshell/test_profile.js
+++ b/services/fxaccounts/tests/xpcshell/test_profile.js
@@ -255,16 +255,26 @@ add_test(function fetchAndCacheProfile_a
Assert.equal(fxa.profileCache.profile.avatar, cachedUrl);
run_next_test();
});
});
// Check that a new profile request within PROFILE_FRESHNESS_THRESHOLD of the
// last one doesn't kick off a new request to check the cached copy is fresh.
add_task(async function fetchAndCacheProfileAfterThreshold() {
+ /*
+ * This test was observed to cause a timeout for... any timer precision reduction.
+ * Even 1 us. Exact reason is still undiagnosed.
+ */
+ Services.prefs.setBoolPref("privacy.reduceTimerPrecision", false);
+
+ registerCleanupFunction(async () => {
+ Services.prefs.clearUserPref("privacy.reduceTimerPrecision");
+ });
+
let numFetches = 0;
let client = mockClient(mockFxa());
client.fetchProfile = async function() {
numFetches += 1;
return {body: {uid: ACCOUNT_UID, email: ACCOUNT_EMAIL, avatar: "myimg"}};
};
let profile = CreateFxAccountsProfile(null, client);
profile.PROFILE_FRESHNESS_THRESHOLD = 1000;
--- a/services/sync/tests/unit/test_addons_engine.js
+++ b/services/sync/tests/unit/test_addons_engine.js
@@ -6,16 +6,17 @@
ChromeUtils.import("resource://gre/modules/AddonManager.jsm");
ChromeUtils.import("resource://gre/modules/Preferences.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://services-common/async.js");
ChromeUtils.import("resource://services-sync/addonsreconciler.js");
ChromeUtils.import("resource://services-sync/engines/addons.js");
ChromeUtils.import("resource://services-sync/service.js");
ChromeUtils.import("resource://services-sync/util.js");
+ChromeUtils.defineModuleGetter(this, "Preferences", "resource://gre/modules/Preferences.jsm");
const prefs = new Preferences();
prefs.set("extensions.getAddons.get.url",
"http://localhost:8888/search/guid:%IDS%");
prefs.set("extensions.install.requireSecureOrigin", false);
let engine;
let reconciler;
@@ -85,16 +86,23 @@ add_task(async function test_find_dupe()
dupe = await engine._findDupe(record);
Assert.equal(null, dupe);
await uninstallAddon(addon, reconciler);
await resetReconciler();
});
add_task(async function test_get_changed_ids() {
+ let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
+ Preferences.set("privacy.reduceTimerPrecision", false);
+
+ registerCleanupFunction(function() {
+ Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
+ });
+
_("Ensure getChangedIDs() has the appropriate behavior.");
_("Ensure getChangedIDs() returns an empty object by default.");
let changes = await engine.getChangedIDs();
Assert.equal("object", typeof(changes));
Assert.equal(0, Object.keys(changes).length);
_("Ensure tracker changes are populated.");
--- a/toolkit/components/extensions/test/xpcshell/test_ext_downloads_search.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_downloads_search.js
@@ -81,20 +81,22 @@ add_task(async function test_search() {
function downloadPath(filename) {
let path = downloadDir.clone();
path.append(filename);
return path.path;
}
Services.prefs.setIntPref("browser.download.folderList", 2);
Services.prefs.setComplexValue("browser.download.dir", nsIFile, downloadDir);
+ Services.prefs.setBoolPref("privacy.reduceTimerPrecision", false);
registerCleanupFunction(async () => {
Services.prefs.clearUserPref("browser.download.folderList");
Services.prefs.clearUserPref("browser.download.dir");
+ Services.prefs.clearUserPref("privacy.reduceTimerPrecision");
await cleanupDir(downloadDir);
await clearDownloads();
});
await clearDownloads().then(downloads => {
info(`removed ${downloads.length} pre-existing downloads from history`);
});
--- a/toolkit/components/places/tests/bookmarks/test_bookmarks_notifications.js
+++ b/toolkit/components/places/tests/bookmarks/test_bookmarks_notifications.js
@@ -1,11 +1,14 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
+ChromeUtils.defineModuleGetter(this, "Preferences",
+ "resource://gre/modules/Preferences.jsm");
+
add_task(async function insert_separator_notification() {
let observer = expectNotifications();
let bm = await PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
parentGuid: PlacesUtils.bookmarks.unfiledGuid});
let itemId = await PlacesUtils.promiseItemId(bm.guid);
let parentId = await PlacesUtils.promiseItemId(bm.parentGuid);
observer.check([ { name: "onItemAdded",
arguments: [ itemId, parentId, bm.index, bm.type,
@@ -103,16 +106,23 @@ add_task(async function insert_bookmark_
arguments: [ itemId, "tags", false, "",
PlacesUtils.toPRTime(bm.lastModified),
bm.type, parentId, bm.guid, bm.parentGuid, "",
Ci.nsINavBookmarksService.SOURCE_DEFAULT ] }
]);
});
add_task(async function update_bookmark_lastModified() {
+ let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
+ Preferences.set("privacy.reduceTimerPrecision", false);
+
+ registerCleanupFunction(function() {
+ Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
+ });
+
let bm = await PlacesUtils.bookmarks.insert({ type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
url: new URL("http://lastmod.example.com/") });
let observer = expectNotifications();
bm = await PlacesUtils.bookmarks.update({ guid: bm.guid,
lastModified: new Date() });
let itemId = await PlacesUtils.promiseItemId(bm.guid);
let parentId = await PlacesUtils.promiseItemId(bm.parentGuid);
--- a/toolkit/components/places/tests/bookmarks/test_keywords.js
+++ b/toolkit/components/places/tests/bookmarks/test_keywords.js
@@ -1,8 +1,11 @@
+ChromeUtils.defineModuleGetter(this, "Preferences",
+ "resource://gre/modules/Preferences.jsm");
+
const URI1 = NetUtil.newURI("http://test1.mozilla.org/");
const URI2 = NetUtil.newURI("http://test2.mozilla.org/");
const URI3 = NetUtil.newURI("http://test3.mozilla.org/");
async function check_keyword(aURI, aKeyword) {
if (aKeyword)
aKeyword = aKeyword.toLowerCase();
@@ -75,16 +78,23 @@ add_task(function test_invalid_input() {
/NS_ERROR_ILLEGAL_VALUE/);
Assert.throws(() => PlacesUtils.bookmarks.setKeywordForBookmark(null, "k"),
/NS_ERROR_ILLEGAL_VALUE/);
Assert.throws(() => PlacesUtils.bookmarks.setKeywordForBookmark(0, "k"),
/NS_ERROR_ILLEGAL_VALUE/);
});
add_task(async function test_addBookmarkAndKeyword() {
+ let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
+ Preferences.set("privacy.reduceTimerPrecision", false);
+
+ registerCleanupFunction(function() {
+ Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
+ });
+
await check_keyword(URI1, null);
let fc = await foreign_count(URI1);
let observer = expectNotifications();
let itemId =
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
URI1,
PlacesUtils.bookmarks.DEFAULT_INDEX,
@@ -123,16 +133,23 @@ add_task(async function test_addBookmark
Assert.equal((await foreign_count(URI1)), fc + 1); // + 1 bookmark
PlacesUtils.bookmarks.removeItem(itemId);
await PlacesTestUtils.promiseAsyncUpdates();
await check_orphans();
});
add_task(async function test_sameKeywordDifferentURI() {
+ let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
+ Preferences.set("privacy.reduceTimerPrecision", false);
+
+ registerCleanupFunction(function() {
+ Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
+ });
+
let fc1 = await foreign_count(URI1);
let fc2 = await foreign_count(URI2);
let observer = expectNotifications();
let itemId =
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
URI2,
PlacesUtils.bookmarks.DEFAULT_INDEX,
--- a/toolkit/components/places/tests/unit/test_async_transactions.js
+++ b/toolkit/components/places/tests/unit/test_async_transactions.js
@@ -7,16 +7,19 @@
const bmsvc = PlacesUtils.bookmarks;
const tagssvc = PlacesUtils.tagging;
const annosvc = PlacesUtils.annotations;
const PT = PlacesTransactions;
const rootGuid = PlacesUtils.bookmarks.rootGuid;
const menuGuid = PlacesUtils.bookmarks.menuGuid;
Components.utils.importGlobalProperties(["URL"]);
+ChromeUtils.defineModuleGetter(this, "Preferences",
+ "resource://gre/modules/Preferences.jsm");
+
// Create and add bookmarks observer.
var observer = {
__proto__: NavBookmarkObserver.prototype,
tagRelatedGuids: new Set(),
reset() {
@@ -1584,16 +1587,23 @@ add_task(async function test_copy() {
await redo();
// Cleanup. This also remove the original item.
await PT.undo();
observer.reset();
await PT.clearTransactionsHistory();
}
+ let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
+ Preferences.set("privacy.reduceTimerPrecision", false);
+
+ registerCleanupFunction(function() {
+ Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
+ });
+
// Test duplicating leafs (bookmark, separator, empty folder)
PT.NewBookmark({ url: new URL("http://test.item.duplicate"),
parentGuid: rootGuid,
annos: [{ name: "Anno", value: "AnnoValue"}] });
let sepTxn = PT.NewSeparator({ parentGuid: rootGuid, index: 1 });
let livemarkTxn = PT.NewLivemark(
{ feedUrl: new URL("http://test.feed.uri"),
parentGuid: rootGuid,
--- a/toolkit/components/places/tests/unit/test_keywords.js
+++ b/toolkit/components/places/tests/unit/test_keywords.js
@@ -1,10 +1,13 @@
"use strict";
+ChromeUtils.defineModuleGetter(this, "Preferences",
+ "resource://gre/modules/Preferences.jsm");
+
async function check_keyword(aExpectExists, aHref, aKeyword, aPostData = null) {
// Check case-insensitivity.
aKeyword = aKeyword.toUpperCase();
let entry = await PlacesUtils.keywords.fetch(aKeyword);
Assert.deepEqual(entry, await PlacesUtils.keywords.fetch({ keyword: aKeyword }));
@@ -170,16 +173,23 @@ add_task(async function test_addKeyword(
await check_keyword(true, "http://example.com/", "keyword");
await PlacesUtils.keywords.remove("keyword");
await check_keyword(false, "http://example.com/", "keyword");
await check_no_orphans();
});
add_task(async function test_addBookmarkAndKeyword() {
+ let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
+ Preferences.set("privacy.reduceTimerPrecision", false);
+
+ registerCleanupFunction(function() {
+ Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
+ });
+
await check_keyword(false, "http://example.com/", "keyword");
let fc = await foreign_count("http://example.com/");
let bookmark = await PlacesUtils.bookmarks.insert({ url: "http://example.com/",
parentGuid: PlacesUtils.bookmarks.unfiledGuid });
let observer = expectBookmarkNotifications();
await PlacesUtils.keywords.insert({ keyword: "keyword", url: "http://example.com/" });
--- a/toolkit/components/places/tests/unit/test_sync_utils.js
+++ b/toolkit/components/places/tests/unit/test_sync_utils.js
@@ -1,11 +1,13 @@
ChromeUtils.import("resource://gre/modules/ObjectUtils.jsm");
ChromeUtils.import("resource://gre/modules/PlacesSyncUtils.jsm");
ChromeUtils.import("resource://testing-common/httpd.js");
+ChromeUtils.defineModuleGetter(this, "Preferences",
+ "resource://gre/modules/Preferences.jsm");
Cu.importGlobalProperties(["URLSearchParams"]);
const DESCRIPTION_ANNO = "bookmarkProperties/description";
const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
const SYNC_PARENT_ANNO = "sync/parent";
var makeGuid = PlacesUtils.history.makeGuid;
@@ -2804,16 +2806,23 @@ add_task(async function test_remove_part
greatGrandChildNextSiblingBmk.recordId,
], "Should move descendants to closest living ancestor");
await PlacesUtils.bookmarks.eraseEverything();
await PlacesSyncUtils.bookmarks.reset();
});
add_task(async function test_migrateOldTrackerEntries() {
+ let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
+ Preferences.set("privacy.reduceTimerPrecision", false);
+
+ registerCleanupFunction(function() {
+ Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
+ });
+
let unknownBmk = await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.menuGuid,
url: "http://getfirefox.com",
title: "Get Firefox!",
});
let newBmk = await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.menuGuid,
url: "http://getthunderbird.com",
--- a/toolkit/components/satchel/test/unit/test_notify.js
+++ b/toolkit/components/satchel/test/unit/test_notify.js
@@ -1,16 +1,17 @@
/*
* Test suite for satchel notifications
*
* Tests notifications dispatched when modifying form history.
*
*/
ChromeUtils.defineModuleGetter(this, "setTimeout", "resource://gre/modules/Timer.jsm");
+ChromeUtils.defineModuleGetter(this, "Preferences", "resource://gre/modules/Preferences.jsm");
const TestObserver = {
observed: [],
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
observe(subject, topic, data) {
if (subject instanceof Ci.nsISupportsString) {
subject = subject.toString();
}
@@ -129,16 +130,23 @@ add_task(async function removeEntriesFor
count = await promiseCountEntries(null, null);
Assert.equal(count, 2, "the other entries are still there");
// Clean-up
await promiseUpdateEntry("remove", null, null);
});
add_task(async function removeEntriesByTimeframe() {
+ let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
+ Preferences.set("privacy.reduceTimerPrecision", false);
+
+ registerCleanupFunction(function() {
+ Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
+ });
+
await promiseAddEntry(entry1[0], entry1[1]);
await promiseAddEntry(entry2[0], entry2[1]);
const cutoffDate = Date.now();
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(res => setTimeout(res, 10));
await promiseAddEntry(entry3[0], entry3[1]);