Files
camoufox/pythonlib/tests/test_shipped_data.py
T
coffeegrind123 c2817c1cae fix(coherence): let macOS draw Intel Mac GPUs, checked as machines
coherence rejected "Intel(R) HD Graphics 400" and "Radeon R9 200
Series" on macOS as a Braswell Atom IGP and a desktop PC card. They are
Firefox's sanitized buckets, not devices: SanitizeRenderer
(FIREFOX_152_0_4_RELEASE) maps an Intel Mac's UHD 630 to the first and
a Radeon Pro 5300M to the second, per Firefox's own TestCiMac and
TestMacAmd. fpgen's pinned model records both from Firefox on macOS at
1.14% each. The rule kept every generated Mac off them, removed 24
real macOS presets in #779 (restored here, 9 + 15), and dropped either
GPU from a caller's Mac preset. ANGLE and llvmpipe stay rejected:
Firefox 152 has no ANGLE-on-Metal path (Bug 2046027 came later).

Intel Macs are now checked as machines instead (intel-mac-hardware),
for every non-Apple GPU on macOS:

- a core count some Intel Mac with that GPU reports. Firefox reports
  physical cores where kern.tcsm_available is set and logical ones
  otherwise, so either counts: 2-8 physical / 4-16 logical for the
  IGP, up to the 2019 Mac Pro for a discrete GPU;
- a screen that is not a notched MacBook's or the 24" iMac's. 45.5% of
  fpgen's Firefox macOS screens are one, and the draw already put an
  Intel or AMD bucket behind 4.9% of them.

The WebGL draw applies the same check, given the core count. The preset
GPU drop moves next to the WebGL draw, after the host core count and
the display clamp: before, a preset's GPU was judged against cores the
launch then replaced. The TypeScript launcher gets the same changes,
and the goldens cover the new check and the narrowed draws.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit d6e2adcb6c)
2026-09-27 20:09:03 +00:00

65 lines
2.9 KiB
Python

"""The data files that ship must not contain an identity we would refuse to use.
`camoufox.coherence` filters at draw time, so an impossible row can never reach
a page either way. This is the second filter, on the data itself: a row that
survives here is one a future refresh could ship, a consumer reading the JSON
directly would get, and a reviewer would take as real. Both filters run the same
rules -- `scripts/clean-fingerprint-data.py --write` is what makes these pass.
Dropped on 2026-09-17: 38 of 435 presets (26 with a GPU their OS cannot report,
7 pairing Apple Silicon with a core count Apple never shipped, 4 with a colour
depth their GPU contradicts, 3 with a phone viewport, 1 claiming 40 touch
points). 24 of them, macOS presets naming "Intel(R) HD Graphics 400" or "Radeon
R9 200 Series", are restored: those are the buckets Firefox reports for an
Intel Mac's GPU (see camoufox.coherence).
"""
import json
import sys
from os.path import dirname, join
from pathlib import Path
import pytest
sys.path.insert(0, join(dirname(__file__), ".."))
from camoufox import coherence # noqa: E402
from camoufox.fingerprints import from_preset # noqa: E402
DATA = Path(__file__).parent.parent / "camoufox"
PRESET_FILES = ("fingerprint-presets.json", "fingerprint-presets-v150.json")
OS_KEY = {"macos": "mac", "windows": "win", "linux": "lin"}
@pytest.mark.parametrize("filename", PRESET_FILES)
def test_every_bundled_preset_is_coherent_as_stored(filename):
presets = json.loads((DATA / filename).read_text())["presets"]
for os_name, entries in presets.items():
assert entries, f"{filename}/{os_name} has no presets left"
for index, preset in enumerate(entries):
config = from_preset(preset, "152")
violations = coherence.validate(config, OS_KEY[os_name])
assert violations == [], (
f"{filename} {os_name}[{index}]: "
+ "; ".join(v.detail for v in violations)
+ " -- run scripts/clean-fingerprint-data.py --write"
)
@pytest.mark.parametrize("filename", PRESET_FILES)
def test_every_preset_gpu_has_webgl_data(filename):
"""A preset records only its GPU's name; the WebGL parameters behind it come
from fpgen. A GPU fpgen has never seen Firefox report on that OS has none, so
launching it would pair the name with another device's parameters."""
from camoufox.webgl import firefox_gpus
presets = json.loads((DATA / filename).read_text())["presets"]
for os_name, entries in presets.items():
known = firefox_gpus(os_name)
for index, preset in enumerate(entries):
gpu = (preset["webgl"]["unmaskedVendor"], preset["webgl"]["unmaskedRenderer"])
assert gpu in known, (
f"{filename} {os_name}[{index}]: {gpu[1]!r} has no WebGL data"
" -- run scripts/clean-fingerprint-data.py --write"
)