Bug 1711206 - Apply Normandy startup preferences before Normandy migrations r=Gijs

This is a major change to the sequencing of Normandy's startup, since it now
applies startup preferences before the first async. This makes preference
changes happen synchronously during BrowserGlue's initialization phase. This
timing is something we have worked around frequently in the past.

This may affect some other features, but I believe they will all still work as
expected.  Future features will be easier to integrate with Normandy, since the
timing of this phase is more predictable now.

Differential Revision: https://phabricator.services.mozilla.com/D115716
This commit is contained in:
Michael Cooper 2021-05-25 15:38:57 +00:00
Родитель 4cfab30bc0
Коммит 8dffd1552c
3 изменённых файлов: 66 добавлений и 1 удалений

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

@ -51,12 +51,15 @@ var Normandy = {
async init({ runAsync = true } = {}) {
// Initialization that needs to happen before the first paint on startup.
// Listen for when Telemetry is disabled or re-enabled.
Services.obs.addObserver(
this,
TelemetryUtils.TELEMETRY_UPLOAD_DISABLED_TOPIC
);
await NormandyMigrations.applyAll();
// It is important this happens before the first `await`. Note that this
// also happens before migrations are applied.
this.rolloutPrefsChanged = this.applyStartupPrefs(
STARTUP_ROLLOUT_PREFS_BRANCH
);
@ -65,6 +68,8 @@ var Normandy = {
);
this.defaultPrefsHaveBeenApplied.resolve();
await NormandyMigrations.applyAll();
if (runAsync) {
Services.obs.addObserver(this, UI_AVAILABLE_NOTIFICATION);
} else {
@ -179,12 +184,16 @@ var Normandy = {
* Copy a preference subtree from one branch to another, being careful about
* types, and return the values the target branch originally had. Prefs will
* be read from the user branch and applied to the default branch.
*
* @param sourcePrefix
* The pref prefix to read prefs from.
* @returns
* The original values that each pref had on the default branch.
*/
applyStartupPrefs(sourcePrefix) {
// Note that this is called before Normandy's migrations are applied. This
// currently has no effect, but future changes should be careful to be
// backwards compatible.
const originalValues = {};
const sourceBranch = Services.prefs.getBranch(sourcePrefix);
const targetBranch = Services.prefs.getDefaultBranch("");

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

@ -0,0 +1,55 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const { Normandy } = ChromeUtils.import("resource://normandy/Normandy.jsm");
const { NormandyMigrations } = ChromeUtils.import(
"resource://normandy/NormandyMigrations.jsm"
);
/* import-globals-from utils.js */
load("utils.js");
NormandyTestUtils.init({ add_task });
const { decorate_task } = NormandyTestUtils;
// Normandy's initialization function should set the start preferences before
// its first `await`.
decorate_task(
NormandyTestUtils.withStub(Normandy, "finishInit"),
NormandyTestUtils.withStub(NormandyMigrations, "applyAll"),
NormandyTestUtils.withMockPreferences(),
async function test_normandy_init_applies_startup_prefs_synchronously({
mockPreferences,
}) {
const experimentPref = "test.experiment";
const rolloutPref = "test.rollout";
const experimentStartupPref = `app.normandy.startupExperimentPrefs.${experimentPref}`;
const rolloutStartupPref = `app.normandy.startupRolloutPrefs.${rolloutPref}`;
mockPreferences.preserve(experimentPref, "default");
mockPreferences.preserve(rolloutPref, "default");
mockPreferences.set(experimentStartupPref, "experiment");
mockPreferences.set(rolloutStartupPref, "rollout");
Assert.equal(
Services.prefs.getCharPref(experimentPref, "default"),
"default"
);
Assert.equal(Services.prefs.getCharPref(rolloutPref, "default"), "default");
let initPromise = Normandy.init();
// note: There are no awaits before these asserts, so only the part of
// Normandy's initialization before its first await can run.
Assert.equal(
Services.prefs.getCharPref(experimentPref, "default"),
"experiment"
);
Assert.equal(Services.prefs.getCharPref(rolloutPref, "default"), "rollout");
await initPromise;
await Normandy.uninit();
}
);

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

@ -10,6 +10,7 @@ support-files =
utils.js
tags = normandy
[test_Normandy.js]
[test_PrefUtils.js]
[test_addon_unenroll.js]
[test_NormandyApi.js]