Bug 1572711 - Record extensions.blocklist.useXML and services.blocklist.*.checked prefs into new telemetry scalars. r=janerik,leplatrem,Gijs

Depends on D41734

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Luca Greco 2019-08-22 16:32:19 +00:00
Родитель 85ae99d8ee
Коммит b2c8b8875b
5 изменённых файлов: 277 добавлений и 0 удалений

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

@ -252,6 +252,31 @@ class RemoteSettingsClient extends EventEmitter {
return api.bucket(this.bucketName).collection(this.collectionName);
}
/**
* Retrieve the collection timestamp for the last synchronization.
*
* @returns {number}
* The timestamp in milliseconds, returns -1 if retrieving
* the timestamp from the kinto collection fails.
*/
async getLastModified() {
let timestamp = -1;
try {
const collection = await this.openCollection();
timestamp = await collection.db.getLastModified();
} catch (err) {
console.warn(
`Error retrieving the getLastModified timestamp from ${
this.identifier
} RemoteSettingClient`,
err
);
}
return timestamp;
}
/**
* Open the underlying Kinto collection, using the appropriate adapter and options.
*/

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

@ -4487,6 +4487,64 @@ blocklist:
record_in_processes:
- main
lastModified_rs_addons:
bug_numbers:
- 1572711
description: >
Keep track of the last time the "addons" remotesetting blocklist has been successfully
updated (as a datetime string in UTC format), set to "Missing Date" when the timestamp
couldn't be retrieved.
expires: "75"
kind: string
release_channel_collection: opt-out
notification_emails:
- addons-dev-internal@mozilla.com
- lgreco@mozilla.com
- awagner@mozilla.com
products:
- 'firefox'
- 'fennec'
record_in_processes:
- main
lastModified_rs_plugins:
bug_numbers:
- 1572711
description: >
Keep track of the last time the "plugins" remotesetting blocklist has been successfully
updated (as a datetime string in UTC format), set to "Missing Date" when the timestamp
couldn't be retrieved.
expires: "75"
kind: string
release_channel_collection: opt-out
notification_emails:
- addons-dev-internal@mozilla.com
- lgreco@mozilla.com
- awagner@mozilla.com
products:
- 'firefox'
record_in_processes:
- main
useXML:
bug_numbers:
- 1572711
description: >
Keep track of the currently enabled blocklist engine (set to false if the
remote settings blocklist is the one enabled).
expires: "75"
kind: boolean
release_channel_collection: opt-out
notification_emails:
- addons-dev-internal@mozilla.com
- lgreco@mozilla.com
- awagner@mozilla.com
products:
- 'firefox'
- 'fennec'
record_in_processes:
- main
# The following section is for probes testing the Telemetry system. They will not be
# submitted in pings and are only used for testing.
telemetry.test:

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

@ -166,6 +166,14 @@ const PREF_BLOCKLIST_ADDONS_CHECKED_SECONDS =
const PREF_BLOCKLIST_ADDONS_SIGNER = "services.blocklist.addons.signer";
const BlocklistTelemetry = {
/**
* Record the current value of "Blocklist.useXML" into the
* "blocklist.useXML" scalar.
*/
recordUseXML() {
Services.telemetry.scalarSet("blocklist.useXML", Blocklist.useXML);
},
/**
* Record the XML Blocklist lastModified server time into the
* "blocklist.lastModified_xml scalar.
@ -193,6 +201,43 @@ const BlocklistTelemetry = {
}
},
/**
* Record the RemoteSettings Blocklist lastModified server time into the
* "blocklist.lastModified_rs keyed scalar (or "Missing Date" when unable
* to retrieve a valid timestamp).
*
* @param {string} blocklistType
* The blocklist type that has been updated (one of "addons" or "plugins",
* the "gfx" blocklist is not covered by this telemetry).
* @param {RemoteSettingsClient} remoteSettingsClient
* The RemoteSettings client to retrieve the lastModified timestamp from.
*/
async recordRSBlocklistLastModified(blocklistType, remoteSettingsClient) {
// In some tests overrides ensureInitialized and remoteSettingsClient
// can be undefined, and in that case we don't want to record any
// telemetry scalar.
if (!remoteSettingsClient) {
return;
}
let lastModified = await remoteSettingsClient.getLastModified();
if (lastModified > 0) {
// convert from timestamp in ms into UTC datetime string, so it is going
// to be record in the same format used by blocklist.lastModified_xml.
lastModified = new Date(lastModified).toUTCString();
Services.telemetry.scalarSet(
`blocklist.lastModified_rs_${blocklistType}`,
lastModified
);
} else {
Services.telemetry.scalarSet(
`blocklist.lastModified_rs_${blocklistType}`,
"Missing Date"
);
}
},
/**
* Record a telemety event on XML Blocklist update errors.
*
@ -224,6 +269,8 @@ const BlocklistTelemetry = {
},
};
this.BlocklistTelemetry = BlocklistTelemetry;
const Utils = {
/**
* Checks whether this entry is valid for the current OS and ABI.
@ -693,6 +740,8 @@ this.PluginBlocklistRS = {
}
Utils.ensureVersionRangeIsSane(entry);
});
BlocklistTelemetry.recordRSBlocklistLastModified("plugins", this._client);
},
async _filterItem(entry) {
@ -1128,6 +1177,8 @@ this.ExtensionBlocklistRS = {
}
Utils.ensureVersionRangeIsSane(entry);
});
BlocklistTelemetry.recordRSBlocklistLastModified("addons", this._client);
},
async _filterItem(entry) {
@ -3126,6 +3177,7 @@ let Blocklist = {
this._impl.forceUpdate();
}
}
BlocklistTelemetry.recordUseXML();
},
shutdown() {

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

@ -0,0 +1,141 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
AddonTestUtils.init(this);
AddonTestUtils.createAppInfo(
"xpcshell@tests.mozilla.org",
"XPCShell",
"1",
"49"
);
const { TelemetryController } = ChromeUtils.import(
"resource://gre/modules/TelemetryController.jsm"
);
const { TelemetryTestUtils } = ChromeUtils.import(
"resource://testing-common/TelemetryTestUtils.jsm"
);
function assertTelemetryScalars(expectedScalars) {
let scalars = TelemetryTestUtils.getProcessScalars("parent");
for (const scalarName of Object.keys(expectedScalars || {})) {
equal(
scalars[scalarName],
expectedScalars[scalarName],
`Got the expected value for ${scalarName} scalar`
);
}
}
add_task(async function test_setup() {
// Ensure that the telemetry scalar definitions are loaded and the
// AddonManager initialized.
await TelemetryController.testSetup();
await AddonTestUtils.promiseStartupManager();
});
add_task(async function test_blocklist_useXML_scalar() {
// In this folder, `useXML` is already set, and set to false, ie we're using remote settings,
// Blocklist.jsm module is loaded explicitly here to ensure that BlocklistTelemetry
// has been able to record its initial value and it is watching for changes of the pref.
ChromeUtils.import("resource://gre/modules/Blocklist.jsm");
assertTelemetryScalars({
"blocklist.useXML": false,
"blocklist.lastModified_rs_addons": undefined,
"blocklist.lastModified_rs_plugins": undefined,
});
// Switch to XML:
Services.prefs.setBoolPref("extensions.blocklist.useXML", true);
// The useXML scalar should be updated, the lastModified_rs_* scalars should
// still be empty.
assertTelemetryScalars({
"blocklist.useXML": true,
"blocklist.lastModified_rs_addons": undefined,
"blocklist.lastModified_rs_plugins": undefined,
});
// Switch back to RemoteSettings:
Services.prefs.setBoolPref("extensions.blocklist.useXML", false);
assertTelemetryScalars({
"blocklist.useXML": false,
"blocklist.lastModified_rs_addons": undefined,
"blocklist.lastModified_rs_plugins": undefined,
});
});
add_task(async function test_blocklist_lastModified_rs_scalars() {
const now = Date.now();
const lastEntryTimes = {
addons: now - 5000,
plugins: now - 3000,
};
const lastEntryTimesUTC = {};
const toUTC = t => new Date(t).toUTCString();
for (const key of Object.keys(lastEntryTimes)) {
lastEntryTimesUTC[key] = toUTC(lastEntryTimes[key]);
}
const {
BlocklistTelemetry,
ExtensionBlocklistRS,
PluginBlocklistRS,
} = ChromeUtils.import("resource://gre/modules/Blocklist.jsm", null);
// Return a promise resolved when the recordRSBlocklistLastModified method
// has been called (by temporarily replacing the method with a function that
// calls the real method and then resolve the promise).
function promiseScalarRecorded() {
return new Promise(resolve => {
let origFn = BlocklistTelemetry.recordRSBlocklistLastModified;
BlocklistTelemetry.recordRSBlocklistLastModified = async (...args) => {
BlocklistTelemetry.recordRSBlocklistLastModified = origFn;
let res = await origFn.apply(BlocklistTelemetry, args);
resolve();
return res;
};
});
}
async function fakeRemoteSettingsSync(rsClient, lastModified) {
let coll = await rsClient.openCollection();
await coll.db.saveLastModified(lastModified);
await rsClient.emit("sync");
}
info("Test RS plugins blocklist lastModified scalar");
await PluginBlocklistRS.ensureInitialized();
await Promise.all([
promiseScalarRecorded(),
fakeRemoteSettingsSync(PluginBlocklistRS._client, lastEntryTimes.plugins),
]);
assertTelemetryScalars({
"blocklist.useXML": false,
"blocklist.lastModified_rs_addons": undefined,
"blocklist.lastModified_rs_plugins": lastEntryTimesUTC.plugins,
});
info("Test RS addon blocklist lastModified scalar");
await ExtensionBlocklistRS.ensureInitialized();
await Promise.all([
promiseScalarRecorded(),
fakeRemoteSettingsSync(ExtensionBlocklistRS._client, lastEntryTimes.addons),
]);
assertTelemetryScalars({
"blocklist.useXML": false,
"blocklist.lastModified_rs_addons": lastEntryTimesUTC.addons,
"blocklist.lastModified_rs_plugins": lastEntryTimesUTC.plugins,
});
});

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

@ -31,6 +31,7 @@ skip-if = os == "android"
# Bug 676992: test consistently hangs on Android
skip-if = os == "android"
[test_blocklist_targetapp_filter.js]
[test_blocklist_telemetry.js]
[test_blocklistchange.js]
# Times out during parallel runs on desktop
requesttimeoutfactor = 2