Bug 1497365 - send Prio-encoded data for subsessions r=janerik
authorRobert Helmer <rhelmer@mozilla.com>
Mon, 15 Oct 2018 16:52:49 +0000
changeset 499767 45a7ec8b70219b47b26eec692b17b6f7e73fc098
parent 499766 f6e9edf3db436e5dbaf2ff199f43c571e231515b
child 499768 4ccf0f4b0ef23fc71f5593ca269e625c0cca5d56
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjanerik
bugs1497365
milestone64.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 1497365 - send Prio-encoded data for subsessions r=janerik Differential Revision: https://phabricator.services.mozilla.com/D8300
toolkit/components/telemetry/pings/TelemetrySession.jsm
toolkit/components/telemetry/tests/unit/head.js
toolkit/components/telemetry/tests/unit/test_TelemetrySession.js
--- a/toolkit/components/telemetry/pings/TelemetrySession.jsm
+++ b/toolkit/components/telemetry/pings/TelemetrySession.jsm
@@ -103,16 +103,17 @@ function getMsSinceProcessStart() {
  */
 var Policy = {
   now: () => new Date(),
   monotonicNow: getMsSinceProcessStart,
   generateSessionUUID: () => generateUUID(),
   generateSubsessionUUID: () => generateUUID(),
   setSchedulerTickTimeout: (callback, delayMs) => setTimeout(callback, delayMs),
   clearSchedulerTickTimeout: id => clearTimeout(id),
+  prioEncode: (batchID, prioParams) => PrioEncoder.encode(batchID, prioParams),
 };
 
 /**
  * Get the ping type based on the payload.
  * @param {Object} aPayload The ping payload.
  * @return {String} A string representing the ping type.
  */
 function getPingType(aPayload) {
@@ -978,17 +979,17 @@ var Impl = {
       // Add process measurements to payload.
       payloadObj.processes[processType] = processPayload;
     }
 
     payloadObj.info = info;
 
     // Collect Prio-encoded measurements.
     if (Services.prefs.getBoolPref(PRIO_ENABLED_PREF, false)) {
-      payloadObj.prio = protect(() => this._prioEncode());
+      payloadObj.prio = protect(() => this._prioEncode(payloadObj));
     }
 
     // Add extended set measurements for chrome process.
     if (Telemetry.canRecordExtended) {
       payloadObj.slowSQL = protect(() => Telemetry.slowSQL);
       payloadObj.fileIOReports = protect(() => Telemetry.fileIOReports);
       payloadObj.lateWrites = protect(() => Telemetry.lateWrites);
 
@@ -1602,45 +1603,50 @@ var Impl = {
     this._log.trace("markNewProfilePingSent");
     this._newProfilePingSent = true;
     return TelemetryStorage.saveSessionData(this._getSessionDataObject());
   },
 
   /**
    * Encodes data for experimental Prio pilot project.
    *
+   * @param {Object} measurements - measurements taken until now. Histograms will have been cleared if
+   *                 this is a subsession, so use this to get the correct values.
    * @return {Object} An object containing Prio-encoded data.
    */
-  _prioEncode() {
-    // First, map the Telemetry histogram names to the params PrioEncoder.encode() expects.
+  _prioEncode(payloadObj) {
+    // First, map the Telemetry histogram names to the params PrioEncoder expects.
     const prioEncodedHistograms = {
       "BROWSER_IS_USER_DEFAULT": "browserIsUserDefault",
       "NEWTAB_PAGE_ENABLED": "newTabPageEnabled",
       "PDF_VIEWER_USED": "pdfViewerUsed",
     };
 
     // Build list of Prio parameters, using the first value recorded in each histogram.
     let prioParams = {};
     for (const [histogramName, prioName] of Object.entries(prioEncodedHistograms)) {
       try {
-        const histogram = Telemetry.getHistogramById(histogramName);
-        const firstCount = Boolean(histogram.snapshot().sum);
-        prioParams[prioName] = firstCount;
+        if (histogramName in payloadObj.histograms) {
+          const histogram = payloadObj.histograms[histogramName];
+          prioParams[prioName] = Boolean(histogram.sum);
+        } else {
+          prioParams[prioName] = false;
+        }
 
       } catch (ex) {
         this._log.error(ex);
       }
     }
 
     // Prio encode the data and add to payload.
     const batchID = Services.appinfo.appBuildID;
 
     let prioEncodedData;
 
     try {
-      prioEncodedData = PrioEncoder.encode(batchID, prioParams);
+      prioEncodedData = Policy.prioEncode(batchID, prioParams);
     } catch (ex) {
       this._log.error(ex);
     }
 
     return prioEncodedData;
   },
 };
--- a/toolkit/components/telemetry/tests/unit/head.js
+++ b/toolkit/components/telemetry/tests/unit/head.js
@@ -284,16 +284,21 @@ function fakeGzipCompressStringForNextPi
   let send = ChromeUtils.import("resource://gre/modules/TelemetrySend.jsm", {});
   let largePayload = generateString(length);
   send.Policy.gzipCompressString = (data) => {
     send.Policy.gzipCompressString = send.gzipCompressString;
     return largePayload;
   };
 }
 
+function fakePrioEncode() {
+  const m = ChromeUtils.import("resource://gre/modules/TelemetrySession.jsm", {});
+  m.Policy.prioEncode = (batchID, prioParams) => prioParams;
+}
+
 // Return a date that is |offset| ms in the future from |date|.
 function futureDate(date, offset) {
   return new Date(date.getTime() + offset);
 }
 
 function truncateToDays(aMsec) {
   return Math.floor(aMsec / MILLISECONDS_PER_DAY);
 }
--- a/toolkit/components/telemetry/tests/unit/test_TelemetrySession.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetrySession.js
@@ -925,16 +925,47 @@ add_task(async function test_environment
   Assert.equal(ping.environment.settings.userPrefs[PREF_TEST], 1);
   Assert.equal(ping.payload.info.reason, REASON_ENVIRONMENT_CHANGE);
   subsessionStartDate = new Date(ping.payload.info.subsessionStartDate);
   Assert.equal(subsessionStartDate.toISOString(), startHour.toISOString());
 
   Assert.ok(!(COUNT_ID in ping.payload.histograms));
   Assert.ok(!(KEYED_ID in ping.payload.keyedHistograms));
 
+  // Trigger and collect another ping. The histograms should be reset.
+  startHour = TelemetryUtils.truncateToHours(now);
+  gMonotonicNow = fakeMonotonicNow(gMonotonicNow + 10 * MILLISECONDS_PER_MINUTE);
+  now = fakeNow(futureDate(now, 10 * MILLISECONDS_PER_MINUTE));
+
+  fakePrioEncode();
+
+  // Set histograms to expected state.
+  let prioMeasures = [
+    "BROWSER_IS_USER_DEFAULT",
+    "NEWTAB_PAGE_ENABLED",
+  ];
+
+  for (let measure of prioMeasures) {
+    const value = Telemetry.getHistogramById(measure);
+    value.clear();
+    value.add(1);
+  }
+
+  let expectedPrioResult = {
+    "browserIsUserDefault": true,
+    "newTabPageEnabled": true,
+    "pdfViewerUsed": false,
+  };
+
+  Preferences.set(PREF_TEST, 3);
+  ping = await PingServer.promiseNextPing();
+  Assert.ok(!!ping);
+
+  Assert.deepEqual(ping.payload.prio, expectedPrioResult);
+
   await TelemetryController.testShutdown();
 });
 
 add_task(async function test_experimentAnnotations_subsession() {
   if (gIsAndroid) {
     // We don't split subsessions on environment changes yet on Android.
     return;
   }