summaryrefslogtreecommitdiffstats
path: root/toolkit/xre/test/marionette
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/xre/test/marionette')
-rw-r--r--toolkit/xre/test/marionette/gen_win32k_tests.py212
-rw-r--r--toolkit/xre/test/marionette/marionette.ini6
-rw-r--r--toolkit/xre/test/marionette/test_exitcode.py31
-rw-r--r--toolkit/xre/test/marionette/test_fission_autostart.py410
-rw-r--r--toolkit/xre/test/marionette/test_win32k_enrollment.py2506
-rw-r--r--toolkit/xre/test/marionette/test_win32k_enrollment.template.py204
-rw-r--r--toolkit/xre/test/marionette/win32k_tests.txt167
7 files changed, 3536 insertions, 0 deletions
diff --git a/toolkit/xre/test/marionette/gen_win32k_tests.py b/toolkit/xre/test/marionette/gen_win32k_tests.py
new file mode 100644
index 0000000000..e0a39776db
--- /dev/null
+++ b/toolkit/xre/test/marionette/gen_win32k_tests.py
@@ -0,0 +1,212 @@
+#!/usr/bin/env python3
+
+import re
+
+RE_DEFAULT = re.compile(r"\[D=([TF])\] ")
+RE_TRANSITION = re.compile(r"([a-zA-Z0-9 \[\]=#_-]+) *->(.*)")
+RE_ASSERTION = re.compile(
+ r"\[A S=([a-zA-Z01_]+) SS=([a-zA-Z01_]+) ES=([a-zA-Z01_]+) P=([a-zA-Z_]+) ESP=([a-zA-Z_]+)\]"
+)
+RE_ASSERTION_SHORTHAND = re.compile(r"\[A#([0-9T]+)\]")
+
+# ======================================================================
+# ======================================================================
+
+testnum = 1
+
+
+def start_test(line):
+ global testnum
+ output.write(
+ """
+ def test_{0}(self):
+ # {1}...\n""".format(
+ testnum, line[0:80]
+ )
+ )
+ testnum += 1
+
+
+def set_default(d):
+ output.write(
+ """
+ if self.default_is is not {0}:
+ return\n""".format(
+ "True" if d == "T" else "False"
+ )
+ )
+
+
+def enroll(e):
+ if e.endswith("-C"):
+ e = e[:-2]
+ output.write("\n # Re-set enrollment pref, like Normandy would do\n")
+ output.write(
+ " self.set_enrollment_status(ExperimentStatus.ENROLLED_{0})\n".format(
+ e.upper()
+ )
+ )
+
+
+def set_pref(enabled):
+ output.write(
+ "\n self.marionette.set_pref(Prefs.WIN32K, {0})\n".format(str(enabled))
+ )
+
+
+def set_e10s(enable):
+ if enable:
+ output.write(
+ """
+ app_version = self.execute_script("return Services.appinfo.version")
+ self.restart(env={ENV_DISABLE_E10S: app_version})
+ self.set_env(ENV_DISABLE_E10S, "null")\n"""
+ )
+ else:
+ raise Exception("Not implemented")
+
+
+def set_header(enable):
+ if enable:
+ output.write(
+ """
+ self.restart(env={ENV_DISABLE_WIN32K: "1"})\n"""
+ )
+ else:
+ output.write(
+ """
+ self.set_env(ENV_DISABLE_WIN32K, "")\n"""
+ )
+
+
+def set_bad_requirements(enabled):
+ output.write(
+ """
+ self.marionette.set_pref(Prefs.WEBGL, {0})\n""".format(
+ "False" if enabled else "True"
+ )
+ )
+
+
+def restart():
+ output.write("\n self.restart()\n")
+
+
+def print_assertion(assertion):
+ if not assertion:
+ return
+ output.write(
+ """
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.{0},
+ sessionStatus=ContentWin32kLockdownState.{1},
+ experimentStatus=ExperimentStatus.{2},
+ pref={3},
+ enrollmentStatusPref=ExperimentStatus.{4},
+ )\n""".format(
+ *assertion
+ )
+ )
+
+
+# ======================================================================
+# ======================================================================
+
+TESTS = open("win32k_tests.txt", "r").readlines()
+
+output = open("test_win32k_enrollment.py", "w", newline="\n")
+header = open("test_win32k_enrollment.template.py", "r")
+for l in header:
+ output.write(l)
+
+mappings = {}
+for line in TESTS:
+ line = line.strip()
+ if not line:
+ continue
+
+ if line.startswith("#"):
+ continue
+ elif line.startswith("> "):
+ line = line[2:]
+ key, value = line.split(":")
+ mappings[key.strip()] = value.strip()
+ continue
+ elif line.startswith("-"):
+ line = line[1:].strip()
+ elif line.startswith("+"):
+ line = line[1:].strip()
+ import pdb
+
+ pdb.set_trace()
+ else:
+ raise Exception("unknown line type: " + line)
+
+ # We can't handle Safe Mode right now
+ if "Safe Mode" in line:
+ continue
+
+ # If we have no assertions defined, skip the test entirely
+ if "[A" not in line:
+ continue
+
+ if not RE_DEFAULT.match(line):
+ raise Exception("'{0}' does not match the default regex".format(line))
+ default = RE_DEFAULT.search(line).groups(1)[0]
+
+ start_test(line)
+
+ set_default(default)
+
+ line = line[6:]
+
+ while line:
+ # this is a horrible hack for the line ending to avoid making the
+ # regex more complicated and having to fix it
+ if not line.endswith(" ->"):
+ line += " ->"
+
+ groups = RE_TRANSITION.search(line).groups()
+ start = groups[0].strip()
+ end = groups[1].strip()
+
+ if RE_ASSERTION.search(start):
+ assertion = RE_ASSERTION.search(start).groups()
+ start = start[0 : start.index("[")].strip()
+ elif RE_ASSERTION_SHORTHAND.search(start):
+ key = RE_ASSERTION_SHORTHAND.search(start).groups()[0]
+ assertion = RE_ASSERTION.search(mappings[key]).groups()
+ start = start[0 : start.index("[")].strip()
+ else:
+ assertion = ""
+
+ if start == "Nothing":
+ pass
+ elif start.startswith("Enrolled "):
+ enroll(start[9:])
+ elif start == "E10S":
+ set_e10s(True)
+ elif start == "Header-On":
+ set_header(True)
+ elif start == "Header-Off":
+ set_header(False)
+ elif start == "Bad Requirements":
+ set_bad_requirements(True)
+ elif start == "Restart":
+ restart()
+ elif start == "On":
+ set_pref(True)
+ elif start == "Off":
+ set_pref(False)
+ else:
+ raise Exception("Unknown Action: " + start)
+
+ print_assertion(assertion)
+
+ line = end.strip()
+
+ if RE_ASSERTION.match(line):
+ print_assertion(RE_ASSERTION.search(line).groups())
+ elif RE_ASSERTION_SHORTHAND.search(line):
+ key = RE_ASSERTION_SHORTHAND.search(line).groups()[0]
+ print_assertion(RE_ASSERTION.search(mappings[key]).groups())
diff --git a/toolkit/xre/test/marionette/marionette.ini b/toolkit/xre/test/marionette/marionette.ini
new file mode 100644
index 0000000000..bb49d6c5de
--- /dev/null
+++ b/toolkit/xre/test/marionette/marionette.ini
@@ -0,0 +1,6 @@
+[test_fission_autostart.py]
+[test_win32k_enrollment.py]
+skip-if =
+ os != 'win'
+ ccov # Bug 1757102
+[test_exitcode.py]
diff --git a/toolkit/xre/test/marionette/test_exitcode.py b/toolkit/xre/test/marionette/test_exitcode.py
new file mode 100644
index 0000000000..4ce7306122
--- /dev/null
+++ b/toolkit/xre/test/marionette/test_exitcode.py
@@ -0,0 +1,31 @@
+from marionette_harness import MarionetteTestCase
+
+
+class TestFissionAutostart(MarionetteTestCase):
+ def test_normal_exit(self):
+ self.marionette.set_context(self.marionette.CONTEXT_CHROME)
+
+ def call_quit():
+ self.marionette.execute_script(
+ """
+ Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit);
+ """,
+ sandbox="system",
+ )
+
+ self.marionette.quit(callback=call_quit)
+ self.assertEqual(self.marionette.instance.runner.returncode, 0)
+
+ def test_exit_code(self):
+ self.marionette.set_context(self.marionette.CONTEXT_CHROME)
+
+ def call_quit():
+ self.marionette.execute_script(
+ """
+ Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit, 5);
+ """,
+ sandbox="system",
+ )
+
+ self.marionette.quit(callback=call_quit)
+ self.assertEqual(self.marionette.instance.runner.returncode, 5)
diff --git a/toolkit/xre/test/marionette/test_fission_autostart.py b/toolkit/xre/test/marionette/test_fission_autostart.py
new file mode 100644
index 0000000000..b830c0eaca
--- /dev/null
+++ b/toolkit/xre/test/marionette/test_fission_autostart.py
@@ -0,0 +1,410 @@
+from contextlib import contextmanager
+
+from marionette_harness import MarionetteTestCase
+
+
+class ExperimentStatus:
+ UNENROLLED = 0
+ ENROLLED_CONTROL = 1
+ ENROLLED_TREATMENT = 2
+ DISQUALIFIED = 3
+
+
+class Prefs:
+ ENROLLMENT_STATUS = "fission.experiment.enrollmentStatus"
+ STARTUP_ENROLLMENT_STATUS = "fission.experiment.startupEnrollmentStatus"
+ FISSION_AUTOSTART = "fission.autostart"
+ FISSION_AUTOSTART_SESSION = "fission.autostart.session"
+
+
+ENV_ENABLE_FISSION = "MOZ_FORCE_ENABLE_FISSION"
+ENV_DISABLE_FISSION = "MOZ_FORCE_DISABLE_FISSION"
+ENV_DISABLE_E10S = "MOZ_FORCE_DISABLE_E10S"
+
+
+DECISION_STATUS = {
+ "experimentControl": 1,
+ "experimentTreatment": 2,
+ "disabledByE10sEnv": 3,
+ "enabledByEnv": 4,
+ "disabledByEnv": 5,
+ "enabledByDefault": 7,
+ "disabledByDefault": 8,
+ "enabledByUserPref": 9,
+ "disabledByUserPref": 10,
+ "disabledByE10sOther": 11,
+}
+
+
+class TestFissionAutostart(MarionetteTestCase):
+ SANDBOX_NAME = "fission-autostart"
+
+ def execute_script(self, code, *args, **kwargs):
+ with self.marionette.using_context(self.marionette.CONTEXT_CHROME):
+ return self.marionette.execute_script(
+ code, new_sandbox=False, sandbox=self.SANDBOX_NAME, *args, **kwargs
+ )
+
+ def get_fission_status(self):
+ return self.execute_script(
+ r"""
+ let win = Services.wm.getMostRecentWindow("navigator:browser");
+ return {
+ fissionAutostart: Services.appinfo.fissionAutostart,
+ fissionExperimentStatus: Services.appinfo.fissionExperimentStatus,
+ decisionStatus: Services.appinfo.fissionDecisionStatus,
+ decisionStatusString: Services.appinfo.fissionDecisionStatusString,
+ useRemoteSubframes: win.docShell.nsILoadContext.useRemoteSubframes,
+ fissionAutostartSession: Services.prefs.getBoolPref("fission.autostart.session"),
+ dynamicFissionAutostart: Services.prefs.getBoolPref("fission.autostart"),
+ };
+ """
+ )
+
+ def check_fission_status(self, enabled, experiment, decision, dynamic=None):
+ if dynamic is None:
+ dynamic = enabled
+
+ expected = {
+ "fissionAutostart": enabled,
+ "fissionExperimentStatus": experiment,
+ "decisionStatus": DECISION_STATUS[decision],
+ "decisionStatusString": decision,
+ "useRemoteSubframes": enabled,
+ "fissionAutostartSession": enabled,
+ "dynamicFissionAutostart": dynamic,
+ }
+
+ status = self.get_fission_status()
+
+ for prop, value in expected.items():
+ self.assertEqual(
+ status[prop],
+ value,
+ "%s should have the value `%r`, but has `%r`"
+ % (prop, value, status[prop]),
+ )
+
+ def set_env(self, env, value):
+ self.execute_script(
+ "env.set(arguments[0], arguments[1]);", script_args=(env, value)
+ )
+
+ def get_env(self, env):
+ return self.execute_script("return env.get(arguments[0]);", script_args=(env,))
+
+ def set_enrollment_status(self, status):
+ self.marionette.set_pref(Prefs.ENROLLMENT_STATUS, status, default_branch=True)
+
+ startup_status = self.marionette.get_pref(Prefs.STARTUP_ENROLLMENT_STATUS)
+ self.assertEqual(
+ startup_status,
+ status,
+ "Startup enrollment status (%r) should match new "
+ "session status (%r)" % (startup_status, status),
+ )
+
+ def restart(self, prefs=None, env=None):
+ if prefs:
+ self.marionette.set_prefs(prefs)
+
+ if env:
+ for name, value in env.items():
+ self.set_env(name, value)
+
+ self.marionette.restart(in_app=True, clean=False)
+ self.setUpSession()
+
+ # Sanity check our environment.
+ if prefs:
+ for key, val in prefs.items():
+ if val is not None:
+ self.assertEqual(self.marionette.get_pref(key), val)
+ if env:
+ for key, val in env.items():
+ self.assertEqual(self.get_env(key), val or "")
+
+ def setUpSession(self):
+ self.marionette.set_context(self.marionette.CONTEXT_CHROME)
+
+ self.execute_script(
+ r"""
+ // We're running in a function, in a sandbox, that inherits from an
+ // X-ray wrapped window. Anything we want to be globally available
+ // needs to be defined on that window.
+ window.env = Services.env;
+ """
+ )
+
+ @contextmanager
+ def full_restart(self):
+ profile = self.marionette.instance.profile
+ try:
+ self.marionette.quit()
+ yield profile
+ finally:
+ self.marionette.start_session()
+ self.setUpSession()
+
+ def setUp(self):
+ super(TestFissionAutostart, self).setUp()
+
+ # If we have configured marionette to require a particular value for
+ # `fission.autostart`, remove it as a forced pref until `tearDown`, and
+ # perform a clean restart, so we run this test without the pref
+ # pre-configured.
+ self.fissionRequired = None
+ if Prefs.FISSION_AUTOSTART in self.marionette.instance.required_prefs:
+ self.fissionRequired = self.marionette.instance.required_prefs[
+ Prefs.FISSION_AUTOSTART
+ ]
+ del self.marionette.instance.required_prefs[Prefs.FISSION_AUTOSTART]
+ self.marionette.restart(in_app=False, clean=True)
+
+ self.setUpSession()
+
+ # Fission status must start out with `enabledByDefault`
+ self.check_fission_status(
+ enabled=True,
+ experiment=ExperimentStatus.UNENROLLED,
+ decision="enabledByDefault",
+ )
+
+ def tearDown(self):
+ if self.fissionRequired is not None:
+ self.marionette.instance.required_prefs[
+ Prefs.FISSION_AUTOSTART
+ ] = self.fissionRequired
+ self.marionette.restart(in_app=False, clean=True)
+
+ super(TestFissionAutostart, self).tearDown()
+
+ def test_runtime_changes(self):
+ """Tests that changes to preferences during runtime do not have any
+ effect on the current session."""
+
+ self.check_fission_status(
+ enabled=True,
+ experiment=ExperimentStatus.UNENROLLED,
+ decision="enabledByDefault",
+ )
+
+ self.restart(prefs={Prefs.FISSION_AUTOSTART: False})
+
+ self.check_fission_status(
+ enabled=False,
+ experiment=ExperimentStatus.UNENROLLED,
+ decision="disabledByUserPref",
+ )
+
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+ self.check_fission_status(
+ enabled=False,
+ experiment=ExperimentStatus.UNENROLLED,
+ decision="disabledByUserPref",
+ )
+
+ self.marionette.set_pref(Prefs.FISSION_AUTOSTART, True)
+ self.check_fission_status(
+ enabled=False,
+ experiment=ExperimentStatus.UNENROLLED,
+ decision="disabledByUserPref",
+ dynamic=True,
+ )
+
+ self.marionette.clear_pref(Prefs.FISSION_AUTOSTART)
+ self.check_fission_status(
+ enabled=False,
+ experiment=ExperimentStatus.UNENROLLED,
+ decision="disabledByUserPref",
+ dynamic=True,
+ )
+
+ self.restart()
+ self.check_fission_status(
+ enabled=False,
+ experiment=ExperimentStatus.ENROLLED_CONTROL,
+ decision="experimentControl",
+ )
+
+ self.marionette.set_pref(
+ Prefs.ENROLLMENT_STATUS, ExperimentStatus.UNENROLLED, default_branch=True
+ )
+ self.check_fission_status(
+ enabled=False,
+ experiment=ExperimentStatus.ENROLLED_CONTROL,
+ decision="experimentControl",
+ )
+
+ self.set_env(ENV_ENABLE_FISSION, "1")
+ self.check_fission_status(
+ enabled=False,
+ experiment=ExperimentStatus.ENROLLED_CONTROL,
+ decision="experimentControl",
+ )
+
+ def test_fission_precedence(self):
+ self.check_fission_status(
+ enabled=True,
+ experiment=ExperimentStatus.UNENROLLED,
+ decision="enabledByDefault",
+ )
+
+ self.restart(
+ prefs={Prefs.FISSION_AUTOSTART: False}, env={ENV_ENABLE_FISSION: "1"}
+ )
+ self.check_fission_status(
+ enabled=True,
+ experiment=ExperimentStatus.UNENROLLED,
+ decision="enabledByEnv",
+ dynamic=False,
+ )
+
+ self.restart(
+ prefs={Prefs.FISSION_AUTOSTART: True},
+ env={ENV_DISABLE_FISSION: "1", ENV_ENABLE_FISSION: ""},
+ )
+ self.check_fission_status(
+ enabled=False,
+ experiment=ExperimentStatus.UNENROLLED,
+ decision="disabledByEnv",
+ dynamic=True,
+ )
+
+ self.restart(
+ prefs={Prefs.FISSION_AUTOSTART: False}, env={ENV_DISABLE_FISSION: ""}
+ )
+ self.check_fission_status(
+ enabled=False,
+ experiment=ExperimentStatus.UNENROLLED,
+ decision="disabledByUserPref",
+ )
+
+ self.restart(prefs={Prefs.FISSION_AUTOSTART: None})
+ self.check_fission_status(
+ enabled=True,
+ experiment=ExperimentStatus.UNENROLLED,
+ decision="enabledByDefault",
+ )
+
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+ self.restart()
+ self.check_fission_status(
+ enabled=True,
+ experiment=ExperimentStatus.ENROLLED_TREATMENT,
+ decision="experimentTreatment",
+ )
+
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+ self.restart()
+ self.check_fission_status(
+ enabled=False,
+ experiment=ExperimentStatus.ENROLLED_CONTROL,
+ decision="experimentControl",
+ )
+
+ self.marionette.set_pref(Prefs.FISSION_AUTOSTART, True)
+ self.check_fission_status(
+ enabled=False,
+ experiment=ExperimentStatus.ENROLLED_CONTROL,
+ decision="experimentControl",
+ dynamic=True,
+ )
+
+ self.assertEqual(
+ self.marionette.get_pref(Prefs.ENROLLMENT_STATUS),
+ ExperimentStatus.DISQUALIFIED,
+ "Setting fission.autostart should disqualify",
+ )
+
+ self.restart()
+ self.check_fission_status(
+ enabled=True,
+ experiment=ExperimentStatus.DISQUALIFIED,
+ decision="enabledByUserPref",
+ )
+
+ app_version = self.execute_script("return Services.appinfo.version")
+ self.restart(env={ENV_DISABLE_E10S: app_version})
+ self.check_fission_status(
+ enabled=False,
+ experiment=ExperimentStatus.DISQUALIFIED,
+ decision="disabledByE10sEnv",
+ dynamic=True,
+ )
+
+ def test_fission_startup(self):
+ # Starting the browser with STARTUP_ENROLLMENT_STATUS set to treatment
+ # should make the current session run under treatment.
+ with self.full_restart() as profile:
+ profile.set_preferences(
+ {
+ Prefs.STARTUP_ENROLLMENT_STATUS: ExperimentStatus.ENROLLED_TREATMENT,
+ },
+ filename="prefs.js",
+ )
+
+ self.assertEqual(
+ self.marionette.get_pref(Prefs.ENROLLMENT_STATUS),
+ ExperimentStatus.UNENROLLED,
+ "Dynamic pref should be unenrolled",
+ )
+ self.assertEqual(
+ self.marionette.get_pref(Prefs.STARTUP_ENROLLMENT_STATUS),
+ ExperimentStatus.ENROLLED_TREATMENT,
+ "Startup pref should be in treatment",
+ )
+ self.check_fission_status(
+ enabled=True,
+ experiment=ExperimentStatus.ENROLLED_TREATMENT,
+ decision="experimentTreatment",
+ )
+
+ # If normandy doesn't re-set `ENROLLMENT_STATUS` during the session, it
+ # should be cleared back to disabled after a restart.
+ self.marionette.restart(in_app=True, clean=False)
+
+ self.assertEqual(
+ self.marionette.get_pref(Prefs.ENROLLMENT_STATUS),
+ ExperimentStatus.UNENROLLED,
+ "Should unenroll dynamic pref after shutdown",
+ )
+ self.assertEqual(
+ self.marionette.get_pref(Prefs.STARTUP_ENROLLMENT_STATUS),
+ ExperimentStatus.UNENROLLED,
+ "Should unenroll startup pref after shutdown",
+ )
+ self.check_fission_status(
+ enabled=True,
+ experiment=ExperimentStatus.UNENROLLED,
+ decision="enabledByDefault",
+ )
+
+ # If the browser is started with a customized `fisison.autostart`,
+ # while also enrolled in an experiment, the experiment should be
+ # disqualified at startup.
+ with self.full_restart() as profile:
+ profile.set_preferences(
+ {
+ Prefs.FISSION_AUTOSTART: True,
+ Prefs.STARTUP_ENROLLMENT_STATUS: ExperimentStatus.ENROLLED_TREATMENT,
+ },
+ filename="prefs.js",
+ )
+
+ self.assertEqual(
+ self.marionette.get_pref(Prefs.ENROLLMENT_STATUS),
+ ExperimentStatus.DISQUALIFIED,
+ "Should disqualify dynamic pref on startup",
+ )
+ self.assertEqual(
+ self.marionette.get_pref(Prefs.STARTUP_ENROLLMENT_STATUS),
+ ExperimentStatus.DISQUALIFIED,
+ "Should disqualify startup pref on startup",
+ )
+
+ self.check_fission_status(
+ enabled=True,
+ experiment=ExperimentStatus.DISQUALIFIED,
+ decision="enabledByUserPref",
+ )
diff --git a/toolkit/xre/test/marionette/test_win32k_enrollment.py b/toolkit/xre/test/marionette/test_win32k_enrollment.py
new file mode 100644
index 0000000000..d09331319b
--- /dev/null
+++ b/toolkit/xre/test/marionette/test_win32k_enrollment.py
@@ -0,0 +1,2506 @@
+from contextlib import contextmanager
+
+from marionette_harness import MarionetteTestCase
+
+
+class ExperimentStatus:
+ UNENROLLED = 0
+ ENROLLED_CONTROL = 1
+ ENROLLED_TREATMENT = 2
+ DISQUALIFIED = 3
+
+
+class ContentWin32kLockdownState:
+ LockdownEnabled = 1
+ MissingWebRender = 2
+ OperatingSystemNotSupported = 3
+ PrefNotSet = 4
+ MissingRemoteWebGL = 5
+ MissingNonNativeTheming = 6
+ DisabledByEnvVar = 7
+ DisabledBySafeMode = 8
+ DisabledByE10S = 9
+ DisabledByUserPref = 10
+ EnabledByUserPref = 11
+ DisabledByControlGroup = 12
+ EnabledByTreatmentGroup = 13
+ DisabledByDefault = 14
+ EnabledByDefault = 15
+
+
+class Prefs:
+ ENROLLMENT_STATUS = "security.sandbox.content.win32k-experiment.enrollmentStatus"
+ STARTUP_ENROLLMENT_STATUS = (
+ "security.sandbox.content.win32k-experiment.startupEnrollmentStatus"
+ )
+ WIN32K = "security.sandbox.content.win32k-disable"
+ WEBGL = "webgl.out-of-process"
+
+
+ENV_DISABLE_WIN32K = "MOZ_ENABLE_WIN32K"
+ENV_DISABLE_E10S = "MOZ_FORCE_DISABLE_E10S"
+
+
+class TestWin32kAutostart(MarionetteTestCase):
+ SANDBOX_NAME = "win32k-autostart"
+
+ def execute_script(self, code, *args, **kwargs):
+ with self.marionette.using_context(self.marionette.CONTEXT_CHROME):
+ return self.marionette.execute_script(
+ code, new_sandbox=False, sandbox=self.SANDBOX_NAME, *args, **kwargs
+ )
+
+ def get_win32k_status(self):
+ return self.execute_script(
+ r"""
+ let win = Services.wm.getMostRecentWindow("navigator:browser");
+ let ses = "security.sandbox.content.win32k-experiment.startupEnrollmentStatus";
+ return {
+ win32kSessionStatus: Services.appinfo.win32kSessionStatus,
+ win32kStatus: Services.appinfo.win32kLiveStatusTestingOnly,
+ win32kExperimentStatus: Services.appinfo.win32kExperimentStatus,
+ win32kPref: Services.prefs.getBoolPref("security.sandbox.content.win32k-disable"),
+ win32kStartupEnrollmentStatusPref: Services.prefs.getIntPref(ses),
+ };
+ """
+ )
+
+ def check_win32k_status(
+ self, status, sessionStatus, experimentStatus, pref, enrollmentStatusPref
+ ):
+ # We CANNOT check win32kEnrollmentStatusPref after a restart because we only set this
+ # pref on the default branch, and it goes away after a restart, so we only check
+ # the startupEnrollmentStatusPref
+ expected = {
+ "win32kSessionStatus": sessionStatus,
+ "win32kStatus": status,
+ "win32kExperimentStatus": experimentStatus,
+ "win32kPref": pref,
+ "win32kStartupEnrollmentStatusPref": enrollmentStatusPref,
+ }
+
+ status = self.get_win32k_status()
+
+ for prop, value in expected.items():
+ self.assertEqual(
+ status[prop],
+ value,
+ "%s should have the value `%r`, but has `%r`"
+ % (prop, value, status[prop]),
+ )
+
+ def set_env(self, env, value):
+ self.execute_script(
+ "env.set(arguments[0], arguments[1]);", script_args=(env, value)
+ )
+
+ def get_env(self, env):
+ return self.execute_script("return env.get(arguments[0]);", script_args=(env,))
+
+ def set_enrollment_status(self, status):
+ self.marionette.set_pref(Prefs.ENROLLMENT_STATUS, status, default_branch=True)
+
+ updated_status = self.marionette.get_pref(Prefs.ENROLLMENT_STATUS)
+ self.assertTrue(
+ status == updated_status or updated_status == ExperimentStatus.DISQUALIFIED
+ )
+ startup_status = self.marionette.get_pref(Prefs.STARTUP_ENROLLMENT_STATUS)
+ self.assertEqual(
+ startup_status,
+ updated_status,
+ "Startup enrollment status (%r) should match "
+ "session status (%r)" % (startup_status, updated_status),
+ )
+
+ def restart(self, prefs=None, env=None):
+ if prefs:
+ self.marionette.set_prefs(prefs)
+
+ if env:
+ for name, value in env.items():
+ self.set_env(name, value)
+
+ self.marionette.restart(in_app=True, clean=False)
+ self.setUpSession()
+
+ # Sanity check our environment.
+ if prefs:
+ for key, val in prefs.items():
+ if val is not None:
+ self.assertEqual(self.marionette.get_pref(key), val)
+ if env:
+ for key, val in env.items():
+ self.assertEqual(self.get_env(key), val or "")
+
+ def setUpSession(self):
+ self.marionette.set_context(self.marionette.CONTEXT_CHROME)
+
+ self.execute_script(
+ r"""
+ // We're running in a function, in a sandbox, that inherits from an
+ // X-ray wrapped window. Anything we want to be globally available
+ // needs to be defined on that window.
+ window.env = Services.env;
+ """
+ )
+
+ @contextmanager
+ def full_restart(self):
+ profile = self.marionette.instance.profile
+ try:
+ self.marionette.quit()
+ yield profile
+ finally:
+ self.marionette.start_session()
+ self.setUpSession()
+
+ def setUp(self):
+ super(TestWin32kAutostart, self).setUp()
+
+ # If we have configured marionette to require a particular value for
+ # `win32k.autostart`, remove it as a forced pref until `tearDown`, and
+ # perform a clean restart, so we run this test without the pref
+ # pre-configured.
+ self.win32kRequired = None
+ if Prefs.WIN32K in self.marionette.instance.required_prefs:
+ self.win32kRequired = self.marionette.instance.required_prefs[Prefs.WIN32K]
+ del self.marionette.instance.required_prefs[Prefs.WIN32K]
+ self.marionette.restart(in_app=False, clean=True)
+
+ self.setUpSession()
+
+ # Marionette doesn't let you set preferences on the default branch before startup
+ # so we can't test the default=False and default=True scenarios in one test
+ # What we can do is generate all the tests, and then only run the runs for which
+ # the default is. (And run the other ones locally to make sure they work before
+ # we land it.)
+ prefJS = 'return Services.prefs.getBoolPref("security.sandbox.content.win32k-disable");'
+ self.default_is = self.execute_script(prefJS)
+
+ if self.default_is is False:
+ # Win32k status must start out with `disabledByDefault`
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+ else:
+ # Win32k status must start out with `enabledByDefault`
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def tearDown(self):
+ if self.win32kRequired is not None:
+ self.marionette.instance.required_prefs[Prefs.WIN32K] = self.win32kRequired
+ self.marionette.restart(in_app=False, clean=True)
+
+ super(TestWin32kAutostart, self).tearDown()
+
+ def test_1(self):
+ # [D=F] Nothing [A#1] -> Enrolled Control [A S=DisabledByDefault SS=DisabledByDefa...
+
+ if self.default_is is not False:
+ return
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ def test_2(self):
+ # [D=F] Nothing [A#1] -> Enrolled Treatment [A S=DisabledByDefault SS=DisabledByDe...
+
+ if self.default_is is not False:
+ return
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ def test_3(self):
+ # [D=F] Nothing [A#1] -> On [A S=EnabledByUserPref SS=DisabledByDefault ES=UNENROL...
+
+ if self.default_is is not False:
+ return
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByUserPref,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_4(self):
+ # [D=F] Nothing [A#1] -> Off [A#1] -> Restart [A#1]...
+
+ if self.default_is is not False:
+ return
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.marionette.set_pref(Prefs.WIN32K, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_5(self):
+ # [D=F] Nothing [A#1] -> On -> Bad Requirements [A S=MissingRemoteWebGL SS=Disable...
+
+ if self.default_is is not False:
+ return
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.marionette.set_pref(Prefs.WEBGL, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_6(self):
+ # [D=F] Nothing [A#1] -> On -> E10S [A S=DisabledByE10S SS=DisabledByE10S ES=UNENR...
+
+ if self.default_is is not False:
+ return
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ app_version = self.execute_script("return Services.appinfo.version")
+ self.restart(env={ENV_DISABLE_E10S: app_version})
+ self.set_env(ENV_DISABLE_E10S, "null")
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByE10S,
+ sessionStatus=ContentWin32kLockdownState.DisabledByE10S,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_7(self):
+ # [D=F] Nothing [A#1] -> On -> Header-On [A S=DisabledByEnvVar SS=DisabledByEnvVar...
+
+ if self.default_is is not False:
+ return
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.restart(env={ENV_DISABLE_WIN32K: "1"})
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByEnvVar,
+ sessionStatus=ContentWin32kLockdownState.DisabledByEnvVar,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.set_env(ENV_DISABLE_WIN32K, "")
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.DisabledByEnvVar,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_8(self):
+ # [D=T] Nothing [A#1T] -> Enrolled Control [A S=EnabledByDefault SS=EnabledByDefau...
+
+ if self.default_is is not True:
+ return
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ def test_9(self):
+ # [D=T] Nothing [A#1T] -> Enrolled Treatment [A S=EnabledByDefault SS=EnabledByDef...
+
+ if self.default_is is not True:
+ return
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ def test_10(self):
+ # [D=T] Nothing [A#1T] -> On [A S=EnabledByDefault SS=EnabledByDefault ES=UNENROLL...
+
+ if self.default_is is not True:
+ return
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_11(self):
+ # [D=T] Nothing [A#1T] -> Off [A S=DisabledByUserPref SS=EnabledByDefault ES=UNENR...
+
+ if self.default_is is not True:
+ return
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.marionette.set_pref(Prefs.WIN32K, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.DisabledByUserPref,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_12(self):
+ # [D=T] Nothing [A#1T] -> On -> Bad Requirements [A S=MissingRemoteWebGL SS=Enable...
+
+ if self.default_is is not True:
+ return
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.marionette.set_pref(Prefs.WEBGL, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_13(self):
+ # [D=T] Nothing [A#1T] -> On -> E10S [A S=DisabledByE10S SS=DisabledByE10S ES=UNEN...
+
+ if self.default_is is not True:
+ return
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ app_version = self.execute_script("return Services.appinfo.version")
+ self.restart(env={ENV_DISABLE_E10S: app_version})
+ self.set_env(ENV_DISABLE_E10S, "null")
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByE10S,
+ sessionStatus=ContentWin32kLockdownState.DisabledByE10S,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_14(self):
+ # [D=T] Nothing [A#1T] -> On -> Header-On [A S=DisabledByEnvVar SS=DisabledByEnvVa...
+
+ if self.default_is is not True:
+ return
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.restart(env={ENV_DISABLE_WIN32K: "1"})
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByEnvVar,
+ sessionStatus=ContentWin32kLockdownState.DisabledByEnvVar,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.set_env(ENV_DISABLE_WIN32K, "")
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByEnvVar,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_15(self):
+ # [D=F] On [A#3] -> Restart [A#4] -> Enrolled Control [A S=EnabledByUserPref SS=En...
+
+ if self.default_is is not False:
+ return
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByUserPref,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByUserPref,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByUserPref,
+ experimentStatus=ExperimentStatus.DISQUALIFIED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.DISQUALIFIED,
+ )
+
+ def test_16(self):
+ # [D=F] On [A#3] -> Restart [A#4] -> Enrolled Treatment [A S=EnabledByUserPref SS=...
+
+ if self.default_is is not False:
+ return
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByUserPref,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByUserPref,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByUserPref,
+ experimentStatus=ExperimentStatus.DISQUALIFIED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.DISQUALIFIED,
+ )
+
+ def test_17(self):
+ # [D=F] On [A#3] -> Restart [A#4] -> Off [A S=DisabledByDefault SS=EnabledByUserPr...
+
+ if self.default_is is not False:
+ return
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByUserPref,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.marionette.set_pref(Prefs.WIN32K, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByUserPref,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_18(self):
+ # [D=F] On [A#3] -> Restart [A#4] -> Bad Requirements [A S=MissingRemoteWebGL SS=E...
+
+ if self.default_is is not False:
+ return
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByUserPref,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.marionette.set_pref(Prefs.WEBGL, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.EnabledByUserPref,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_19(self):
+ # [D=F] On [A#3] -> Restart [A#4] -> E10S [A S=DisabledByE10S SS=DisabledByE10S ES...
+
+ if self.default_is is not False:
+ return
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByUserPref,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ app_version = self.execute_script("return Services.appinfo.version")
+ self.restart(env={ENV_DISABLE_E10S: app_version})
+ self.set_env(ENV_DISABLE_E10S, "null")
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByE10S,
+ sessionStatus=ContentWin32kLockdownState.DisabledByE10S,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByUserPref,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_20(self):
+ # [D=F] On [A#3] -> Restart [A#4] -> Header-On [A S=DisabledByEnvVar SS=DisabledBy...
+
+ if self.default_is is not False:
+ return
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByUserPref,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart(env={ENV_DISABLE_WIN32K: "1"})
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByEnvVar,
+ sessionStatus=ContentWin32kLockdownState.DisabledByEnvVar,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.set_env(ENV_DISABLE_WIN32K, "")
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByUserPref,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_21(self):
+ # [D=T] On [A#3T] -> Restart [A#4T] -> Enrolled Control [A S=EnabledByDefault SS=E...
+
+ if self.default_is is not True:
+ return
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ def test_22(self):
+ # [D=T] On [A#3T] -> Restart [A#4T] -> Enrolled Treatment [A S=EnabledByDefault SS...
+
+ if self.default_is is not True:
+ return
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ def test_23(self):
+ # [D=T] On [A#3T] -> Restart [A#4T] -> Off [A S=DisabledByUserPref SS=EnabledByDef...
+
+ if self.default_is is not True:
+ return
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.marionette.set_pref(Prefs.WIN32K, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.DisabledByUserPref,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_24(self):
+ # [D=T] On [A#3T] -> Restart [A#4T] -> Bad Requirements [A S=MissingRemoteWebGL SS...
+
+ if self.default_is is not True:
+ return
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.marionette.set_pref(Prefs.WEBGL, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_25(self):
+ # [D=T] On [A#3T] -> Restart [A#4T] -> E10S [A S=DisabledByE10S SS=DisabledByE10S ...
+
+ if self.default_is is not True:
+ return
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ app_version = self.execute_script("return Services.appinfo.version")
+ self.restart(env={ENV_DISABLE_E10S: app_version})
+ self.set_env(ENV_DISABLE_E10S, "null")
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByE10S,
+ sessionStatus=ContentWin32kLockdownState.DisabledByE10S,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_26(self):
+ # [D=T] On [A#3T] -> Restart [A#4T] -> Header-On [A S=DisabledByEnvVar SS=Disabled...
+
+ if self.default_is is not True:
+ return
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart(env={ENV_DISABLE_WIN32K: "1"})
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByEnvVar,
+ sessionStatus=ContentWin32kLockdownState.DisabledByEnvVar,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.set_env(ENV_DISABLE_WIN32K, "")
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_27(self):
+ # [D=F] Enrolled Control [A#5] -> Restart [A#6] -> Enrolled Control-C -> On [A S=E...
+
+ if self.default_is is not False:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.DISQUALIFIED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByUserPref,
+ experimentStatus=ExperimentStatus.DISQUALIFIED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.DISQUALIFIED,
+ )
+
+ def test_28(self):
+ # [D=F] Enrolled Control [A#5] -> Restart [A#6] -> Off [A#6]...
+
+ if self.default_is is not False:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.marionette.set_pref(Prefs.WIN32K, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ def test_29(self):
+ # [D=F] Enrolled Control [A#5] -> Restart [A#6] -> Enrolled Control-C -> Bad Requi...
+
+ if self.default_is is not False:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.marionette.set_pref(Prefs.WEBGL, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.DISQUALIFIED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.DISQUALIFIED,
+ )
+
+ def test_30(self):
+ # [D=F] Enrolled Control [A#5] -> Restart [A#6] -> Enrolled Control-C -> E10S [A S...
+
+ if self.default_is is not False:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ app_version = self.execute_script("return Services.appinfo.version")
+ self.restart(env={ENV_DISABLE_E10S: app_version})
+ self.set_env(ENV_DISABLE_E10S, "null")
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByE10S,
+ sessionStatus=ContentWin32kLockdownState.DisabledByE10S,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ def test_31(self):
+ # [D=F] Enrolled Control [A#5] -> Restart [A#6] -> Enrolled Control-C -> Header-On...
+
+ if self.default_is is not False:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.restart(env={ENV_DISABLE_WIN32K: "1"})
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByEnvVar,
+ sessionStatus=ContentWin32kLockdownState.DisabledByEnvVar,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.set_env(ENV_DISABLE_WIN32K, "")
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ def test_32(self):
+ # [D=T] Enrolled Control [A#5T] -> Restart [A#6T] -> Enrolled Control-C -> On [A S...
+
+ if self.default_is is not True:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ def test_33(self):
+ # [D=T] Enrolled Control [A#5T] -> Restart [A#6T] -> Off [A S=DisabledByUserPref S...
+
+ if self.default_is is not True:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.marionette.set_pref(Prefs.WIN32K, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.DISQUALIFIED,
+ )
+
+ def test_34(self):
+ # [D=T] Enrolled Control [A#5T] -> Restart [A#6T] -> Enrolled Control-C -> Bad Req...
+
+ if self.default_is is not True:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.marionette.set_pref(Prefs.WEBGL, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.DISQUALIFIED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.DISQUALIFIED,
+ )
+
+ def test_35(self):
+ # [D=T] Enrolled Control [A#5T] -> Restart [A#6T] -> Enrolled Control-C -> E10S [A...
+
+ if self.default_is is not True:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ app_version = self.execute_script("return Services.appinfo.version")
+ self.restart(env={ENV_DISABLE_E10S: app_version})
+ self.set_env(ENV_DISABLE_E10S, "null")
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByE10S,
+ sessionStatus=ContentWin32kLockdownState.DisabledByE10S,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ def test_36(self):
+ # [D=T] Enrolled Control [A#5T] -> Restart [A#6T] -> Enrolled Control-C -> Header-...
+
+ if self.default_is is not True:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.restart(env={ENV_DISABLE_WIN32K: "1"})
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByEnvVar,
+ sessionStatus=ContentWin32kLockdownState.DisabledByEnvVar,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.set_env(ENV_DISABLE_WIN32K, "")
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByControlGroup,
+ sessionStatus=ContentWin32kLockdownState.DisabledByControlGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_CONTROL,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ def test_37(self):
+ # [D=F] Enrolled Treatment [A#7] -> Restart [A#8] -> Enrolled Treatment-C -> On [A...
+
+ if self.default_is is not False:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.DISQUALIFIED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByUserPref,
+ experimentStatus=ExperimentStatus.DISQUALIFIED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.DISQUALIFIED,
+ )
+
+ def test_38(self):
+ # [D=F] Enrolled Treatment [A#7] -> Restart [A#8] -> Enrolled Treatment-C -> Off [...
+
+ if self.default_is is not False:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.marionette.set_pref(Prefs.WIN32K, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ def test_39(self):
+ # [D=F] Enrolled Treatment [A#7] -> Restart [A#8] -> Enrolled Treatment-C -> Bad R...
+
+ if self.default_is is not False:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.marionette.set_pref(Prefs.WEBGL, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.DISQUALIFIED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.DISQUALIFIED,
+ )
+
+ def test_40(self):
+ # [D=F] Enrolled Treatment [A#7] -> Restart [A#8] -> Enrolled Treatment-C -> E10S ...
+
+ if self.default_is is not False:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ app_version = self.execute_script("return Services.appinfo.version")
+ self.restart(env={ENV_DISABLE_E10S: app_version})
+ self.set_env(ENV_DISABLE_E10S, "null")
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByE10S,
+ sessionStatus=ContentWin32kLockdownState.DisabledByE10S,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ def test_41(self):
+ # [D=F] Enrolled Treatment [A#7] -> Restart [A#8] -> Enrolled Treatment-C -> Heade...
+
+ if self.default_is is not False:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.restart(env={ENV_DISABLE_WIN32K: "1"})
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByEnvVar,
+ sessionStatus=ContentWin32kLockdownState.DisabledByEnvVar,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.set_env(ENV_DISABLE_WIN32K, "")
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ def test_42(self):
+ # [D=T] Enrolled Treatment [A#7T] -> Restart [A#8T] -> Enrolled Treatment-C -> On ...
+
+ if self.default_is is not True:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ def test_43(self):
+ # [D=T] Enrolled Treatment [A#7T] -> Restart [A#8T] -> Enrolled Treatment-C -> Off...
+
+ if self.default_is is not True:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.marionette.set_pref(Prefs.WIN32K, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.DISQUALIFIED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByUserPref,
+ sessionStatus=ContentWin32kLockdownState.DisabledByUserPref,
+ experimentStatus=ExperimentStatus.DISQUALIFIED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.DISQUALIFIED,
+ )
+
+ def test_44(self):
+ # [D=T] Enrolled Treatment [A#7T] -> Restart [A#8T] -> Enrolled Treatment-C -> Bad...
+
+ if self.default_is is not True:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.marionette.set_pref(Prefs.WEBGL, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.DISQUALIFIED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.DISQUALIFIED,
+ )
+
+ def test_45(self):
+ # [D=T] Enrolled Treatment [A#7T] -> Restart [A#8T] -> Enrolled Treatment-C -> E10...
+
+ if self.default_is is not True:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ app_version = self.execute_script("return Services.appinfo.version")
+ self.restart(env={ENV_DISABLE_E10S: app_version})
+ self.set_env(ENV_DISABLE_E10S, "null")
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByE10S,
+ sessionStatus=ContentWin32kLockdownState.DisabledByE10S,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ def test_46(self):
+ # [D=T] Enrolled Treatment [A#7T] -> Restart [A#8T] -> Enrolled Treatment-C -> Hea...
+
+ if self.default_is is not True:
+ return
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.restart(env={ENV_DISABLE_WIN32K: "1"})
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByEnvVar,
+ sessionStatus=ContentWin32kLockdownState.DisabledByEnvVar,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.set_env(ENV_DISABLE_WIN32K, "")
+
+ # Re-set enrollment pref, like Normandy would do
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ sessionStatus=ContentWin32kLockdownState.EnabledByTreatmentGroup,
+ experimentStatus=ExperimentStatus.ENROLLED_TREATMENT,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ def test_47(self):
+ # [D=F] Bad Requirements [A#9] -> Restart [A#10] -> Enrolled Control [A S=MissingR...
+
+ if self.default_is is not False:
+ return
+
+ self.marionette.set_pref(Prefs.WEBGL, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.DISQUALIFIED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.DISQUALIFIED,
+ )
+
+ def test_48(self):
+ # [D=F] Bad Requirements [A#9] -> Restart [A#10] -> Enrolled Treatment [A S=Missin...
+
+ if self.default_is is not False:
+ return
+
+ self.marionette.set_pref(Prefs.WEBGL, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.DISQUALIFIED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.DISQUALIFIED,
+ )
+
+ def test_49(self):
+ # [D=F] Bad Requirements [A#9] -> Restart [A#10] -> On [A S=MissingRemoteWebGL SS=...
+
+ if self.default_is is not False:
+ return
+
+ self.marionette.set_pref(Prefs.WEBGL, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_50(self):
+ # [D=F] Bad Requirements [A#9] -> Restart [A#10] -> Off [A S=MissingRemoteWebGL SS...
+
+ if self.default_is is not False:
+ return
+
+ self.marionette.set_pref(Prefs.WEBGL, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.marionette.set_pref(Prefs.WIN32K, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_51(self):
+ # [D=T] Bad Requirements [A#9T] -> Restart [A#10T] -> Enrolled Control [A S=Missin...
+
+ if self.default_is is not True:
+ return
+
+ self.marionette.set_pref(Prefs.WEBGL, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_CONTROL)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_CONTROL,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.DISQUALIFIED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.DISQUALIFIED,
+ )
+
+ def test_52(self):
+ # [D=T] Bad Requirements [A#9T] -> Restart [A#10T] -> Enrolled Treatment [A S=Miss...
+
+ if self.default_is is not True:
+ return
+
+ self.marionette.set_pref(Prefs.WEBGL, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+ self.set_enrollment_status(ExperimentStatus.ENROLLED_TREATMENT)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.ENROLLED_TREATMENT,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.DISQUALIFIED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.DISQUALIFIED,
+ )
+
+ def test_53(self):
+ # [D=T] Bad Requirements [A#9T] -> Restart [A#10T] -> On [A S=MissingRemoteWebGL S...
+
+ if self.default_is is not True:
+ return
+
+ self.marionette.set_pref(Prefs.WEBGL, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.marionette.set_pref(Prefs.WIN32K, True)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def test_54(self):
+ # [D=T] Bad Requirements [A#9T] -> Restart [A#10T] -> Off [A S=MissingRemoteWebGL ...
+
+ if self.default_is is not True:
+ return
+
+ self.marionette.set_pref(Prefs.WEBGL, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.restart()
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ self.marionette.set_pref(Prefs.WIN32K, False)
+
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.MissingRemoteWebGL,
+ sessionStatus=ContentWin32kLockdownState.MissingRemoteWebGL,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
diff --git a/toolkit/xre/test/marionette/test_win32k_enrollment.template.py b/toolkit/xre/test/marionette/test_win32k_enrollment.template.py
new file mode 100644
index 0000000000..30dc7fed33
--- /dev/null
+++ b/toolkit/xre/test/marionette/test_win32k_enrollment.template.py
@@ -0,0 +1,204 @@
+from contextlib import contextmanager
+
+from marionette_harness import MarionetteTestCase
+
+
+class ExperimentStatus:
+ UNENROLLED = 0
+ ENROLLED_CONTROL = 1
+ ENROLLED_TREATMENT = 2
+ DISQUALIFIED = 3
+
+
+class ContentWin32kLockdownState:
+ LockdownEnabled = 1
+ MissingWebRender = 2
+ OperatingSystemNotSupported = 3
+ PrefNotSet = 4
+ MissingRemoteWebGL = 5
+ MissingNonNativeTheming = 6
+ DisabledByEnvVar = 7
+ DisabledBySafeMode = 8
+ DisabledByE10S = 9
+ DisabledByUserPref = 10
+ EnabledByUserPref = 11
+ DisabledByControlGroup = 12
+ EnabledByTreatmentGroup = 13
+ DisabledByDefault = 14
+ EnabledByDefault = 15
+
+
+class Prefs:
+ ENROLLMENT_STATUS = "security.sandbox.content.win32k-experiment.enrollmentStatus"
+ STARTUP_ENROLLMENT_STATUS = (
+ "security.sandbox.content.win32k-experiment.startupEnrollmentStatus"
+ )
+ WIN32K = "security.sandbox.content.win32k-disable"
+ WEBGL = "webgl.out-of-process"
+
+
+ENV_DISABLE_WIN32K = "MOZ_ENABLE_WIN32K"
+ENV_DISABLE_E10S = "MOZ_FORCE_DISABLE_E10S"
+
+
+class TestWin32kAutostart(MarionetteTestCase):
+ SANDBOX_NAME = "win32k-autostart"
+
+ def execute_script(self, code, *args, **kwargs):
+ with self.marionette.using_context(self.marionette.CONTEXT_CHROME):
+ return self.marionette.execute_script(
+ code, new_sandbox=False, sandbox=self.SANDBOX_NAME, *args, **kwargs
+ )
+
+ def get_win32k_status(self):
+ return self.execute_script(
+ r"""
+ let win = Services.wm.getMostRecentWindow("navigator:browser");
+ let ses = "security.sandbox.content.win32k-experiment.startupEnrollmentStatus";
+ return {
+ win32kSessionStatus: Services.appinfo.win32kSessionStatus,
+ win32kStatus: Services.appinfo.win32kLiveStatusTestingOnly,
+ win32kExperimentStatus: Services.appinfo.win32kExperimentStatus,
+ win32kPref: Services.prefs.getBoolPref("security.sandbox.content.win32k-disable"),
+ win32kStartupEnrollmentStatusPref: Services.prefs.getIntPref(ses),
+ };
+ """
+ )
+
+ def check_win32k_status(
+ self, status, sessionStatus, experimentStatus, pref, enrollmentStatusPref
+ ):
+ # We CANNOT check win32kEnrollmentStatusPref after a restart because we only set this
+ # pref on the default branch, and it goes away after a restart, so we only check
+ # the startupEnrollmentStatusPref
+ expected = {
+ "win32kSessionStatus": sessionStatus,
+ "win32kStatus": status,
+ "win32kExperimentStatus": experimentStatus,
+ "win32kPref": pref,
+ "win32kStartupEnrollmentStatusPref": enrollmentStatusPref,
+ }
+
+ status = self.get_win32k_status()
+
+ for prop, value in expected.items():
+ self.assertEqual(
+ status[prop],
+ value,
+ "%s should have the value `%r`, but has `%r`"
+ % (prop, value, status[prop]),
+ )
+
+ def set_env(self, env, value):
+ self.execute_script(
+ "env.set(arguments[0], arguments[1]);", script_args=(env, value)
+ )
+
+ def get_env(self, env):
+ return self.execute_script("return env.get(arguments[0]);", script_args=(env,))
+
+ def set_enrollment_status(self, status):
+ self.marionette.set_pref(Prefs.ENROLLMENT_STATUS, status, default_branch=True)
+
+ updated_status = self.marionette.get_pref(Prefs.ENROLLMENT_STATUS)
+ self.assertTrue(
+ status == updated_status or updated_status == ExperimentStatus.DISQUALIFIED
+ )
+ startup_status = self.marionette.get_pref(Prefs.STARTUP_ENROLLMENT_STATUS)
+ self.assertEqual(
+ startup_status,
+ updated_status,
+ "Startup enrollment status (%r) should match "
+ "session status (%r)" % (startup_status, updated_status),
+ )
+
+ def restart(self, prefs=None, env=None):
+ if prefs:
+ self.marionette.set_prefs(prefs)
+
+ if env:
+ for name, value in env.items():
+ self.set_env(name, value)
+
+ self.marionette.restart(in_app=True, clean=False)
+ self.setUpSession()
+
+ # Sanity check our environment.
+ if prefs:
+ for key, val in prefs.items():
+ if val is not None:
+ self.assertEqual(self.marionette.get_pref(key), val)
+ if env:
+ for key, val in env.items():
+ self.assertEqual(self.get_env(key), val or "")
+
+ def setUpSession(self):
+ self.marionette.set_context(self.marionette.CONTEXT_CHROME)
+
+ self.execute_script(
+ r"""
+ // We're running in a function, in a sandbox, that inherits from an
+ // X-ray wrapped window. Anything we want to be globally available
+ // needs to be defined on that window.
+ window.env = Services.env;
+ """
+ )
+
+ @contextmanager
+ def full_restart(self):
+ profile = self.marionette.instance.profile
+ try:
+ self.marionette.quit()
+ yield profile
+ finally:
+ self.marionette.start_session()
+ self.setUpSession()
+
+ def setUp(self):
+ super(TestWin32kAutostart, self).setUp()
+
+ # If we have configured marionette to require a particular value for
+ # `win32k.autostart`, remove it as a forced pref until `tearDown`, and
+ # perform a clean restart, so we run this test without the pref
+ # pre-configured.
+ self.win32kRequired = None
+ if Prefs.WIN32K in self.marionette.instance.required_prefs:
+ self.win32kRequired = self.marionette.instance.required_prefs[Prefs.WIN32K]
+ del self.marionette.instance.required_prefs[Prefs.WIN32K]
+ self.marionette.restart(in_app=False, clean=True)
+
+ self.setUpSession()
+
+ # Marionette doesn't let you set preferences on the default branch before startup
+ # so we can't test the default=False and default=True scenarios in one test
+ # What we can do is generate all the tests, and then only run the runs for which
+ # the default is. (And run the other ones locally to make sure they work before
+ # we land it.)
+ prefJS = 'return Services.prefs.getBoolPref("security.sandbox.content.win32k-disable");'
+ self.default_is = self.execute_script(prefJS)
+
+ if self.default_is is False:
+ # Win32k status must start out with `disabledByDefault`
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.DisabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.DisabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=False,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+ else:
+ # Win32k status must start out with `enabledByDefault`
+ self.check_win32k_status(
+ status=ContentWin32kLockdownState.EnabledByDefault,
+ sessionStatus=ContentWin32kLockdownState.EnabledByDefault,
+ experimentStatus=ExperimentStatus.UNENROLLED,
+ pref=True,
+ enrollmentStatusPref=ExperimentStatus.UNENROLLED,
+ )
+
+ def tearDown(self):
+ if self.win32kRequired is not None:
+ self.marionette.instance.required_prefs[Prefs.WIN32K] = self.win32kRequired
+ self.marionette.restart(in_app=False, clean=True)
+
+ super(TestWin32kAutostart, self).tearDown()
diff --git a/toolkit/xre/test/marionette/win32k_tests.txt b/toolkit/xre/test/marionette/win32k_tests.txt
new file mode 100644
index 0000000000..76068de268
--- /dev/null
+++ b/toolkit/xre/test/marionette/win32k_tests.txt
@@ -0,0 +1,167 @@
+#############################################
+# This file serves as the test case list for gen_win32k_tests.py
+
+#############################################
+# Only here for reference:
+
+# MissingWebRender = 2
+# OperatingSystemNotSupported = 3
+# MissingRemoteWebGL = 5
+# DisabledByEnvVar = 7
+# DisabledBySafeMode = 8
+# DisabledByE10S = 9
+# DisabledByUserPref = 10
+# EnabledByUserPref = 11
+# DisabledByControlGroup = 12
+# EnabledByTreatmentGroup = 13
+# DisabledByDefault = 14
+# EnabledByDefault = 15
+
+# UNENROLLED
+# ENROLLED_CONTROL
+# ENROLLED_TREATMENT
+# DISQUALIFIED
+
+#############################################
+# Assertion Mappings
+# Shorthand values for the test cases below. Instead of writing out the whole thing
+# you can just do [A#5]
+
+ > 1 : [A S=DisabledByDefault SS=DisabledByDefault ES=UNENROLLED P=False ESP=UNENROLLED]
+ > 1T : [A S=EnabledByDefault SS=EnabledByDefault ES=UNENROLLED P=True ESP=UNENROLLED]
+ > 2 : [A S=EnabledByDefault SS=EnabledByDefault ES=UNENROLLED P=True ESP=UNENROLLED]
+ > 3 : [A S=EnabledByUserPref SS=DisabledByDefault ES=UNENROLLED P=True ESP=UNENROLLED]
+ > 3T : [A S=EnabledByDefault SS=EnabledByDefault ES=UNENROLLED P=True ESP=UNENROLLED]
+ > 4 : [A S=EnabledByUserPref SS=EnabledByUserPref ES=UNENROLLED P=True ESP=UNENROLLED]
+ > 4T : [A S=EnabledByDefault SS=EnabledByDefault ES=UNENROLLED P=True ESP=UNENROLLED]
+ > 5 : [A S=DisabledByDefault SS=DisabledByDefault ES=UNENROLLED P=False ESP=ENROLLED_CONTROL]
+ > 5T : [A S=EnabledByDefault SS=EnabledByDefault ES=UNENROLLED P=True ESP=ENROLLED_CONTROL]
+ > 6 : [A S=DisabledByControlGroup SS=DisabledByControlGroup ES=ENROLLED_CONTROL P=False ESP=ENROLLED_CONTROL]
+ > 6T : [A S=DisabledByControlGroup SS=DisabledByControlGroup ES=ENROLLED_CONTROL P=True ESP=ENROLLED_CONTROL]
+ > 7 : [A S=DisabledByDefault SS=DisabledByDefault ES=UNENROLLED P=False ESP=ENROLLED_TREATMENT]
+ > 7T : [A S=EnabledByDefault SS=EnabledByDefault ES=UNENROLLED P=True ESP=ENROLLED_TREATMENT]
+ > 8 : [A S=EnabledByTreatmentGroup SS=EnabledByTreatmentGroup ES=ENROLLED_TREATMENT P=False ESP=ENROLLED_TREATMENT]
+ > 8T : [A S=EnabledByTreatmentGroup SS=EnabledByTreatmentGroup ES=ENROLLED_TREATMENT P=True ESP=ENROLLED_TREATMENT]
+ > 9 : [A S=MissingRemoteWebGL SS=DisabledByDefault ES=UNENROLLED P=False ESP=UNENROLLED]
+ > 9T : [A S=MissingRemoteWebGL SS=EnabledByDefault ES=UNENROLLED P=True ESP=UNENROLLED]
+ > 10 : [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=UNENROLLED P=False ESP=UNENROLLED]
+ > 10T: [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=UNENROLLED P=True ESP=UNENROLLED]
+
+
+# TODO
+# - win32k env var tests
+
+
+#############################################
+# Tests
+
+# Syntax:
+# [D=T] - is the default value for win32k lockdown pref 'false' or 'true'
+# Action -> Action
+# Valid Actions:
+# Nothing
+# Enrolled Control/Treatment
+# On/Off (changes win32k pref)
+# Restart
+# E10s (Restarts with E10s disabled)
+# Header-On - Restart with MOZ_ENABLE_WIN32K set
+# Header-Off - unset MOZ_ENABLE_WIN32K but do not restart
+# Bad Requirements - sets webg out of process to false, invalidating win32k
+# Enrolled /Control/Treatment]-C:
+# The enrollment pref is set by normandy on _every_ startup on the
+# default branch, where it doesn't persist.
+# This action represents normandy doing its normal set that
+# occurs after a restart. If Normandy doesn't do it, the
+# startupEnrollmentPref is set back to 0 after restart, which is expected.
+# [A S= SS= ES= P= ESP=] - trigger an assertion check for the listed values
+# S - 'Status' or the current value of calculating GetWin32kLockdownState()
+# SS - 'Session Status' or the current value of set-once-at-startup static variable gWin32kStatus
+# ES - 'Experiment Status' or the value of gWin32kExperimentStatus
+# P - 'Pref' or the value of security.sandbox.content.win32k-disable
+# ESP- 'Enrollment Status Pref' or the value of security.sandbox.content.win32k-experiment.startupEnrollmentStatus
+# [A#5] - trigger an assertion check from the mapping table above
+
+
+# Safe Mode tests are currently not generated, as I don't know how to make marionette restart in safe mode
+
+#################
+ - [D=F] Nothing [A#1] -> Enrolled Control [A S=DisabledByDefault SS=DisabledByDefault ES=UNENROLLED P=False ESP=ENROLLED_CONTROL] -> Restart [A S=DisabledByControlGroup SS=DisabledByControlGroup ES=ENROLLED_CONTROL P=False ESP=ENROLLED_CONTROL]
+ - [D=F] Nothing [A#1] -> Enrolled Treatment [A S=DisabledByDefault SS=DisabledByDefault ES=UNENROLLED P=False ESP=ENROLLED_TREATMENT] -> Restart [A S=EnabledByTreatmentGroup SS=EnabledByTreatmentGroup ES=ENROLLED_TREATMENT P=False ESP=ENROLLED_TREATMENT]
+ - [D=F] Nothing [A#1] -> On [A S=EnabledByUserPref SS=DisabledByDefault ES=UNENROLLED P=True ESP=UNENROLLED] -> Restart [A S=EnabledByUserPref SS=EnabledByUserPref ES=UNENROLLED P=True ESP=UNENROLLED]
+ - [D=F] Nothing [A#1] -> Off [A#1] -> Restart [A#1]
+ - [D=F] Nothing [A#1] -> On -> Bad Requirements [A S=MissingRemoteWebGL SS=DisabledByDefault ES=UNENROLLED P=True ESP=UNENROLLED] -> Restart [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=UNENROLLED P=True ESP=UNENROLLED]
+ - [D=F] Nothing [A#1] -> On -> E10S [A S=DisabledByE10S SS=DisabledByE10S ES=UNENROLLED P=True ESP=UNENROLLED]
+ - [D=F] Nothing [A#1] -> On -> Header-On [A S=DisabledByEnvVar SS=DisabledByEnvVar ES=UNENROLLED P=True ESP=UNENROLLED] -> Header-Off [A S=EnabledByUserPref SS=DisabledByEnvVar ES=UNENROLLED P=True ESP=UNENROLLED]
+ - [D=F] Nothing [A#1] -> Safe Mode -> Restart
+
+#################
+ - [D=T] Nothing [A#1T] -> Enrolled Control [A S=EnabledByDefault SS=EnabledByDefault ES=UNENROLLED P=True ESP=ENROLLED_CONTROL] -> Restart [A S=DisabledByControlGroup SS=DisabledByControlGroup ES=ENROLLED_CONTROL P=True ESP=ENROLLED_CONTROL]
+ - [D=T] Nothing [A#1T] -> Enrolled Treatment [A S=EnabledByDefault SS=EnabledByDefault ES=UNENROLLED P=True ESP=ENROLLED_TREATMENT] -> Restart [A S=EnabledByTreatmentGroup SS=EnabledByTreatmentGroup ES=ENROLLED_TREATMENT P=True ESP=ENROLLED_TREATMENT]
+ - [D=T] Nothing [A#1T] -> On [A S=EnabledByDefault SS=EnabledByDefault ES=UNENROLLED P=True ESP=UNENROLLED] -> Restart [A S=EnabledByDefault SS=EnabledByDefault ES=UNENROLLED P=True ESP=UNENROLLED]
+ - [D=T] Nothing [A#1T] -> Off [A S=DisabledByUserPref SS=EnabledByDefault ES=UNENROLLED P=False ESP=UNENROLLED] -> Restart [A S=DisabledByUserPref SS=DisabledByUserPref ES=UNENROLLED P=False ESP=UNENROLLED]
+ - [D=T] Nothing [A#1T] -> On -> Bad Requirements [A S=MissingRemoteWebGL SS=EnabledByDefault ES=UNENROLLED P=True ESP=UNENROLLED] -> Restart [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=UNENROLLED P=True ESP=UNENROLLED]
+ - [D=T] Nothing [A#1T] -> On -> E10S [A S=DisabledByE10S SS=DisabledByE10S ES=UNENROLLED P=True ESP=UNENROLLED]
+ - [D=T] Nothing [A#1T] -> On -> Header-On [A S=DisabledByEnvVar SS=DisabledByEnvVar ES=UNENROLLED P=True ESP=UNENROLLED] -> Header-Off [A S=EnabledByDefault SS=DisabledByEnvVar ES=UNENROLLED P=True ESP=UNENROLLED]
+ - [D=T] Nothing [A#1T] -> Safe Mode -> Restart
+
+#################
+ - [D=F] On [A#3] -> Restart [A#4] -> Enrolled Control [A S=EnabledByUserPref SS=EnabledByUserPref ES=UNENROLLED P=True ESP=ENROLLED_CONTROL] -> Restart [A S=EnabledByUserPref SS=EnabledByUserPref ES=DISQUALIFIED P=True ESP=DISQUALIFIED]
+ - [D=F] On [A#3] -> Restart [A#4] -> Enrolled Treatment [A S=EnabledByUserPref SS=EnabledByUserPref ES=UNENROLLED P=True ESP=ENROLLED_TREATMENT] -> Restart [A S=EnabledByUserPref SS=EnabledByUserPref ES=DISQUALIFIED P=True ESP=DISQUALIFIED]
+ - [D=F] On [A#3] -> Restart [A#4] -> Off [A S=DisabledByDefault SS=EnabledByUserPref ES=UNENROLLED P=False ESP=UNENROLLED] -> Restart [A S=DisabledByDefault SS=DisabledByDefault ES=UNENROLLED P=False ESP=UNENROLLED]
+ - [D=F] On [A#3] -> Restart [A#4] -> Bad Requirements [A S=MissingRemoteWebGL SS=EnabledByUserPref ES=UNENROLLED P=True ESP=UNENROLLED]
+ - [D=F] On [A#3] -> Restart [A#4] -> E10S [A S=DisabledByE10S SS=DisabledByE10S ES=UNENROLLED P=True ESP=UNENROLLED] -> Restart [A#4]
+ - [D=F] On [A#3] -> Restart [A#4] -> Header-On [A S=DisabledByEnvVar SS=DisabledByEnvVar ES=UNENROLLED P=True ESP=UNENROLLED] -> Header-Off -> Restart [A#4]
+ - [D=F] On [A#3] -> Restart [A#4] -> Safe Mode
+
+#################
+ - [D=T] On [A#3T] -> Restart [A#4T] -> Enrolled Control [A S=EnabledByDefault SS=EnabledByDefault ES=UNENROLLED P=True ESP=ENROLLED_CONTROL] -> Restart [A S=DisabledByControlGroup SS=DisabledByControlGroup ES=ENROLLED_CONTROL P=True ESP=ENROLLED_CONTROL]
+ - [D=T] On [A#3T] -> Restart [A#4T] -> Enrolled Treatment [A S=EnabledByDefault SS=EnabledByDefault ES=UNENROLLED P=True ESP=ENROLLED_TREATMENT] -> Restart [A S=EnabledByTreatmentGroup SS=EnabledByTreatmentGroup ES=ENROLLED_TREATMENT P=True ESP=ENROLLED_TREATMENT]
+ - [D=T] On [A#3T] -> Restart [A#4T] -> Off [A S=DisabledByUserPref SS=EnabledByDefault ES=UNENROLLED P=False ESP=UNENROLLED] -> Restart [A S=DisabledByUserPref SS=DisabledByUserPref ES=UNENROLLED P=False ESP=UNENROLLED]
+ - [D=T] On [A#3T] -> Restart [A#4T] -> Bad Requirements [A S=MissingRemoteWebGL SS=EnabledByDefault ES=UNENROLLED P=True ESP=UNENROLLED]
+ - [D=T] On [A#3T] -> Restart [A#4T] -> E10S [A S=DisabledByE10S SS=DisabledByE10S ES=UNENROLLED P=True ESP=UNENROLLED] -> Restart [A#4T]
+ - [D=T] On [A#3T] -> Restart [A#4T] -> Header-On [A S=DisabledByEnvVar SS=DisabledByEnvVar ES=UNENROLLED P=True ESP=UNENROLLED] -> Header-Off -> Restart [A#4T]
+ - [D=T] On [A#3T] -> Restart [A#4T] -> Safe Mode
+
+#################
+ - [D=F] Enrolled Control [A#5] -> Restart [A#6] -> Enrolled Control-C -> On [A S=EnabledByUserPref SS=DisabledByControlGroup ES=ENROLLED_CONTROL P=True ESP=DISQUALIFIED] -> Restart [A S=EnabledByUserPref SS=EnabledByUserPref ES=DISQUALIFIED P=True ESP=DISQUALIFIED]
+ - [D=F] Enrolled Control [A#5] -> Restart [A#6] -> Off [A#6]
+ - [D=F] Enrolled Control [A#5] -> Restart [A#6] -> Enrolled Control-C -> Bad Requirements [A S=MissingRemoteWebGL SS=DisabledByControlGroup ES=ENROLLED_CONTROL P=False ESP=ENROLLED_CONTROL] -> Restart [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=DISQUALIFIED P=False ESP=DISQUALIFIED]
+ - [D=F] Enrolled Control [A#5] -> Restart [A#6] -> Enrolled Control-C -> E10S [A S=DisabledByE10S SS=DisabledByE10S ES=ENROLLED_CONTROL P=False ESP=ENROLLED_CONTROL] -> Enrolled Control-C -> Restart [A#6]
+ - [D=F] Enrolled Control [A#5] -> Restart [A#6] -> Enrolled Control-C -> Header-On [A S=DisabledByEnvVar SS=DisabledByEnvVar ES=ENROLLED_CONTROL P=False ESP=ENROLLED_CONTROL] -> Header-Off -> Enrolled Control-C -> Restart [A#6]
+ - [D=F] Enrolled Control [A#5] -> Restart [A#6] -> Safe Mode ->
+
+#################
+ - [D=T] Enrolled Control [A#5T] -> Restart [A#6T] -> Enrolled Control-C -> On [A S=DisabledByControlGroup SS=DisabledByControlGroup ES=ENROLLED_CONTROL P=True ESP=ENROLLED_CONTROL] -> Restart [A S=DisabledByControlGroup SS=DisabledByControlGroup ES=ENROLLED_CONTROL P=True ESP=ENROLLED_CONTROL]
+ - [D=T] Enrolled Control [A#5T] -> Restart [A#6T] -> Off [A S=DisabledByUserPref SS=DisabledByControlGroup ES=ENROLLED_CONTROL P=False ESP=DISQUALIFIED]
+ - [D=T] Enrolled Control [A#5T] -> Restart [A#6T] -> Enrolled Control-C -> Bad Requirements [A S=MissingRemoteWebGL SS=DisabledByControlGroup ES=ENROLLED_CONTROL P=True ESP=ENROLLED_CONTROL] -> Restart [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=DISQUALIFIED P=True ESP=DISQUALIFIED]
+ - [D=T] Enrolled Control [A#5T] -> Restart [A#6T] -> Enrolled Control-C -> E10S [A S=DisabledByE10S SS=DisabledByE10S ES=ENROLLED_CONTROL P=True ESP=ENROLLED_CONTROL] -> Enrolled Control-C -> Restart [A#6T]
+ - [D=T] Enrolled Control [A#5T] -> Restart [A#6T] -> Enrolled Control-C -> Header-On [A S=DisabledByEnvVar SS=DisabledByEnvVar ES=ENROLLED_CONTROL P=True ESP=ENROLLED_CONTROL] -> Header-Off -> Enrolled Control-C -> Restart [A#6T]
+ - [D=T] Enrolled Control [A#5T] -> Restart [A#6T] -> Safe Mode ->
+
+#################
+ - [D=F] Enrolled Treatment [A#7] -> Restart [A#8] -> Enrolled Treatment-C -> On [A S=EnabledByUserPref SS=EnabledByTreatmentGroup ES=ENROLLED_TREATMENT P=True ESP=DISQUALIFIED] -> Restart [A S=EnabledByUserPref SS=EnabledByUserPref ES=DISQUALIFIED P=True ESP=DISQUALIFIED]
+ - [D=F] Enrolled Treatment [A#7] -> Restart [A#8] -> Enrolled Treatment-C -> Off [A#8] -> Restart [A#8]
+ - [D=F] Enrolled Treatment [A#7] -> Restart [A#8] -> Enrolled Treatment-C -> Bad Requirements [A S=MissingRemoteWebGL SS=EnabledByTreatmentGroup ES=ENROLLED_TREATMENT P=False ESP=ENROLLED_TREATMENT] -> Restart [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=DISQUALIFIED P=False ESP=DISQUALIFIED]
+ - [D=F] Enrolled Treatment [A#7] -> Restart [A#8] -> Enrolled Treatment-C -> E10S [A S=DisabledByE10S SS=DisabledByE10S ES=ENROLLED_TREATMENT P=False ESP=ENROLLED_TREATMENT] -> Enrolled Treatment-C -> Restart [A#8]
+ - [D=F] Enrolled Treatment [A#7] -> Restart [A#8] -> Enrolled Treatment-C -> Header-On [A S=DisabledByEnvVar SS=DisabledByEnvVar ES=ENROLLED_TREATMENT P=False ESP=ENROLLED_TREATMENT] -> Header-Off -> Enrolled Treatment-C -> Restart [A#8]
+ - [D=F] Enrolled Treatment [A#7] -> Restart [A#8] -> Safe Mode ->
+
+#################
+ - [D=T] Enrolled Treatment [A#7T] -> Restart [A#8T] -> Enrolled Treatment-C -> On [A S=EnabledByTreatmentGroup SS=EnabledByTreatmentGroup ES=ENROLLED_TREATMENT P=True ESP=ENROLLED_TREATMENT] -> Restart [A S=EnabledByTreatmentGroup SS=EnabledByTreatmentGroup ES=ENROLLED_TREATMENT P=True ESP=ENROLLED_TREATMENT]
+ - [D=T] Enrolled Treatment [A#7T] -> Restart [A#8T] -> Enrolled Treatment-C -> Off [A S=DisabledByUserPref SS=EnabledByTreatmentGroup ES=ENROLLED_TREATMENT P=False ESP=DISQUALIFIED] -> Restart [A S=DisabledByUserPref SS=DisabledByUserPref ES=DISQUALIFIED P=False ESP=DISQUALIFIED]
+ - [D=T] Enrolled Treatment [A#7T] -> Restart [A#8T] -> Enrolled Treatment-C -> Bad Requirements [A S=MissingRemoteWebGL SS=EnabledByTreatmentGroup ES=ENROLLED_TREATMENT P=True ESP=ENROLLED_TREATMENT] -> Restart [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=DISQUALIFIED P=True ESP=DISQUALIFIED]
+ - [D=T] Enrolled Treatment [A#7T] -> Restart [A#8T] -> Enrolled Treatment-C -> E10S [A S=DisabledByE10S SS=DisabledByE10S ES=ENROLLED_TREATMENT P=True ESP=ENROLLED_TREATMENT] -> Enrolled Treatment-C -> Restart [A#8T]
+ - [D=T] Enrolled Treatment [A#7T] -> Restart [A#8T] -> Enrolled Treatment-C -> Header-On [A S=DisabledByEnvVar SS=DisabledByEnvVar ES=ENROLLED_TREATMENT P=True ESP=ENROLLED_TREATMENT] -> Header-Off -> Enrolled Treatment-C -> Restart [A#8T]
+ - [D=T] Enrolled Treatment [A#7T] -> Restart [A#8T] -> Safe Mode ->
+
+#################
+ - [D=F] Bad Requirements [A#9] -> Restart [A#10] -> Enrolled Control [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=UNENROLLED P=False ESP=ENROLLED_CONTROL] -> Restart [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=DISQUALIFIED P=False ESP=DISQUALIFIED]
+ - [D=F] Bad Requirements [A#9] -> Restart [A#10] -> Enrolled Treatment [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=UNENROLLED P=False ESP=ENROLLED_TREATMENT] -> Restart [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=DISQUALIFIED P=False ESP=DISQUALIFIED]
+ - [D=F] Bad Requirements [A#9] -> Restart [A#10] -> On [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=UNENROLLED P=True ESP=UNENROLLED]
+ - [D=F] Bad Requirements [A#9] -> Restart [A#10] -> Off [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=UNENROLLED P=False ESP=UNENROLLED]
+
+#################
+ - [D=T] Bad Requirements [A#9T] -> Restart [A#10T] -> Enrolled Control [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=UNENROLLED P=True ESP=ENROLLED_CONTROL] -> Restart [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=DISQUALIFIED P=True ESP=DISQUALIFIED]
+ - [D=T] Bad Requirements [A#9T] -> Restart [A#10T] -> Enrolled Treatment [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=UNENROLLED P=True ESP=ENROLLED_TREATMENT] -> Restart [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=DISQUALIFIED P=True ESP=DISQUALIFIED]
+ - [D=T] Bad Requirements [A#9T] -> Restart [A#10T] -> On [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=UNENROLLED P=True ESP=UNENROLLED]
+ - [D=T] Bad Requirements [A#9T] -> Restart [A#10T] -> Off [A S=MissingRemoteWebGL SS=MissingRemoteWebGL ES=UNENROLLED P=False ESP=UNENROLLED]