ci: give test threads the stack the product gives itself

main.rs runs the owner thread and every tokio worker at
CODEWHALE_MAIN_STACK_BYTES (16 MiB) because the engine and runtime-thread
futures are genuinely deep — 8c98bedc75 landed the worker half of that
after a debug `agent` dispatch measured a 2.25-2.5 MiB high-water mark and
died on the guard page.

`#[tokio::test]` builds its own runtime and never sees that. So the test
lanes ran the same code on ~2 MiB, and ~1 MiB on Windows: a configuration
that never ships. That is what aborted the entire Windows test binary with
STATUS_STACK_OVERFLOW in start_turn_accepts_dynamic_tools_and_environment_
id, taking ~9.7k unreported results with it and masking every other
Windows failure — the same masking 78afd8d3d4 called out when it Box::pin'd
that one frame. Box::pin fixed the frame; the environment mismatch stayed,
so the abort returned as soon as codegen moved frame sizes again.

Set RUST_MIN_STACK to the same 16 MiB on the CI test lane and on
release.yml's parity gate. std reads it for any thread spawned without an
explicit size, which covers both libtest's per-test threads and tokio's
workers, so the whole suite gets production's stack instead of the
harness default.

This is not a bigger hammer for a deep-recursion bug: 16 MiB is exactly
what the product already guarantees this code, so the tests now measure
the shipped configuration rather than a stricter one no user runs.
This commit is contained in:
CodeWhale Bot
2026-08-06 10:00:57 -07:00
parent 70d34e1f22
commit 6b7eb20ef1
2 changed files with 20 additions and 0 deletions
+14
View File
@@ -428,6 +428,20 @@ jobs:
- name: Run tests
if: needs.changes.outputs.heavy == 'true' && (matrix.os != 'ubuntu-latest' || github.event_name == 'workflow_dispatch')
run: cargo test --workspace --all-features --locked
env:
# Give test threads the stack the product gives itself. main.rs runs
# the owner thread and every tokio worker at
# CODEWHALE_MAIN_STACK_BYTES (16 MiB) because the engine and
# runtime-thread futures are genuinely deep. `#[tokio::test]` builds
# its own runtime and never sees that, so tests ran the same code on
# ~2 MiB (~1 MiB on Windows) — a configuration that never ships.
# That gap is what aborted the whole Windows test binary with
# STATUS_STACK_OVERFLOW in start_turn_accepts_dynamic_tools_and_
# environment_id, masking every other Windows result (78afd8d3d4
# Box::pin'd that one frame; the mismatch itself remained). std reads
# this for any thread spawned without an explicit size, which covers
# both libtest's per-test threads and tokio's workers.
RUST_MIN_STACK: '16777216'
# The Ubuntu lint lane validates non-RSS backlog fields. Run the same
# source-bound measurement on macOS so loss or growth of RSS evidence
# fails closed instead of becoming an unsupported-field skip.
+6
View File
@@ -163,6 +163,12 @@ jobs:
-A clippy::assertions_on_constants
- name: Workspace tests
run: cargo test --workspace --all-features --locked
env:
# Match the CI test lane: test threads get the same stack the product
# gives itself (main.rs CODEWHALE_MAIN_STACK_BYTES). See the note in
# ci.yml's "Run tests" step. Without it this gate runs the deep
# engine/runtime futures on a stack that never ships.
RUST_MIN_STACK: '16777216'
- name: Protocol schema parity
run: cargo test -p codewhale-protocol --test parity_protocol --locked
- name: State persistence parity