Bug 1169159 - Add basic test coverage for Telemetry child payloads. r=gfritzsche

This commit is contained in:
Alessio Placitelli 2015-06-08 00:12:00 +02:00
parent 1368c560b4
commit a8986bae12
6 changed files with 132 additions and 22 deletions

View File

@ -97,6 +97,7 @@ function run_test()
function stop_high_accuracy_watch() {
geolocation.clearWatch(watchID2);
check_results();
do_test_finished();
}
function check_results()

View File

@ -155,6 +155,13 @@ this.TelemetryController = Object.freeze({
return Impl.setupTelemetry(true);
},
/**
* Used only for testing purposes.
*/
setupContent: function() {
return Impl.setupContentTelemetry(true);
},
/**
* Send a notification.
*/
@ -689,6 +696,21 @@ let Impl = {
return this._delayedInitTaskDeferred.promise;
},
/**
* This triggers basic telemetry initialization for content processes.
* @param {Boolean} [testing=false] True if we are in test mode, false otherwise.
*/
setupContentTelemetry: function (testing = false) {
this._testMode = testing;
// We call |enableTelemetryRecording| here to make sure that Telemetry.canRecord* flags
// are in sync between chrome and content processes.
if (!this.enableTelemetryRecording()) {
this._log.trace("setupContentTelemetry - Content process recording disabled.");
return;
}
},
// Do proper shutdown waiting and cleanup.
_cleanupOnShutdown: Task.async(function*() {
if (!this._initialized) {
@ -760,13 +782,8 @@ let Impl = {
// profile-after-change is only registered for chrome processes.
return this.setupTelemetry();
case "app-startup":
// app-startup is only registered for content processes. We call
// |enableTelemetryRecording| here to make sure that Telemetry.canRecord* flags
// are in sync between chrome and content processes.
if (!this.enableTelemetryRecording()) {
this._log.trace("observe - Content process recording disabled.");
return;
}
// app-startup is only registered for content processes.
return this.setupContentTelemetry();
break;
}
},

View File

@ -58,7 +58,7 @@ const MIN_SUBSESSION_LENGTH_MS = 10 * 60 * 1000;
#expand const HISTOGRAMS_FILE_VERSION = "__HISTOGRAMS_FILE_VERSION__";
const LOGGER_NAME = "Toolkit.Telemetry";
const LOGGER_PREFIX = "TelemetrySession::";
const LOGGER_PREFIX = "TelemetrySession" + (IS_CONTENT_PROCESS ? "#content::" : "::");
const PREF_BRANCH = "toolkit.telemetry.";
const PREF_PREVIOUS_BUILDID = PREF_BRANCH + "previousBuildID";
@ -775,7 +775,7 @@ this.TelemetrySession = Object.freeze({
let Impl = {
_histograms: {},
_initialized: false,
_log: null,
_logger: null,
_prevValues: {},
// Regex that matches histograms we care about during startup.
// Keep this in sync with gen-histogram-bucket-ranges.py.
@ -817,6 +817,13 @@ let Impl = {
// Used to serialize session state writes to disk.
_stateSaveSerializer: new SaveSerializer(),
get _log() {
if (!this._logger) {
this._logger = Log.repository.getLoggerWithMessagePrefix(LOGGER_NAME, LOGGER_PREFIX);
}
return this._logger;
},
/**
* Gets a series of simple measurements (counters). At the moment, this
* only returns startup data from nsIAppStartup.getStartupInfo().
@ -1415,10 +1422,6 @@ let Impl = {
*/
setupChromeProcess: function setupChromeProcess(testing) {
this._initStarted = true;
if (testing && !this._log) {
this._log = Log.repository.getLoggerWithMessagePrefix(LOGGER_NAME, LOGGER_PREFIX);
}
this._log.trace("setupChromeProcess");
if (this._delayedInitTask) {
@ -1718,10 +1721,6 @@ let Impl = {
* This observer drives telemetry.
*/
observe: function (aSubject, aTopic, aData) {
if (!this._log) {
this._log = Log.repository.getLoggerWithMessagePrefix(LOGGER_NAME, LOGGER_PREFIX);
}
// Prevent the cycle collector begin topic from cluttering the log.
if (aTopic != TOPIC_CYCLE_COLLECTOR_BEGIN) {
this._log.trace("observe - " + aTopic + " notified.");

View File

@ -186,12 +186,14 @@ function promiseRejects(promise) {
return promise.then(() => false, () => true);
}
// Set logging preferences for all the tests.
Services.prefs.setCharPref("toolkit.telemetry.log.level", "Trace");
TelemetryController.initLogging();
if (runningInParent) {
// Set logging preferences for all the tests.
Services.prefs.setCharPref("toolkit.telemetry.log.level", "Trace");
// Telemetry archiving should be on.
Services.prefs.setBoolPref("toolkit.telemetry.archive.enabled", true);
}
// Telemetry archiving should be on.
Services.prefs.setBoolPref("toolkit.telemetry.archive.enabled", true);
TelemetryController.initLogging();
// Avoid timers interrupting test behavior.
fakeSchedulerTimer(() => {}, () => {});

View File

@ -0,0 +1,89 @@
Cu.import("resource://gre/modules/TelemetryController.jsm", this);
Cu.import("resource://gre/modules/TelemetrySession.jsm", this);
Cu.import("resource://gre/modules/PromiseUtils.jsm", this);
const Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
const MESSAGE_TELEMETRY_PAYLOAD = "Telemetry:Payload";
const PLATFORM_VERSION = "1.9.2";
const APP_VERSION = "1";
const APP_ID = "xpcshell@tests.mozilla.org";
const APP_NAME = "XPCShell";
function run_child_test() {
// Setup histograms with some fixed values.
let flagHist = Telemetry.getHistogramById("TELEMETRY_TEST_FLAG");
flagHist.add(1);
let countHist = Telemetry.getHistogramById("TELEMETRY_TEST_COUNT");
countHist.add();
countHist.add();
let flagKeyed = Telemetry.getKeyedHistogramById("TELEMETRY_TEST_KEYED_FLAG");
flagKeyed.add("a", 1);
flagKeyed.add("b", 1);
let countKeyed = Telemetry.getKeyedHistogramById("TELEMETRY_TEST_KEYED_COUNT");
countKeyed.add("a");
countKeyed.add("b");
countKeyed.add("b");
// Check payload values.
const payload = TelemetrySession.getPayload("test-ping");
check_histogram_values(payload);
}
function check_histogram_values(payload) {
const hs = payload.histograms;
Assert.ok("TELEMETRY_TEST_COUNT" in hs, "Should have count test histogram.");
Assert.ok("TELEMETRY_TEST_FLAG" in hs, "Should have flag test histogram.");
Assert.equal(hs["TELEMETRY_TEST_COUNT"].sum, 2,
"Count test histogram should have the right value.");
Assert.equal(hs["TELEMETRY_TEST_FLAG"].sum, 1,
"Flag test histogram should have the right value.");
const kh = payload.keyedHistograms;
Assert.ok("TELEMETRY_TEST_KEYED_COUNT" in kh, "Should have keyed count test histogram.");
Assert.ok("TELEMETRY_TEST_KEYED_FLAG" in kh, "Should have keyed flag test histogram.");
Assert.equal(kh["TELEMETRY_TEST_KEYED_COUNT"]["a"].sum, 1,
"Keyed count test histogram should have the right value.");
Assert.equal(kh["TELEMETRY_TEST_KEYED_COUNT"]["b"].sum, 2,
"Keyed count test histogram should have the right value.");
Assert.equal(kh["TELEMETRY_TEST_KEYED_FLAG"]["a"].sum, 1,
"Keyed flag test histogram should have the right value.");
Assert.equal(kh["TELEMETRY_TEST_KEYED_FLAG"]["b"].sum, 1,
"Keyed flag test histogram should have the right value.");
}
add_task(function*() {
if (!runningInParent) {
TelemetryController.setupContent();
run_child_test();
return;
}
// Setup.
do_get_profile(true);
loadAddonManager(APP_ID, APP_NAME, APP_VERSION, PLATFORM_VERSION);
Services.prefs.setBoolPref("toolkit.telemetry.enabled", true);
yield TelemetryController.setup();
yield TelemetrySession.setup();
// Run test in child and wait until it is finished.
yield run_test_in_child("test_ChildHistograms.js");
// Gather payload from child.
let promiseMessage = do_await_remote_message(MESSAGE_TELEMETRY_PAYLOAD);
TelemetrySession.requestChildPayloads();
yield promiseMessage;
// Check child payload.
const payload = TelemetrySession.getPayload("test-ping");
Assert.ok("childPayloads" in payload, "Should have child payloads.");
Assert.equal(payload.childPayloads.length, 1, "Should have received one child payload so far.");
Assert.ok("histograms" in payload.childPayloads[0], "Child payload should have histograms.");
Assert.ok("keyedHistograms" in payload.childPayloads[0], "Child payload should have keyed histograms.");
check_histogram_values(payload.childPayloads[0]);
do_test_finished();
});

View File

@ -50,3 +50,5 @@ skip-if = os == "android" # Disabled due to intermittent orange on Android
skip-if = android_version == "18"
[test_ThreadHangStats.js]
run-sequentially = Bug 1046307, test can fail intermittently when CPU load is high
[test_ChildHistograms.js]
skip-if = os == "android"