Skip to content

Commit 6f58201

Browse files
committed
Bug 1773583 - Synchronously fetch NimbusEnrollment schema in NimbusTestUtils r=emcminn
Differential Revision: https://phabricator.services.mozilla.com/D176175 UltraBlame original commit: 3642698fa9e48a18de9aeb060e8887dcb9fb16c1
1 parent 1cd42d3 commit 6f58201

File tree

4 files changed

+57
-25
lines changed

4 files changed

+57
-25
lines changed

toolkit/components/nimbus/test/NimbusTestUtils.sys.mjs

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import { ExperimentStore } from "resource://nimbus/lib/ExperimentStore.sys.mjs";
66
import { FileTestUtils } from "resource://testing-common/FileTestUtils.sys.mjs";
7+
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
78

89
const lazy = {};
910

@@ -19,6 +20,36 @@ ChromeUtils.defineESModuleGetters(lazy, {
1920
sinon: "resource://testing-common/Sinon.sys.mjs",
2021
});
2122

23+
XPCOMUtils.defineLazyModuleGetters(lazy, {
24+
NetUtil: "resource://gre/modules/NetUtil.jsm",
25+
});
26+
27+
function fetchSchemaSync(uri) {
28+
// Yes, this is doing a sync load, but this is only done *once* and we cache
29+
// the result after *and* it is test-only.
30+
const channel = lazy.NetUtil.newChannel({
31+
uri,
32+
loadUsingSystemPrincipal: true,
33+
});
34+
const stream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(
35+
Ci.nsIScriptableInputStream
36+
);
37+
38+
stream.init(channel.open());
39+
40+
const available = stream.available();
41+
const json = stream.read(available);
42+
stream.close();
43+
44+
return JSON.parse(json);
45+
}
46+
47+
XPCOMUtils.defineLazyGetter(lazy, "enrollmentSchema", () => {
48+
return fetchSchemaSync(
49+
"resource://nimbus/schemas/NimbusEnrollment.schema.json"
50+
);
51+
});
52+
2253
const { SYNC_DATA_PREF_BRANCH, SYNC_DEFAULTS_PREF_BRANCH } = ExperimentStore;
2354

2455
const PATH = FileTestUtils.getTempFile("shared-data-map").path;
@@ -97,11 +128,7 @@ export const ExperimentTestUtils = {
97128
`Experiment ${experiment.slug} not valid`
98129
);
99130
},
100-
async validateEnrollment(enrollment) {
101-
const schema = await fetchSchema(
102-
"resource://nimbus/schemas/NimbusEnrollment.schema.json"
103-
);
104-
131+
validateEnrollment(enrollment) {
105132
// We still have single feature experiment recipes for backwards
106133
// compatibility testing but we don't do schema validation
107134
if (!enrollment.branch.features && enrollment.branch.feature) {
@@ -111,7 +138,7 @@ export const ExperimentTestUtils = {
111138
return (
112139
this._validateFeatureValueEnum(enrollment) &&
113140
this._validateSchema(
114-
schema,
141+
lazy.enrollmentSchema,
115142
enrollment,
116143
`Enrollment ${enrollment.slug} is not valid`
117144
)
@@ -217,6 +244,12 @@ export const ExperimentFakes = {
217244
return promise;
218245
};
219246
},
247+
/**
248+
* Enroll in an experiment branch with the given feature configuration.
249+
*
250+
* NB: It is unnecessary to await the enrollmentPromise.
251+
* See bug 1773583 and bug 1829412.
252+
*/
220253
async enrollWithFeatureConfig(
221254
featureConfig,
222255
{ manager = lazy.ExperimentAPI._manager, isRollout = false } = {}
@@ -255,6 +288,12 @@ export const ExperimentFakes = {
255288

256289
return doExperimentCleanup;
257290
},
291+
/**
292+
* Enroll in the given recipe.
293+
*
294+
* NB: It is unnecessary to await the enrollmentPromise.
295+
* See bug 1773583 and bug 1829412.
296+
*/
258297
enrollmentHelper(
259298
recipe,
260299
{ manager = lazy.ExperimentAPI._manager, source = "enrollmentHelper" } = {}

toolkit/components/nimbus/test/browser/browser_remotesettingsexperimentloader_remote_defaults.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -93,20 +93,21 @@ const REMOTE_CONFIGURATION_BAR = ExperimentFakes.recipe("bar-rollout", {
9393

9494
const SYNC_DEFAULTS_PREF_BRANCH = "nimbus.syncdefaultsstore.";
9595

96+
add_setup(function() {
97+
const client = RemoteSettings("nimbus-desktop-experiments");
98+
sinon.stub(client, "get").resolves([]);
99+
100+
registerCleanupFunction(() => client.get.restore());
101+
});
102+
96103
async function setup(configuration) {
97104
const client = RemoteSettings("nimbus-desktop-experiments");
98-
await client.db.importChanges(
99-
{},
100-
Date.now(),
101-
configuration || [REMOTE_CONFIGURATION_FOO, REMOTE_CONFIGURATION_BAR],
102-
{
103-
clear: true,
104-
}
105+
client.get.resolves(
106+
configuration ?? [REMOTE_CONFIGURATION_FOO, REMOTE_CONFIGURATION_BAR]
105107
);
106108

107109

108-
const cleanup = () =>
109-
client.db.importChanges({}, Date.now(), [], { clear: true });
110+
const cleanup = () => client.get.resolves([]);
110111
return { client, cleanup };
111112
}
112113

toolkit/components/nimbus/test/browser/head.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ add_setup(function() {
2727
);
2828
sandbox
2929
.stub(ExperimentManager.store, "addEnrollment")
30-
.callsFake(async enrollment => {
31-
await ExperimentTestUtils.validateEnrollment(enrollment);
30+
.callsFake(enrollment => {
31+
ExperimentTestUtils.validateEnrollment(enrollment);
3232
return origAddExperiment(enrollment);
3333
});
3434

toolkit/components/nimbus/test/unit/test_ExperimentManager_lifecycle.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,6 @@ add_task(async function test_onRecipe_enroll() {
141141
sandbox.spy(manager, "updateEnrollment");
142142

143143
const fooRecipe = ExperimentFakes.recipe("foo");
144-
const experimentUpdate = new Promise(resolve =>
145-
manager.store.on(`update:${fooRecipe.slug}`, resolve)
146-
);
147144
await manager.onStartup();
148145
await manager.onRecipe(fooRecipe, "test");
149146

@@ -152,7 +149,6 @@ add_task(async function test_onRecipe_enroll() {
152149
true,
153150
"should call .enroll() the first time a recipe is seen"
154151
);
155-
await experimentUpdate;
156152
Assert.equal(
157153
manager.store.has("foo"),
158154
true,
@@ -205,15 +201,11 @@ add_task(async function test_onRecipe_rollout_update() {
205201
};
206202

207203
fooRecipe.branches = fooRecipe.branches.slice(0, 1);
208-
const experimentUpdate = new Promise(resolve =>
209-
manager.store.on(`update:${fooRecipe.slug}`, resolve)
210-
);
211204

212205
await manager.onStartup();
213206
await manager.onRecipe(fooRecipe, "test");
214207

215208

216-
await experimentUpdate;
217209

218210
await manager.onRecipe(fooRecipe, "test");
219211

0 commit comments

Comments
 (0)