Bug 1064333 - Add the stable client id to the telemetry ping. r=froydnj, a=lmandel
authorGeorg Fritzsche <georg.fritzsche@googlemail.com>
Fri, 17 Oct 2014 17:24:04 +0200
changeset 225901 ad6d502a38c9
parent 225900 8fbc0d8bb83d
child 225902 ec67776fc5e3
push id4063
push usergeorg.fritzsche@googlemail.com
push date2014-11-02 23:54 +0000
treeherdermozilla-beta@1ca39da5df9d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj, lmandel
bugs1064333
milestone34.0
Bug 1064333 - Add the stable client id to the telemetry ping. r=froydnj, a=lmandel
toolkit/components/telemetry/TelemetryPing.jsm
toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
toolkit/components/telemetry/tests/unit/test_TelemetryPingBuildID.js
toolkit/components/telemetry/tests/unit/test_TelemetrySendOldPings.js
--- a/toolkit/components/telemetry/TelemetryPing.jsm
+++ b/toolkit/components/telemetry/TelemetryPing.jsm
@@ -242,16 +242,17 @@ let Impl = {
   _slowSQLStartup: {},
   _prevSession: null,
   _hasWindowRestoredObserver: false,
   _hasXulWindowVisibleObserver: false,
   _startupIO : {},
   // The previous build ID, if this is the first run with a new build.
   // Undefined if this is not the first run, or the previous build ID is unknown.
   _previousBuildID: undefined,
+  _clientID: null,
 
   /**
    * Gets a series of simple measurements (counters). At the moment, this
    * only returns startup data from nsIAppStartup.getStartupInfo().
    *
    * @return simple measurements as a dictionary.
    */
   getSimpleMeasurements: function getSimpleMeasurements(forSavedSession) {
@@ -696,17 +697,18 @@ let Impl = {
       fileIOReports: Telemetry.fileIOReports,
       chromeHangs: Telemetry.chromeHangs,
       threadHangStats: this.getThreadHangStats(Telemetry.threadHangStats),
       lateWrites: Telemetry.lateWrites,
       addonHistograms: this.getAddonHistograms(),
       addonDetails: AddonManagerPrivate.getTelemetryDetails(),
       UIMeasurements: UITelemetry.getUIMeasurements(),
       log: TelemetryLog.entries(),
-      info: info
+      info: info,
+      clientID: this._clientID,
     };
 
     if (Object.keys(this._slowSQLStartup).length != 0 &&
         (Object.keys(this._slowSQLStartup.mainThread).length ||
          Object.keys(this._slowSQLStartup.otherThreads).length)) {
       payloadObj.slowSQLStartup = this._slowSQLStartup;
     }
 
@@ -952,16 +954,21 @@ let Impl = {
           // since it's never sent to the server. All that this.send does with
           // the reason is check to make sure it's not a test-ping.
           yield this.send("overdue-flush", this._server);
         }
 
         this.attachObservers();
         this.gatherMemory();
 
+        let drs = Cc["@mozilla.org/datareporting/service;1"]
+                    .getService(Ci.nsISupports)
+                    .wrappedJSObject;
+        this._clientID = yield drs.getClientID();
+
         Telemetry.asyncFetchTelemetryData(function () {});
         delete this._timer;
         deferred.resolve();
       }.bind(this));
     }
 
     this._timer.initWithCallback(timerCallback.bind(this),
                                  aTesting ? TELEMETRY_TEST_DELAY : TELEMETRY_DELAY,
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
@@ -36,21 +36,30 @@ const FAILED_PROFILE_LOCK_ATTEMPTS = 2;
 const PR_WRONLY = 0x2;
 const PR_CREATE_FILE = 0x8;
 const PR_TRUNCATE = 0x20;
 const RW_OWNER = 0600;
 
 const NUMBER_OF_THREADS_TO_LAUNCH = 30;
 let gNumberOfThreadsLaunched = 0;
 
+const PREF_BRANCH = "toolkit.telemetry.";
+const PREF_ENABLED = PREF_BRANCH + "enabled";
+
 const Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
 
 let gHttpServer = new HttpServer();
 let gServerStarted = false;
 let gRequestIterator = null;
+let gDataReportingClientID = null;
+
+XPCOMUtils.defineLazyGetter(this, "gDatareportingService",
+  () => Cc["@mozilla.org/datareporting/service;1"]
+          .getService(Ci.nsISupports)
+          .wrappedJSObject);
 
 function sendPing () {
   TelemetryPing.gatherStartup();
   if (gServerStarted) {
     return TelemetryPing.testPing("http://localhost:" + gHttpServer.identity.primaryPort);
   } else {
     return TelemetryPing.testPing("http://doesnotexist");
   }
@@ -153,16 +162,20 @@ function checkPayloadInfo(payload, reaso
   }
 
   do_check_eq(payload.info.reason, reason);
   do_check_true("appUpdateChannel" in payload.info);
   do_check_true("locale" in payload.info);
   do_check_true("revision" in payload.info);
   do_check_true(payload.info.revision.startsWith("http"));
 
+  do_check_true("clientID" in payload);
+  do_check_neq(payload.clientID, null);
+  do_check_eq(payload.clientID, gDataReportingClientID);
+
   try {
     // If we've not got nsIGfxInfoDebug, then this will throw and stop us doing
     // this test.
     let gfxInfo = Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfoDebug);
     let isWindows = ("@mozilla.org/windows-registry-key;1" in Components.classes);
     let isOSX = ("nsILocalFileMac" in Components.interfaces);
 
     if (isWindows || isOSX) {
@@ -352,16 +365,23 @@ function run_test() {
   } catch (x) {
     // If we can't test gfxInfo, that's fine, we'll note it later.
   }
 
   // Addon manager needs a profile directory
   do_get_profile();
   createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
 
+  Services.prefs.setBoolPref(PREF_ENABLED, true);
+
+  // Send the needed startup notifications to the datareporting service
+  // to ensure that it has been initialized.
+  gDatareportingService.observe(null, "app-startup", null);
+  gDatareportingService.observe(null, "profile-after-change", null);
+
   // Make it look like we've previously failed to lock a profile a couple times.
   write_fake_failedprofilelocks_file();
 
   // Make it look like we've shutdown before.
   write_fake_shutdown_file();
 
   let currentMaxNumberOfThreads = Telemetry.maximalNumberOfConcurrentThreads;
   do_check_true(currentMaxNumberOfThreads > 0);
@@ -398,16 +418,22 @@ function actualTest() {
   LightweightThemeManager.currentTheme = dummyTheme("1234");
 
   // fake plugin host for consistent flash version data
   registerFakePluginHost();
 
   run_next_test();
 }
 
+add_task(function* asyncSetup() {
+  yield TelemetryPing.setup();
+
+  gDataReportingClientID = yield gDatareportingService.getClientID();
+});
+
 // Ensure that not overwriting an existing file fails silently
 add_task(function* test_overwritePing() {
   let ping = {slug: "foo"}
   yield TelemetryFile.savePing(ping, true);
   yield TelemetryFile.savePing(ping, false);
   yield TelemetryFile.cleanupPingFile(ping);
 });
 
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryPingBuildID.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryPingBuildID.js
@@ -10,20 +10,26 @@
  * 2) previousBuildID in prefs, equal to current build ID:
  *     -> no previousBuildID in telemetry, prefs not updated.
  * 3) previousBuildID in prefs, not equal to current build ID:
  *     -> previousBuildID in telemetry, new value set in prefs.
  */
 
 "use strict"
 
-const Cu = Components.utils;
+const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm", this);
 Cu.import("resource://gre/modules/TelemetryPing.jsm", this);
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyGetter(this, "gDatareportingService",
+  () => Cc["@mozilla.org/datareporting/service;1"]
+          .getService(Ci.nsISupports)
+          .wrappedJSObject);
 
 // Force the Telemetry enabled preference so that TelemetryPing.reset() doesn't exit early.
 Services.prefs.setBoolPref(TelemetryPing.Constants.PREF_ENABLED, true);
 
 // Set up our dummy AppInfo object so we can control the appBuildID.
 Cu.import("resource://testing-common/AppInfo.jsm", this);
 updateAppInfo();
 
@@ -60,10 +66,16 @@ add_task(function* test_newBuild() {
   let buildIDPref = Services.prefs.getCharPref(TelemetryPing.Constants.PREF_PREVIOUS_BUILDID);
   do_check_eq(NEW_BUILD_ID, buildIDPref);
 });
 
 
 function run_test() {
   // Make sure we have a profile directory.
   do_get_profile();
+
+  // Send the needed startup notifications to the datareporting service
+  // to ensure that it has been initialized.
+  gDatareportingService.observe(null, "app-startup", null);
+  gDatareportingService.observe(null, "profile-after-change", null);
+
   run_next_test();
 }
--- a/toolkit/components/telemetry/tests/unit/test_TelemetrySendOldPings.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetrySendOldPings.js
@@ -18,18 +18,24 @@ const Cr = Components.results;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm", this);
 Cu.import("resource://testing-common/httpd.js", this);
 Cu.import("resource://gre/modules/Promise.jsm", this);
 Cu.import("resource://gre/modules/TelemetryFile.jsm", this);
 Cu.import("resource://gre/modules/TelemetryPing.jsm", this);
 Cu.import("resource://gre/modules/Task.jsm", this);
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 let {OS: {File, Path, Constants}} = Cu.import("resource://gre/modules/osfile.jsm", {});
 
+XPCOMUtils.defineLazyGetter(this, "gDatareportingService",
+  () => Cc["@mozilla.org/datareporting/service;1"]
+          .getService(Ci.nsISupports)
+          .wrappedJSObject);
+
 // We increment TelemetryFile's MAX_PING_FILE_AGE and
 // OVERDUE_PING_FILE_AGE by 1 minute so that our test pings exceed
 // those points in time, even taking into account file system imprecision.
 const ONE_MINUTE_MS = 60 * 1000;
 const EXPIRED_PING_FILE_AGE = TelemetryFile.MAX_PING_FILE_AGE + ONE_MINUTE_MS;
 const OVERDUE_PING_FILE_AGE = TelemetryFile.OVERDUE_PING_FILE_AGE + ONE_MINUTE_MS;
 
 const PING_SAVE_FOLDER = "saved-telemetry-pings";
@@ -185,16 +191,22 @@ function resetTelemetry() {
 function startTelemetry() {
   return TelemetryPing.setup();
 }
 
 function run_test() {
   gHttpServer.registerPrefixHandler("/submit/telemetry/", pingHandler);
   gHttpServer.start(-1);
   do_get_profile();
+
+  // Send the needed startup notifications to the datareporting service
+  // to ensure that it has been initialized.
+  gDatareportingService.observe(null, "app-startup", null);
+  gDatareportingService.observe(null, "profile-after-change", null);
+
   Services.prefs.setBoolPref(TelemetryPing.Constants.PREF_ENABLED, true);
   Services.prefs.setCharPref(TelemetryPing.Constants.PREF_SERVER,
                              "http://localhost:" + gHttpServer.identity.primaryPort);
   run_next_test();
 }
 
 /**
  * Test that pings that are considered too old are just chucked out