From 3e07c10261ecaf83e115ea2ee0979fc77851c6a4 Mon Sep 17 00:00:00 2001 From: Tin Dang Date: Tue, 11 Aug 2026 01:20:16 +0700 Subject: [PATCH 1/2] fix(test): ci_covers_monoio must read the workflow through a CRLF-normalizing reader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All 5 tests in `tests/ci_covers_monoio.rs` failed on the Windows job of the first main push after #464. Not a Windows runtime problem — the suite is a repo-config test that parses `.github/workflows/ci.yml` with the needle `"\n :\n"`. A Windows checkout (`core.autocrlf=true`) ends every line `\r\n`, so the needle never matches, `job_block` returns `None`, and each caller's `.expect()` panics. Same for `workflow_env_block`. Mechanism confirmed against the real file rather than assumed: LF content, needle found: True CRLF content, needle found: False <- the panic CRLF after normalize : True `workflow()` now normalizes through `normalize_newlines`, and a new test — `the_parsers_survive_a_windows_crlf_checkout` — feeds a synthetic CRLF fixture through both parsers. It runs on every platform, which matters: Windows is skipped on all PRs, so this class is invisible until a main push. Verified non-vacuous by neutering the normalizer, which reddens exactly that test with its own message, then restoring it (6/6 green). Note for whoever reads the same main run: the Crash Matrix failure alongside this one is unrelated — it lives in `integration-tests.yml`, which #464 never touched and which sets its own workflow-level MOON_NO_URING. That failure is the known 8s-startup timeout on a hosted runner. author: Tin Dang --- CHANGELOG.md | 5 ++++- tests/ci_covers_monoio.rs | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 185e31fb..abd5b54b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 workflow-level `env:`, which merges into every job and cannot be unset by one, so the job whose whole point is io_uring ran with io_uring force-disabled. `monoio_yield_overhead_is_microscopic` caught it at 1.45ms/yield (the `sleep(ZERO)` timer-park signature). That variable is now per-job, - and `ci_covers_monoio.rs` asserts **both** scopes. + and `ci_covers_monoio.rs` asserts **both** scopes. The guard suite itself then failed on + Windows — it matched `"\n :\n"` against a CRLF checkout — so it now normalizes line + endings and carries a platform-independent CRLF regression test (Windows is skipped on every + PR, so that class is invisible until a main push). - **Client-compat harness: raw-RESP diff against a real `redis-server` (`scripts/test-client-compat.sh`).** Moon's existing Redis comparison diff --git a/tests/ci_covers_monoio.rs b/tests/ci_covers_monoio.rs index 38427494..d37c3175 100644 --- a/tests/ci_covers_monoio.rs +++ b/tests/ci_covers_monoio.rs @@ -19,7 +19,43 @@ use std::path::PathBuf; fn workflow() -> String { let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(".github/workflows/ci.yml"); - std::fs::read_to_string(&path).unwrap_or_else(|e| panic!("cannot read {}: {e}", path.display())) + let raw = std::fs::read_to_string(&path) + .unwrap_or_else(|e| panic!("cannot read {}: {e}", path.display())); + // Normalize CRLF. `job_block` and `workflow_env_block` scan for `\n :\n` + // and for indentation immediately after a newline; on a Windows checkout + // (`core.autocrlf=true`) every line ends `\r\n`, so those needles never match + // and each caller's `.expect()` fires — all 5 tests failed that way on the + // first main push, invisible to PR CI because Windows is skipped there. + normalize_newlines(&raw) +} + +fn normalize_newlines(s: &str) -> String { + s.replace("\r\n", "\n") +} + +/// The regression guard for the above, runnable on ANY platform — Windows is +/// skipped on every PR, so a CRLF bug here is otherwise invisible until main. +#[test] +fn the_parsers_survive_a_windows_crlf_checkout() { + let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(".github/workflows/ci.yml"); + let lf = std::fs::read_to_string(&path).expect("read ci.yml"); + let crlf = lf.replace('\n', "\r\n"); + assert!( + crlf.contains("\r\n"), + "synthetic CRLF fixture did not convert — the test would prove nothing" + ); + + let yaml = normalize_newlines(&crlf); + assert!( + job_block(&yaml, "check-monoio").is_some(), + "job_block cannot find `check-monoio` in a CRLF checkout. Its needle is \ + \"\\n :\\n\", which a \\r\\n line ending breaks — read the workflow \ + through `workflow()`, never `read_to_string` directly." + ); + assert!( + workflow_env_block(&yaml).contains("CARGO_TERM_COLOR"), + "workflow_env_block returned nothing usable on a CRLF checkout" + ); } /// Return the body of a top-level job block, from ` :` to the next From 450188809fac3ba2ec103d08d4cf80fe91c5a4e8 Mon Sep 17 00:00:00 2001 From: Tin Dang Date: Tue, 11 Aug 2026 01:31:31 +0700 Subject: [PATCH 2/2] fix(test): the CRLF regression test made the same assumption it tests for MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `the_parsers_survive_a_windows_crlf_checkout` built its fixture as `read_to_string(..).replace('\n', "\r\n")`. On a Windows checkout the bytes on disk are ALREADY CRLF, so that yields `\r\r\n` — a fixture no correct normalizer can rescue — and the test failed on its own first Windows run while correctly clearing the five failures it was written to fix. Assuming the file is LF is precisely the bug under test. Normalize first, then synthesize CRLF, and assert the fixture is well-formed (`\r\n` present, `\r\r` absent) so a malformed fixture reddens loudly instead of passing vacuously. Simulated both checkout styles against the real file: LF checkout fixture_ok=True parse_ok=True (previous version: True) CRLF checkout fixture_ok=True parse_ok=True (previous version: False) author: Tin Dang --- tests/ci_covers_monoio.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/ci_covers_monoio.rs b/tests/ci_covers_monoio.rs index d37c3175..203cf176 100644 --- a/tests/ci_covers_monoio.rs +++ b/tests/ci_covers_monoio.rs @@ -38,11 +38,17 @@ fn normalize_newlines(s: &str) -> String { #[test] fn the_parsers_survive_a_windows_crlf_checkout() { let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(".github/workflows/ci.yml"); - let lf = std::fs::read_to_string(&path).expect("read ci.yml"); + let raw = std::fs::read_to_string(&path).expect("read ci.yml"); + // Normalize FIRST. On a Windows checkout the bytes on disk are already CRLF, + // so converting the raw text would produce `\r\r\n` — a fixture that no + // amount of correct normalizing can rescue, which is how this very test + // failed on its own first Windows run. Assuming the file is LF is exactly + // the bug under test. + let lf = normalize_newlines(&raw); let crlf = lf.replace('\n', "\r\n"); assert!( - crlf.contains("\r\n"), - "synthetic CRLF fixture did not convert — the test would prove nothing" + crlf.contains("\r\n") && !crlf.contains("\r\r"), + "synthetic CRLF fixture is malformed — the test would prove nothing" ); let yaml = normalize_newlines(&crlf);