Bug 1596661 - Add keyed scalars to browser.telemetry r=rpl

Differential Revision: https://phabricator.services.mozilla.com/D53142

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Drew Willcoxon 2019-11-19 17:05:25 +00:00
Родитель 82def0e31f
Коммит 2de3334d5a
3 изменённых файлов: 420 добавлений и 78 удалений

Просмотреть файл

@ -94,6 +94,30 @@ this.telemetry = class extends ExtensionAPI {
throw new ExtensionUtils.ExtensionError(ex);
}
},
keyedScalarAdd(name, key, value) {
desktopCheck();
try {
Services.telemetry.keyedScalarAdd(name, key, value);
} catch (ex) {
throw new ExtensionUtils.ExtensionError(ex);
}
},
keyedScalarSet(name, key, value) {
desktopCheck();
try {
Services.telemetry.keyedScalarSet(name, key, value);
} catch (ex) {
throw new ExtensionUtils.ExtensionError(ex);
}
},
keyedScalarSetMaximum(name, key, value) {
desktopCheck();
try {
Services.telemetry.keyedScalarSetMaximum(name, key, value);
} catch (ex) {
throw new ExtensionUtils.ExtensionError(ex);
}
},
recordEvent(category, method, object, value, extra) {
desktopCheck();
try {

Просмотреть файл

@ -201,6 +201,82 @@
}
]
},
{
"name": "keyedScalarAdd",
"type": "function",
"description": "Adds the value to the given keyed scalar.",
"async": true,
"parameters": [
{
"name": "name",
"type": "string",
"description": "The scalar name"
},
{
"name": "key",
"type": "string",
"description": "The key name"
},
{
"name": "value",
"type": "integer",
"minimum": 1,
"description": "The numeric value to add to the scalar. Only unsigned integers supported."
}
]
},
{
"name": "keyedScalarSet",
"type": "function",
"description": "Sets the keyed scalar to the given value. Throws if the value type doesn't match the scalar type.",
"async": true,
"parameters": [
{
"name": "name",
"type": "string",
"description": "The scalar name."
},
{
"name": "key",
"type": "string",
"description": "The key name."
},
{
"name": "value",
"description": "The value to set the scalar to.",
"choices": [
{ "type": "string" },
{ "type": "boolean" },
{ "type": "integer" },
{ "type": "object", "additionalProperties": { "type": "any" } }
]
}
]
},
{
"name": "keyedScalarSetMaximum",
"type": "function",
"description": "Sets the keyed scalar to the maximum of the current and the passed value",
"async": true,
"parameters": [
{
"name": "name",
"type": "string",
"description": "The scalar name."
},
{
"name": "key",
"type": "string",
"description": "The key name."
},
{
"name": "value",
"type": "integer",
"minimum": 0,
"description": "The numeric value to set the scalar to. Only unsigned integers supported."
}
]
},
{
"name": "recordEvent",
"type": "function",

Просмотреть файл

@ -67,7 +67,6 @@ if (AppConstants.MOZ_BUILD_APP === "browser") {
add_task(async function test_telemetry_scalar_add() {
Services.telemetry.clearScalars();
await run({
backgroundScript: async () => {
await browser.telemetry.scalarAdd(
@ -78,11 +77,11 @@ if (AppConstants.MOZ_BUILD_APP === "browser") {
},
doneSignal: "scalar_add",
});
const scalars = Services.telemetry.getSnapshotForScalars("main", false);
equal(scalars.parent["telemetry.test.unsigned_int_kind"], 1);
Services.telemetry.clearScalars();
TelemetryTestUtils.assertScalar(
TelemetryTestUtils.getProcessScalars("parent", false, true),
"telemetry.test.unsigned_int_kind",
1
);
});
add_task(async function test_telemetry_scalar_add_unknown_name() {
@ -95,14 +94,9 @@ if (AppConstants.MOZ_BUILD_APP === "browser") {
doneSignal: "scalar_add_unknown_name",
});
});
messages = messages.filter(
msg => /telemetry.test.does_not_exist - Unknown scalar./
);
equal(
messages.length,
1,
"Telemetry should throw if an unknown scalar is incremented"
Assert.ok(
messages.find(({ message }) => message.includes("Unknown scalar")),
"Telemetry should warn if an unknown scalar is incremented"
);
});
@ -134,20 +128,16 @@ if (AppConstants.MOZ_BUILD_APP === "browser") {
doneSignal: "scalar_add_invalid_keyed_scalar",
});
});
messages = messages.filter(
msg => /Attempting to manage a keyed scalar as a scalar/
);
equal(
messages.length,
1,
"Telemetry should throw if a keyed scalar is incremented"
Assert.ok(
messages.find(({ message }) =>
message.includes("Attempting to manage a keyed scalar as a scalar")
),
"Telemetry should warn if a scalarAdd is called for a keyed scalar"
);
});
add_task(async function test_telemetry_scalar_set() {
Services.telemetry.clearScalars();
await run({
backgroundScript: async () => {
await browser.telemetry.scalarSet("telemetry.test.boolean_kind", true);
@ -155,11 +145,11 @@ if (AppConstants.MOZ_BUILD_APP === "browser") {
},
doneSignal: "scalar_set",
});
const scalars = Services.telemetry.getSnapshotForScalars("main", false);
equal(scalars.parent["telemetry.test.boolean_kind"], true);
Services.telemetry.clearScalars();
TelemetryTestUtils.assertScalar(
TelemetryTestUtils.getProcessScalars("parent", false, true),
"telemetry.test.boolean_kind",
true
);
});
add_task(async function test_telemetry_scalar_set_unknown_name() {
@ -175,18 +165,14 @@ if (AppConstants.MOZ_BUILD_APP === "browser") {
doneSignal: "scalar_set_unknown_name",
});
});
messages = messages.filter(msg => /Unknown scalar/);
equal(
messages.length,
1,
"Telemetry should throw if an unknown scalar is set"
Assert.ok(
messages.find(({ message }) => message.includes("Unknown scalar")),
"Telemetry should warn if an unknown scalar is set"
);
});
add_task(async function test_telemetry_scalar_set_maximum() {
Services.telemetry.clearScalars();
await run({
backgroundScript: async () => {
await browser.telemetry.scalarSetMaximum(
@ -197,11 +183,11 @@ if (AppConstants.MOZ_BUILD_APP === "browser") {
},
doneSignal: "scalar_set_maximum",
});
const scalars = Services.telemetry.getSnapshotForScalars("main", false);
equal(scalars.parent["telemetry.test.unsigned_int_kind"], 123);
Services.telemetry.clearScalars();
TelemetryTestUtils.assertScalar(
TelemetryTestUtils.getProcessScalars("parent", false, true),
"telemetry.test.unsigned_int_kind",
123
);
});
add_task(async function test_telemetry_scalar_set_maximum_unknown_name() {
@ -217,12 +203,9 @@ if (AppConstants.MOZ_BUILD_APP === "browser") {
doneSignal: "scalar_set_maximum_unknown_name",
});
});
messages = messages.filter(msg => /Unknown scalar/);
equal(
messages.length,
1,
"Telemetry should throw if an unknown scalar is set"
Assert.ok(
messages.find(({ message }) => message.includes("Unknown scalar")),
"Telemetry should warn if an unknown scalar is set"
);
});
@ -244,6 +227,261 @@ if (AppConstants.MOZ_BUILD_APP === "browser") {
});
});
add_task(async function test_telemetry_keyed_scalar_add() {
Services.telemetry.clearScalars();
await run({
backgroundScript: async () => {
await browser.telemetry.keyedScalarAdd(
"telemetry.test.keyed_unsigned_int",
"foo",
1
);
browser.test.notifyPass("keyed_scalar_add");
},
doneSignal: "keyed_scalar_add",
});
TelemetryTestUtils.assertKeyedScalar(
TelemetryTestUtils.getProcessScalars("parent", true, true),
"telemetry.test.keyed_unsigned_int",
"foo",
1
);
});
add_task(async function test_telemetry_keyed_scalar_add_unknown_name() {
let { messages } = await promiseConsoleOutput(async () => {
await run({
backgroundScript: async () => {
await browser.telemetry.keyedScalarAdd(
"telemetry.test.does_not_exist",
"foo",
1
);
browser.test.notifyPass("keyed_scalar_add_unknown_name");
},
doneSignal: "keyed_scalar_add_unknown_name",
});
});
Assert.ok(
messages.find(({ message }) => message.includes("Unknown scalar")),
"Telemetry should warn if an unknown keyed scalar is incremented"
);
});
add_task(async function test_telemetry_keyed_scalar_add_illegal_value() {
await run({
backgroundScript: () => {
browser.test.assertThrows(
() =>
browser.telemetry.keyedScalarAdd(
"telemetry.test.keyed_unsigned_int",
"foo",
{}
),
/Incorrect argument types for telemetry.keyedScalarAdd/,
"The second 'value' argument to keyedScalarAdd must be an integer, string, or boolean"
);
browser.test.notifyPass("keyed_scalar_add_illegal_value");
},
doneSignal: "keyed_scalar_add_illegal_value",
});
});
add_task(async function test_telemetry_keyed_scalar_add_invalid_scalar() {
let { messages } = await promiseConsoleOutput(async function() {
await run({
backgroundScript: async () => {
await browser.telemetry.keyedScalarAdd(
"telemetry.test.unsigned_int_kind",
"foo",
1
);
browser.test.notifyPass("keyed_scalar_add_invalid_scalar");
},
doneSignal: "keyed_scalar_add_invalid_scalar",
});
});
Assert.ok(
messages.find(({ message }) =>
message.includes(
"Attempting to manage a keyed scalar as a scalar (or vice-versa)"
)
),
"Telemetry should warn if a scalar is incremented as a keyed scalar"
);
});
add_task(async function test_telemetry_keyed_scalar_add_long_key() {
let { messages } = await promiseConsoleOutput(async () => {
await run({
backgroundScript: async () => {
await browser.telemetry.keyedScalarAdd(
"telemetry.test.keyed_unsigned_int",
"X".repeat(73),
1
);
browser.test.notifyPass("keyed_scalar_add_long_key");
},
doneSignal: "keyed_scalar_add_long_key",
});
});
Assert.ok(
messages.find(({ message }) =>
message.includes("The key length must be limited to 72 characters.")
),
"Telemetry should warn if keyed scalar's key is too long"
);
});
add_task(async function test_telemetry_keyed_scalar_set() {
Services.telemetry.clearScalars();
await run({
backgroundScript: async () => {
await browser.telemetry.keyedScalarSet(
"telemetry.test.keyed_boolean_kind",
"foo",
true
);
browser.test.notifyPass("keyed_scalar_set");
},
doneSignal: "keyed_scalar_set",
});
TelemetryTestUtils.assertKeyedScalar(
TelemetryTestUtils.getProcessScalars("parent", true, true),
"telemetry.test.keyed_boolean_kind",
"foo",
true
);
});
add_task(async function test_telemetry_keyed_scalar_set_unknown_name() {
let { messages } = await promiseConsoleOutput(async function() {
await run({
backgroundScript: async () => {
await browser.telemetry.keyedScalarSet(
"telemetry.test.does_not_exist",
"foo",
true
);
browser.test.notifyPass("keyed_scalar_set_unknown_name");
},
doneSignal: "keyed_scalar_set_unknown_name",
});
});
Assert.ok(
messages.find(({ message }) => message.includes("Unknown scalar")),
"Telemetry should warn if an unknown keyed scalar is incremented"
);
});
add_task(async function test_telemetry_keyed_scalar_set_long_key() {
let { messages } = await promiseConsoleOutput(async () => {
await run({
backgroundScript: async () => {
await browser.telemetry.keyedScalarSet(
"telemetry.test.keyed_unsigned_int",
"X".repeat(73),
1
);
browser.test.notifyPass("keyed_scalar_set_long_key");
},
doneSignal: "keyed_scalar_set_long_key",
});
});
Assert.ok(
messages.find(({ message }) =>
message.includes("The key length must be limited to 72 characters")
),
"Telemetry should warn if keyed scalar's key is too long"
);
});
add_task(async function test_telemetry_keyed_scalar_set_maximum() {
Services.telemetry.clearScalars();
await run({
backgroundScript: async () => {
await browser.telemetry.keyedScalarSetMaximum(
"telemetry.test.keyed_unsigned_int",
"foo",
123
);
browser.test.notifyPass("keyed_scalar_set_maximum");
},
doneSignal: "keyed_scalar_set_maximum",
});
TelemetryTestUtils.assertKeyedScalar(
TelemetryTestUtils.getProcessScalars("parent", true, true),
"telemetry.test.keyed_unsigned_int",
"foo",
123
);
});
add_task(
async function test_telemetry_keyed_scalar_set_maximum_unknown_name() {
let { messages } = await promiseConsoleOutput(async function() {
await run({
backgroundScript: async () => {
await browser.telemetry.keyedScalarSetMaximum(
"telemetry.test.does_not_exist",
"foo",
1
);
browser.test.notifyPass("keyed_scalar_set_maximum_unknown_name");
},
doneSignal: "keyed_scalar_set_maximum_unknown_name",
});
});
Assert.ok(
messages.find(({ message }) => message.includes("Unknown scalar")),
"Telemetry should warn if an unknown keyed scalar is set"
);
}
);
add_task(
async function test_telemetry_keyed_scalar_set_maximum_illegal_value() {
await run({
backgroundScript: () => {
browser.test.assertThrows(
() =>
browser.telemetry.keyedScalarSetMaximum(
"telemetry.test.keyed_unsigned_int",
"foo",
"string"
),
/Incorrect argument types for telemetry.keyedScalarSetMaximum/,
"The third 'value' argument to keyedScalarSetMaximum must be a scalar"
);
browser.test.notifyPass("keyed_scalar_set_maximum_illegal_value");
},
doneSignal: "keyed_scalar_set_maximum_illegal_value",
});
}
);
add_task(async function test_telemetry_keyed_scalar_set_maximum_long_key() {
let { messages } = await promiseConsoleOutput(async () => {
await run({
backgroundScript: async () => {
await browser.telemetry.keyedScalarSetMaximum(
"telemetry.test.keyed_unsigned_int",
"X".repeat(73),
1
);
browser.test.notifyPass("keyed_scalar_set_maximum_long_key");
},
doneSignal: "keyed_scalar_set_maximum_long_key",
});
});
Assert.ok(
messages.find(({ message }) =>
message.includes("The key length must be limited to 72 characters")
),
"Telemetry should warn if keyed scalar's key is too long"
);
});
add_task(async function test_telemetry_record_event() {
Services.telemetry.clearEvents();
Services.telemetry.setEventRecordingEnabled("telemetry.test", true);
@ -319,7 +557,6 @@ if (AppConstants.MOZ_BUILD_APP === "browser") {
add_task(async function test_telemetry_register_scalars_string() {
Services.telemetry.clearScalars();
await run({
backgroundScript: async () => {
await browser.telemetry.registerScalars("telemetry.test.dynamic", {
@ -337,16 +574,15 @@ if (AppConstants.MOZ_BUILD_APP === "browser") {
},
doneSignal: "register_scalars_string",
});
const scalars = Services.telemetry.getSnapshotForScalars("main", false);
equal(scalars.dynamic["telemetry.test.dynamic.webext_string"], "hello");
Services.telemetry.clearScalars();
TelemetryTestUtils.assertScalar(
TelemetryTestUtils.getProcessScalars("parent", false, true),
"telemetry.test.dynamic.webext_string",
"hello"
);
});
add_task(async function test_telemetry_register_scalars_multiple() {
Services.telemetry.clearScalars();
await run({
backgroundScript: async () => {
await browser.telemetry.registerScalars("telemetry.test.dynamic", {
@ -373,17 +609,21 @@ if (AppConstants.MOZ_BUILD_APP === "browser") {
},
doneSignal: "register_scalars_multiple",
});
const scalars = Services.telemetry.getSnapshotForScalars("main", false);
equal(scalars.dynamic["telemetry.test.dynamic.webext_string"], "hello");
equal(scalars.dynamic["telemetry.test.dynamic.webext_string_too"], "world");
Services.telemetry.clearScalars();
const scalars = TelemetryTestUtils.getProcessScalars("parent", false, true);
TelemetryTestUtils.assertScalar(
scalars,
"telemetry.test.dynamic.webext_string",
"hello"
);
TelemetryTestUtils.assertScalar(
scalars,
"telemetry.test.dynamic.webext_string_too",
"world"
);
});
add_task(async function test_telemetry_register_scalars_boolean() {
Services.telemetry.clearScalars();
await run({
backgroundScript: async () => {
await browser.telemetry.registerScalars("telemetry.test.dynamic", {
@ -401,16 +641,15 @@ if (AppConstants.MOZ_BUILD_APP === "browser") {
},
doneSignal: "register_scalars_boolean",
});
const scalars = Services.telemetry.getSnapshotForScalars("main", false);
equal(scalars.dynamic["telemetry.test.dynamic.webext_boolean"], true);
Services.telemetry.clearScalars();
TelemetryTestUtils.assertScalar(
TelemetryTestUtils.getProcessScalars("dynamic", false, true),
"telemetry.test.dynamic.webext_boolean",
true
);
});
add_task(async function test_telemetry_register_scalars_count() {
Services.telemetry.clearScalars();
await run({
backgroundScript: async () => {
await browser.telemetry.registerScalars("telemetry.test.dynamic", {
@ -428,11 +667,11 @@ if (AppConstants.MOZ_BUILD_APP === "browser") {
},
doneSignal: "register_scalars_count",
});
const scalars = Services.telemetry.getSnapshotForScalars("main", false);
equal(scalars.dynamic["telemetry.test.dynamic.webext_count"], 123);
Services.telemetry.clearScalars();
TelemetryTestUtils.assertScalar(
TelemetryTestUtils.getProcessScalars("dynamic", false, true),
"telemetry.test.dynamic.webext_count",
123
);
});
add_task(async function test_telemetry_register_events() {
@ -457,14 +696,17 @@ if (AppConstants.MOZ_BUILD_APP === "browser") {
doneSignal: "register_events",
});
let events = Services.telemetry.snapshotEvents(
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS
TelemetryTestUtils.assertEvents(
[
{
category: "telemetry.test.dynamic",
method: "test1",
object: "object1",
},
],
{ category: "telemetry.test.dynamic" },
{ process: "dynamic" }
);
let expected = [["telemetry.test.dynamic", "test1", "object1"]];
equal(events.dynamic.length, expected.length);
deepEqual(events.dynamic.map(e => e.slice(1)), expected);
Services.telemetry.clearEvents();
});
add_task(async function test_telemetry_submit_ping() {