aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/screenshots/tests/test_envhash.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/screenshots/tests/test_envhash.py')
-rw-r--r--scripts/screenshots/tests/test_envhash.py105
1 files changed, 105 insertions, 0 deletions
diff --git a/scripts/screenshots/tests/test_envhash.py b/scripts/screenshots/tests/test_envhash.py
new file mode 100644
index 0000000..20ab1f9
--- /dev/null
+++ b/scripts/screenshots/tests/test_envhash.py
@@ -0,0 +1,105 @@
+from __future__ import annotations
+
+import copy
+import json
+import os
+import unittest
+from pathlib import Path
+
+import helpers # noqa: F401 (sets sys.path)
+
+import envhash
+
+# The fixture is owned by the C++ side; its own test checks the same values.
+GPGFRONTEND = Path(os.environ.get("GF_SHOTS_GPGFRONTEND",
+ str(helpers.PIPELINE_DIR.parents[2] / "GpgFrontend")))
+CROSS_CHECK_FIXTURE = GPGFRONTEND / "resource" / "screenshot" / "env-hash-fixture.json"
+
+
+def sample_env() -> dict:
+ return {
+ "schema": 1,
+ "os": {"product": "Windows 11 Pro", "kernel": "10.0.26100", "build": "26100"},
+ "qt_version": "6.8.2", "platform_name": "windows",
+ "screen": {"name": "DISPLAY1", "size": [2560, 1600], "geometry": [0, 0, 2560, 1600],
+ "dpr": 2, "logical_dpi": 96, "physical_dpi": 96.4},
+ "style": "windows11", "color_scheme": "light", "color_scheme_method": "hint",
+ "locale": "en_US", "clock": "2026-01-15T10:00:00Z",
+ "font_requested": ["Noto Sans", "思源黑体"], "font_resolved": ["Noto Sans", "思源黑体"],
+ "system_font": "Segoe UI", "gnupg_version": "2.4.7", "gpgme_version": "1.24.2",
+ "gpg_clock": {"gpg_conf": "applied", "agent_conf": "applied"},
+ "ui_clock_probe": "ok", "gpg_clock_probe": "ok", "tz_offset_check": 0,
+ "build_commit": "abc", "display": ":99", "profile_path": "/tmp/x/.tmp-1", "gate_failures": [],
+ }
+
+
+FONTS = [{"family": "Noto Sans", "sha256": "aa"}, {"family": "思源黑体", "sha256": "bb"},
+ {"family": "Segoe UI", "sha256": "cc"}]
+
+
+def final(env: dict, fonts: list = FONTS, platform: str = "windows11") -> str:
+ return envhash.final_env_hash(envhash.env_hash_core(env), platform, fonts)
+
+
+class CrossCheckTest(unittest.TestCase):
+ def test_cpp_fixture_reproduces_byte_for_byte(self) -> None:
+ if not CROSS_CHECK_FIXTURE.exists():
+ self.skipTest(f"C++ fixture not found at {CROSS_CHECK_FIXTURE} (set GF_SHOTS_GPGFRONTEND)")
+ fixture = json.loads(CROSS_CHECK_FIXTURE.read_text(encoding="utf-8"))
+ self.assertEqual(envhash.canonical_core(fixture["env"]).decode("utf-8"), fixture["canonical"])
+ self.assertEqual(envhash.env_hash_core(fixture["env"]), fixture["env_hash_core"])
+ self.assertEqual(envhash.platform_tag(fixture["env"], under_xvfb=False), "windows11")
+
+ def test_canonical_form_is_compact_sorted_utf8(self) -> None:
+ text = envhash.canonical_core(sample_env()).decode("utf-8")
+ self.assertTrue(text.startswith('{"clock":"2026-01-15T10:00:00Z","color_scheme":"light"'))
+ self.assertIn('"思源黑体"', text) # ensure_ascii=False
+ self.assertIn('"physical_dpi":96,', text) # DPI hashed as an integer
+ self.assertNotIn(" ", text.replace("Noto Sans", "").replace("Segoe UI", "").replace("Windows 11 Pro", ""))
+
+
+class HashSensitivityTest(unittest.TestCase):
+ def test_key_order_and_volatile_fields_do_not_matter(self) -> None:
+ base = final(sample_env())
+ reordered = dict(reversed(list(sample_env().items())))
+ self.assertEqual(final(reordered), base)
+ env = sample_env()
+ env.update(display=":42", profile_path="/tmp/other/.tmp-2", build_commit="zzz",
+ color_scheme_method="palette")
+ env["screen"]["name"] = "OTHER"
+ env["screen"]["geometry"] = [100, 50, 2560, 1600]
+ env["os"]["kernel"] = "6.1"
+ self.assertEqual(final(env), base)
+
+ def test_render_relevant_changes_do(self) -> None:
+ base = final(sample_env())
+ for key, value in (("color_scheme", "dark"), ("locale", "zh_CN"), ("clock", "2026-02-01T10:00:00Z")):
+ env = sample_env()
+ env[key] = value
+ self.assertNotEqual(final(env), base, key)
+ env = sample_env()
+ env["font_requested"] = ["Noto Sans"]
+ self.assertNotEqual(final(env), base)
+ fonts = copy.deepcopy(FONTS)
+ fonts[1]["sha256"] = "changed"
+ self.assertNotEqual(final(sample_env(), fonts), base)
+ self.assertNotEqual(final(sample_env(), platform="linux-xvfb"), base)
+
+ def test_platform_tags(self) -> None:
+ env = sample_env()
+ self.assertEqual(envhash.platform_tag(env, False), "windows11")
+ env["os"] = {"product": "Windows 10", "build": "19045"}
+ self.assertEqual(envhash.platform_tag(env, False), "windows-other")
+ env["platform_name"] = "xcb"
+ self.assertEqual(envhash.platform_tag(env, True), "linux-xvfb")
+ self.assertEqual(envhash.platform_tag(env, False), "linux-xcb")
+
+ def test_lock_env_drops_run_volatile_fields(self) -> None:
+ stripped = envhash.strip_volatile(sample_env())
+ self.assertNotIn("profile_path", stripped)
+ self.assertNotIn("display", stripped)
+ self.assertIn("build_commit", stripped)
+
+
+if __name__ == "__main__":
+ unittest.main()