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>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script type="application/javascript;version=1.7"
|
||||
src="healthreport_pingData.js">
|
||||
</script>
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
function init() {
|
||||
window.addEventListener("message", function process(e) {
|
||||
// The init function of abouthealth.js schedules an initial payload event,
|
||||
// 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
|
||||
// for the extra event to arrive here before progressing with the actual
|
||||
// test.
|
||||
if (e.data.type == "payload") {
|
||||
window.removeEventListener("message", process, false);
|
||||
|
||||
window.addEventListener("message", doTest, false);
|
||||
doTest();
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
function checkSubmissionValue(payload, expectedValue) {
|
||||
return payload.enabled == expectedValue;
|
||||
}
|
||||
|
||||
function validatePayload(payload) {
|
||||
payload = JSON.parse(payload);
|
||||
|
||||
// xxxmpc - this is some pretty low-bar validation, but we have plenty of tests of that API elsewhere
|
||||
if (!payload.thisPingDate)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function isArray(arg) {
|
||||
return Object.prototype.toString.call(arg) === '[object Array]';
|
||||
}
|
||||
|
||||
function writeDiagnostic(text) {
|
||||
let node = document.createTextNode(text);
|
||||
let br = document.createElement("br");
|
||||
document.body.appendChild(node);
|
||||
document.body.appendChild(br);
|
||||
}
|
||||
|
||||
function validateCurrentTelemetryEnvironment(data) {
|
||||
// Simple check for now: check that the received object has the expected
|
||||
// top-level properties.
|
||||
const expectedKeys = ["profile", "settings", "system", "build", "partner", "addons"];
|
||||
return expectedKeys.every(key => (key in data));
|
||||
}
|
||||
|
||||
function validateCurrentTelemetryPingData(ping) {
|
||||
// Simple check for now: check that the received object has the expected
|
||||
// top-level properties and that the type and reason match.
|
||||
const expectedKeys = ["environment", "clientId", "payload", "application",
|
||||
"version", "type", "id"];
|
||||
return expectedKeys.every(key => (key in ping)) &&
|
||||
(ping.type == "main") &&
|
||||
("info" in ping.payload) &&
|
||||
("reason" in ping.payload.info) &&
|
||||
(ping.payload.info.reason == "gather-subsession-payload");
|
||||
}
|
||||
|
||||
function validateTelemetryPingList(list) {
|
||||
if (!isArray(list)) {
|
||||
console.log("Telemetry ping list is not an array.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (list.length != TEST_PINGS.length) {
|
||||
console.log("Telemetry ping length is not correct.");
|
||||
return false;
|
||||
}
|
||||
|
||||
let valid = true;
|
||||
for (let i=0; i<list.length; ++i) {
|
||||
let received = list[i];
|
||||
let expected = TEST_PINGS[i];
|
||||
if (received.type != expected.type ||
|
||||
received.timestampCreated != expected.date.getTime()) {
|
||||
writeDiagnostic("Telemetry ping " + i + " does not match.");
|
||||
writeDiagnostic("Expected: " + JSON.stringify(expected));
|
||||
writeDiagnostic("Received: " + JSON.stringify(received));
|
||||
valid = false;
|
||||
} else {
|
||||
writeDiagnostic("Telemetry ping " + i + " matches.");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function validateTelemetryPingData(expected, received) {
|
||||
const receivedDate = new Date(received.creationDate);
|
||||
if (received.id != expected.id ||
|
||||
received.type != expected.type ||
|
||||
receivedDate.getTime() != expected.date.getTime()) {
|
||||
writeDiagnostic("Telemetry ping data for " + expected.id + " doesn't match.");
|
||||
writeDiagnostic("Expected: " + JSON.stringify(expected));
|
||||
writeDiagnostic("Received: " + JSON.stringify(received));
|
||||
return false;
|
||||
}
|
||||
|
||||
writeDiagnostic("Telemetry ping data for " + expected.id + " matched.");
|
||||
return true;
|
||||
}
|
||||
|
||||
var tests = [
|
||||
{
|
||||
info: "Checking initial value is enabled",
|
||||
event: "RequestCurrentPrefs",
|
||||
payloadType: "prefs",
|
||||
validateResponse: function(payload) {
|
||||
return checkSubmissionValue(payload, true);
|
||||
},
|
||||
},
|
||||
{
|
||||
info: "Verifying disabling works",
|
||||
event: "DisableDataSubmission",
|
||||
payloadType: "prefs",
|
||||
validateResponse: function(payload) {
|
||||
return checkSubmissionValue(payload, false);
|
||||
},
|
||||
},
|
||||
{
|
||||
info: "Verifying we're still disabled",
|
||||
event: "RequestCurrentPrefs",
|
||||
payloadType: "prefs",
|
||||
validateResponse: function(payload) {
|
||||
return checkSubmissionValue(payload, false);
|
||||
},
|
||||
},
|
||||
{
|
||||
info: "Verifying we can get a payload while submission is disabled",
|
||||
event: "RequestCurrentPayload",
|
||||
payloadType: "payload",
|
||||
validateResponse: function(payload) {
|
||||
return validatePayload(payload);
|
||||
},
|
||||
},
|
||||
{
|
||||
info: "Verifying enabling works",
|
||||
event: "EnableDataSubmission",
|
||||
payloadType: "prefs",
|
||||
validateResponse: function(payload) {
|
||||
return checkSubmissionValue(payload, true);
|
||||
},
|
||||
},
|
||||
{
|
||||
info: "Verifying we're still re-enabled",
|
||||
event: "RequestCurrentPrefs",
|
||||
payloadType: "prefs",
|
||||
validateResponse: function(payload) {
|
||||
return checkSubmissionValue(payload, true);
|
||||
},
|
||||
},
|
||||
{
|
||||
info: "Verifying we can get a payload after re-enabling",
|
||||
event: "RequestCurrentPayload",
|
||||
payloadType: "payload",
|
||||
validateResponse: function(payload) {
|
||||
return validatePayload(payload);
|
||||
},
|
||||
},
|
||||
{
|
||||
info: "Verifying that we can get the current Telemetry environment data",
|
||||
event: "RequestCurrentEnvironment",
|
||||
payloadType: "telemetry-current-environment-data",
|
||||
validateResponse: function(payload) {
|
||||
return validateCurrentTelemetryEnvironment(payload);
|
||||
},
|
||||
},
|
||||
{
|
||||
info: "Verifying that we can get the current Telemetry ping data",
|
||||
event: "RequestCurrentPingData",
|
||||
payloadType: "telemetry-current-ping-data",
|
||||
validateResponse: function(payload) {
|
||||
return validateCurrentTelemetryPingData(payload);
|
||||
},
|
||||
},
|
||||
{
|
||||
info: "Verifying that we get the proper Telemetry ping list",
|
||||
event: "RequestTelemetryPingList",
|
||||
payloadType: "telemetry-ping-list",
|
||||
validateResponse: function(payload) {
|
||||
// Validate the ping list
|
||||
if (!validateTelemetryPingList(payload)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now that we received the ping ids, set up additional test tasks
|
||||
// that check loading the individual pings.
|
||||
for (let i=0; i<TEST_PINGS.length; ++i) {
|
||||
TEST_PINGS[i].id = payload[i].id;
|
||||
tests.push({
|
||||
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 validateTelemetryPingData(TEST_PINGS[i], payload.pingData);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
var currentTest = -1;
|
||||
function doTest(evt) {
|
||||
if (evt) {
|
||||
if (currentTest < 0 || !evt.data.content)
|
||||
return; // not yet testing
|
||||
|
||||
var test = tests[currentTest];
|
||||
if (evt.data.type != test.payloadType)
|
||||
return; // skip unrequested events
|
||||
|
||||
var error = JSON.stringify(evt.data.content);
|
||||
var pass = false;
|
||||
try {
|
||||
pass = test.validateResponse(evt.data.content)
|
||||
} catch (e) {}
|
||||
reportResult(test.info, pass, error);
|
||||
}
|
||||
// start the next test if there are any left
|
||||
if (tests[++currentTest])
|
||||
sendToBrowser(tests[currentTest].event, tests[currentTest].eventData);
|
||||
else
|
||||
reportFinished();
|
||||
}
|
||||
|
||||
function reportResult(info, pass, error) {
|
||||
var data = {type: "testResult", info: info, pass: pass, error: error};
|
||||
var event = new CustomEvent("FirefoxHealthReportTestResponse", {detail: {data: data}, bubbles: true});
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
function reportFinished(cmd) {
|
||||
var data = {type: "testsComplete", count: tests.length};
|
||||
var event = new CustomEvent("FirefoxHealthReportTestResponse", {detail: {data: data}, bubbles: true});
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
function sendToBrowser(type, eventData) {
|
||||
eventData = eventData || {};
|
||||
let detail = {command: type};
|
||||
for (let key of Object.keys(eventData)) {
|
||||
detail[key] = eventData[key];
|
||||
}
|
||||
|
||||
var event = new CustomEvent("RemoteHealthReportCommand", {detail: detail, bubbles: true});
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
</body>
|
||||
</html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script type="application/javascript;version=1.7"
|
||||
src="healthreport_pingData.js">
|
||||
</script>
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
function init() {
|
||||
window.addEventListener("message", function process(e) {
|
||||
// The init function of abouthealth.js schedules an initial payload event,
|
||||
// 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
|
||||
// for the extra event to arrive here before progressing with the actual
|
||||
// test.
|
||||
if (e.data.type == "payload") {
|
||||
window.removeEventListener("message", process, false);
|
||||
|
||||
window.addEventListener("message", doTest, false);
|
||||
doTest();
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
function checkSubmissionValue(payload, expectedValue) {
|
||||
return payload.enabled == expectedValue;
|
||||
}
|
||||
|
||||
function validatePayload(payload) {
|
||||
payload = JSON.parse(payload);
|
||||
|
||||
// xxxmpc - this is some pretty low-bar validation, but we have plenty of tests of that API elsewhere
|
||||
if (!payload.thisPingDate)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function isArray(arg) {
|
||||
return Object.prototype.toString.call(arg) === '[object Array]';
|
||||
}
|
||||
|
||||
function writeDiagnostic(text) {
|
||||
let node = document.createTextNode(text);
|
||||
let br = document.createElement("br");
|
||||
document.body.appendChild(node);
|
||||
document.body.appendChild(br);
|
||||
}
|
||||
|
||||
function validateCurrentTelemetryEnvironment(data) {
|
||||
// Simple check for now: check that the received object has the expected
|
||||
// top-level properties.
|
||||
const expectedKeys = ["profile", "settings", "system", "build", "partner", "addons"];
|
||||
return expectedKeys.every(key => (key in data));
|
||||
}
|
||||
|
||||
function validateCurrentTelemetryPingData(ping) {
|
||||
// Simple check for now: check that the received object has the expected
|
||||
// top-level properties and that the type and reason match.
|
||||
const expectedKeys = ["environment", "clientId", "payload", "application",
|
||||
"version", "type", "id"];
|
||||
return expectedKeys.every(key => (key in ping)) &&
|
||||
(ping.type == "main") &&
|
||||
("info" in ping.payload) &&
|
||||
("reason" in ping.payload.info) &&
|
||||
(ping.payload.info.reason == "gather-subsession-payload");
|
||||
}
|
||||
|
||||
function validateTelemetryPingList(list) {
|
||||
if (!isArray(list)) {
|
||||
console.log("Telemetry ping list is not an array.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Telemetry may generate other pings (e.g. "deletion" pings), so filter those
|
||||
// out.
|
||||
const TEST_TYPES_REGEX = /^test-telemetryArchive/;
|
||||
list = list.filter(p => TEST_TYPES_REGEX.test(p.type));
|
||||
|
||||
if (list.length != TEST_PINGS.length) {
|
||||
console.log("Telemetry ping length is not correct.");
|
||||
return false;
|
||||
}
|
||||
|
||||
let valid = true;
|
||||
for (let i=0; i<list.length; ++i) {
|
||||
let received = list[i];
|
||||
let expected = TEST_PINGS[i];
|
||||
if (received.type != expected.type ||
|
||||
received.timestampCreated != expected.date.getTime()) {
|
||||
writeDiagnostic("Telemetry ping " + i + " does not match.");
|
||||
writeDiagnostic("Expected: " + JSON.stringify(expected));
|
||||
writeDiagnostic("Received: " + JSON.stringify(received));
|
||||
valid = false;
|
||||
} else {
|
||||
writeDiagnostic("Telemetry ping " + i + " matches.");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function validateTelemetryPingData(expected, received) {
|
||||
const receivedDate = new Date(received.creationDate);
|
||||
if (received.id != expected.id ||
|
||||
received.type != expected.type ||
|
||||
receivedDate.getTime() != expected.date.getTime()) {
|
||||
writeDiagnostic("Telemetry ping data for " + expected.id + " doesn't match.");
|
||||
writeDiagnostic("Expected: " + JSON.stringify(expected));
|
||||
writeDiagnostic("Received: " + JSON.stringify(received));
|
||||
return false;
|
||||
}
|
||||
|
||||
writeDiagnostic("Telemetry ping data for " + expected.id + " matched.");
|
||||
return true;
|
||||
}
|
||||
|
||||
var tests = [
|
||||
{
|
||||
info: "Checking initial value is enabled",
|
||||
event: "RequestCurrentPrefs",
|
||||
payloadType: "prefs",
|
||||
validateResponse: function(payload) {
|
||||
return checkSubmissionValue(payload, true);
|
||||
},
|
||||
},
|
||||
{
|
||||
info: "Verifying disabling works",
|
||||
event: "DisableDataSubmission",
|
||||
payloadType: "prefs",
|
||||
validateResponse: function(payload) {
|
||||
return checkSubmissionValue(payload, false);
|
||||
},
|
||||
},
|
||||
{
|
||||
info: "Verifying we're still disabled",
|
||||
event: "RequestCurrentPrefs",
|
||||
payloadType: "prefs",
|
||||
validateResponse: function(payload) {
|
||||
return checkSubmissionValue(payload, false);
|
||||
},
|
||||
},
|
||||
{
|
||||
info: "Verifying we can get a payload while submission is disabled",
|
||||
event: "RequestCurrentPayload",
|
||||
payloadType: "payload",
|
||||
validateResponse: function(payload) {
|
||||
return validatePayload(payload);
|
||||
},
|
||||
},
|
||||
{
|
||||
info: "Verifying enabling works",
|
||||
event: "EnableDataSubmission",
|
||||
payloadType: "prefs",
|
||||
validateResponse: function(payload) {
|
||||
return checkSubmissionValue(payload, true);
|
||||
},
|
||||
},
|
||||
{
|
||||
info: "Verifying we're still re-enabled",
|
||||
event: "RequestCurrentPrefs",
|
||||
payloadType: "prefs",
|
||||
validateResponse: function(payload) {
|
||||
return checkSubmissionValue(payload, true);
|
||||
},
|
||||
},
|
||||
{
|
||||
info: "Verifying we can get a payload after re-enabling",
|
||||
event: "RequestCurrentPayload",
|
||||
payloadType: "payload",
|
||||
validateResponse: function(payload) {
|
||||
return validatePayload(payload);
|
||||
},
|
||||
},
|
||||
{
|
||||
info: "Verifying that we can get the current Telemetry environment data",
|
||||
event: "RequestCurrentEnvironment",
|
||||
payloadType: "telemetry-current-environment-data",
|
||||
validateResponse: function(payload) {
|
||||
return validateCurrentTelemetryEnvironment(payload);
|
||||
},
|
||||
},
|
||||
{
|
||||
info: "Verifying that we can get the current Telemetry ping data",
|
||||
event: "RequestCurrentPingData",
|
||||
payloadType: "telemetry-current-ping-data",
|
||||
validateResponse: function(payload) {
|
||||
return validateCurrentTelemetryPingData(payload);
|
||||
},
|
||||
},
|
||||
{
|
||||
info: "Verifying that we get the proper Telemetry ping list",
|
||||
event: "RequestTelemetryPingList",
|
||||
payloadType: "telemetry-ping-list",
|
||||
validateResponse: function(payload) {
|
||||
// Validate the ping list
|
||||
if (!validateTelemetryPingList(payload)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now that we received the ping ids, set up additional test tasks
|
||||
// that check loading the individual pings.
|
||||
for (let i=0; i<TEST_PINGS.length; ++i) {
|
||||
TEST_PINGS[i].id = payload[i].id;
|
||||
tests.push({
|
||||
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 validateTelemetryPingData(TEST_PINGS[i], payload.pingData);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
var currentTest = -1;
|
||||
function doTest(evt) {
|
||||
if (evt) {
|
||||
if (currentTest < 0 || !evt.data.content)
|
||||
return; // not yet testing
|
||||
|
||||
var test = tests[currentTest];
|
||||
if (evt.data.type != test.payloadType)
|
||||
return; // skip unrequested events
|
||||
|
||||
var error = JSON.stringify(evt.data.content);
|
||||
var pass = false;
|
||||
try {
|
||||
pass = test.validateResponse(evt.data.content)
|
||||
} catch (e) {}
|
||||
reportResult(test.info, pass, error);
|
||||
}
|
||||
// start the next test if there are any left
|
||||
if (tests[++currentTest])
|
||||
sendToBrowser(tests[currentTest].event, tests[currentTest].eventData);
|
||||
else
|
||||
reportFinished();
|
||||
}
|
||||
|
||||
function reportResult(info, pass, error) {
|
||||
var data = {type: "testResult", info: info, pass: pass, error: error};
|
||||
var event = new CustomEvent("FirefoxHealthReportTestResponse", {detail: {data: data}, bubbles: true});
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
function reportFinished(cmd) {
|
||||
var data = {type: "testsComplete", count: tests.length};
|
||||
var event = new CustomEvent("FirefoxHealthReportTestResponse", {detail: {data: data}, bubbles: true});
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
function sendToBrowser(type, eventData) {
|
||||
eventData = eventData || {};
|
||||
let detail = {command: type};
|
||||
for (let key of Object.keys(eventData)) {
|
||||
detail[key] = eventData[key];
|
||||
}
|
||||
|
||||
var event = new CustomEvent("RemoteHealthReportCommand", {detail: detail, bubbles: true});
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
</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");
|
||||
|
||||
const PING_FORMAT_VERSION = 4;
|
||||
const DELETION_PING_TYPE = "deletion";
|
||||
const TEST_PING_TYPE = "test-ping-type";
|
||||
|
||||
const PLATFORM_VERSION = "1.9.2";
|
||||
@ -174,6 +175,25 @@ add_task(function* test_simplePing() {
|
||||
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() {
|
||||
// Send a ping with a clientId.
|
||||
yield sendPing(true, false);
|
||||
@ -231,6 +251,14 @@ add_task(function* test_archivePings() {
|
||||
const uploadPref = isUnified ? PREF_FHR_UPLOAD_ENABLED : PREF_ENABLED;
|
||||
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.
|
||||
registerPingHandler(() => Assert.ok(false, "Telemetry must not send pings if not allowed to."));
|
||||
let pingId = yield sendPing(true, true);
|
||||
|
Loading…
Reference in New Issue
Block a user