Bug 1270191 - Disable telemetry upload during tests. r=grisha draft
authorMichael Comella <michael.l.comella@gmail.com>
Tue, 31 May 2016 17:04:40 -0700
changeset 373642 c2d56638e078012766e8f7c9b64de6d3988e6dbc
parent 373641 1642484993287d489060e95e3fbeb62232b422c6
child 373643 3c96cf81f729911bfefcc103f46068bd9b8fb202
push id19801
push usermichael.l.comella@gmail.com
push dateWed, 01 Jun 2016 00:25:38 +0000
reviewersgrisha
bugs1270191
milestone49.0a1
Bug 1270191 - Disable telemetry upload during tests. r=grisha MozReview-Commit-ID: GoQQRfGRvd4
build/mobile/remoteautomation.py
mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
mobile/android/base/java/org/mozilla/gecko/telemetry/TelemetryUploadService.java
--- a/build/mobile/remoteautomation.py
+++ b/build/mobile/remoteautomation.py
@@ -83,18 +83,26 @@ class RemoteAutomation(Automation):
         # Crash on non-local network connections by default.
         # MOZ_DISABLE_NONLOCAL_CONNECTIONS can be set to "0" to temporarily
         # enable non-local connections for the purposes of local testing.
         # Don't override the user's choice here.  See bug 1049688.
         env.setdefault('MOZ_DISABLE_NONLOCAL_CONNECTIONS', '1')
 
         # Disable Switchboard by default. This will prevent nonlocal
         # network connections to the Switchboard server.
+        # Passing any value expect the empty string will disable it so to
+        # enable, don't pass a value.
         env.setdefault('MOZ_DISABLE_SWITCHBOARD', '1')
 
+        # Disable Java telemetry by default to
+        # prevent network connections during testing.
+        # Passing any value expect the empty string will disable it so to
+        # enable, don't pass a value.
+        env.setdefault('MOZ_DISABLE_TELEMETRY', '1')
+
         # Set WebRTC logging in case it is not set yet.
         # On Android, environment variables cannot contain ',' so the
         # standard WebRTC setting for NSPR_LOG_MODULES is not available.
         # env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5,jsep:5,MediaPipelineFactory:5')
         env.setdefault('R_LOG_LEVEL', '6')
         env.setdefault('R_LOG_DESTINATION', 'stderr')
         env.setdefault('R_LOG_VERBOSE', '1')
 
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -73,16 +73,17 @@ import org.mozilla.gecko.search.SearchEn
 import org.mozilla.gecko.sync.repositories.android.FennecTabsRepository;
 import org.mozilla.gecko.tabqueue.TabQueueHelper;
 import org.mozilla.gecko.tabqueue.TabQueuePrompt;
 import org.mozilla.gecko.tabs.TabHistoryController;
 import org.mozilla.gecko.tabs.TabHistoryController.OnShowTabHistory;
 import org.mozilla.gecko.tabs.TabHistoryFragment;
 import org.mozilla.gecko.tabs.TabHistoryPage;
 import org.mozilla.gecko.tabs.TabsPanel;
+import org.mozilla.gecko.telemetry.TelemetryUploadService;
 import org.mozilla.gecko.telemetry.measurements.SearchCountMeasurements;
 import org.mozilla.gecko.telemetry.TelemetryDispatcher;
 import org.mozilla.gecko.telemetry.UploadTelemetryCorePingCallback;
 import org.mozilla.gecko.telemetry.measurements.SessionMeasurements;
 import org.mozilla.gecko.toolbar.AutocompleteHandler;
 import org.mozilla.gecko.toolbar.BrowserToolbar;
 import org.mozilla.gecko.toolbar.BrowserToolbar.TabEditingState;
 import org.mozilla.gecko.toolbar.ToolbarProgressView;
@@ -771,16 +772,17 @@ public class BrowserApp extends GeckoApp
      * until Gecko is loaded, and we need to know this before then.
      *
      * This method should be called early since other initialization
      * may depend on its results.
      */
     private void configureForTestsBasedOnEnvironment(final Intent intent) {
         final HashMap<String, String> envVars = IntentUtils.getEnvVarMap(intent);
         Experiments.setDisabledFromEnvVar(envVars);
+        TelemetryUploadService.setDisabledFromEnvVar(envVars);
     }
 
     /**
      * Initializes the default Switchboard URLs the first time.
      * @param intent
      */
     private void initSwitchboard(final Intent intent) {
         if (Experiments.isDisabled() || !AppConstants.MOZ_SWITCHBOARD) {
--- a/mobile/android/base/java/org/mozilla/gecko/telemetry/TelemetryUploadService.java
+++ b/mobile/android/base/java/org/mozilla/gecko/telemetry/TelemetryUploadService.java
@@ -25,33 +25,64 @@ import org.mozilla.gecko.telemetry.store
 import org.mozilla.gecko.util.DateUtil;
 import org.mozilla.gecko.util.NetworkUtils;
 import org.mozilla.gecko.util.StringUtils;
 
 import java.io.IOException;
 import java.net.URISyntaxException;
 import java.security.GeneralSecurityException;
 import java.util.Calendar;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
 /**
  * The service that handles retrieving a list of telemetry pings to upload from the given
  * {@link TelemetryPingStore}, uploading those payloads to the associated server, and reporting
  * back to the Store which uploads were a success.
  */
 public class TelemetryUploadService extends IntentService {
     private static final String LOGTAG = StringUtils.safeSubstring("Gecko" + TelemetryUploadService.class.getSimpleName(), 0, 23);
     private static final String WORKER_THREAD_NAME = LOGTAG + "Worker";
 
+    private static final String ENV_VAR_NAME = "MOZ_DISABLE_TELEMETRY";
+
     public static final String ACTION_UPLOAD = "upload";
     public static final String EXTRA_STORE = "store";
 
+    /**
+     * An override for telemetry via Intents.
+     *
+     * BrowserApp.onCreate, which sets the disabled state, should run before
+     * TelemetryUploadService, so we don't have to synchronize/volatile.
+     */
+    private static Boolean isDisabledByLaunchingIntent = null;
+
+    /**
+     * As a sanity check, this method should only be called once.
+     */
+    public static void setDisabledFromEnvVar(final HashMap<String, String> envVarMap) {
+        if (isDisabledByLaunchingIntent != null) {
+            throw new IllegalStateException("Disabled state already set");
+        }
+        isDisabledByLaunchingIntent = envVarMap.containsKey(ENV_VAR_NAME);
+        if (isDisabledByLaunchingIntent) {
+            Log.d(LOGTAG, "Telemetry disabled by environment variable: " + ENV_VAR_NAME);
+        }
+    }
+
+    private static boolean isDisabledByLaunchingIntent() {
+        if (isDisabledByLaunchingIntent == null) {
+            throw new IllegalStateException("Disabled state not yet set.");
+        }
+        return isDisabledByLaunchingIntent;
+    }
+
     public TelemetryUploadService() {
         super(WORKER_THREAD_NAME);
 
         // Intent redelivery can fail hard (e.g. we OOM as we try to upload, the Intent gets redelivered, repeat)
         // so for simplicity, we avoid it. We expect the upload service to eventually get called again by the caller.
         setIntentRedelivery(false);
     }
 
@@ -177,16 +208,21 @@ public class TelemetryUploadService exte
      * Note that this method logs debug statements when upload is disabled.
      */
     public static boolean isUploadEnabledByAppConfig(final Context context) {
         if (!TelemetryConstants.UPLOAD_ENABLED) {
             Log.d(LOGTAG, "Telemetry upload feature is compile-time disabled");
             return false;
         }
 
+        if (isDisabledByLaunchingIntent()) {
+            Log.d(LOGTAG, "Telemetry upload feature is disabled by intent (in testing?)");
+            return false;
+        }
+
         if (!GeckoPreferences.getBooleanPref(context, GeckoPreferences.PREFS_HEALTHREPORT_UPLOAD_ENABLED, true)) {
             Log.d(LOGTAG, "Telemetry upload opt-out");
             return false;
         }
 
         return true;
     }