diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /toolkit/xre/test/marionette | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | toolkit/xre/test/marionette/gen_win32k_tests.py | 212 | ||||
-rw-r--r-- | toolkit/xre/test/marionette/marionette.ini | 6 | ||||
-rw-r--r-- | toolkit/xre/test/marionette/test_exitcode.py | 31 | ||||
-rw-r--r-- | toolkit/xre/test/marionette/test_fission_autostart.py | 247 | ||||
-rw-r--r-- | toolkit/xre/test/marionette/test_win32k_enrollment.py | 2506 | ||||
-rw-r--r-- | toolkit/xre/test/marionette/test_win32k_enrollment.template.py | 204 | ||||
-rw-r--r-- | toolkit/xre/test/marionette/win32k_tests.txt | 167 |
7 files changed, 3373 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..e34087aca9 --- /dev/null +++ b/toolkit/xre/test/marionette/test_fission_autostart.py @@ -0,0 +1,247 @@ +from contextlib import contextmanager + +from marionette_harness import MarionetteTestCase + + +class ExperimentStatus: + UNENROLLED = 0 + ENROLLED_CONTROL = 1 + ENROLLED_TREATMENT = 2 + DISQUALIFIED = 3 + + +class Prefs: + 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, + 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, decision, dynamic=None): + if dynamic is None: + dynamic = enabled + + expected = { + "fissionAutostart": enabled, + "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 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, + 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, + decision="enabledByDefault", + ) + + self.restart(prefs={Prefs.FISSION_AUTOSTART: False}) + + self.check_fission_status( + enabled=False, + decision="disabledByUserPref", + ) + + self.marionette.set_pref(Prefs.FISSION_AUTOSTART, True) + self.check_fission_status( + enabled=False, + decision="disabledByUserPref", + dynamic=True, + ) + + self.marionette.clear_pref(Prefs.FISSION_AUTOSTART) + self.check_fission_status( + enabled=False, + decision="disabledByUserPref", + dynamic=True, + ) + + self.restart() + self.check_fission_status( + enabled=True, + decision="enabledByDefault", + ) + + def test_fission_precedence(self): + self.check_fission_status( + enabled=True, + decision="enabledByDefault", + ) + + self.restart( + prefs={Prefs.FISSION_AUTOSTART: False}, env={ENV_ENABLE_FISSION: "1"} + ) + self.check_fission_status( + enabled=True, + 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, + decision="disabledByEnv", + dynamic=True, + ) + + self.restart( + prefs={Prefs.FISSION_AUTOSTART: False}, env={ENV_DISABLE_FISSION: ""} + ) + self.check_fission_status( + enabled=False, + decision="disabledByUserPref", + ) + + self.restart(prefs={Prefs.FISSION_AUTOSTART: None}) + self.check_fission_status( + enabled=True, + decision="enabledByDefault", + ) + + app_version = self.execute_script("return Services.appinfo.version") + self.restart(env={ENV_DISABLE_E10S: app_version}) + self.check_fission_status( + enabled=False, + decision="disabledByE10sEnv", + dynamic=True, + ) 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]
|