mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 14:55:47 +00:00
Bug 1120379 - Add tests for the deletion ping. r=gfritzsche
This commit is contained in:
parent
8b8d56a308
commit
d05706c0a0
@ -1,267 +1,272 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<script type="application/javascript;version=1.7"
|
<script type="application/javascript;version=1.7"
|
||||||
src="healthreport_pingData.js">
|
src="healthreport_pingData.js">
|
||||||
</script>
|
</script>
|
||||||
<script type="application/javascript;version=1.7">
|
<script type="application/javascript;version=1.7">
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
window.addEventListener("message", function process(e) {
|
window.addEventListener("message", function process(e) {
|
||||||
// The init function of abouthealth.js schedules an initial payload event,
|
// The init function of abouthealth.js schedules an initial payload event,
|
||||||
// which will be sent after the payload data has been collected. This extra
|
// which will be sent after the payload data has been collected. This extra
|
||||||
// event can cause unexpected successes/failures in this test, so we wait
|
// event can cause unexpected successes/failures in this test, so we wait
|
||||||
// for the extra event to arrive here before progressing with the actual
|
// for the extra event to arrive here before progressing with the actual
|
||||||
// test.
|
// test.
|
||||||
if (e.data.type == "payload") {
|
if (e.data.type == "payload") {
|
||||||
window.removeEventListener("message", process, false);
|
window.removeEventListener("message", process, false);
|
||||||
|
|
||||||
window.addEventListener("message", doTest, false);
|
window.addEventListener("message", doTest, false);
|
||||||
doTest();
|
doTest();
|
||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSubmissionValue(payload, expectedValue) {
|
function checkSubmissionValue(payload, expectedValue) {
|
||||||
return payload.enabled == expectedValue;
|
return payload.enabled == expectedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
function validatePayload(payload) {
|
function validatePayload(payload) {
|
||||||
payload = JSON.parse(payload);
|
payload = JSON.parse(payload);
|
||||||
|
|
||||||
// xxxmpc - this is some pretty low-bar validation, but we have plenty of tests of that API elsewhere
|
// xxxmpc - this is some pretty low-bar validation, but we have plenty of tests of that API elsewhere
|
||||||
if (!payload.thisPingDate)
|
if (!payload.thisPingDate)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isArray(arg) {
|
function isArray(arg) {
|
||||||
return Object.prototype.toString.call(arg) === '[object Array]';
|
return Object.prototype.toString.call(arg) === '[object Array]';
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeDiagnostic(text) {
|
function writeDiagnostic(text) {
|
||||||
let node = document.createTextNode(text);
|
let node = document.createTextNode(text);
|
||||||
let br = document.createElement("br");
|
let br = document.createElement("br");
|
||||||
document.body.appendChild(node);
|
document.body.appendChild(node);
|
||||||
document.body.appendChild(br);
|
document.body.appendChild(br);
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateCurrentTelemetryEnvironment(data) {
|
function validateCurrentTelemetryEnvironment(data) {
|
||||||
// Simple check for now: check that the received object has the expected
|
// Simple check for now: check that the received object has the expected
|
||||||
// top-level properties.
|
// top-level properties.
|
||||||
const expectedKeys = ["profile", "settings", "system", "build", "partner", "addons"];
|
const expectedKeys = ["profile", "settings", "system", "build", "partner", "addons"];
|
||||||
return expectedKeys.every(key => (key in data));
|
return expectedKeys.every(key => (key in data));
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateCurrentTelemetryPingData(ping) {
|
function validateCurrentTelemetryPingData(ping) {
|
||||||
// Simple check for now: check that the received object has the expected
|
// Simple check for now: check that the received object has the expected
|
||||||
// top-level properties and that the type and reason match.
|
// top-level properties and that the type and reason match.
|
||||||
const expectedKeys = ["environment", "clientId", "payload", "application",
|
const expectedKeys = ["environment", "clientId", "payload", "application",
|
||||||
"version", "type", "id"];
|
"version", "type", "id"];
|
||||||
return expectedKeys.every(key => (key in ping)) &&
|
return expectedKeys.every(key => (key in ping)) &&
|
||||||
(ping.type == "main") &&
|
(ping.type == "main") &&
|
||||||
("info" in ping.payload) &&
|
("info" in ping.payload) &&
|
||||||
("reason" in ping.payload.info) &&
|
("reason" in ping.payload.info) &&
|
||||||
(ping.payload.info.reason == "gather-subsession-payload");
|
(ping.payload.info.reason == "gather-subsession-payload");
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateTelemetryPingList(list) {
|
function validateTelemetryPingList(list) {
|
||||||
if (!isArray(list)) {
|
if (!isArray(list)) {
|
||||||
console.log("Telemetry ping list is not an array.");
|
console.log("Telemetry ping list is not an array.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list.length != TEST_PINGS.length) {
|
// Telemetry may generate other pings (e.g. "deletion" pings), so filter those
|
||||||
console.log("Telemetry ping length is not correct.");
|
// out.
|
||||||
return false;
|
const TEST_TYPES_REGEX = /^test-telemetryArchive/;
|
||||||
}
|
list = list.filter(p => TEST_TYPES_REGEX.test(p.type));
|
||||||
|
|
||||||
let valid = true;
|
if (list.length != TEST_PINGS.length) {
|
||||||
for (let i=0; i<list.length; ++i) {
|
console.log("Telemetry ping length is not correct.");
|
||||||
let received = list[i];
|
return false;
|
||||||
let expected = TEST_PINGS[i];
|
}
|
||||||
if (received.type != expected.type ||
|
|
||||||
received.timestampCreated != expected.date.getTime()) {
|
let valid = true;
|
||||||
writeDiagnostic("Telemetry ping " + i + " does not match.");
|
for (let i=0; i<list.length; ++i) {
|
||||||
writeDiagnostic("Expected: " + JSON.stringify(expected));
|
let received = list[i];
|
||||||
writeDiagnostic("Received: " + JSON.stringify(received));
|
let expected = TEST_PINGS[i];
|
||||||
valid = false;
|
if (received.type != expected.type ||
|
||||||
} else {
|
received.timestampCreated != expected.date.getTime()) {
|
||||||
writeDiagnostic("Telemetry ping " + i + " matches.");
|
writeDiagnostic("Telemetry ping " + i + " does not match.");
|
||||||
}
|
writeDiagnostic("Expected: " + JSON.stringify(expected));
|
||||||
}
|
writeDiagnostic("Received: " + JSON.stringify(received));
|
||||||
|
valid = false;
|
||||||
return true;
|
} else {
|
||||||
}
|
writeDiagnostic("Telemetry ping " + i + " matches.");
|
||||||
|
}
|
||||||
function validateTelemetryPingData(expected, received) {
|
}
|
||||||
const receivedDate = new Date(received.creationDate);
|
|
||||||
if (received.id != expected.id ||
|
return true;
|
||||||
received.type != expected.type ||
|
}
|
||||||
receivedDate.getTime() != expected.date.getTime()) {
|
|
||||||
writeDiagnostic("Telemetry ping data for " + expected.id + " doesn't match.");
|
function validateTelemetryPingData(expected, received) {
|
||||||
writeDiagnostic("Expected: " + JSON.stringify(expected));
|
const receivedDate = new Date(received.creationDate);
|
||||||
writeDiagnostic("Received: " + JSON.stringify(received));
|
if (received.id != expected.id ||
|
||||||
return false;
|
received.type != expected.type ||
|
||||||
}
|
receivedDate.getTime() != expected.date.getTime()) {
|
||||||
|
writeDiagnostic("Telemetry ping data for " + expected.id + " doesn't match.");
|
||||||
writeDiagnostic("Telemetry ping data for " + expected.id + " matched.");
|
writeDiagnostic("Expected: " + JSON.stringify(expected));
|
||||||
return true;
|
writeDiagnostic("Received: " + JSON.stringify(received));
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
var tests = [
|
|
||||||
{
|
writeDiagnostic("Telemetry ping data for " + expected.id + " matched.");
|
||||||
info: "Checking initial value is enabled",
|
return true;
|
||||||
event: "RequestCurrentPrefs",
|
}
|
||||||
payloadType: "prefs",
|
|
||||||
validateResponse: function(payload) {
|
var tests = [
|
||||||
return checkSubmissionValue(payload, true);
|
{
|
||||||
},
|
info: "Checking initial value is enabled",
|
||||||
},
|
event: "RequestCurrentPrefs",
|
||||||
{
|
payloadType: "prefs",
|
||||||
info: "Verifying disabling works",
|
validateResponse: function(payload) {
|
||||||
event: "DisableDataSubmission",
|
return checkSubmissionValue(payload, true);
|
||||||
payloadType: "prefs",
|
},
|
||||||
validateResponse: function(payload) {
|
},
|
||||||
return checkSubmissionValue(payload, false);
|
{
|
||||||
},
|
info: "Verifying disabling works",
|
||||||
},
|
event: "DisableDataSubmission",
|
||||||
{
|
payloadType: "prefs",
|
||||||
info: "Verifying we're still disabled",
|
validateResponse: function(payload) {
|
||||||
event: "RequestCurrentPrefs",
|
return checkSubmissionValue(payload, false);
|
||||||
payloadType: "prefs",
|
},
|
||||||
validateResponse: function(payload) {
|
},
|
||||||
return checkSubmissionValue(payload, false);
|
{
|
||||||
},
|
info: "Verifying we're still disabled",
|
||||||
},
|
event: "RequestCurrentPrefs",
|
||||||
{
|
payloadType: "prefs",
|
||||||
info: "Verifying we can get a payload while submission is disabled",
|
validateResponse: function(payload) {
|
||||||
event: "RequestCurrentPayload",
|
return checkSubmissionValue(payload, false);
|
||||||
payloadType: "payload",
|
},
|
||||||
validateResponse: function(payload) {
|
},
|
||||||
return validatePayload(payload);
|
{
|
||||||
},
|
info: "Verifying we can get a payload while submission is disabled",
|
||||||
},
|
event: "RequestCurrentPayload",
|
||||||
{
|
payloadType: "payload",
|
||||||
info: "Verifying enabling works",
|
validateResponse: function(payload) {
|
||||||
event: "EnableDataSubmission",
|
return validatePayload(payload);
|
||||||
payloadType: "prefs",
|
},
|
||||||
validateResponse: function(payload) {
|
},
|
||||||
return checkSubmissionValue(payload, true);
|
{
|
||||||
},
|
info: "Verifying enabling works",
|
||||||
},
|
event: "EnableDataSubmission",
|
||||||
{
|
payloadType: "prefs",
|
||||||
info: "Verifying we're still re-enabled",
|
validateResponse: function(payload) {
|
||||||
event: "RequestCurrentPrefs",
|
return checkSubmissionValue(payload, true);
|
||||||
payloadType: "prefs",
|
},
|
||||||
validateResponse: function(payload) {
|
},
|
||||||
return checkSubmissionValue(payload, true);
|
{
|
||||||
},
|
info: "Verifying we're still re-enabled",
|
||||||
},
|
event: "RequestCurrentPrefs",
|
||||||
{
|
payloadType: "prefs",
|
||||||
info: "Verifying we can get a payload after re-enabling",
|
validateResponse: function(payload) {
|
||||||
event: "RequestCurrentPayload",
|
return checkSubmissionValue(payload, true);
|
||||||
payloadType: "payload",
|
},
|
||||||
validateResponse: function(payload) {
|
},
|
||||||
return validatePayload(payload);
|
{
|
||||||
},
|
info: "Verifying we can get a payload after re-enabling",
|
||||||
},
|
event: "RequestCurrentPayload",
|
||||||
{
|
payloadType: "payload",
|
||||||
info: "Verifying that we can get the current Telemetry environment data",
|
validateResponse: function(payload) {
|
||||||
event: "RequestCurrentEnvironment",
|
return validatePayload(payload);
|
||||||
payloadType: "telemetry-current-environment-data",
|
},
|
||||||
validateResponse: function(payload) {
|
},
|
||||||
return validateCurrentTelemetryEnvironment(payload);
|
{
|
||||||
},
|
info: "Verifying that we can get the current Telemetry environment data",
|
||||||
},
|
event: "RequestCurrentEnvironment",
|
||||||
{
|
payloadType: "telemetry-current-environment-data",
|
||||||
info: "Verifying that we can get the current Telemetry ping data",
|
validateResponse: function(payload) {
|
||||||
event: "RequestCurrentPingData",
|
return validateCurrentTelemetryEnvironment(payload);
|
||||||
payloadType: "telemetry-current-ping-data",
|
},
|
||||||
validateResponse: function(payload) {
|
},
|
||||||
return validateCurrentTelemetryPingData(payload);
|
{
|
||||||
},
|
info: "Verifying that we can get the current Telemetry ping data",
|
||||||
},
|
event: "RequestCurrentPingData",
|
||||||
{
|
payloadType: "telemetry-current-ping-data",
|
||||||
info: "Verifying that we get the proper Telemetry ping list",
|
validateResponse: function(payload) {
|
||||||
event: "RequestTelemetryPingList",
|
return validateCurrentTelemetryPingData(payload);
|
||||||
payloadType: "telemetry-ping-list",
|
},
|
||||||
validateResponse: function(payload) {
|
},
|
||||||
// Validate the ping list
|
{
|
||||||
if (!validateTelemetryPingList(payload)) {
|
info: "Verifying that we get the proper Telemetry ping list",
|
||||||
return false;
|
event: "RequestTelemetryPingList",
|
||||||
}
|
payloadType: "telemetry-ping-list",
|
||||||
|
validateResponse: function(payload) {
|
||||||
// Now that we received the ping ids, set up additional test tasks
|
// Validate the ping list
|
||||||
// that check loading the individual pings.
|
if (!validateTelemetryPingList(payload)) {
|
||||||
for (let i=0; i<TEST_PINGS.length; ++i) {
|
return false;
|
||||||
TEST_PINGS[i].id = payload[i].id;
|
}
|
||||||
tests.push({
|
|
||||||
info: "Verifying that we can get the proper Telemetry ping data #" + (i + 1),
|
// Now that we received the ping ids, set up additional test tasks
|
||||||
event: "RequestTelemetryPingData",
|
// that check loading the individual pings.
|
||||||
eventData: { id: TEST_PINGS[i].id },
|
for (let i=0; i<TEST_PINGS.length; ++i) {
|
||||||
payloadType: "telemetry-ping-data",
|
TEST_PINGS[i].id = payload[i].id;
|
||||||
validateResponse: function(payload) {
|
tests.push({
|
||||||
return validateTelemetryPingData(TEST_PINGS[i], payload.pingData);
|
info: "Verifying that we can get the proper Telemetry ping data #" + (i + 1),
|
||||||
},
|
event: "RequestTelemetryPingData",
|
||||||
});
|
eventData: { id: TEST_PINGS[i].id },
|
||||||
}
|
payloadType: "telemetry-ping-data",
|
||||||
|
validateResponse: function(payload) {
|
||||||
return true;
|
return validateTelemetryPingData(TEST_PINGS[i], payload.pingData);
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
];
|
}
|
||||||
|
|
||||||
var currentTest = -1;
|
return true;
|
||||||
function doTest(evt) {
|
},
|
||||||
if (evt) {
|
},
|
||||||
if (currentTest < 0 || !evt.data.content)
|
];
|
||||||
return; // not yet testing
|
|
||||||
|
var currentTest = -1;
|
||||||
var test = tests[currentTest];
|
function doTest(evt) {
|
||||||
if (evt.data.type != test.payloadType)
|
if (evt) {
|
||||||
return; // skip unrequested events
|
if (currentTest < 0 || !evt.data.content)
|
||||||
|
return; // not yet testing
|
||||||
var error = JSON.stringify(evt.data.content);
|
|
||||||
var pass = false;
|
var test = tests[currentTest];
|
||||||
try {
|
if (evt.data.type != test.payloadType)
|
||||||
pass = test.validateResponse(evt.data.content)
|
return; // skip unrequested events
|
||||||
} catch (e) {}
|
|
||||||
reportResult(test.info, pass, error);
|
var error = JSON.stringify(evt.data.content);
|
||||||
}
|
var pass = false;
|
||||||
// start the next test if there are any left
|
try {
|
||||||
if (tests[++currentTest])
|
pass = test.validateResponse(evt.data.content)
|
||||||
sendToBrowser(tests[currentTest].event, tests[currentTest].eventData);
|
} catch (e) {}
|
||||||
else
|
reportResult(test.info, pass, error);
|
||||||
reportFinished();
|
}
|
||||||
}
|
// start the next test if there are any left
|
||||||
|
if (tests[++currentTest])
|
||||||
function reportResult(info, pass, error) {
|
sendToBrowser(tests[currentTest].event, tests[currentTest].eventData);
|
||||||
var data = {type: "testResult", info: info, pass: pass, error: error};
|
else
|
||||||
var event = new CustomEvent("FirefoxHealthReportTestResponse", {detail: {data: data}, bubbles: true});
|
reportFinished();
|
||||||
document.dispatchEvent(event);
|
}
|
||||||
}
|
|
||||||
|
function reportResult(info, pass, error) {
|
||||||
function reportFinished(cmd) {
|
var data = {type: "testResult", info: info, pass: pass, error: error};
|
||||||
var data = {type: "testsComplete", count: tests.length};
|
var event = new CustomEvent("FirefoxHealthReportTestResponse", {detail: {data: data}, bubbles: true});
|
||||||
var event = new CustomEvent("FirefoxHealthReportTestResponse", {detail: {data: data}, bubbles: true});
|
document.dispatchEvent(event);
|
||||||
document.dispatchEvent(event);
|
}
|
||||||
}
|
|
||||||
|
function reportFinished(cmd) {
|
||||||
function sendToBrowser(type, eventData) {
|
var data = {type: "testsComplete", count: tests.length};
|
||||||
eventData = eventData || {};
|
var event = new CustomEvent("FirefoxHealthReportTestResponse", {detail: {data: data}, bubbles: true});
|
||||||
let detail = {command: type};
|
document.dispatchEvent(event);
|
||||||
for (let key of Object.keys(eventData)) {
|
}
|
||||||
detail[key] = eventData[key];
|
|
||||||
}
|
function sendToBrowser(type, eventData) {
|
||||||
|
eventData = eventData || {};
|
||||||
var event = new CustomEvent("RemoteHealthReportCommand", {detail: detail, bubbles: true});
|
let detail = {command: type};
|
||||||
document.dispatchEvent(event);
|
for (let key of Object.keys(eventData)) {
|
||||||
}
|
detail[key] = eventData[key];
|
||||||
|
}
|
||||||
</script>
|
|
||||||
</head>
|
var event = new CustomEvent("RemoteHealthReportCommand", {detail: detail, bubbles: true});
|
||||||
<body onload="init()">
|
document.dispatchEvent(event);
|
||||||
</body>
|
}
|
||||||
</html>
|
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body onload="init()">
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
@ -21,6 +21,7 @@ Cu.import("resource://gre/modules/Promise.jsm", this);
|
|||||||
Cu.import("resource://gre/modules/Preferences.jsm");
|
Cu.import("resource://gre/modules/Preferences.jsm");
|
||||||
|
|
||||||
const PING_FORMAT_VERSION = 4;
|
const PING_FORMAT_VERSION = 4;
|
||||||
|
const DELETION_PING_TYPE = "deletion";
|
||||||
const TEST_PING_TYPE = "test-ping-type";
|
const TEST_PING_TYPE = "test-ping-type";
|
||||||
|
|
||||||
const PLATFORM_VERSION = "1.9.2";
|
const PLATFORM_VERSION = "1.9.2";
|
||||||
@ -174,6 +175,25 @@ add_task(function* test_simplePing() {
|
|||||||
checkPingFormat(ping, TEST_PING_TYPE, false, false);
|
checkPingFormat(ping, TEST_PING_TYPE, false, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
add_task(function* test_deletionPing() {
|
||||||
|
const isUnified = Preferences.get(PREF_UNIFIED, false);
|
||||||
|
if (!isUnified) {
|
||||||
|
// Skipping the test if unified telemetry is off, as no deletion ping will
|
||||||
|
// be generated.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable FHR upload: this should trigger a deletion ping.
|
||||||
|
Preferences.set(PREF_FHR_UPLOAD_ENABLED, false);
|
||||||
|
|
||||||
|
let request = yield gRequestIterator.next();
|
||||||
|
let ping = decodeRequestPayload(request);
|
||||||
|
checkPingFormat(ping, DELETION_PING_TYPE, true, false);
|
||||||
|
|
||||||
|
// Restore FHR Upload.
|
||||||
|
Preferences.set(PREF_FHR_UPLOAD_ENABLED, true);
|
||||||
|
});
|
||||||
|
|
||||||
add_task(function* test_pingHasClientId() {
|
add_task(function* test_pingHasClientId() {
|
||||||
// Send a ping with a clientId.
|
// Send a ping with a clientId.
|
||||||
yield sendPing(true, false);
|
yield sendPing(true, false);
|
||||||
@ -231,6 +251,14 @@ add_task(function* test_archivePings() {
|
|||||||
const uploadPref = isUnified ? PREF_FHR_UPLOAD_ENABLED : PREF_ENABLED;
|
const uploadPref = isUnified ? PREF_FHR_UPLOAD_ENABLED : PREF_ENABLED;
|
||||||
Preferences.set(uploadPref, false);
|
Preferences.set(uploadPref, false);
|
||||||
|
|
||||||
|
// If we're using unified telemetry, disabling ping upload will generate a "deletion"
|
||||||
|
// ping. Catch it.
|
||||||
|
if (isUnified) {
|
||||||
|
let request = yield gRequestIterator.next();
|
||||||
|
let ping = decodeRequestPayload(request);
|
||||||
|
checkPingFormat(ping, DELETION_PING_TYPE, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
// Register a new Ping Handler that asserts if a ping is received, then send a ping.
|
// Register a new Ping Handler that asserts if a ping is received, then send a ping.
|
||||||
registerPingHandler(() => Assert.ok(false, "Telemetry must not send pings if not allowed to."));
|
registerPingHandler(() => Assert.ok(false, "Telemetry must not send pings if not allowed to."));
|
||||||
let pingId = yield sendPing(true, true);
|
let pingId = yield sendPing(true, true);
|
||||||
|
Loading…
Reference in New Issue
Block a user