If the prefFlips feature receives a configuration that conflicts with the local
pref store (e.g., a pref has a default branch value of one type and the feature
configuration contains that same pref with a value of a different type), then
the call to set the pref will throw. We now catch those errors and trigger
unenrollment with reason `prefFlips-failed`.
Differential Revision: https://phabricator.services.mozilla.com/D217502
The prefFlips feature was not caching the original (pre-experiment) values for
the prefs it was setting anywhere that would survive a restart. We now store
these on the enrollment in the store under
`enrollment.prefFlips.originalValues`. This storage is similar, but not
identical, to the `prefs` storage, which is used to cache information about
`setPref` experiments. That storage cannot be repurposed for this without
intertwining the Nimbus-owned setPref support and the prefFlips feature.
Differential Revision: https://phabricator.services.mozilla.com/D216445
This patch implements the prefFlips feature that was added as a placeholder in
bug 1896720. The schema has been updated to fix a bug, as the accepted values
for the `branch` key were incorrect. Additionally, the schema now forbids pref
flips that would clear the default branch, as that is something we cannot do.
When a setPref experiment is currently enrolled and a prefFlips experiment
would enroll that touches the same prefs, the setPref experiment is unenrolled
and vice versa (i.e., the old experiment will always unenroll). This is an edge
case, as we do not expect this to happen in practice (since if a pref is
covered by a feature with setPref, the prefFlips feature probably shouldn't be
used to change it). Unenrollment telemetry has been updated to add a new
"prefFlips-conflict" reason for this case, which also includes the slug of the
experiment that caused unenrollment (as `conflictingSlug` / `conflicting_slug`
in legacy and Glean, respectively).
Differential Revision: https://phabricator.services.mozilla.com/D213506
This does 2 things:
1. It includes the current experiment configuration in the targeting
snapshots written by browsing profiles. This will allow to target
experiments in the background update task based on the experiments
that the default browsing profile is enrolled into. Hopefully this
will avoid tricky `setPref` based coordination problems like the one
that caused Bug 1852093.
2. It instruments the targeting snapshot experiment configuration
during the background update, using the Glean experiments API, and
thereby including it in all Glean pings (including `background-update`
pings). Hopefully this will allow easier analysis; we've had a
difficult time joining background update tasks through to browsing
profiles in particular experiments, and this should co-locate the
required data, allowing to inspect only background update pings.
N.b. `defineProperty` without `enumerable: true` means that
`Object.keys(...)` does not properly iterate the properties.
Presumably this was an oversight.
Differential Revision: https://phabricator.services.mozilla.com/D200125
The setPref variable annotation now requires both the pref to set and the
branch that should be used. Previously this was determined by the
isEarlyStartup feature annotation: true meant that prefs would be set on the
user branch and false meant that they would be set on the default branch. All
setPref annotations have been updated to stay consistent with that model.
Differential Revision: https://phabricator.services.mozilla.com/D199062
Pref observers registered for prefs like "foo" will also fire for pref changes
on "foo.bar", etc. If a feature registered nested prefs like these, then a
change to pref "foo.bar" would trigger the pref listener for "foo.bar" and
cause spurious unenrollments, especially when attempting to enroll in both an
experiment and rollout at the same time, and when trying to unenroll from an
experiment when also enrolled in a rollout.
Differential Revision: https://phabricator.services.mozilla.com/D187936
While here, the assertEmptyStore and cleanupStore functions from
test_ExperimentManager_prefs.js were refactored into a function in head.js so
that it could be used in the test suite to cleanup for leaky tests.
Differential Revision: https://phabricator.services.mozilla.com/D178111