Bug 1374270 - Support sending health ping on shutdown via PingSender. r=Dexter
authorKate Ustiuzhanina <kustiuzhanina@mozilla.com>
Fri, 28 Jul 2017 15:49:52 +0100
changeset 371674 db29261fe4c7afebd6490ad21a2df6239d185c6c
parent 371673 9368bd8045136706950cde7cf718fda5492499e8
child 371675 2c7389aef3bc6ac357b49af91f89485bfd2756ad
push id32252
push userkwierso@gmail.com
push dateSat, 29 Jul 2017 00:17:07 +0000
treeherdermozilla-central@ec329722b2f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersDexter
bugs1374270
milestone56.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 1374270 - Support sending health ping on shutdown via PingSender. r=Dexter
toolkit/components/telemetry/TelemetryHealthPing.jsm
toolkit/components/telemetry/docs/data/health-ping.rst
toolkit/components/telemetry/tests/unit/test_TelemetryHealthPing.js
--- a/toolkit/components/telemetry/TelemetryHealthPing.jsm
+++ b/toolkit/components/telemetry/TelemetryHealthPing.jsm
@@ -153,23 +153,28 @@ this.TelemetryHealthPing = {
       return Promise.resolve();
     }
 
     this._log.trace("_submitPing(" + reason + ")");
     let payload = this._assemblePayload(reason);
     this._clearData();
     this._lastSendTime = Utils.monotonicNow();
 
+    let options = {
+      addClientId: true,
+      usePingSender: reason === this.Reason.SHUT_DOWN
+    };
+
     return new Promise(r =>
       // If we submit the health ping immediately, the send task would be triggered again
       // before discarding oversized pings from the queue.
       // To work around this, we send the ping on the next tick.
       Services.tm.dispatchToMainThread(() => r(
         TelemetryController
-          .submitExternalPing(this.HEALTH_PING_TYPE, payload, {addClientId: true}))));
+          .submitExternalPing(this.HEALTH_PING_TYPE, payload, options))));
   },
 
   /**
    * Accumulate failure information and trigger a ping immediately or on timeout.
    * @param {String} failureType The type of failure (e.g. "timeout", ...).
    * @param {String} failureSubType The subtype of failure (e.g. ping type, ...).
    * @returns {Promise} Test-only, resolved when the ping is stored or sent.
    */
--- a/toolkit/components/telemetry/docs/data/health-ping.rst
+++ b/toolkit/components/telemetry/docs/data/health-ping.rst
@@ -42,17 +42,17 @@ Send behavior
 
 * The size of other assembled ping exceed the ping limit.
 * There was a failure while sending other ping.
 
 After recording the data, ping will be sent:
 
 * immediately, with the reason ``immediate`` , if it is first ping in the session or it passed at least one hour from the previous submission.
 * after 1 hour minus the time passed from previous submission, with the reason ``delayed`` , if less than an hour passed from the previous submission.
-* on shutdown, with the reason ``shutdown`` , if recorded data is not empty.
+* on shutdown, with the reason ``shutdown`` using :doc:`../internals/pingsender`, if recorded data is not empty.
 
 Field details
 -------------
 
 reason
 ~~~~~~
 The ``reason`` field contains the information about when "health" ping was submitted. Now it supports three types:
 
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryHealthPing.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryHealthPing.js
@@ -36,16 +36,17 @@ add_task(async function setup() {
   // Make sure we don't generate unexpected pings due to pref changes.
   await setEmptyPrefWatchlist();
   Services.prefs.setBoolPref("toolkit.telemetry.enabled", true);
   Preferences.set(TelemetryUtils.Preferences.HealthPingEnabled, true);
 
   await TelemetryController.testSetup();
   PingServer.start();
   TelemetrySend.setServer("http://localhost:" + PingServer.port);
+  Preferences.set(TelemetryUtils.Preferences.Server, "http://localhost:" + PingServer.port);
 });
 
 add_task(async function test_sendImmediately() {
   PingServer.clearRequests();
   TelemetryHealthPing.testReset();
 
   await TelemetryHealthPing.recordSendFailure("testProblem");
   let ping = await PingServer.promiseNextPing();
@@ -174,11 +175,52 @@ add_task(async function test_sendOnlyTop
       [PING_TYPE + 5]: 4,
       [PING_TYPE + 4]: 3,
       [PING_TYPE + 3]: 2,
       [PING_TYPE + 2]: 1
     }
   });
 });
 
+add_task(async function test_usePingSenderOnShutdown() {
+  if (gIsAndroid ||
+      (AppConstants.platform == "linux" && OS.Constants.Sys.bits == 32)) {
+    // We don't support the pingsender on Android, yet, see bug 1335917.
+    // We also don't support the pingsender testing on Treeherder for
+    // Linux 32 bit (due to missing libraries). So skip it there too.
+    // See bug 1310703 comment 78.
+    return;
+  }
+
+  TelemetryHealthPing.testReset();
+  PingServer.clearRequests();
+
+  // This first failure should immediately trigger a ping.
+  // After this, subsequent failures should be throttled.
+  await TelemetryHealthPing.recordSendFailure("testFailure");
+  await PingServer.promiseNextPing();
+
+  TelemetryHealthPing.recordSendFailure("testFailure");
+  let nextRequest = PingServer.promiseNextRequest();
+
+  await TelemetryController.testReset();
+  await TelemetryController.testShutdown();
+  let request = await nextRequest;
+  let ping = decodeRequestPayload(request);
+
+  checkHealthPingStructure(ping, {
+    [TelemetryHealthPing.FailureType.SEND_FAILURE]: {
+      "testFailure": 1
+    },
+    "os": TelemetryHealthPing.OsInfo,
+    "reason": TelemetryHealthPing.Reason.SHUT_DOWN
+  });
+
+  // Check that the health ping is sent at shutdown using the pingsender.
+  Assert.equal(request.getHeader("User-Agent"), "pingsender/1.0",
+    "Should have received the correct user agent string.");
+  Assert.equal(request.getHeader("X-PingSender-Version"), "1.0",
+    "Should have received the correct PingSender version string.");
+});
+
 add_task(async function cleanup() {
   await PingServer.stop();
 });