Backed out changeset 2dc86982439a (bug 1451031) for xpcshell failures on services/common/tests/unit/test_blocklist_clients.js.

This commit is contained in:
Cosmin Sabou 2018-05-22 19:51:34 +03:00
parent 828ab007c4
commit a6fd990875
6 changed files with 9 additions and 269 deletions

View File

@ -11,8 +11,8 @@ var EXPORTED_SYMBOLS = [
ChromeUtils.import("resource://gre/modules/Services.jsm");
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm", {});
ChromeUtils.defineModuleGetter(this, "RemoteSettings", "resource://services-common/remote-settings.js");
ChromeUtils.defineModuleGetter(this, "jexlFilterFunc", "resource://services-common/remote-settings.js");
ChromeUtils.defineModuleGetter(this, "RemoteSettings",
"resource://services-common/remote-settings.js");
const PREF_BLOCKLIST_BUCKET = "services.blocklist.bucket";
const PREF_BLOCKLIST_ONECRL_COLLECTION = "services.blocklist.onecrl.collection";
@ -132,22 +132,17 @@ async function updateJSONBlocklist(client, { data: { current: records } }) {
* This custom filter function is used to limit the entries returned
* by `RemoteSettings("...").get()` depending on the target app information
* defined on entries.
*
* When landing Bug 1451031, this function will have to check if the `entry`
* has a JEXL attribute and rely on the JEXL filter function in priority.
* The legacy target app mechanism will be kept in place for old entries.
*/
async function targetAppFilter(entry, environment) {
// If the entry has JEXL filters, they should prevail.
// The legacy target app mechanism will be kept in place for old entries.
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1463377
const { filters } = entry;
if (filters) {
return jexlFilterFunc(entry, environment);
}
async function targetAppFilter(entry, { appID, version: appVersion }) {
// Keep entries without target information.
if (!("versionRange" in entry)) {
return entry;
}
const { appID, version: appVersion } = environment;
const { versionRange } = entry;
// Gfx blocklist has a specific versionRange object, which is not a list.

View File

@ -103,18 +103,6 @@ It is possible to package a dump of the server records that will be loaded into
Now, when ``RemoteSettings("some-key").get()`` is called from an empty profile, the ``some-key.json`` file is going to be loaded before the results are returned.
Targets and A/B testing
=======================
In order to deliver settings to subsets of the population, you can set targets on entries (platform, language, channel, version range, preferences values, samples, etc.) when editing records on the server.
From the client API standpoint, this is completely transparent: the ``.get()`` method — as well as the event data — will always filter the entries on which the target matches.
.. note::
The remote settings targets follow the same approach as the :ref:`Normandy recipe client <components/normandy>` (ie. JEXL filters),
Uptake Telemetry
================

View File

@ -4,10 +4,7 @@
"use strict";
var EXPORTED_SYMBOLS = [
"RemoteSettings",
"jexlFilterFunc"
];
var EXPORTED_SYMBOLS = ["RemoteSettings"];
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
@ -24,7 +21,6 @@ ChromeUtils.defineModuleGetter(this, "UptakeTelemetry",
"resource://services-common/uptake-telemetry.js");
ChromeUtils.defineModuleGetter(this, "ClientEnvironmentBase",
"resource://gre/modules/components-utils/ClientEnvironment.jsm");
ChromeUtils.defineModuleGetter(this, "FilterExpressions", "resource://normandy/lib/FilterExpressions.jsm");
const PREF_SETTINGS_SERVER = "services.settings.server";
const PREF_SETTINGS_DEFAULT_BUCKET = "services.settings.default_bucket";
@ -66,27 +62,6 @@ class ClientEnvironment extends ClientEnvironmentBase {
}
}
/**
* Default entry filtering function, in charge of excluding remote settings entries
* where the JEXL expression evaluates into a falsy value.
*/
async function jexlFilterFunc(entry, environment) {
const { filters } = entry;
if (!filters) {
return entry;
}
let result;
try {
const context = {
environment
};
result = await FilterExpressions.eval(filters, context);
} catch (e) {
Cu.reportError(e);
}
return result ? entry : null;
}
function mergeChanges(collection, localRecords, changes) {
const records = {};
@ -175,7 +150,7 @@ async function fetchLatestChanges(url, lastEtag) {
class RemoteSettingsClient {
constructor(collectionName, { bucketName, signerName, filterFunc = jexlFilterFunc, lastCheckTimePref }) {
constructor(collectionName, { bucketName, signerName, filterFunc, lastCheckTimePref }) {
this.collectionName = collectionName;
this.bucketName = bucketName;
this.signerName = signerName;

View File

@ -245,51 +245,6 @@ add_task(async function test_sync_event_data_is_filtered_for_target() {
});
add_task(clear_state);
add_task(async function test_entries_are_filtered_when_jexl_filters_is_present() {
const records = [{
willMatch: true,
}, {
willMatch: true,
filters: null
}, {
willMatch: true,
filters: "1 == 1"
}, {
willMatch: false,
filters: "1 == 2"
}, {
willMatch: true,
filters: "1 == 1",
versionRange: [{
targetApplication: [{
guid: "some-guid"
}],
}]
}, {
willMatch: false, // jexl prevails over versionRange.
filters: "1 == 2",
versionRange: [{
targetApplication: [{
guid: "xpcshell@tests.mozilla.org",
minVersion: "0",
maxVersion: "*",
}],
}]
}
];
for (let {client} of gBlocklistClients) {
const collection = await client.openCollection();
for (const record of records) {
await collection.create(record);
}
await collection.db.saveLastModified(42); // Prevent from loading JSON dump.
const list = await client.get();
equal(list.length, 4);
ok(list.every(e => e.willMatch));
}
});
add_task(clear_state);
// get a response for a given request from sample data
function getSampleResponse(req, port) {

View File

@ -1,171 +0,0 @@
const { RemoteSettings } = ChromeUtils.import("resource://services-common/remote-settings.js", {});
let client;
async function createRecords(records) {
const collection = await client.openCollection();
await collection.clear();
for (const record of records) {
await collection.create(record);
}
await collection.db.saveLastModified(42); // Prevent from loading JSON dump.
}
function run_test() {
client = RemoteSettings("some-key");
run_next_test();
}
add_task(async function test_returns_all_without_target() {
await createRecords([{
passwordSelector: "#pass-signin"
}, {
filters: null,
}, {
filters: "",
}]);
const list = await client.get();
equal(list.length, 3);
});
add_task(async function test_filters_can_be_disabled() {
const c = RemoteSettings("no-jexl", { filterFunc: null });
const collection = await c.openCollection();
await collection.create({
filters: "1 == 2"
});
await collection.db.saveLastModified(42); // Prevent from loading JSON dump.
const list = await c.get();
equal(list.length, 1);
});
add_task(async function test_returns_entries_where_jexl_is_true() {
await createRecords([{
willMatch: true,
filters: "1"
}, {
willMatch: true,
filters: "[42]"
}, {
willMatch: true,
filters: "1 == 2 || 1 == 1"
}, {
willMatch: true,
filters: 'environment.appID == "xpcshell@tests.mozilla.org"'
}, {
willMatch: false,
filters: "environment.version == undefined"
}, {
willMatch: true,
filters: "environment.unknown == undefined"
}, {
willMatch: false,
filters: "1 == 2"
}]);
const list = await client.get();
equal(list.length, 5);
ok(list.every(e => e.willMatch));
});
add_task(async function test_ignores_entries_where_jexl_is_invalid() {
await createRecords([{
filters: "true === true" // JavaScript Error: "Invalid expression token: ="
}, {
filters: "Objects.keys({}) == []" // Token ( (openParen) unexpected in expression
}]);
const list = await client.get();
equal(list.length, 0);
});
add_task(async function test_support_of_date_filters() {
await createRecords([{
willMatch: true,
filters: '"1982-05-08"|date < "2016-03-22"|date'
}, {
willMatch: false,
filters: '"2000-01-01"|date < "1970-01-01"|date'
}]);
const list = await client.get();
equal(list.length, 1);
ok(list.every(e => e.willMatch));
});
add_task(async function test_support_of_preferences_filters() {
await createRecords([{
willMatch: true,
filters: '"services.settings.last_etag"|preferenceValue == 42'
}, {
willMatch: true,
filters: '"services.settings.changes.path"|preferenceExists == true'
}, {
willMatch: true,
filters: '"services.settings.changes.path"|preferenceIsUserSet == false'
}, {
willMatch: true,
filters: '"services.settings.last_etag"|preferenceIsUserSet == true'
}]);
// Set a pref for the user.
Services.prefs.setIntPref("services.settings.last_etag", 42);
const list = await client.get();
equal(list.length, 4);
ok(list.every(e => e.willMatch));
});
add_task(async function test_support_of_intersect_operator() {
await createRecords([{
willMatch: true,
filters: '{foo: 1, bar: 2}|keys intersect ["foo"]'
}, {
willMatch: true,
filters: '(["a", "b"] intersect ["a", 1, 4]) == "a"'
}, {
willMatch: false,
filters: '(["a", "b"] intersect [3, 1, 4]) == "c"'
}, {
willMatch: true,
filters: `
[1, 2, 3]
intersect
[3, 4, 5]
`
}]);
const list = await client.get();
equal(list.length, 3);
ok(list.every(e => e.willMatch));
});
add_task(async function test_support_of_samples() {
await createRecords([{
willMatch: true,
filters: '"always-true"|stableSample(1)'
}, {
willMatch: false,
filters: '"always-false"|stableSample(0)'
}, {
willMatch: true,
filters: '"turns-to-true-0"|stableSample(0.5)'
}, {
willMatch: false,
filters: '"turns-to-false-1"|stableSample(0.5)'
}, {
willMatch: true,
filters: '"turns-to-true-0"|bucketSample(0, 50, 100)'
}, {
willMatch: false,
filters: '"turns-to-false-1"|bucketSample(0, 50, 100)'
}]);
const list = await client.get();
equal(list.length, 3);
ok(list.every(e => e.willMatch));
});

View File

@ -22,8 +22,6 @@ tags = blocklist
tags = remote-settings blocklist
[test_remote_settings_poll.js]
tags = remote-settings blocklist
[test_remote_settings_jexl_filters.js]
tags = remote-settings
[test_kinto.js]
tags = blocklist