Repository navigation
feat(ops): run test suites in WSL2 from a native-Windows checkout, CC-638 - #683
Merged
Merged
Conversation
…-638) Native Windows spends tens of milliseconds per spawned process, so large suites do not finish locally. The helper syncs the working tree into WSL, fixes the mode bits NTFS does not carry, and runs named suites with timing. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011c6rVDk6zyfgLPEfbVrZi9
…NUL lists, safer paths, sourceable pure functions (CC-638) Review: exec bit on the two new files, summary scraping lost the summary line with 2+ skipped cases and deleted the log, newline/dash file names in the exec list, scratch name collisions, no in-WSL re-check before rm -rf, timing claims omitted the per-call sync, and no Linux-runnable coverage of the pure functions. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011c6rVDk6zyfgLPEfbVrZi9
…-run-tests-in-wsl.sh CI runs shellcheck without -x; matches the convention in test-state-status.sh. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011c6rVDk6zyfgLPEfbVrZi9
…ts against a stand-in wsl.exe (CC-638) Concurrent runs no longer replace each other's tree; --changed hands the changed paths to tests/bin/run-tests.sh inside WSL; the sync, run, cleanup and --changed paths are covered on Linux by a stand-in wsl.exe. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011c6rVDk6zyfgLPEfbVrZi9
…hs as a pure function (CC-638) CI already runs the suites on Linux; the stand-in could not catch the two Windows-only bugs found. Keep pure-function tests (suite names, file/exec lists, changed paths incl. deleted/renamed/space/origin-main/bad ref, result parsing). --changed resolved before any WSL work with the ACMR filter; sweep covers the whole scratch parent; in-WSL re-check before writing into it; rtw_wsl_run; ticket text rewritten. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011c6rVDk6zyfgLPEfbVrZi9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ops/diagnostics/run-tests-in-wsl.sh: from a native-Windows Git Bash checkout it copies the working tree (tracked plus untracked-not-ignored, uncommitted edits included) into its own scratch directory in WSL2, clears the fake mode bits and restores the real executable bits, makes it a git repo, runs the namedtests/shellsuites with a time limit and prints one row per suite. A failing suite also prints its failed-case line and the log path.--changed [--base REF]hands the paths this working tree changed (added, copied, modified, renamed; untracked included; deleted excluded) totests/bin/run-tests.shinside WSL, so it chooses the suites. Resolved before any WSL work: a bad ref or an empty change set costs nothing.test-doctor.shmore than an hour,test-guards.shmore than 10 minutes). Onepmctl dispatch runis about 320 process starts; removing them one batch at a time gives 3 to 10 percent per batch (CC-636, CC-637). WSL2 is already the project's release-sign-off platform.docs/platform-support.md(not a sandbox; does not replace native verification), CHANGELOG, registrations (suite registry, CI step, variable inventories).Decision: no stand-in wsl.exe
An earlier round tested the sync, cleanup and
--changedflow on Linux through a fakewsl.exeand a test-only environment variable. Removed on the maintainer's point that CI already runs the suites themselves on Linux: the fake could not catch the two Windows-only bugs found while building this (below), and it needed a test-only hook. The sync-and-run path therefore has no automated test; it was verified by hand against the realwsl.exe(see Evidence). The pure functions are tested on any platform.Evidence (one machine, single measurements, noisy)
test-lint-frontmatter2 to 3 s in WSL vs 27 s natively,test-executor-router4 vs 34 s,test-state-status17 vs 62 s (23 passed in WSL; the native run has one pre-existing NTFS failure, so the work differs),test-guards110 s in WSL (305 passed, 0 failed) vs more than 10 minutes natively. Small suites end up only about 3 times faster end to end.wsl.exeon this host: a passing run (tree removed), a failing, a slow (--timeout 4) and a quiet suite (rows: exit 1 with failed-case line and log path; 124 "timed out"; 0 with a "prints no summary line" note; helper exit 1),--keep,--sync-only, and a real--changedrun on this branch. That run found the paths against origin/main, and because this branch changestests/lib/test-suite-runner.sh(widely used)run-tests.shescalated to the whole suite and hit the 500 s limit: the helper reported "timed out ... (raise --timeout)", printed the log path and kept the tree. Documented.tests/shell/test-run-tests-in-wsl.sh: 10 passed, 1 skipped natively (the skip is the refusal off native Windows); 11 passed in WSL. Cases: help, usage errors, platform refusal, suite-name normalization, file and exec lists (including a file executable on disk but 100644 in the index), changed paths (modified, deleted, renamed, space in name, ignored, base HEAD, base HEAD~1, default origin/main when present, unknown ref refused with a hint), result parsing. Mutation checks, each killed by a case: every tracked file executable; first marker wins; no--diff-filter(deleted path appears).lint-jq-lf,lint-script-domain-inventory,lint-test-suite-registry,lint-test-docstrings,lint-doc-wikilinks,lint-portable-repo-paths,lint-surface-coverage,lint-readme-surface-lists, the whole-treelint-shellcheck(301 files) and shellcheck on both new files in the CI form (no-x): clean.Two bugs I introduced and fixed
/home/...argument towsl.exeintoC:/Program Files/Git/home/..., which created a junk directory namedC:in the repo root (untracked, deleted by exact name).MSYS2_ARG_CONV_EXCLis now set for the onewsl.execommand only and never exported (git is a native program too).git add -Ain WSL recorded mode 100755 for everything andlint-jq-lftreated every library as an entry. Mode bits are now cleared first and only the real ones restored.Gate and review
tail -n 3, NUL-separated exec list, in-WSL path re-check, non-empty$HOME, exec bit on the new files, timings including the sync, not-a-sandbox note, pure-function tests). Round 2 (before the stand-in was removed): security approve; critic and qa-tester changes-requested or advisory; risk warn; architecture advisory. Findings applied:--diff-filter=ACMR, git failures reported instead of silent exits, a bad base ref gets a hint, the change set is resolved before the sync, the sweep covers the whole scratch parent (not a glob built from the directory name), the path is re-checked inside WSL before writing the changed list,rtw_wsl_runprefix, the test-only variable removed, docs and the ticket rewritten.chmod 644) have no automated test (need native Windows plus WSL2);--changedcan escalate to the whole suite and needs a larger--timeout;run-tests.shwithout--basecompares with HEAD only while the helper uses the merge base with origin/main (stated in the help); an early failure leaves its scratch tree until the next start sweeps it;test-gate-digest.shandtest-jq-lf.share also committed without the exec bit (pre-existing, not touched).tests/shell/test-run-tests-in-wsl.sh(no case added to a pre-existing suite). Its cases pin the helper's contract on any platform: argument handling and platform refusal (observable by exit code and message), suite-name normalization (names become paths inside WSL, so a security-relevant boundary), the file and exec lists (a wrong mode set brokelint-jq-lfin WSL once), the changed-path set (a deleted path or a wrong base changes which suites run), and result parsing (a missing or malformed status must never look like a pass). Each is implementation-independent and cheap; mutation-checked where noted.🤖 Generated with Claude Code
https://claude.ai/code/session_011c6rVDk6zyfgLPEfbVrZi9