Skip to content

fix(tests): Windows-safe encoding in test suite + runner drive-letter path split - #81965

Merged
teknium1 merged 7 commits into
mainfrom
fix/windows-test-encoding
Aug 8, 2026
Merged

fix(tests): Windows-safe encoding in test suite + runner drive-letter path split#81965
teknium1 merged 7 commits into
mainfrom
fix/windows-test-encoding

Conversation

@teknium1

@teknium1 teknium1 commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Test-infrastructure cluster: suite files that fail on Windows hosts (locale-default reads/writes) and the parallel runner's ':' path split breaking on drive letters.

Changes

Validation

Result
touched files through real runner green
stale-base gate 0 behind

Infographic

tests-pass-windows

Adolanium and others added 7 commits August 8, 2026 11:54
…indows

`tests/hermes_cli/test_plugins_cmd.py::TestNoAutoActivation::test_compressor_default_ignores_plugin`
fails on every Windows machine:

    UnicodeDecodeError: 'charmap' codec can't decode byte 0x8f in
    position 47744: character maps to <undefined>

The test reads `run_agent.py` back as text to assert a removed comment is
gone, but called `open()` with no `encoding=`. Python then falls back to
the locale preferred encoding, which is cp1252 on a default Windows
install rather than UTF-8. `run_agent.py` contains nine bytes cp1252
leaves undefined, so the read raises before the assertion is reached. On
Linux and macOS the preferred encoding is UTF-8 and the same line is
fine, which is why CI never caught it.

That one line is the only active failure. The rest of this change closes
the same gap in the files it touches, which `scripts/check-windows-footguns.py`
flags and which the #71014 read_text campaign has been working through
elsewhere in the tree:

- `tests/hermes_cli/test_plugins_cmd.py`: nine bare `write_text`/`read_text`
  calls writing YAML manifests, config and plugin sources
- `tests/tools/test_web_tools_truncate.py`: reads stored extracted web text,
  which is arbitrary content from the internet
- `tests/stress/test_atypical_scenarios.py`: writes and reads worker task
  ids and a barrier file

All three files are now clean under `check-windows-footguns.py`.

Reads go through `Path.read_text(encoding="utf-8")` rather than
`open(...).read()`, which also closes the handle instead of leaving it to
the garbage collector. On Windows a live handle blocks tmpdir cleanup, so
that part is not cosmetic either.

No new test. The repaired test is the regression coverage: it fails
before this change and passes after, on Windows.
…n parallel runner

Two Windows bugs in scripts/run_tests_parallel.py:

- --files/--paths/HERMES_TEST_PATHS were split on ':', which shreds
  absolute Windows paths at the drive letter ('C:\repo\tests' ->
  ['C', '\repo\tests']): the drive letter became a phantom discovery
  root and the rooted remainder only resolved by WindowsPath
  re-anchoring it onto repo_root's drive. New _split_pathspec() keeps
  drive-letter colons glued to their path and accepts ';' (os.pathsep)
  on Windows, while ':'-joined lists (CI generate job) keep working.

- With piped stdout (CI, subprocess capture) Windows encodes the
  runner's output as the ANSI code page, so printing the per-file
  progress glyphs raised UnicodeEncodeError inside the executor
  done-callback and every progress line was silently lost -- which is
  also why test_bare_value_flag_keeps_its_value failed on win32 (no
  '1[check]' line, and the summary says '1 tests passed', which does not
  contain '1 passed'). The runner now reconfigures its own
  stdout/stderr to UTF-8 on Windows, and the tests decode the captured
  output as UTF-8.

Adds regression tests: os.pathsep-joined absolute roots (all
platforms) and no-phantom-drive-root (win32).

Fixes #57149
test_cli_entrypoint_end_to_end copies add_contributor.py with
read_text()/write_text() and no encoding argument, so both fall back to
the system locale. add_contributor.py contains UTF-8 multi-byte
characters (an em dash), which makes the read raise UnicodeDecodeError
on any non-UTF-8 Windows locale (observed on cp950 / Traditional
Chinese). The trailing mapping-file read gets the same treatment for
symmetry.

Same footgun class as the subprocess text=True sweep in #60741, just on
the pathlib read_text/write_text side.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Three desktop UI tests froze en-US-formatted strings while the
implementation formatters deliberately use the runtime locale
(new Intl.DateTimeFormat(undefined, ...) / Intl.NumberFormat(undefined,
...)) — runtime-locale output is the intended behavior for a localized
UI. On any non-en-US dev machine the tests fail even though the code is
correct:

    # zh-CN host:
    time.test.ts -> expected '三月' to be 'March'
    billing      -> Unable to find text 'Threshold: minimum is $10.'
                    (zh-CN renders USD as 'US$10')
    billing      -> Unable to find text '$25 added. Balance is refreshing.'

Assert the behavior contract instead of the frozen snapshot, per the
repo's testing guidance (behavior contracts over snapshots):

- time.test.ts: same-year month buckets render via fmtMonth, prior-year
  via fmtMonthYear — assert sessionBucketLabel(bucket) equals the shared
  formatter's output for bucket.at, with bucket-kind narrowing.
- billing/index.test.tsx: interpolate formatMoney(10) / formatMoney(25)
  into the expected strings.

No production code changes.

Verified: zh-CN host 40/40, LANG=C.UTF-8 40/40, tsc clean, eslint clean.
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on 377faff

⚠️ Warnings

OSV vulnerability scan · View job

64 known vulnerabilities found in pinned dependencies.

How to fix:

Review the findings in the Security tab. Update the affected dependencies if a patched version is available.


debug info

CI timings

CI timings · View report · View job

Wall time 7m33s vs 6m56s (+8.9%). 23 job(s) slower, 8 faster, 3 unchanged.

  • JS & TS checks / apps/desktop / check:test:ui: +78.0s
  • Python tests / Run tests slice 7/12: +36.0s
  • JS & TS checks / apps/desktop / check:lint: +34.0s
  • Python tests / Run tests slice 3/12: +19.0s
  • JS & TS checks / apps/desktop / check:test:desktop:platforms: +12.0s

@alt-glitch alt-glitch added type/test Test coverage or test infrastructure P3 Low — cosmetic, nice to have comp/cli CLI entry point, hermes_cli/, setup wizard comp/desktop Electron desktop app (apps/desktop/*) platform/windows Native Windows-specific behavior or breakage sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows sweeper:risk-automation Sweeper risk: may affect CI, automerge, label sync, or maintainer automation labels Aug 8, 2026
@teknium1
teknium1 merged commit ad82fc9 into main Aug 8, 2026
56 checks passed
@teknium1
teknium1 deleted the fix/windows-test-encoding branch August 8, 2026 19:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have platform/windows Native Windows-specific behavior or breakage sweeper:risk-automation Sweeper risk: may affect CI, automerge, label sync, or maintainer automation sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows type/test Test coverage or test infrastructure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: test_plugins_cmd fails on Windows with UnicodeDecodeError reading run_agent.py

7 participants