forked from mirrors/gecko-dev
Differential Revision: https://phabricator.services.mozilla.com/D14647 --HG-- extra : moz-landing-system : lando
301 lines
9.6 KiB
JavaScript
301 lines
9.6 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
"use strict";
|
|
|
|
// This file tests the functionality of the preference service when using a
|
|
// shared memory snapshot. In this configuration, a snapshot of the initial
|
|
// state of the preferences database is made when we first spawn a child
|
|
// process, and changes after that point are stored as entries in a dynamic hash
|
|
// table, on top of the snapshot.
|
|
|
|
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
const {ExtensionTestUtils} = ChromeUtils.import("resource://testing-common/ExtensionXPCShellUtils.jsm");
|
|
|
|
ExtensionTestUtils.init(this);
|
|
|
|
let contentPage;
|
|
|
|
const {prefs} = Services;
|
|
const defaultPrefs = prefs.getDefaultBranch("");
|
|
|
|
const FRAME_SCRIPT_INIT = `
|
|
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
var {prefs} = Services;
|
|
var defaultPrefs = prefs.getDefaultBranch("");
|
|
`;
|
|
|
|
function try_(fn) {
|
|
try {
|
|
return fn();
|
|
} catch (e) {
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
function getPref(pref) {
|
|
let flags = {
|
|
locked: try_(() => prefs.prefIsLocked(pref)),
|
|
hasUser: try_(() => prefs.prefHasUserValue(pref)),
|
|
};
|
|
|
|
switch (prefs.getPrefType(pref)) {
|
|
case prefs.PREF_INT:
|
|
return {
|
|
...flags,
|
|
type: "Int",
|
|
user: try_(() => prefs.getIntPref(pref)),
|
|
default: try_(() => defaultPrefs.getIntPref(pref)),
|
|
};
|
|
case prefs.PREF_BOOL:
|
|
return {
|
|
...flags,
|
|
type: "Bool",
|
|
user: try_(() => prefs.getBoolPref(pref)),
|
|
default: try_(() => defaultPrefs.getBoolPref(pref)),
|
|
};
|
|
case prefs.PREF_STRING:
|
|
return {
|
|
...flags,
|
|
type: "String",
|
|
user: try_(() => prefs.getStringPref(pref)),
|
|
default: try_(() => defaultPrefs.getStringPref(pref)),
|
|
};
|
|
}
|
|
return {};
|
|
}
|
|
|
|
function getPrefs(prefNames) {
|
|
let result = {};
|
|
for (let pref of prefNames) {
|
|
result[pref] = getPref(pref);
|
|
}
|
|
result.childList = prefs.getChildList("");
|
|
return result;
|
|
}
|
|
|
|
function checkPref(pref, proc, val, type, userVal, defaultVal, expectedFlags = {}) {
|
|
info(`Check "${pref}" ${proc} value`);
|
|
|
|
equal(val.type, type, `Expected type for "${pref}"`);
|
|
equal(val.user, userVal, `Expected user value for "${pref}"`);
|
|
|
|
// We only send changes to the content process when they'll make a visible
|
|
// difference, so ignore content process default values when we have a defined
|
|
// user value.
|
|
if (proc !== "content" || val.user === undefined) {
|
|
equal(val.default, defaultVal, `Expected default value for "${pref}"`);
|
|
}
|
|
|
|
for (let [flag, value] of Object.entries(expectedFlags)) {
|
|
equal(val[flag], value, `Expected ${flag} value for "${pref}"`);
|
|
}
|
|
}
|
|
|
|
function getPrefList() {
|
|
return prefs.getChildList("");
|
|
}
|
|
|
|
const TESTS = {
|
|
"exists.thenDoesNot": {
|
|
beforeContent(PREF) {
|
|
prefs.setBoolPref(PREF, true);
|
|
|
|
ok(getPrefList().includes(PREF), `Parent list includes "${PREF}"`);
|
|
},
|
|
contentStartup(PREF, val, childList) {
|
|
ok(getPrefList().includes(PREF), `Parent list includes "${PREF}"`);
|
|
ok(childList.includes(PREF), `Child list includes "${PREF}"`);
|
|
|
|
prefs.clearUserPref(PREF);
|
|
ok(!getPrefList().includes(PREF), `Parent list doesn't include "${PREF}"`);
|
|
},
|
|
contentUpdate1(PREF, val, childList) {
|
|
ok(!getPrefList().includes(PREF), `Parent list doesn't include "${PREF}"`);
|
|
ok(!childList.includes(PREF), `Child list doesn't include "${PREF}"`);
|
|
|
|
prefs.setCharPref(PREF, "foo");
|
|
ok(getPrefList().includes(PREF), `Parent list includes "${PREF}"`);
|
|
checkPref(PREF, "parent", getPref(PREF), "String", "foo");
|
|
},
|
|
contentUpdate2(PREF, val, childList) {
|
|
ok(getPrefList().includes(PREF), `Parent list includes "${PREF}"`);
|
|
ok(childList.includes(PREF), `Child list includes "${PREF}"`);
|
|
|
|
checkPref(PREF, "parent", getPref(PREF), "String", "foo");
|
|
checkPref(PREF, "child", val, "String", "foo");
|
|
},
|
|
},
|
|
"doesNotExists.thenDoes": {
|
|
contentStartup(PREF, val, childList) {
|
|
ok(!getPrefList().includes(PREF), `Parent list doesn't include "${PREF}"`);
|
|
ok(!childList.includes(PREF), `Child list doesn't include "${PREF}"`);
|
|
|
|
prefs.setIntPref(PREF, 42);
|
|
ok(getPrefList().includes(PREF), `Parent list includes "${PREF}"`);
|
|
},
|
|
contentUpdate1(PREF, val, childList) {
|
|
ok(getPrefList().includes(PREF), `Parent list includes "${PREF}"`);
|
|
ok(childList.includes(PREF), `Child list includes "${PREF}"`);
|
|
|
|
checkPref(PREF, "parent", getPref(PREF), "Int", 42);
|
|
checkPref(PREF, "child", val, "Int", 42);
|
|
},
|
|
},
|
|
};
|
|
|
|
const PREFS = [
|
|
{type: "Bool", values: [true, false, true]},
|
|
{type: "Int", values: [24, 42, 73]},
|
|
{type: "String", values: ["meh", "hem", "hrm"]},
|
|
];
|
|
|
|
for (let {type, values} of PREFS) {
|
|
let set = `set${type}Pref`;
|
|
|
|
function prefTest(opts) {
|
|
function check(pref, proc, val, {expectedVal, defaultVal = undefined, expectedDefault = defaultVal, expectedFlags = {}}) {
|
|
checkPref(pref, proc, val, type, expectedVal, expectedDefault, expectedFlags);
|
|
}
|
|
|
|
function updatePref(PREF,
|
|
{userVal = undefined,
|
|
defaultVal = undefined,
|
|
flags = {}}) {
|
|
info(`Update "${PREF}"`);
|
|
if (userVal !== undefined) {
|
|
prefs[set](PREF, userVal);
|
|
}
|
|
if (defaultVal !== undefined) {
|
|
defaultPrefs[set](PREF, defaultVal);
|
|
}
|
|
if (flags.locked === true) {
|
|
prefs.lockPref(PREF);
|
|
} else if (flags.locked === false) {
|
|
prefs.unlockPref(PREF);
|
|
}
|
|
}
|
|
|
|
return {
|
|
beforeContent(PREF) {
|
|
updatePref(PREF, opts.initial);
|
|
check(PREF, "parent", getPref(PREF), opts.initial);
|
|
},
|
|
contentStartup(PREF, contentVal) {
|
|
check(PREF, "content", contentVal, opts.initial);
|
|
check(PREF, "parent", getPref(PREF), opts.initial);
|
|
|
|
updatePref(PREF, opts.change1);
|
|
check(PREF, "parent", getPref(PREF), opts.change1);
|
|
},
|
|
contentUpdate1(PREF, contentVal) {
|
|
check(PREF, "content", contentVal, opts.change1);
|
|
check(PREF, "parent", getPref(PREF), opts.change1);
|
|
|
|
if (opts.change2) {
|
|
updatePref(PREF, opts.change2);
|
|
check(PREF, "parent", getPref(PREF), opts.change2);
|
|
}
|
|
},
|
|
contentUpdate2(PREF, contentVal) {
|
|
if (opts.change2) {
|
|
check(PREF, "content", contentVal, opts.change2);
|
|
check(PREF, "parent", getPref(PREF), opts.change2);
|
|
}
|
|
},
|
|
};
|
|
}
|
|
|
|
for (let i of [0, 1]) {
|
|
let userVal = values[i];
|
|
let defaultVal = values[+!i];
|
|
|
|
TESTS[`type.${type}.${i}.default`] = prefTest({
|
|
initial: {defaultVal, expectedVal: defaultVal},
|
|
change1: {defaultVal: values[2], expectedVal: values[2]},
|
|
});
|
|
|
|
TESTS[`type.${type}.${i}.user`] = prefTest({
|
|
initial: {userVal, expectedVal: userVal},
|
|
change1: {defaultVal: values[2], expectedVal: userVal},
|
|
change2: {userVal: values[2],
|
|
expectedDefault: values[2],
|
|
expectedVal: values[2]},
|
|
});
|
|
|
|
TESTS[`type.${type}.${i}.both`] = prefTest({
|
|
initial: {userVal, defaultVal, expectedVal: userVal},
|
|
change1: {defaultVal: values[2], expectedVal: userVal},
|
|
change2: {userVal: values[2],
|
|
expectedDefault: values[2],
|
|
expectedVal: values[2]},
|
|
});
|
|
|
|
TESTS[`type.${type}.${i}.both.thenLock`] = prefTest({
|
|
initial: {userVal, defaultVal, expectedVal: userVal},
|
|
change1: {expectedDefault: defaultVal,
|
|
expectedVal: defaultVal,
|
|
flags: {locked: true},
|
|
expectFlags: {locked: true}},
|
|
});
|
|
|
|
TESTS[`type.${type}.${i}.both.thenUnlock`] = prefTest({
|
|
initial: {userVal, defaultVal, expectedVal: defaultVal,
|
|
flags: {locked: true}, expectedFlags: {locked: true}},
|
|
change1: {expectedDefault: defaultVal,
|
|
expectedVal: userVal,
|
|
flags: {locked: false},
|
|
expectFlags: {locked: false}},
|
|
});
|
|
|
|
TESTS[`type.${type}.${i}.both.locked`] = prefTest({
|
|
initial: {userVal, defaultVal, expectedVal: defaultVal,
|
|
flags: {locked: true}, expectedFlags: {locked: true}},
|
|
change1: {userVal: values[2],
|
|
expectedDefault: defaultVal,
|
|
expectedVal: defaultVal,
|
|
expectedFlags: {locked: true}},
|
|
change2: {defaultVal: values[2],
|
|
expectedDefault: defaultVal,
|
|
expectedVal: defaultVal,
|
|
expectedFlags: {locked: true}},
|
|
});
|
|
}
|
|
}
|
|
|
|
add_task(async function test_sharedMap_prefs() {
|
|
let prefValues = {};
|
|
|
|
async function runChecks(op) {
|
|
for (let [pref, ops] of Object.entries(TESTS)) {
|
|
if (ops[op]) {
|
|
info(`Running ${op} for "${pref}"`);
|
|
await ops[op](pref,
|
|
prefValues[pref] || undefined,
|
|
prefValues.childList || undefined);
|
|
}
|
|
}
|
|
}
|
|
|
|
await runChecks("beforeContent");
|
|
|
|
contentPage = await ExtensionTestUtils.loadContentPage("about:blank", {remote: true});
|
|
registerCleanupFunction(() => contentPage.close());
|
|
|
|
contentPage.addFrameScriptHelper(FRAME_SCRIPT_INIT);
|
|
contentPage.addFrameScriptHelper(try_);
|
|
contentPage.addFrameScriptHelper(getPref);
|
|
|
|
let prefNames = Object.keys(TESTS);
|
|
prefValues = await contentPage.spawn(prefNames, getPrefs);
|
|
|
|
await runChecks("contentStartup");
|
|
|
|
prefValues = await contentPage.spawn(prefNames, getPrefs);
|
|
|
|
await runChecks("contentUpdate1");
|
|
|
|
prefValues = await contentPage.spawn(prefNames, getPrefs);
|
|
|
|
await runChecks("contentUpdate2");
|
|
});
|