Bug 1424341 Add tests for privacy.reduceTimerPrecision for the performance API draft
authorTom Ritter <tom@mozilla.com>
Tue, 12 Dec 2017 23:58:53 -0600
changeset 718836 dac8763669c1c6f0068f527edff612baa010bc8b
parent 718835 33d81b8b54039ca55625b5a98ec87002f804ac8f
child 718837 144429b6a7f5573d8b0e0ddaad1b22da3afe707f
push id95052
push userbmo:tom@mozilla.com
push dateWed, 10 Jan 2018 21:56:43 +0000
bugs1424341
milestone59.0a1
Bug 1424341 Add tests for privacy.reduceTimerPrecision for the performance API This commit also adds a test for secureConnectionStart which was missing, and rewords the error messages to be more readable when reviewing test failures. MozReview-Commit-ID: LpkRGe81eq1
browser/components/resistfingerprinting/test/browser/browser_performanceAPI.js
browser/components/resistfingerprinting/test/browser/file_workerPerformance.js
--- a/browser/components/resistfingerprinting/test/browser/browser_performanceAPI.js
+++ b/browser/components/resistfingerprinting/test/browser/browser_performanceAPI.js
@@ -12,74 +12,153 @@ const PERFORMANCE_TIMINGS = [
   "unloadEventEnd",
   "redirectStart",
   "redirectEnd",
   "fetchStart",
   "domainLookupStart",
   "domainLookupEnd",
   "connectStart",
   "connectEnd",
+  "secureConnectionStart",
   "requestStart",
   "responseStart",
   "responseEnd",
   "domLoading",
   "domInteractive",
   "domContentLoadedEventStart",
   "domContentLoadedEventEnd",
   "domComplete",
   "loadEventStart",
   "loadEventEnd",
 ];
 
-add_task(async function setup() {
+add_task(async function runRPTests() {
   await SpecialPowers.pushPrefEnv({"set":
-    [["privacy.resistFingerprinting", true]]
+    //Run one set of tests with both true to confirm p.rP overrides p.rTP
+    [["privacy.resistFingerprinting", true],
+     ["privacy.reduceTimerPrecision", true]]
   });
-});
 
-add_task(async function runTests() {
   let tab = await BrowserTestUtils.openNewForegroundTab(
     gBrowser, TEST_PATH + "file_dummy.html");
 
   await ContentTask.spawn(tab.linkedBrowser, PERFORMANCE_TIMINGS, async function(list) {
+    const isRounded = x => (Math.floor(x / 100) * 100) === x;
+
+    ok(isRounded(content.performance.timeOrigin), `For resistFingerprinting, performance.timeOrigin is not correctly rounded: ` + content.performance.timeOrigin);
+
     // Check that whether the performance timing API is correctly spoofed.
     for (let time of list) {
-      is(content.performance.timing[time], 0, `The timing(${time}) is correctly spoofed.`);
+      is(content.performance.timing[time], 0, `For resistFingerprinting, the timing(${time}) is not correctly spoofed.`);
     }
 
     // Try to add some entries.
     content.performance.mark("Test");
     content.performance.mark("Test-End");
     content.performance.measure("Test-Measure", "Test", "Test-End");
 
     // Check that no entries for performance.getEntries/getEntriesByType/getEntriesByName.
-    is(content.performance.getEntries().length, 0, "No entries for performance.getEntries()");
-    is(content.performance.getEntriesByType("resource").length, 0, "No entries for performance.getEntriesByType()");
-    is(content.performance.getEntriesByName("Test", "mark").length, 0, "No entries for performance.getEntriesByName()");
+    is(content.performance.getEntries().length, 0, "For resistFingerprinting, there should be no entries for performance.getEntries()");
+    is(content.performance.getEntriesByType("resource").length, 0, "For resistFingerprinting, there should be no entries for performance.getEntriesByType()");
+    is(content.performance.getEntriesByName("Test", "mark").length, 0, "For resistFingerprinting, there should be no entries for performance.getEntriesByName()");
 
   });
 
   await BrowserTestUtils.removeTab(tab);
 });
 
-add_task(async function runTestsForWorker() {
+add_task(async function runRPTestsForWorker() {
+  await SpecialPowers.pushPrefEnv({"set":
+    [["privacy.resistFingerprinting", true],
+     ["privacy.reduceTimerPrecision", false]]
+  });
+
   let tab = await BrowserTestUtils.openNewForegroundTab(
     gBrowser, TEST_PATH + "file_dummy.html");
 
   await ContentTask.spawn(tab.linkedBrowser, null, async function() {
     await 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") {
           resolve();
         } else {
           ok(false, "Unknown message type");
           resolve();
         }
       };
-      worker.postMessage({type: "runTests"});
+      worker.postMessage({type: "runRPTests"});
     });
   });
 
   await BrowserTestUtils.removeTab(tab);
 });
+
+add_task(async function runRTPTests() {
+  await SpecialPowers.pushPrefEnv({"set":
+    [["privacy.resistFingerprinting", false],
+     ["privacy.reduceTimerPrecision", true]]
+  });
+
+  let tab = await BrowserTestUtils.openNewForegroundTab(
+    gBrowser, TEST_PATH + "file_dummy.html");
+
+  await ContentTask.spawn(tab.linkedBrowser, PERFORMANCE_TIMINGS, async function(list) {
+    const isRounded = x => (Math.floor(x / 100) * 100) === x;
+
+    ok(isRounded(content.performance.timeOrigin), `For reduceTimerPrecision, performance.timeOrigin is not correctly rounded: ` + content.performance.timeOrigin);
+
+    // Check that whether the performance timing API is correctly spoofed.
+    for (let time of list) {
+      ok(isRounded(content.performance.timing[time]), `For reduceTimerPrecision, the timing(${time}) is not correctly rounded.`);
+    }
+
+    // Try to add some entries.
+    content.performance.mark("Test");
+    content.performance.mark("Test-End");
+    content.performance.measure("Test-Measure", "Test", "Test-End");
+
+    // Check that no entries for performance.getEntries/getEntriesByType/getEntriesByName.
+    is(content.performance.getEntries().length, 4, "For reduceTimerPrecision, there should be 4 entries for performance.getEntries()");
+    for(var i=0; i<4; i++) {
+      let startTime = content.performance.getEntries()[i].startTime;
+      let duration = content.performance.getEntries()[i].duration;
+      ok(isRounded(startTime), "For reduceTimerPrecision, performance.getEntries(" + i.toString() + ").startTime is not rounded: " + startTime.toString());
+      ok(isRounded(duration), "For reduceTimerPrecision, performance.getEntries(" + i.toString() + ").duration is not rounded: " + duration.toString());
+    }
+    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()");
+
+  });
+
+  await BrowserTestUtils.removeTab(tab);
+});
+
+add_task(async function runRTPTestsForWorker() {
+  await SpecialPowers.pushPrefEnv({"set":
+    [["privacy.resistFingerprinting", false],
+     ["privacy.reduceTimerPrecision", true]]
+  });
+
+  let tab = await BrowserTestUtils.openNewForegroundTab(
+    gBrowser, TEST_PATH + "file_dummy.html");
+
+  await ContentTask.spawn(tab.linkedBrowser, null, async function() {
+    await 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") {
+          resolve();
+        } else {
+          ok(false, "Unknown message type");
+          resolve();
+        }
+      };
+      worker.postMessage({type: "runRTPTests"});
+    });
+  });
+
+  await BrowserTestUtils.removeTab(tab);
+});
\ No newline at end of file
--- a/browser/components/resistfingerprinting/test/browser/file_workerPerformance.js
+++ b/browser/components/resistfingerprinting/test/browser/file_workerPerformance.js
@@ -5,29 +5,57 @@ function ok(a, msg) {
 function is(a, b, msg) {
   ok(a === b, msg);
 }
 
 function finish() {
   postMessage({type: "finish"});
 }
 
-function runTests() {
+function runRPTests() {
+  const isRounded = x => (Math.floor(x / 100) * 100) === x;
+  //ok(isRounded(performance.timeOrigin), `For resistFingerprinting, performance.timeOrigin is not correctly rounded: ` + performance.timeOrigin);
+
   // Try to add some entries.
   performance.mark("Test");
   performance.mark("Test-End");
   performance.measure("Test-Measure", "Test", "Test-End");
 
   // Check that no entries for performance.getEntries/getEntriesByType/getEntriesByName.
-  is(performance.getEntries().length, 0, "No entries for performance.getEntries() for workers");
-  is(performance.getEntriesByType("resource").length, 0, "No entries for performance.getEntriesByType() for workers");
-  is(performance.getEntriesByName("Test", "mark").length, 0, "No entries for performance.getEntriesByName() for workers");
+  is(performance.getEntries().length, 0, "For resistFingerprinting: No entries for performance.getEntries() for workers");
+  is(performance.getEntriesByType("resource").length, 0, "For resistFingerprinting: No entries for performance.getEntriesByType() for workers");
+  is(performance.getEntriesByName("Test", "mark").length, 0, "For resistFingerprinting: No entries for performance.getEntriesByName() for workers");
+
+  finish();
+}
+
+function runRTPTests() {
+  const isRounded = x => (Math.floor(x / 100) * 100) === x;
+  //ok(isRounded(performance.timeOrigin), `For reduceTimerPrecision, performance.timeOrigin is not correctly rounded: ` + performance.timeOrigin);
+
+  // Try to add some entries.
+  performance.mark("Test");
+  performance.mark("Test-End");
+  performance.measure("Test-Measure", "Test", "Test-End");
+
+  // Check that no entries for performance.getEntries/getEntriesByType/getEntriesByName.
+  is(performance.getEntries().length, 3, "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), "For reduceTimerPrecision, performance.getEntries(" + i.toString() + ").startTime is not rounded: " + startTime.toString());
+    ok(isRounded(duration), "For reduceTimerPrecision, performance.getEntries(" + i.toString() + ").duration is not rounded: " + duration.toString());
+  }
+  is(performance.getEntriesByType("mark").length, 2, "For reduceTimerPrecision: Incorrect number of entries for performance.getEntriesByType() for workers: " + performance.getEntriesByType("resource").length);
+  is(performance.getEntriesByName("Test", "mark").length, 1, "For reduceTimerPrecision: Incorrect number of entries for performance.getEntriesByName() for workers: " + performance.getEntriesByName("Test", "mark").length);
 
   finish();
 }
 
 self.onmessage = function(e) {
-  if (e.data.type === "runTests") {
-    runTests();
+  if (e.data.type === "runRPTests") {
+    runRPTests();
+  } else if (e.data.type === "runRTPTests") {
+    runRTPTests();
   } else {
     ok(false, "Unknown message type");
   }
 };