From b88e8116e9e1f7e2f6e8b211536311cd17feca9a Mon Sep 17 00:00:00 2001 From: akbash Date: Fri, 18 Sep 2026 02:13:13 +0300 Subject: test: add local windows input gauntlet (#4298) * test: add local windows input gauntlet refs #4251 * test: add local windows input gauntlet Harden elevation and channel identity checks, distinguish known host limitations, and surface incomplete cleanup. refs #4251 * test(windows): harden input gauntlet execution refs #4251 * test(windows): make input gauntlet self-contained refs #4251 * test(windows): bound input gauntlet failure paths refs #4251 * test(windows): extend input qualification gauntlet refs #4251 * test(windows): complete input qualification matrix refs #4251 --------- Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com> Co-authored-by: Jonathan Liebig --- scripts/test_windows_input.py | 243 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 scripts/test_windows_input.py (limited to 'scripts/test_windows_input.py') diff --git a/scripts/test_windows_input.py b/scripts/test_windows_input.py new file mode 100644 index 00000000..f8a70eee --- /dev/null +++ b/scripts/test_windows_input.py @@ -0,0 +1,243 @@ +"""Portable tests of the gauntlet's oracle, not Windows input qualification.""" +import copy +import unittest +from scripts.windows_input.report import catalogue, channel_identity_errors, herdr_protocol_label, known_host_gap, qualification_matrix, summarize, verdict + + +class WindowsInputGauntletTests(unittest.TestCase): + def setUp(self): + self.matrix = catalogue() + self.cases = {case["id"]: case for case in self.matrix["cases"]} + self.evidence = dict(ready=True, focus_verified=True, complete=True, width=121, height=24, + outer_geometry=[121, 24, 0x298], pane_geometry=[100, 20, 0x200], + final_outer_geometry=[121, 24, 0x298], final_pane_geometry=[100, 20, 0x200]) + + def test_catalogue_has_unique_cases_and_geometry_boundaries(self): + self.assertEqual(len(self.cases), len(self.matrix["cases"])) + self.assertEqual(self.matrix["widths"], [80, 119, 120, 121, 132, 160, 240]) + self.assertEqual(self.matrix["heights"], [24, 50]) + for case in self.cases.values(): + self.assertTrue(case["id"]) + self.assertLessEqual(set(case["expected"]), set(self.matrix["modes"])) + for expected in case["expected"].values(): + for value in expected.get("hex", []): + self.assertTrue(bytes.fromhex(value)) + self.assertEqual(self.cases["dead-acute"]["kind"], "layout-key") + self.assertEqual(self.cases["altgr-euro"]["kind"], "manual") + + def test_default_catalogue_does_not_inject_terminal_host_actions(self): + for case_id in ["ctrl-v", "alt-enter", "ctrl-shift-up", "ctrl-shift-down", "ctrl-shift-home", "ctrl-shift-end"]: + self.assertEqual(self.cases[case_id]["kind"], "qualification", case_id) + + def test_kitty_function_keys_accept_native_and_legacy_encodings(self): + self.assertEqual(self.cases["shift-tab"]["expected"]["kitty"]["hex"], ["1b5b5a", "1b5b393b3275"]) + self.assertEqual(self.cases["up"]["expected"]["kitty"]["hex"], ["1b5b41", "1b5b353734313975"]) + + def test_shift_enter_cannot_pass_with_plain_enter_or_trailing_duplicates(self): + case = self.cases["shift-enter"] + correct = "1b5b32373b323b31337e" + for value, status in [("0d", "fail"), (correct, "pass"), (correct + "0d", "fail")]: + self.assertEqual(verdict(case, "mok2", {**self.evidence, "hex": value})[0], status) + self.assertEqual(verdict(case, "legacy", {**self.evidence, "hex": "0d"})[0], "unsupported") + + def test_focus_readiness_and_actual_geometry_are_required(self): + case = self.cases["letter-a"] + good = {**self.evidence, "hex": "61"} + for field in ["ready", "focus_verified", "complete", "pane_geometry", "outer_geometry", "final_pane_geometry", "final_outer_geometry"]: + value = copy.deepcopy(good) + value.pop(field) + self.assertEqual(verdict(case, "legacy", value)[0], "inconclusive", field) + self.assertEqual(verdict(case, "legacy", {**good, "outer_geometry": [120, 24]})[0], "inconclusive") + for malformed in [1, "121,24", {}, [121], [121, "24"], [True, 24]]: + self.assertEqual(verdict(case, "legacy", {**good, "pane_geometry": malformed})[0], "inconclusive") + + def test_native_modifiers_release_and_repeat_are_not_discarded(self): + # type, down, repeat, vk, scan, Unicode, control-state + self.evidence["scans"] = [42, 28] + records = [[1, 1, 1, 13, 28, 13, 16], [1, 0, 1, 13, 28, 13, 16]] + case = self.cases["shift-enter"] + self.assertEqual(verdict(case, "native", {**self.evidence, "records": records})[0], "pass") + for index, value in [(6, 0), (2, 2), (3, 10), (4, 0), (5, 122)]: + bad = copy.deepcopy(records) + bad[0][index] = value + self.assertEqual(verdict(case, "native", {**self.evidence, "records": bad})[0], "fail") + self.assertEqual(verdict(case, "native", {**self.evidence, "records": records[:1]})[0], "fail") + extra = [[1, 1, 1, 16, 42, 0, 16]] + records + self.assertEqual(verdict(case, "native", {**self.evidence, "records": extra})[0], "fail") + balanced = extra + [[1, 0, 1, 16, 42, 0, 0]] + self.assertEqual(verdict(case, "native", {**self.evidence, "records": balanced})[0], "pass") + + def test_herdr_native_page_keys_must_be_consumed_before_the_pane(self): + case = self.cases["page-up"] + evidence = {**self.evidence, "path": "herdr", "scans": [73]} + records = [[1, 1, 1, 33, 73, 0, 0], [1, 0, 1, 33, 73, 0, 0]] + self.assertEqual(verdict(case, "native", {**evidence, "records": []})[0], "inconclusive") + self.assertEqual(verdict(case, "native", {**evidence, "records": [[4, 0, 0, 0, 0, 0, 0]]})[0], "inconclusive") + self.assertEqual(verdict(case, "native", {**evidence, "records": records})[0], "fail") + self.assertEqual(verdict(case, "native", {**evidence, "records": [None]})[0], "inconclusive") + self.assertEqual(verdict(case, "native", {**evidence, "path": "direct", "records": records})[0], "pass") + for mode in ("legacy", "mok2", "kitty"): + self.assertEqual(verdict(case, mode, {**evidence, "hex": ""})[0], "inconclusive") + self.assertEqual(verdict(case, mode, {**evidence, "hex": "1b5b357e"})[0], "fail") + + def test_paste_requires_one_envelope_and_complete_unicode_payload(self): + case = self.cases["paste-unicode"] + payload = case["text"].replace("\n", "\r\n").encode() + framed = b"\x1b[200~" + payload + b"\x1b[201~" + for data, expected in [(framed, "pass"), (payload, "fail"), (framed * 2, "fail"), + (framed[:-1], "fail"), (framed + b"\r", "fail"), + (b"\x1b[200~\xff\x1b[201~", "fail")]: + self.assertEqual(verdict(case, "kitty", {**self.evidence, "hex": data.hex()})[0], expected) + + def test_mouse_interleave_requires_ordered_motion_and_paste(self): + case = self.cases["mouse-interleave"] + motion = b"\x1b[<35;10;5M" + paste = b"\x1b[200~mouse\r\npaste\x1b[201~" + good = b"a" + motion + paste + motion + b"b" + self.assertEqual(verdict(case, "kitty", {**self.evidence, "hex": good.hex()})[0], "pass") + for bad in (good.replace(motion, b"", 1), good + b"b", b"a" + motion + motion + paste + b"b"): + self.assertEqual(verdict(case, "kitty", {**self.evidence, "hex": bad.hex()})[0], "fail") + + def test_runtime_mode_transition_has_one_exact_order(self): + case = self.cases["mode-transitions"] + for mode in ("legacy", "mok2", "kitty"): + expected = case["expected"][mode]["hex"][0] + self.assertEqual(verdict(case, mode, {**self.evidence, "hex": expected})[0], "pass") + self.assertEqual(verdict(case, mode, {**self.evidence, "hex": expected + "0d"})[0], "fail") + direct = {**self.evidence, "path": "direct"} + for observed in ("a\rb\rc\rd\re\rf", "a\rb\rc\x1b[13;2ud\re\rf"): + self.assertEqual(verdict(case, "legacy", {**direct, "hex": observed.encode().hex()})[0], "unsupported") + + def test_mouse_focus_refresh_requires_reports_on_both_sides(self): + case = self.cases["mouse-focus-refresh"] + mouse = b"\x1b[<35;10;5M\x1b[<0;10;5M\x1b[<0;10;5m\x1b[<64;10;5M" + good = b"a" + mouse + b"bc" + mouse + b"d" + self.assertEqual(verdict(case, "legacy", {**self.evidence, "hex": good.hex()})[0], "pass") + for bad in (b"ab" + b"c" + mouse + b"d", b"a" + mouse + b"bcd"): + self.assertEqual(verdict(case, "legacy", {**self.evidence, "hex": bad.hex()})[0], "fail") + + def test_qualification_matrix_uses_observed_results_only(self): + observations = [ + {"host": "stable", "case": "shift-enter", "path": "herdr", "mode": "mok2", "status": "pass"}, + {"host": "stable", "case": "shift-enter", "path": "direct", "mode": "legacy", "status": "unsupported"}, + {"host": "stable", "case": "shift-enter", "path": "direct", "mode": "kitty", "status": "pass"}, + {"host": "stable", "case": "shift-enter", "path": "direct", "mode": "kitty", "status": "inconclusive"}, + ] + rows = {row[0]: row[1:] for row in qualification_matrix({"channels": ["stable"], "observations": observations})} + self.assertEqual(rows["Shift+Enter"], ("PASS", "X - becomes Enter", "PASS**")) + self.assertEqual(rows["Multiline paste"], ("NOT TESTED", "NOT TESTED", "NOT TESTED")) + observations.append({"host": "stable", "case": "dead-acute", "path": "herdr", "mode": "mok2", "status": "pass"}) + observations.extend([ + {"host": "stable", "case": "letter-a", "path": "direct", "mode": "legacy", "width": 80, "status": "pass"}, + {"host": "stable", "case": "shift-enter", "path": "direct", "mode": "legacy", "width": 80, "status": "unsupported"}, + {"host": "stable", "case": "paste-lf", "path": "direct", "mode": "legacy", "width": 80, "status": "pass"}, + {"host": "stable", "case": "mouse-focus-refresh", "path": "herdr", "mode": "legacy", "width": 80, "status": "pass"}, + {"host": "stable", "case": "mouse-focus-refresh", "path": "direct", "mode": "legacy", "width": 80, "status": "pass"}, + {"host": "stable", "case": "mouse-focus-refresh", "path": "direct", "mode": "kitty", "width": 80, "status": "pass"}, + ]) + rows = {row[0]: row[1:] for row in qualification_matrix({"channels": ["stable"], "observations": observations})} + self.assertEqual(rows["Dead-key composition"][0], "PASS") + self.assertEqual(rows["Resize 120 -> 80"][1], "PASS") + self.assertEqual(rows["Mouse after resize"], ("PASS", "PASS", "PASS")) + self.assertEqual(rows["AltGr"], ("MANUAL", "MANUAL", "MANUAL")) + self.assertEqual(rows["IME composition"], ("MANUAL", "MANUAL", "MANUAL")) + + def test_qualification_matrix_requires_every_selected_channel(self): + observations = [ + {"host": "stable", "case": "shift-enter", "path": "herdr", "mode": "mok2", "status": "pass"}, + ] + for result in ({"channels": ["stable", "preview"], "observations": observations}, + {"observations": observations}): + rows = {row[0]: row[1:] for row in qualification_matrix(result)} + self.assertEqual(rows["Shift+Enter"][0], "PARTIAL") + + def test_herdr_protocol_label_requires_every_run_to_prove_transport(self): + result = {"hosts": [{"channel": "stable", "runs": [{"nonce": "one", "path": "herdr", "mode": "native"}, + {"nonce": "two", "path": "herdr", "mode": "native"}]}], + "observations": [{"host": "stable", "nonce": "one", "path": "herdr", "mode": "native", + "input_reader": "windows-console", + "input_transport": "win32-serialized"}]} + self.assertEqual(herdr_protocol_label(result), "Herdr default (UNKNOWN)*") + result["observations"].append({"host": "stable", "nonce": "two", "path": "herdr", "mode": "native", + "input_reader": "windows-console", + "input_transport": "win32-serialized"}) + self.assertEqual(herdr_protocol_label(result), "Win32 (Herdr)*") + result["hosts"].append({"channel": "preview", "runs": [{"nonce": "one", "path": "herdr", "mode": "native"}]}) + self.assertEqual(herdr_protocol_label(result), "Herdr default (UNKNOWN)*") + + def test_empty_partial_and_duplicate_reports_never_become_green(self): + self.assertFalse(summarize({})["observed_checks_passed"]) + row = {**self.evidence, "case": "letter-a", "host": "stable", "path": "herdr", "mode": "legacy", "hex": "61", "phase": 1, + "width": 120, "height": 30, "outer_geometry": [120, 30], "final_outer_geometry": [120, 30]} + self.assertFalse(summarize({"observations": [row]})["observed_checks_passed"]) + with self.assertRaisesRegex(ValueError, "Duplicate"): + summarize({"observations": [row, row]}) + later = {**row, "phase": 2, "width": 80, "height": 24, "outer_geometry": [80, 24], "final_outer_geometry": [80, 24]} + host = {"channel": "stable", "runs": [{"nonce": "owned", "path": "herdr", "mode": "legacy", "pid": 123, "hwnd": 456, + "elevated": False, "image_identity": "image-s", "installation_identity": "install-s"}]} + row.update(nonce="owned", capture_id="first") + later.update(nonce="owned", capture_id="second") + self.assertEqual(summarize({"observations": [row, later], "hosts": [host], "controller_elevated": False})["counts"]["pass"], 2) + stale = {**later, "capture_id": "first"} + self.assertEqual(summarize({"observations": [row, stale], "hosts": [host], "controller_elevated": False})["counts"]["inconclusive"], 1) + forged_hosts = [{"channel": name, "runs": [{}]} for name in ("stable", "preview")] + partial = summarize({"observations": [row], "hosts": forged_hosts}) + self.assertFalse(partial["observed_checks_passed"]) + self.assertGreater(partial["coverage_missing"], 0) + for status in ["unsupported", "not_run", "inconclusive"]: + self.assertEqual(verdict(self.cases["letter-a"], "legacy", {**row, "status": status})[0], status) + + def test_malformed_native_records_are_inconclusive_not_exceptions(self): + evidence = {**self.evidence, "scans": [30]} + for records in [None, 7, "records", [None], [[1, 1, 1, 65, 30, 97, None]], + [[True, 1, 1, 65, 30, 97, 0]], [[1, 1, 1, 65, 30, 97, "0"]]]: + self.assertEqual(verdict(self.cases["letter-a"], "native", {**evidence, "records": records})[0], "inconclusive") + + def test_known_host_gap_only_exempts_observed_terminal_versions_and_cases(self): + row = {**self.evidence, "case": "shift-enter", "host": "stable", "path": "direct", "mode": "mok2", "hex": "0d", "phase": 1, + "width": 120, "height": 30, "outer_geometry": [120, 30], "final_outer_geometry": [120, 30], + "nonce": "owned", "capture_id": "fresh"} + for path, version, raw, expected in [("direct", "1.24.11911.0", "0d", "unsupported"), + ("direct", "1.25.1912.0", "0d", "unsupported"), + ("direct", "1.26.1.0", "0d", "fail"), + ("herdr", "1.24.11911.0", "0d", "fail"), + ("direct", "1.24.11911.0", "", "fail")]: + observation = {**row, "path": path, "hex": raw} + run = {"nonce": "owned", "path": path, "mode": "mok2", "pid": 123, "hwnd": 456, "terminal_version": version, + "elevated": False, "image_identity": "image-s", "installation_identity": "install-s"} + document = {"observations": [observation], "hosts": [{"channel": "stable", "runs": [run]}], "controller_elevated": False} + result = summarize(document)["observations"][0] + self.assertEqual(result["status"], expected) + self.assertEqual(result["failure_scope"], "direct_host" if path == "direct" else "through_herdr_not_yet_attributed") + document["controller_elevated"] = True + self.assertEqual(summarize(document)["observations"][0]["status"], "inconclusive") + document["controller_elevated"] = False + run["elevated"] = True + self.assertEqual(summarize(document)["observations"][0]["status"], "inconclusive") + + def test_direct_mok_legacy_fallback_is_case_and_version_bounded(self): + case = self.cases["shift-tab"] + direct = {**self.evidence, "path": "direct", "mode": "mok2", "hex": "1b5b5a"} + self.assertTrue(known_host_gap(direct, case, "1.25.2607.10002")) + self.assertFalse(known_host_gap(direct, case, "1.26.0.0")) + self.assertFalse(known_host_gap({**direct, "path": "herdr"}, case, "1.25.2607.10002")) + self.assertFalse(known_host_gap({**direct, "hex": "1b5b32373b323b397e"}, case, "1.25.2607.10002")) + + def test_duplicate_channel_identity_is_rejected_at_both_stages(self): + hosts = [{"channel": name, "launcher_identity": name + "-exe", "installation_identity": name + "-dir", + "runs": [{"image_identity": name + "-image", "installation_identity": name + "-dir", "process_identity": name + "-pid/start"}]} + for name in ("stable", "preview")] + self.assertEqual(channel_identity_errors(hosts), []) + for field in ("launcher_identity", "installation_identity"): + duplicate = copy.deepcopy(hosts) + duplicate[1][field] = duplicate[0][field] + self.assertTrue(channel_identity_errors(duplicate)) + self.assertTrue(summarize({"hosts": duplicate})["errors"]) + for field in ("image_identity", "installation_identity", "process_identity"): + duplicate = copy.deepcopy(hosts) + duplicate[1]["runs"][0][field] = duplicate[0]["runs"][0][field] + self.assertTrue(channel_identity_errors(duplicate)) + + +if __name__ == "__main__": + unittest.main() -- cgit v1.2.3