From 16bfe8b0bb1fbe007d6adb5c9dd4c3adbe3f6438 Mon Sep 17 00:00:00 2001 From: droidnoob Date: Sat, 30 May 2026 03:05:39 +0530 Subject: [PATCH 1/4] perf(test): wire up cargo-nextest opt-in - Ship `.config/nextest.toml` with a default + `slow` profile so the workspace runs the same way for everyone who installs nextest. - Document install + invocation in CONTRIBUTING.md alongside the existing `cargo test` workflow, including the `--ignored` periodic sweep convention. Refs hew-v2ib. --- .config/nextest.toml | 26 ++++++++++++++++++++++++++ CONTRIBUTING.md | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 .config/nextest.toml diff --git a/.config/nextest.toml b/.config/nextest.toml new file mode 100644 index 0000000..cb03506 --- /dev/null +++ b/.config/nextest.toml @@ -0,0 +1,26 @@ +# cargo-nextest configuration. +# +# Install: `cargo install --locked cargo-nextest` +# Run : `cargo nextest run --workspace` +# +# The default profile is what pre-commit / day-to-day runs use. The `slow` +# profile additionally runs tests marked `#[ignore]` — used in CI and for the +# periodic local sweep: +# +# cargo nextest run --workspace --profile slow + +[profile.default] +# Show the slowest tests first when something fails — easier triage than the +# default ordering. +status-level = "fail" +failure-output = "immediate-final" +final-status-level = "slow" + +# Tests that legitimately need to spawn real subprocesses can occasionally +# exceed cargo's default 60s timeout under cold-cache CI. 120s gives headroom +# without masking a genuine hang. +slow-timeout = { period = "60s", terminate-after = 2 } + +[profile.slow] +# Inherits from default; the CLI invocation toggles `--run-ignored all`. +slow-timeout = { period = "90s", terminate-after = 2 } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a7022c9..6c4a5dd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,11 +65,52 @@ Allowed prefixes: `feat`, `fix`, `chore`, `docs`, `refactor`, `perf`, ```sh cargo build # 1.x s incremental, ~30s cold -cargo test # full suite; ~2s after warm cache +cargo test # full suite; ~25s warm cache cargo clippy --all-targets -- -D warnings cargo fmt --all ``` +### Faster tests via `cargo-nextest` (recommended) + +The default `cargo test` runs each test binary serially and reports +per-test output. [`cargo-nextest`](https://nexte.st) runs every binary +in parallel with a tighter scheduler — on this workspace it cuts the +suite from ~25s to under 20s on warm cache, and the `.githooks/pre-commit` +hook automatically prefers it when present. + +Install once per machine: + +```sh +cargo install --locked cargo-nextest +``` + +Then: + +```sh +cargo nextest run --workspace # default profile — skips #[ignore]d tests +cargo nextest run --workspace --profile slow --run-ignored all # periodic full sweep +``` + +Plain `cargo test` is still supported (CI keeps it in the matrix to +guarantee both invocations stay green). + +### Slow tests gated behind `#[ignore = "slow"]` + +A small set of heavy e2e tests — parallel-loop worktree drivers, the +real-git merge-conflict simulator — carry `#[ignore = "slow"]` so the +default `cargo test` / `cargo nextest run` keeps the pre-commit gate fast. +Run them explicitly before tagging a release or merging anything that +touches the loop runner: + +```sh +cargo test --workspace -- --include-ignored +# or +cargo nextest run --workspace --profile slow --run-ignored all +``` + +CI runs the full sweep on every PR, so missing this locally never lands +silently. + Tests are organised as: - **Unit tests** alongside each module under `hew-core/src/`. From 3e001b5293279063580840468dbfeec6b97e24b1 Mon Sep 17 00:00:00 2001 From: droidnoob Date: Sat, 30 May 2026 03:06:03 +0530 Subject: [PATCH 2/4] perf(test): mark loop_parallel_e2e tests #[ignore = "slow"] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both tests drive the full parallel-loop runner against a real git repo (seed + worker branches + merge-back), which is exactly the kind of e2e the periodic sweep covers — not the pre-commit gate. Skipping them by default keeps the inner-loop signal fast; CI runs them via `--include-ignored`. Refs hew-v2ib. --- hew/tests/loop_parallel_e2e.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hew/tests/loop_parallel_e2e.rs b/hew/tests/loop_parallel_e2e.rs index d225fbe..614a05e 100644 --- a/hew/tests/loop_parallel_e2e.rs +++ b/hew/tests/loop_parallel_e2e.rs @@ -343,6 +343,7 @@ fn read_manifest(repo: &Path) -> serde_json::Value { } #[test] +#[ignore = "slow"] fn e2e_parallel_jobs_2_with_mock_spawner() { if !git_available() { eprintln!("git not on PATH, skipping"); @@ -409,6 +410,7 @@ fn e2e_parallel_jobs_2_with_mock_spawner() { } #[test] +#[ignore = "slow"] fn e2e_parallel_merge_conflict_files_bug_task() { if !git_available() { eprintln!("git not on PATH, skipping"); From ec91726e3eb72d0077cb30f506355a34c45e65c5 Mon Sep 17 00:00:00 2001 From: droidnoob Date: Sat, 30 May 2026 03:06:56 +0530 Subject: [PATCH 3/4] perf(test): pre-commit hook prefers cargo-nextest when available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Falls back to `cargo test --quiet` so contributors without nextest stay unblocked. On a warm cache nextest takes ~17s vs ~26s for `cargo test` on this workspace — pre-commit becomes meaningfully cheaper for the people who installed it without forcing a new dep on everyone else. Refs hew-v2ib. --- .githooks/pre-commit | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.githooks/pre-commit b/.githooks/pre-commit index 01ceeb4..cb87e06 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -63,9 +63,19 @@ echo "pre-commit: cargo clippy --all-targets -- -D warnings" cargo clippy --all-targets --quiet -- -D warnings # Tests are gated separately. CI runs them regardless. +# +# Prefer `cargo nextest` when it's on PATH — same coverage, faster wall +# clock (~17s vs ~26s on this workspace, M-series, warm cache). Falls back +# to `cargo test --quiet` so contributors without nextest aren't blocked. +# CONTRIBUTING.md documents how to install it. if [[ "${HEW_HOOK_NO_TESTS:-}" != "1" ]]; then - echo "pre-commit: cargo test" - cargo test --quiet + if command -v cargo-nextest >/dev/null 2>&1; then + echo "pre-commit: cargo nextest run --workspace" + cargo nextest run --workspace + else + echo "pre-commit: cargo test" + cargo test --quiet + fi fi echo "pre-commit: ok" From 30aa63472853a50677755da10652385fd01dc41b Mon Sep 17 00:00:00 2001 From: droidnoob Date: Sat, 30 May 2026 03:07:09 +0530 Subject: [PATCH 4/4] ci(test): include ignored slow tests The pre-commit hook and default `cargo test` skip `#[ignore = "slow"]` tests for inner-loop speed. CI is the only place those tests have to run, so add `--include-ignored` to the matrix invocation. Refs hew-v2ib. --- .github/workflows/ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 998da2a..71e5a7f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,7 +60,10 @@ jobs: # actually `rustup-init`). Hit us on macos-latest/1.91 — keep this off. cache-bin: "false" - run: cargo build --all-targets --locked - - run: cargo test --all-targets --locked + # `--include-ignored` runs the `#[ignore = "slow"]` tests that the + # pre-commit gate and default `cargo test` invocation skip. CI is the + # one place that periodic-sweep coverage must never go missing. + - run: cargo test --all-targets --locked -- --include-ignored audit: name: cargo-audit