Bug 1421500 - Disable back-off for SafeBrowsing testcases not testing back-off. r?francois draft
authorDimiL <dlee@mozilla.com>
Fri, 08 Dec 2017 12:18:34 +0800
changeset 711581 eba69f92a29651ce7923b9eeb0efbb6e6b9215cb
parent 709416 457b0fe91e0d49a5bc35014fb6f86729cd5bac9b
child 743822 873520d86fcc250e50d94d523ccf82957ef6cd50
push id93085
push userbmo:dlee@mozilla.com
push dateThu, 14 Dec 2017 02:48:02 +0000
reviewersfrancois
bugs1421500
milestone59.0a1
Bug 1421500 - Disable back-off for SafeBrowsing testcases not testing back-off. r?francois After this patch landed, we will have 3 cases: 1. For providers are not "test", for example, google, google4, mozilla ... etc backoff CANNOT be disabled. 2. For "test" provider, if preference "browser.safebrowsing.provider.test.disableBackoff" is ON backoff is disabled. 3. For "test" provider, if preference "browser.safebrowsing.provider.test.disableBackoff" is Off backoff is NOT disabled. So if your testcase will use listmanager or hashcompleter, you should try to use "test" provider if possible, otherwise testcase may encounter intermittent failure due to backoff. MozReview-Commit-ID: 3BDxs0ARyQM
toolkit/components/url-classifier/nsUrlClassifierHashCompleter.js
toolkit/components/url-classifier/nsUrlClassifierLib.js
toolkit/components/url-classifier/nsUrlClassifierListManager.js
toolkit/components/url-classifier/tests/unit/head_urlclassifier.js
toolkit/components/url-classifier/tests/unit/test_hashcompleter.js
--- a/toolkit/components/url-classifier/nsUrlClassifierHashCompleter.js
+++ b/toolkit/components/url-classifier/nsUrlClassifierHashCompleter.js
@@ -223,17 +223,18 @@ HashCompleter.prototype = {
       // Initialize request backoffs separately, since requests are deleted
       // after they are dispatched.
       var jslib = Cc["@mozilla.org/url-classifier/jslib;1"]
                   .getService().wrappedJSObject;
 
       // Using the V4 backoff algorithm for both V2 and V4. See bug 1273398.
       this._backoffs[aGethashUrl] = new jslib.RequestBackoffV4(
         10 /* keep track of max requests */,
-        0 /* don't throttle on successful requests per time period */);
+        0 /* don't throttle on successful requests per time period */,
+        gUrlUtil.getProvider(aTableName) /* used by testcase */);
     }
 
     if (!this._nextGethashTimeMs[aGethashUrl]) {
       this._nextGethashTimeMs[aGethashUrl] = 0;
     }
 
     // Start off this request. Without dispatching to a thread, every call to
     // complete makes an individual HTTP request.
--- a/toolkit/components/url-classifier/nsUrlClassifierLib.js
+++ b/toolkit/components/url-classifier/nsUrlClassifierLib.js
@@ -3,20 +3,23 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // We wastefully reload the same JS files across components.  This puts all
 // the common JS files used by safebrowsing and url-classifier into a
 // single component.
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
+const Cu = Components.utils;
 const G_GDEBUG = false;
 
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
 
+const PREF_DISABLE_TEST_BACKOFF = "browser.safebrowsing.provider.test.disableBackoff";
 /**
  * Partially applies a function to a particular "this object" and zero or
  * more arguments. The result is a new function with some arguments of the first
  * function pre-filled and the value of |this| "pre-specified".
  *
  * Remaining arguments specified at call-time are appended to the pre-
  * specified ones.
  *
@@ -78,31 +81,42 @@ this.HTTP_TEMPORARY_REDIRECT    = 307;
  *     we double this time for consecutive errors
  * @param maxTimeout Number time (ms) maximum timeout period
  * @param tolerance Checking next request tolerance.
  */
 this.RequestBackoff =
 function RequestBackoff(maxErrors, retryIncrement,
                         maxRequests, requestPeriod,
                         timeoutIncrement, maxTimeout,
-                        tolerance) {
+                        tolerance, provider = null) {
   this.MAX_ERRORS_ = maxErrors;
   this.RETRY_INCREMENT_ = retryIncrement;
   this.MAX_REQUESTS_ = maxRequests;
   this.REQUEST_PERIOD_ = requestPeriod;
   this.TIMEOUT_INCREMENT_ = timeoutIncrement;
   this.MAX_TIMEOUT_ = maxTimeout;
   this.TOLERANCE_ = tolerance;
 
   // Queue of ints keeping the time of all requests
   this.requestTimes_ = [];
 
   this.numErrors_ = 0;
   this.errorTimeout_ = 0;
   this.nextRequestTime_ = 0;
+
+  // For test provider, we will disable backoff if preference is set to false.
+  if (provider === "test") {
+    this.canMakeRequestDefault = this.canMakeRequest;
+    this.canMakeRequest = function() {
+      if (Services.prefs.getBoolPref(PREF_DISABLE_TEST_BACKOFF, true)) {
+        return true;
+      }
+      return this.canMakeRequestDefault();
+    };
+  }
 };
 
 /**
  * Reset the object for reuse. This deliberately doesn't clear requestTimes_.
  */
 RequestBackoff.prototype.reset = function() {
   this.numErrors_ = 0;
   this.errorTimeout_ = 0;
@@ -170,28 +184,30 @@ RequestBackoff.prototype.isErrorStatus =
           HTTP_SEE_OTHER == status ||
           HTTP_TEMPORARY_REDIRECT == status);
 };
 
 // Wrap a general-purpose |RequestBackoff| to a v4-specific one
 // since both listmanager and hashcompleter would use it.
 // Note that |maxRequests| and |requestPeriod| is still configurable
 // to throttle pending requests.
-function RequestBackoffV4(maxRequests, requestPeriod) {
+function RequestBackoffV4(maxRequests, requestPeriod,
+                          provider = null) {
   let rand = Math.random();
   let retryInterval = Math.floor(15 * 60 * 1000 * (rand + 1)); // 15 ~ 30 min.
   let backoffInterval = Math.floor(30 * 60 * 1000 * (rand + 1)); // 30 ~ 60 min.
 
   return new RequestBackoff(2 /* max errors */,
                 retryInterval /* retry interval, 15~30 min */,
                   maxRequests /* num requests */,
                 requestPeriod /* request time, 60 min */,
               backoffInterval /* backoff interval, 60 min */,
           24 * 60 * 60 * 1000 /* max backoff, 24hr */,
-                         1000 /* tolerance of 1 sec */);
+                         1000 /* tolerance of 1 sec */,
+                     provider /* provider name */);
 }
 
 // Expose this whole component.
 var lib = this;
 
 function UrlClassifierLib() {
   this.wrappedJSObject = lib;
 }
--- a/toolkit/components/url-classifier/nsUrlClassifierListManager.js
+++ b/toolkit/components/url-classifier/nsUrlClassifierListManager.js
@@ -96,17 +96,18 @@ PROT_ListManager.prototype.registerTable
 
   // Keep track of all of our update URLs.
   if (!this.needsUpdate_[updateUrl]) {
     this.needsUpdate_[updateUrl] = {};
 
     // Using the V4 backoff algorithm for both V2 and V4. See bug 1273398.
     this.requestBackoffs_[updateUrl] = new RequestBackoffV4(
                                             4 /* num requests */,
-                               60 * 60 * 1000 /* request time, 60 min */);
+                               60 * 60 * 1000 /* request time, 60 min */,
+                                 providerName /* used by testcase */);
   }
   this.needsUpdate_[updateUrl][tableName] = false;
 
   return true;
 };
 
 /**
  * Unregister a table table from list
--- a/toolkit/components/url-classifier/tests/unit/head_urlclassifier.js
+++ b/toolkit/components/url-classifier/tests/unit/head_urlclassifier.js
@@ -21,16 +21,17 @@ Cc["@mozilla.org/psm;1"].getService(Ci.n
 
 // Disable hashcompleter noise for tests
 Services.prefs.setIntPref("urlclassifier.gethashnoise", 0);
 
 // Enable malware/phishing checking for tests
 Services.prefs.setBoolPref("browser.safebrowsing.malware.enabled", true);
 Services.prefs.setBoolPref("browser.safebrowsing.blockedURIs.enabled", true);
 Services.prefs.setBoolPref("browser.safebrowsing.phishing.enabled", true);
+Services.prefs.setBoolPref("browser.safebrowsing.provider.test.disableBackoff", true);
 
 // Enable all completions for tests
 Services.prefs.setCharPref("urlclassifier.disallow_completions", "");
 
 // Hash completion timeout
 Services.prefs.setIntPref("urlclassifier.gethash.timeout_ms", 5000);
 
 function delFile(name) {
--- a/toolkit/components/url-classifier/tests/unit/test_hashcompleter.js
+++ b/toolkit/components/url-classifier/tests/unit/test_hashcompleter.js
@@ -235,16 +235,18 @@ var completer = Cc["@mozilla.org/url-cla
 
 var gethashUrl;
 
 // Expected highest completion set for which the server sends a response.
 var expectedMaxServerCompletionSet = 0;
 var maxServerCompletionSet = 0;
 
 function run_test() {
+  // This test case exercises the backoff functionality so we can't leave it disabled.
+  Services.prefs.setBoolPref("browser.safebrowsing.provider.test.disableBackoff", false);
   // Generate a random completion set that return successful responses.
   completionSets.push(getRandomCompletionSet(false));
   // We backoff after receiving an error, so requests shouldn't reach the
   // server after that.
   expectedMaxServerCompletionSet = completionSets.length;
   // Generate some completion sets that return 503s.
   for (let j = 0; j < 10; ++j) {
     completionSets.push(getRandomCompletionSet(true));
@@ -388,13 +390,15 @@ callback.prototype = {
     if (currentCompletionSet < completionSets.length &&
         finishedCompletions == completionSets[currentCompletionSet].length) {
       runNextCompletion();
     }
   },
 };
 
 function finish() {
+  Services.prefs.clearUserPref("browser.safebrowsing.provider.test.disableBackoff");
+
   do_check_eq(expectedMaxServerCompletionSet, maxServerCompletionSet);
   server.stop(function() {
     do_test_finished();
   });
 }