From 44018a2d14442f1e37cdb53d4455f4033e7eecaf Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Sun, 18 Oct 2026 12:48:47 +0000 Subject: [PATCH 1/2] Fix flaky retained-parse watch test on Windows Windows can report one write as several change events, each rebuilding and re-reporting A. Wait for those rebuilds before counting, then poll for A's re-parse after the edit of B. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0193XhTJFgkaaGZTNw9Uqd5v Signed-off-by: Christoph Knittel --- rewatch-ocaml/tests/run.sh | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/rewatch-ocaml/tests/run.sh b/rewatch-ocaml/tests/run.sh index 694a8da3d4..1f42297c53 100644 --- a/rewatch-ocaml/tests/run.sh +++ b/rewatch-ocaml/tests/run.sh @@ -1923,10 +1923,25 @@ background_pids="$background_pids $retained_parse_pid" wait_for_initial_build "$retained_parse/watch.log" printf 'let value =\n' >"$retained_parse/src/A.res" wait_for_text "$retained_parse/watch.log" 'This let-binding misses an expression' +# Windows can report one write as several change events, and each one starts +# a rebuild that parses A and reports its error again. Wait until those +# rebuilds are over, so that the counts only grow from the edit of B. failed_parses=$(grep -c '^parse.*A\.res' "$retained_parse/calls.log") +quiet_polls=0 +while [ "$quiet_polls" -lt 10 ]; do + sleep 0.1 + parses=$(grep -c '^parse.*A\.res' "$retained_parse/calls.log") + if [ "$parses" = "$failed_parses" ]; then + quiet_polls=$((quiet_polls + 1)) + else + failed_parses=$parses + quiet_polls=0 + fi +done +reported_errors=$(grep -c 'This let-binding misses an expression' "$retained_parse/watch.log") printf 'let other = 2\n' >"$retained_parse/src/B.res" -wait_for_text "$retained_parse/watch.log" 'This let-binding misses an expression' 2 -test "$(grep -c '^parse.*A\.res' "$retained_parse/calls.log")" -gt "$failed_parses" +wait_for_count "$retained_parse/calls.log" '^parse.*A\.res' $((failed_parses + 1)) +wait_for_text "$retained_parse/watch.log" 'This let-binding misses an expression' $((reported_errors + 1)) grep 'value = 1' "$retained_parse/src/A.js" >/dev/null printf 'let value = 2\n' >"$retained_parse/src/A.res" wait_for_text "$retained_parse/src/A.js" 'value = 2' From de050bf0a1bbf27bd05e43c135593bb7b183fce7 Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Sun, 18 Oct 2026 15:41:40 +0000 Subject: [PATCH 2/2] Compare distinct quiet-watch error reports in the parity check The quiet-watch parity check compares the stderr of Rust and OCaml rewatch after a parse error. macOS and Windows can report one write as several change events, and each rebuild prints the error again, so the check now collapses consecutive identical error reports before comparing. Review: Where did this fail? On macOS in #8902: Rust printed the parse error twice, OCaml once, with identical text. Area: rewatch tests Output: unchanged Tests: ~rewatch-ocaml/tests/check_command_validation.sh Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0193XhTJFgkaaGZTNw9Uqd5v Signed-off-by: Christoph Knittel --- rewatch-ocaml/tests/check_command_validation.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rewatch-ocaml/tests/check_command_validation.sh b/rewatch-ocaml/tests/check_command_validation.sh index d4a0b5a7eb..6e09982bc5 100755 --- a/rewatch-ocaml/tests/check_command_validation.sh +++ b/rewatch-ocaml/tests/check_command_validation.sh @@ -1517,6 +1517,14 @@ for implementation in rust ocaml; do fi normalize_project_path "$work/quiet-watch-$implementation.err" \ "$work/quiet-watch-$implementation.err.norm" "$quiet_watch_project" + # macOS and Windows can report one write as several change events, and each + # rebuild reports the parse error again. Compare the distinct reports only. + node -e ' + const fs = require("fs"); + const blocks = fs.readFileSync(process.argv[1], "utf8").split(/^(?=Error in )/m); + const distinct = blocks.filter((block, i) => block !== blocks[i - 1]); + fs.writeFileSync(process.argv[1], distinct.join("")); + ' "$work/quiet-watch-$implementation.err.norm" done if ! cmp -s "$work/quiet-watch-rust.err.norm" \ "$work/quiet-watch-ocaml.err.norm"; then