Bug 578209: Add capability to send study to random subset of Test Pilot users. r+a=dtownsend DONTBUILD
authorJono S Xia <jdicarlo@mozilla.com>
Fri, 18 Feb 2011 14:49:38 -0800
changeset 62846 ce20375693197918bba1e364e7c653f46b6d5ba0
parent 62845 689f55593c70c8a895d731bc931cd82166e239de
child 62847 ffca7d5d2810fc0842a50f45c078b2458717ba0f
push id1
push userroot
push dateTue, 10 Dec 2013 15:46:25 +0000
bugs578209
milestone2.0b12pre
Bug 578209: Add capability to send study to random subset of Test Pilot users. r+a=dtownsend DONTBUILD
browser/app/profile/extensions/testpilot@labs.mozilla.com/modules/setup.js
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/modules/setup.js
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/modules/setup.js
@@ -51,16 +51,17 @@ const FIRST_RUN_PREF ="extensions.testpi
 const RUN_AT_ALL_PREF = "extensions.testpilot.runStudies";
 const POPUP_SHOW_ON_NEW = "extensions.testpilot.popup.showOnNewStudy";
 const POPUP_SHOW_ON_FINISH = "extensions.testpilot.popup.showOnStudyFinished";
 const POPUP_SHOW_ON_RESULTS = "extensions.testpilot.popup.showOnNewResults";
 const POPUP_CHECK_INTERVAL = "extensions.testpilot.popup.delayAfterStartup";
 const POPUP_REMINDER_INTERVAL = "extensions.testpilot.popup.timeBetweenChecks";
 const ALWAYS_SUBMIT_DATA = "extensions.testpilot.alwaysSubmitData";
 const LOG_FILE_NAME = "TestPilotErrorLog.log";
+const RANDOM_DEPLOY_PREFIX = "extensions.testpilot.deploymentRandomizer";
 
 let TestPilotSetup = {
   didReminderAfterStartup: false,
   startupComplete: false,
   _shortTimer: null,
   _longTimer: null,
   _remoteExperimentLoader: null, // TODO make this a lazy initializer too?
   taskList: [],
@@ -689,31 +690,32 @@ let TestPilotSetup = {
   _experimentRequirementsAreMet: function TPS__requirementsMet(experiment) {
     /* Returns true if we we meet the requirements to run this experiment
      * (e.g. meet the minimum Test Pilot version and Firefox version)
      * false if not.
      * Default is always to run the study - return true UNLESS the study
      * specifies a requirement that we don't meet. */
     let logger = this._logger;
     try {
-      let minTpVer, minFxVer, expName, runOrNotFunc;
+      let minTpVer, minFxVer, expName, runOrNotFunc, randomDeployment;
       /* Could be an experiment, which specifies experimentInfo, or survey,
        * which specifies surveyInfo. */
       let info = experiment.experimentInfo ?
                    experiment.experimentInfo :
                    experiment.surveyInfo;
       if (!info) {
         // If neither one is supplied, study lacks metadata required to run
         logger.warn("Study lacks minimum metadata to run.");
         return false;
       }
       minTpVer = info.minTPVersion;
       minFxVer = info.minFXVersion;
       expName =  info.testName;
       runOrNotFunc = info.runOrNotFunc;
+      randomDeployment = info.randomDeployment;
 
       // Minimum test pilot version:
       if (minTpVer && this._isNewerThanMe(minTpVer)) {
         logger.warn("Not loading " + expName);
         logger.warn("Because it requires Test Pilot version " + minTpVer);
 
         // Let user know there is a newer version of Test Pilot available:
         if (!this._isShowingUpdateNotification()) {
@@ -730,16 +732,35 @@ let TestPilotSetup = {
 
       // Minimum firefox version:
       if (minFxVer && this._isNewerThanFirefox(minFxVer)) {
         logger.warn("Not loading " + expName);
         logger.warn("Because it requires Firefox version " + minFxVer);
         return false;
       }
 
+      // Random deployment (used to give study to random subsample of users)
+      if (randomDeployment) {
+        /* Roll a hundred-sided die. Remember what we roll for later reference.  A study
+         * using random subsample deployment will provide a range (say, 0 ~ 30) which means
+         * only users who roll within that range will run the study. */
+        let prefName = RANDOM_DEPLOY_PREFIX + "." + randomDeployment.rolloutCode;
+        let myRoll = this._prefs.getValue(prefName, null);
+        if (myRoll == null) {
+          myRoll = Math.floor(Math.random()*100);
+          this._prefs.setValue(prefName, myRoll);
+        }
+        if (myRoll < randomDeployment.minRoll) {
+          return false;
+        }
+        if (myRoll > randomDeployment.maxRoll) {
+          return false;
+        }
+      }
+
       /* The all-purpose, arbitrary code "Should this study run?" function - if
        * provided, use its return value. */
       if (runOrNotFunc) {
         return runOrNotFunc();
       }
     } catch (e) {
       logger.warn("Error in requirements check " +  e);
     }