Bug 1064333 - Add the stable client id to the telemetry ping. r=froydnj
--- 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");
}
@@ -157,16 +166,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);
if (Services.appinfo.isOfficial) {
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) {
@@ -374,16 +387,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);
@@ -420,16 +440,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