Bug 1385417 - Fix sendOnTimeout test. r=gfritzsche, a=test-only
authorKate Ustiuzhanina <kustiuzhanina@mozilla.com>
Fri, 04 Aug 2017 10:11:38 +0100
changeset 423384 4923833da3f914e9453fc14feebab00cca320509
parent 423383 c4b95f208eeb55003dbbe7da141e2a995cd4bbcb
child 423385 3b4cf744da12607de4dda7830dd7a7114de84606
push id1517
push userjlorenzo@mozilla.com
push dateThu, 14 Sep 2017 16:50:54 +0000
treeherdermozilla-release@3b41fd564418 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgfritzsche, test-only
bugs1385417
milestone56.0
Bug 1385417 - Fix sendOnTimeout test. r=gfritzsche, a=test-only
toolkit/components/telemetry/tests/unit/test_TelemetryHealthPing.js
--- a/toolkit/components/telemetry/tests/unit/test_TelemetryHealthPing.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetryHealthPing.js
@@ -6,16 +6,17 @@
 
 "use strict";
 
 Cu.import("resource://gre/modules/TelemetryController.jsm", this);
 Cu.import("resource://gre/modules/TelemetryStorage.jsm", this);
 Cu.import("resource://gre/modules/TelemetryUtils.jsm", this);
 Cu.import("resource://gre/modules/Preferences.jsm", this);
 Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
+Cu.import("resource://testing-common/TelemetryArchiveTesting.jsm", this);
 
 XPCOMUtils.defineLazyModuleGetter(this, "TelemetryHealthPing",
                                   "resource://gre/modules/TelemetryHealthPing.jsm");
 
 function checkHealthPingStructure(ping, expectedFailuresDict) {
   let payload = ping.payload;
   Assert.equal(ping.type, TelemetryHealthPing.HEALTH_PING_TYPE, "Should have recorded a health ping.");
 
@@ -25,16 +26,28 @@ function checkHealthPingStructure(ping, 
 }
 
 function fakeHealthSchedulerTimer(set, clear) {
   let telemetryHealthPing = Cu.import("resource://gre/modules/TelemetryHealthPing.jsm", {});
   telemetryHealthPing.Policy.setSchedulerTickTimeout = set;
   telemetryHealthPing.Policy.clearSchedulerTickTimeout = clear;
 }
 
+async function waitForConditionWithPromise(promiseFn, timeoutMsg, tryCount = 30) {
+  const SINGLE_TRY_TIMEOUT = 100;
+  let tries = 0;
+  do {
+    try {
+      return await promiseFn();
+    } catch (ex) {}
+    await new Promise(resolve => do_timeout(SINGLE_TRY_TIMEOUT, resolve));
+  } while (++tries <= tryCount);
+  throw new Error(timeoutMsg);
+}
+
 add_task(async function setup() {
   // Trigger a proper telemetry init.
   do_get_profile(true);
   // 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);
 
@@ -105,44 +118,66 @@ add_task(async function test_sendOverSiz
     },
     "os": TelemetryHealthPing.OsInfo,
     "reason": TelemetryHealthPing.Reason.IMMEDIATE
   });
 });
 
 add_task(async function test_sendOnTimeout() {
   TelemetryHealthPing.testReset();
+  await TelemetrySend.reset();
   PingServer.clearRequests();
   let PING_TYPE = "ping-on-timeout";
 
+  // Disable send retry to make this test more deterministic.
+  fakePingSendTimer(() => {}, () => {});
+
   // Set up small ping submission timeout to always have timeout error.
   TelemetrySend.testSetTimeoutForPingSubmit(2);
 
-  // Reset the timeout after receiving the first ping to be able to send health ping.
-  PingServer.registerPingHandler((request, result) => {
+  await TelemetryController.submitExternalPing(PING_TYPE, {});
+
+  let response;
+  PingServer.registerPingHandler((req, res) => {
     PingServer.resetPingHandler();
-    TelemetrySend.testResetTimeOutToDefault();
+    // We don't finish the response yet to make sure to trigger a timeout.
+    res.processAsync();
+    response = res;
   });
 
-  await TelemetryController.submitExternalPing(PING_TYPE, {});
-  let ping = await PingServer.promiseNextPing();
-  checkHealthPingStructure(ping, {
+  // Wait for health ping.
+  let ac = new TelemetryArchiveTesting.Checker();
+  await ac.promiseInit();
+  await waitForConditionWithPromise(() => {
+    ac.promiseFindPing("health", []);
+  }, "Failed to find health ping");
+
+  if (response) {
+    response.finish();
+  }
+
+  TelemetrySend.testResetTimeOutToDefault();
+  PingServer.resetPingHandler();
+  TelemetrySend.notifyCanUpload();
+
+  let pings = await PingServer.promiseNextPings(2);
+  let healthPing = pings.find(ping => ping.type === "health");
+  checkHealthPingStructure(healthPing, {
     [TelemetryHealthPing.FailureType.SEND_FAILURE]: {
       "timeout": 1
     },
     "os": TelemetryHealthPing.OsInfo,
     "reason": TelemetryHealthPing.Reason.IMMEDIATE
   });
-
-  // Clear pending pings to avoid resending pings which fail with time out error.
   await TelemetryStorage.testClearPendingPings();
 });
 
 add_task(async function test_sendOnlyTopTenDiscardedPings() {
   TelemetryHealthPing.testReset();
+  await TelemetrySend.reset();
   PingServer.clearRequests();
   let PING_TYPE = "sort-discarded";
 
   // This first failure should immediately trigger a ping. After this, subsequent failures should be throttled.
   await TelemetryHealthPing.recordSendFailure("testFailure");
   let testPing = await PingServer.promiseNextPing();
   Assert.equal(testPing.type, TelemetryHealthPing.HEALTH_PING_TYPE, "Should have recorded a health ping.");
 
@@ -150,20 +185,21 @@ add_task(async function test_sendOnlyTop
   // Retrieve delayed call back.
   let pingSubmissionCallBack = null;
   fakeHealthSchedulerTimer((callBack) => pingSubmissionCallBack = callBack, () => {
   });
 
   // Add failures
   for (let i = 1; i < 12; i++) {
     for (let j = 1; j < i; j++) {
-      await TelemetryHealthPing.recordDiscardedPing(PING_TYPE + i);
+      TelemetryHealthPing.recordDiscardedPing(PING_TYPE + i);
     }
   }
 
+  await TelemetrySend.reset();
   await pingSubmissionCallBack();
   let ping = await PingServer.promiseNextPing();
 
   checkHealthPingStructure(ping, {
     "os": TelemetryHealthPing.OsInfo,
     "reason": TelemetryHealthPing.Reason.DELAYED,
     [TelemetryHealthPing.FailureType.DISCARDED_FOR_SIZE]: {
       [PING_TYPE + 11]: 10,