bug 1106122: Telemetry: Add FHR activeTicks value as simple measurement. r=vladan, r=gfritzsche
☠☠ backed out by 9b49d075575f ☠ ☠
authorAvi Halachmi <avihpit@yahoo.com>
Fri, 02 Jan 2015 07:28:42 +0200
changeset 248349 63f90f467985969860d5c30fd9df0cfd07560477
parent 248348 180ffdfd2d27a68c45f712b3673203bbe8622ad4
child 248350 12756e269785fbcdb500450a15911aacd8ee5192
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvladan, gfritzsche
bugs1106122
milestone37.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 1106122: Telemetry: Add FHR activeTicks value as simple measurement. r=vladan, r=gfritzsche
services/datareporting/DataReportingService.js
toolkit/components/telemetry/TelemetryPing.jsm
toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
--- a/services/datareporting/DataReportingService.js
+++ b/services/datareporting/DataReportingService.js
@@ -386,16 +386,25 @@ DataReportingService.prototype = Object.
 
     this._clientID = CommonUtils.generateUUID();
     this._saveClientIdTask = this._saveClientID();
     yield this._saveClientIdTask;
 
     return this._clientID;
   }),
 
+  /**
+   * Returns the SessionRecorder instance associated with the data reporting service.
+   * Returns an actual object only if FHR is enabled and after initialization,
+   * else returns undefined.
+   */
+  getSessionRecorder: function() {
+    return this.sessionRecorder;
+  },
+
   /*
    * Simulate a restart of the service. This is for testing only.
    */
   _reset: Task.async(function* () {
     yield this._loadClientIdTask;
     yield this._saveClientIdTask;
     this._clientID = null;
   }),
--- a/toolkit/components/telemetry/TelemetryPing.jsm
+++ b/toolkit/components/telemetry/TelemetryPing.jsm
@@ -367,16 +367,27 @@ let Impl = {
     try {
       hasPingBeenSent = Telemetry.getHistogramById("TELEMETRY_SUCCESS").snapshot().sum > 0;
     } catch(e) {
     }
     if (!forSavedSession || hasPingBeenSent) {
       ret.savedPings = TelemetryFile.pingsLoaded;
     }
 
+    ret.activeTicks = -1;
+    if ("@mozilla.org/datareporting/service;1" in Cc) {
+      let drs = Cc["@mozilla.org/datareporting/service;1"]
+                  .getService(Ci.nsISupports)
+                  .wrappedJSObject;
+
+      let sr = drs.getSessionRecorder();
+      if (sr)
+        ret.activeTicks = sr.activeTicks;
+    }
+
     ret.pingsOverdue = TelemetryFile.pingsOverdue;
     ret.pingsDiscarded = TelemetryFile.pingsDiscarded;
 
     return ret;
   },
 
   /**
    * When reflecting a histogram into JS, Telemetry hands us an object
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
@@ -40,16 +40,17 @@ 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 PREF_FHR_UPLOAD_ENABLED = "datareporting.healthreport.uploadEnabled";
+const PREF_FHR_SERVICE_ENABLED = "datareporting.healthreport.service.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;
 
@@ -214,16 +215,17 @@ function checkPayload(request, reason, s
   do_check_eq(reason, pathComponents[1]);
   do_check_eq(request.getHeader("content-type"), "application/json; charset=UTF-8");
   do_check_true(payload.simpleMeasurements.uptime >= 0);
   do_check_true(payload.simpleMeasurements.startupInterrupted === 1);
   do_check_eq(payload.simpleMeasurements.shutdownDuration, SHUTDOWN_TIME);
   do_check_eq(payload.simpleMeasurements.savedPings, 1);
   do_check_true("maximalNumberOfConcurrentThreads" in payload.simpleMeasurements);
   do_check_true(payload.simpleMeasurements.maximalNumberOfConcurrentThreads >= gNumberOfThreadsLaunched);
+  do_check_true(payload.simpleMeasurements.activeTicks >= 0);
 
   do_check_eq(payload.simpleMeasurements.failedProfileLockCount,
               FAILED_PROFILE_LOCK_ATTEMPTS);
   let profileDirectory = Services.dirsvc.get("ProfD", Ci.nsIFile);
   let failedProfileLocksFile = profileDirectory.clone();
   failedProfileLocksFile.append("Telemetry.FailedProfileLocks.txt");
   do_check_true(!failedProfileLocksFile.exists());
 
@@ -427,23 +429,31 @@ function run_test() {
   try {
     let gfxInfo = Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfoDebug);
     gfxInfo.spoofVendorID("0xabcd");
     gfxInfo.spoofDeviceID("0x1234");
   } catch (x) {
     // If we can't test gfxInfo, that's fine, we'll note it later.
   }
 
+  // make sure getSessionRecorder() can be called before the DRS init.
+  // It's not a requirement that it returns undefined, but that's how it behaves
+  // now - so just let this test fail if this behavior changes.
+  do_check_true(gDatareportingService.getSessionRecorder() === undefined);
+
   // 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);
   Services.prefs.setBoolPref(PREF_FHR_UPLOAD_ENABLED, true);
 
+  // Initially disable FHR to verify that activeTicks ends up as -1
+  Services.prefs.setBoolPref(PREF_FHR_SERVICE_ENABLED, false);
+
   // Send the needed startup notifications to the datareporting service
   // to ensure that it has been initialized.
   if ("@mozilla.org/datareporting/service;1" in Cc) {
     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.
@@ -490,16 +500,29 @@ function actualTest() {
   registerFakePluginHost();
 
   run_next_test();
 }
 
 add_task(function* asyncSetup() {
   yield TelemetryPing.setup();
 
+  // When FHR is disabled, the payload's activeTicks should be -1.
+  do_check_true(TelemetryPing.getPayload().simpleMeasurements.activeTicks == -1);
+
+  // re-enable FHR and re-init the DRS.
+  // Note: this relies on the fact that the data reporting service reinitializes
+  // itself when calling its 'observe' method, without checking if it's already
+  // initialized. If this DRS behavior changes, this test would need to be adapted.
+  Services.prefs.setBoolPref(PREF_FHR_SERVICE_ENABLED, true);
+  if ("@mozilla.org/datareporting/service;1" in Cc) {
+    gDatareportingService.observe(null, "app-startup", null);
+    gDatareportingService.observe(null, "profile-after-change", null);
+  }
+
   if ("@mozilla.org/datareporting/service;1" in Cc) {
     gDataReportingClientID = yield gDatareportingService.getClientID();
 
     // We should have cached the client id now. Lets confirm that by
     // checking the client id before the async ping setup is finished.
     let promisePingSetup = TelemetryPing.reset();
     do_check_eq(TelemetryPing.clientID, gDataReportingClientID);
     yield promisePingSetup;