Bug 1312015 - Ensure that TPS catches failures when generating sync telemetry r?markh draft
authorThom Chiovoloni <tchiovoloni@mozilla.com>
Tue, 25 Oct 2016 12:13:34 -0400
changeset 429310 892fb30ee12e139d50fa1fc8653b09e375b22609
parent 429294 82104756f2c2d88f83ee3dd51d0d2abaafcf778e
child 534941 3bb169b783bfce5cdaedc2f89bf1f8845866afb3
push id33533
push userbmo:tchiovoloni@mozilla.com
push dateTue, 25 Oct 2016 17:13:19 +0000
reviewersmarkh
bugs1312015
milestone52.0a1
Bug 1312015 - Ensure that TPS catches failures when generating sync telemetry r?markh MozReview-Commit-ID: HdXROi6Ctcj
services/sync/tps/extensions/tps/resource/tps.jsm
--- a/services/sync/tps/extensions/tps/resource/tps.jsm
+++ b/services/sync/tps/extensions/tps/resource/tps.jsm
@@ -18,16 +18,17 @@ Cu.import("resource://gre/modules/Log.js
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/AppConstants.jsm");
 Cu.import("resource://gre/modules/PlacesUtils.jsm");
 Cu.import("resource://services-common/async.js");
 Cu.import("resource://services-sync/constants.js");
 Cu.import("resource://services-sync/main.js");
 Cu.import("resource://services-sync/util.js");
+Cu.import("resource://services-sync/telemetry.js");
 Cu.import("resource://services-sync/bookmark_validator.js");
 Cu.import("resource://services-sync/engines/passwords.js");
 Cu.import("resource://services-sync/engines/forms.js");
 Cu.import("resource://services-sync/engines/addons.js");
 // TPS modules
 Cu.import("resource://tps/logger.jsm");
 
 // Module wrappers for tests
@@ -101,16 +102,18 @@ var TPS = {
   _enabledEngines: null,
   _errors: 0,
   _isTracking: false,
   _operations_pending: 0,
   _phaseFinished: false,
   _phaselist: {},
   _setupComplete: false,
   _syncActive: false,
+  _syncCount: 0,
+  _syncsReportedViaTelemetry: 0,
   _syncErrors: 0,
   _syncWipeAction: null,
   _tabsAdded: 0,
   _tabsFinished: 0,
   _test: null,
   _triggeredSync: false,
   _usSinceEpoch: 0,
   _requestedQuit: false,
@@ -905,26 +908,59 @@ var TPS = {
         prefs.setCharPref('tps.account.password', this.config.fx_account.password);
       }
       else {
         prefs.setCharPref('tps.account.username', this.config.sync_account.username);
         prefs.setCharPref('tps.account.password', this.config.sync_account.password);
         prefs.setCharPref('tps.account.passphrase', this.config.sync_account.passphrase);
       }
 
+      this._interceptSyncTelemetry();
+
       // start processing the test actions
       this._currentAction = 0;
     }
     catch(e) {
       this.DumpError("_executeTestPhase failed", e);
       return;
     }
   },
 
   /**
+   * Override sync telemetry functions so that we can detect errors generating
+   * the sync ping, and count how many pings we report.
+   */
+  _interceptSyncTelemetry() {
+    let originalObserve = SyncTelemetry.observe;
+    let self = this;
+    SyncTelemetry.observe = function() {
+      try {
+        originalObserve.apply(this, arguments);
+      } catch (e) {
+        self.DumpError("Error when generating sync telemetry", e);
+      }
+    };
+    SyncTelemetry.submit = record => {
+      Logger.logInfo("Intercepted sync telemetry submission: " + JSON.stringify(record));
+      this._syncsReportedViaTelemetry += record.syncs.length + (record.discarded || 0);
+      if (record.discarded) {
+        Logger.AssertTrue(record.syncs.length == SyncTelemetry.maxPayloadCount,
+                          "Syncs discarded from ping before maximum payload count reached");
+      }
+      // If this is the shutdown ping, check and see that the telemetry saw all the syncs.
+      if (record.why === "shutdown") {
+        // If we happen to sync outside of tps manually causing it, its not an
+        // error in the telemetry, so we only complain if we didn't see all of them.
+        Logger.AssertTrue(this._syncsReportedViaTelemetry >= this._syncCount,
+                          `Telemetry missed syncs: Saw ${this._syncsReportedViaTelemetry}, should have >= ${this._syncCount}.`);
+      }
+    };
+  },
+
+  /**
    * Register a single phase with the test harness.
    *
    * This is called when loading individual test files.
    *
    * @param  phasename
    *         String name of the phase being loaded.
    * @param  fnlist
    *         Array of functions/actions to perform.
@@ -1096,16 +1132,17 @@ var TPS = {
       this._syncWipeAction = wipeAction;
       Weave.Svc.Prefs.set("firstSync", wipeAction);
     }
     else {
       Weave.Svc.Prefs.reset("firstSync");
     }
 
     this.Login(false);
+    ++this._syncCount;
 
     this._triggeredSync = true;
     this.StartAsyncOperation();
     Weave.Service.sync();
     Logger.logInfo("Sync is complete");
   },
 
   WipeServer: function TPS__WipeServer() {