Bug 1631609 - Stop mocking DoH heuristics for tests. r=johannh
authorNihanth Subramanya <nhnt11@gmail.com>
Fri, 05 Jun 2020 08:10:54 +0000
changeset 534084 286c0c0af787703eb89d593bc0345b4ee9c562cd
parent 534083 60880b504f7335d9164561f77062af60476d3c37
child 534085 d55aac34140857cfed1c680cc9159fb666bd1cb3
push id37482
push usernbeleuzu@mozilla.com
push dateFri, 05 Jun 2020 14:35:19 +0000
treeherdermozilla-central@c835da226e6d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjohannh
bugs1631609
milestone79.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 1631609 - Stop mocking DoH heuristics for tests. r=johannh Depends on D76414 Differential Revision: https://phabricator.services.mozilla.com/D76617
browser/extensions/doh-rollout/background.js
browser/extensions/doh-rollout/experiments/heuristics/api.js
browser/extensions/doh-rollout/test/browser/head.js
--- a/browser/extensions/doh-rollout/background.js
+++ b/browser/extensions/doh-rollout/background.js
@@ -13,21 +13,16 @@ async function log() {
     // eslint-disable-next-line no-console
     console.log(...arguments);
   }
 }
 
 // Gate-keeping pref to run the add-on
 const DOH_ENABLED_PREF = "doh-rollout.enabled";
 
-// When in automation, we parse this string pref as JSON and use it as our
-// heuristics results set. This allows tests to set up different cases and
-// verify the correct response.
-const MOCK_HEURISTICS_PREF = "doh-rollout.heuristics.mockValues";
-
 // Pref that sets DoH to on/off. It has multiple modes:
 // 0: Off (default)
 // 1: null (No setting)
 // 2: Enabled, but will fall back to 0 on DNS lookup failure
 // 3: Always on.
 // 4: null (No setting)
 // 5: Never on.
 const TRR_MODE_PREF = "network.trr.mode";
@@ -218,24 +213,16 @@ const stateManager = {
     }
   },
 };
 
 const rollout = {
   // Pretend that there was a network change at the beginning of time.
   lastNetworkChangeTime: 0,
 
-  async isTesting() {
-    if (this._isTesting === undefined) {
-      this._isTesting = await browser.experiments.heuristics.isTesting();
-    }
-
-    return this._isTesting;
-  },
-
   addDoorhangerListeners() {
     browser.experiments.doorhanger.onDoorhangerAccept.addListener(
       rollout.doorhangerAcceptListener
     );
 
     browser.experiments.doorhanger.onDoorhangerDecline.addListener(
       rollout.doorhangerDeclineListener
     );
@@ -274,27 +261,17 @@ const rollout = {
   async heuristics(evaluateReason) {
     let shouldRunHeuristics = await stateManager.shouldRunHeuristics();
 
     if (!shouldRunHeuristics) {
       return;
     }
 
     // Run heuristics defined in heuristics.js and experiments/heuristics/api.js
-    let results;
-
-    if (await rollout.isTesting()) {
-      results = await browser.experiments.preferences.getCharPref(
-        MOCK_HEURISTICS_PREF,
-        `{ "test": "disable_doh" }`
-      );
-      results = JSON.parse(results);
-    } else {
-      results = await runHeuristics();
-    }
+    let results = await runHeuristics();
 
     // Check if DoH should be disabled
     let decision = Object.values(results).includes("disable_doh")
       ? "disable_doh"
       : "enable_doh";
 
     log("Heuristics decision on " + evaluateReason + ": " + decision);
 
--- a/browser/extensions/doh-rollout/experiments/heuristics/api.js
+++ b/browser/extensions/doh-rollout/experiments/heuristics/api.js
@@ -110,23 +110,31 @@ this.heuristics = class heuristics exten
               return "disable_doh";
             }
 
             // Default return, meaning no policy related to DNSOverHTTPS
             return "no_policy_set";
           },
 
           async checkParentalControls() {
+            if (Cu.isInAutomation) {
+              return "enable_doh";
+            }
+
             if (pcs.parentalControlsEnabled) {
               return "disable_doh";
             }
             return "enable_doh";
           },
 
           async checkThirdPartyRoots() {
+            if (Cu.isInAutomation) {
+              return "enable_doh";
+            }
+
             let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
               Ci.nsIX509CertDB
             );
 
             let allCerts = certdb.getCerts();
             for (let cert of allCerts) {
               if (
                 certdb.isCertTrusted(
--- a/browser/extensions/doh-rollout/test/browser/head.js
+++ b/browser/extensions/doh-rollout/test/browser/head.js
@@ -7,16 +7,30 @@ ChromeUtils.defineModuleGetter(
 );
 
 ChromeUtils.defineModuleGetter(
   this,
   "Preferences",
   "resource://gre/modules/Preferences.jsm"
 );
 
+XPCOMUtils.defineLazyServiceGetter(
+  this,
+  "gDNSService",
+  "@mozilla.org/network/dns-service;1",
+  "nsIDNSService"
+);
+
+XPCOMUtils.defineLazyServiceGetter(
+  this,
+  "gDNSOverride",
+  "@mozilla.org/network/native-dns-override;1",
+  "nsINativeDNSResolverOverride"
+);
+
 const { CommonUtils } = ChromeUtils.import(
   "resource://services-common/utils.js"
 );
 
 const ADDON_ID = "doh-rollout@mozilla.org";
 
 const EXAMPLE_URL = "https://example.com/";
 
@@ -32,42 +46,20 @@ const prefs = {
   DOH_DONE_FIRST_RUN_PREF: "doh-rollout.doneFirstRun",
   DOH_BALROG_MIGRATION_PREF: "doh-rollout.balrog-migration-done",
   DOH_DEBUG_PREF: "doh-rollout.debug",
   DOH_TRR_SELECT_ENABLED_PREF: "doh-rollout.trr-selection.enabled",
   DOH_TRR_SELECT_URI_PREF: "doh-rollout.uri",
   DOH_TRR_SELECT_COMMIT_PREF: "doh-rollout.trr-selection.commit-result",
   DOH_TRR_SELECT_DRY_RUN_RESULT_PREF:
     "doh-rollout.trr-selection.dry-run-result",
-  MOCK_HEURISTICS_PREF: "doh-rollout.heuristics.mockValues",
+  DOH_PROVIDER_STEERING_PREF: "doh-rollout.provider-steering.enabled",
   PROFILE_CREATION_THRESHOLD_PREF: "doh-rollout.profileCreationThreshold",
 };
 
-const fakePassingHeuristics = JSON.stringify({
-  google: "enable_doh",
-  youtube: "enable_doh",
-  zscalerCanary: "enable_doh",
-  canary: "enable_doh",
-  modifiedRoots: "enable_doh",
-  browserParent: "enable_doh",
-  thirdPartyRoots: "enable_doh",
-  policy: "enable_doh",
-});
-
-const fakeFailingHeuristics = JSON.stringify({
-  google: "disable_doh",
-  youtube: "disable_doh",
-  zscalerCanary: "disable_doh",
-  canary: "disable_doh",
-  modifiedRoots: "disable_doh",
-  browserParent: "disable_doh",
-  thirdPartyRoots: "disable_doh",
-  policy: "disable_doh",
-});
-
 async function setup() {
   SpecialPowers.pushPrefEnv({
     set: [["security.notification_enable_delay", 0]],
   });
   let oldCanRecord = Services.telemetry.canRecordExtended;
   Services.telemetry.canRecordExtended = true;
   Services.telemetry.clearEvents();
 
@@ -79,19 +71,46 @@ async function setup() {
   // Enable trr selection for tests. This is off by default so it can be
   // controlled via Normandy.
   Preferences.set(prefs.DOH_TRR_SELECT_ENABLED_PREF, true);
 
   // Enable committing the TRR selection. This pref ships false by default so
   // it can be controlled e.g. via Normandy, but for testing let's set enable.
   Preferences.set(prefs.DOH_TRR_SELECT_COMMIT_PREF, true);
 
+  // Enable provider steering. This pref ships false by default so it can be
+  // controlled e.g. via Normandy, but for testing let's enable.
+  Preferences.set(prefs.DOH_PROVIDER_STEERING_PREF, true);
+
+  // Set up heuristics, all passing by default.
+
+  // Google safesearch overrides
+  gDNSOverride.addIPOverride("www.google.com", "1.1.1.1");
+  gDNSOverride.addIPOverride("google.com", "1.1.1.1");
+  gDNSOverride.addIPOverride("forcesafesearch.google.com", "1.1.1.2");
+
+  // YouTube safesearch overrides
+  gDNSOverride.addIPOverride("www.youtube.com", "2.1.1.1");
+  gDNSOverride.addIPOverride("m.youtube.com", "2.1.1.1");
+  gDNSOverride.addIPOverride("youtubei.googleapis.com", "2.1.1.1");
+  gDNSOverride.addIPOverride("youtube.googleapis.com", "2.1.1.1");
+  gDNSOverride.addIPOverride("www.youtube-nocookie.com", "2.1.1.1");
+  gDNSOverride.addIPOverride("restrict.youtube.com", "2.1.1.2");
+  gDNSOverride.addIPOverride("restrictmoderate.youtube.com", "2.1.1.2");
+
+  // Zscaler override
+  gDNSOverride.addIPOverride("sitereview.zscaler.com", "3.1.1.1");
+
+  // Global canary
+  gDNSOverride.addIPOverride("use-application-dns.net", "4.1.1.1");
+
   registerCleanupFunction(async () => {
     Services.telemetry.canRecordExtended = oldCanRecord;
     Services.telemetry.clearEvents();
+    gDNSOverride.clearOverrides();
     await resetPrefsAndRestartAddon();
   });
 }
 
 async function checkTRRSelectionTelemetry() {
   let events;
   await BrowserTestUtils.waitForCondition(() => {
     events = Services.telemetry.snapshotEvents(
@@ -173,22 +192,27 @@ async function waitForStateTelemetry() {
     ).dynamic;
     return events;
   });
   events = events.filter(e => e[1] == "doh" && e[2] == "state");
   is(events.length, 1, "Found the expected state event.");
   Services.telemetry.clearEvents();
 }
 
+// setPassing/FailingHeuristics are used generically to test that DoH is enabled
+// or disabled correctly. We use the zscaler canary arbitrarily here, individual
+// heuristics are tested separately.
 function setPassingHeuristics() {
-  Preferences.set(prefs.MOCK_HEURISTICS_PREF, fakePassingHeuristics);
+  gDNSOverride.clearHostOverride("sitereview.zscaler.com");
+  gDNSOverride.addIPOverride("sitereview.zscaler.com", "3.1.1.1");
 }
 
 function setFailingHeuristics() {
-  Preferences.set(prefs.MOCK_HEURISTICS_PREF, fakeFailingHeuristics);
+  gDNSOverride.clearHostOverride("sitereview.zscaler.com");
+  gDNSOverride.addIPOverride("sitereview.zscaler.com", "213.152.228.242");
 }
 
 async function restartAddon() {
   let addon = await AddonManager.getAddonByID(ADDON_ID);
   await addon.reload();
 }
 
 async function disableAddon() {