Skip to content

test: stress, fuzz, and run the spawn where bounded tests stop - #39

Merged
P4suta merged 6 commits into
refactor/explicit-spawn-statefrom
test/deep-checks
Oct 13, 2026
Merged

P4suta merged 6 commits into
refactor/explicit-spawn-statefrom
test/deep-checks

Conversation

@P4suta

@P4suta P4suta commented Oct 13, 2026 •

Copy link
Copy Markdown
Owner

Summary

Closes #38.
This PR stacks on #36.

It brings back the checks of #14 that main dropped, and each one now checks a property rather than an absence of panics.

  • The ignored test spawn_cleanup_stress spawns children in thirteen modes and requires the process's handle count to end where it started.
    The modes cover both commits, a dropped suspended child, collected output, written input, a killed tree, transferred handles, a Job, an alternate parent, and two failed spawns.
  • CI runs the Windows tests under cargo careful, whose standard library checks the preconditions of the unsafe operations in sys.
  • CI runs cargo xtask test on a Windows 11 ARM64 runner.
  • A fuzz crate compiles the encoder and the block builder from src/domain.
    Its targets require the parser models to read back every program name, argument, and variable they encode.
  • Miri and AddressSanitizer run the platform-neutral decisions on Linux.
  • WINDOWS_SPAWN_RANDOM_SCALE multiplies the random command lines and environments, which keep their seeds.
  • A nightly workflow runs 100000 stress spawns on x64 and 20000 on i686, the random cases at fifty times their size, and each fuzz target for five hours.
  • ADR 0017 records what each check covers and credits refactor!: enforce spawn invariants mechanically #14, and CONTRIBUTING shows how to run them.

tests/argv_roundtrip.rs propagates its errors instead of calling expect and adopts handles without as.
Its file-wide lint exception and three registry entries go away.

The first ARM64 run found that Windows on ARM64 gives every child PROCESSOR_ARCHITECTURE, even a child whose environment the command cleared.
The random environment test now leaves that variable out, and Command::env_clear states the behavior.

Validation

On Windows 11, x64:

  • cargo xtask test passed.
  • The stress test ran 1300 spawns in 20 seconds, and the handle count stayed at 86.
  • cargo careful test passed 70 unit tests, 34 integration tests, and 36 xtask tests.

On macOS, Apple silicon:

  • Each fuzz target ran for one minute without a failure, 2 million runs for command-line and 8.9 million for environment-block.
  • With the backslashes before a closing quote removed from the encoder, the command-line target failed within seconds.
  • Miri passed the 16 platform-neutral tests, and so did AddressSanitizer.
  • Formatting, Clippy for the host and for x64 and i686 Windows with and without the vector cfg, cargo xtask gates, and the xtask tests passed.
  • actionlint, reuse lint, and typos passed.
    zizmor reports nothing on the new jobs.

In this PR's CI:

  • The stress test ran 1300 spawns in 7.7 seconds on x64 and in 10.5 seconds on i686.
  • On Windows 11 ARM64, cargo xtask test passed 73 unit tests, 36 integration tests, 36 xtask tests, every Lean row, and every random case.
  • The fuzz targets ran for ten minutes each, 13.3 million runs for command-line and 32.2 million for environment-block.
  • Miri passed in 465 seconds, and AddressSanitizer and cargo careful passed.

The nightly workflow runs once this PR reaches main, because GitHub dispatches only a workflow that the default branch holds.
The owner has paused CodeRabbit, so its review of this PR waits for the owner to resume it.

Checklist

  • The relevant local tests ran.
  • Deterministic tests cover each behavior change.
  • The docs state each new or changed ownership, safety, or cleanup contract.
  • The public API doesn't change.
  • The PR holds no secrets or public vulnerability details.
  • The PR stays focused and updates the relevant documentation.

@coderabbitai ignore

@P4suta
P4suta added this pull request to stack #37 October 13, 2026 13:24
@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Note

Reviews paused

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 0387e3be-733f-4dfd-be42-922aa5e1573c
📥 Commits

Reviewing files that changed from the base of the PR and between 8fcc3dc and 92e11fe.

⛔ Files ignored due to path filters (1)
  • fuzz/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • .github/workflows/ci.yml
  • .github/workflows/deep-verification.yml

Included review availability: This review used your included allowance. 7 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 10 reviews per hour.

📜 Recent review details
🧰 Additional context used
🪛 zizmor (1.30.1)
.github/workflows/ci.yml

[info] 100-100: action functionality is already included by the runner (superfluous-actions): use rustup and/or cargo in a script step

(superfluous-actions)

[info] 117-117: action functionality is already included by the runner (superfluous-actions): use rustup and/or cargo in a script step

(superfluous-actions)

[info] 137-137: action functionality is already included by the runner (superfluous-actions): use rustup and/or cargo in a script step

(superfluous-actions)

[info] 151-151: action functionality is already included by the runner (superfluous-actions): use rustup and/or cargo in a script step

(superfluous-actions)

[info] 168-168: action functionality is already included by the runner (superfluous-actions): use rustup and/or cargo in a script step

(superfluous-actions)

[info] 190-190: action functionality is already included by the runner (superfluous-actions): use rustup and/or cargo in a script step

(superfluous-actions)

.github/workflows/deep-verification.yml

[info] 36-36: action functionality is already included by the runner (superfluous-actions): use rustup and/or cargo in a script step

(superfluous-actions)

[info] 56-56: action functionality is already included by the runner (superfluous-actions): use rustup and/or cargo in a script step

(superfluous-actions)

[info] 76-76: action functionality is already included by the runner (superfluous-actions): use rustup and/or cargo in a script step

(superfluous-actions)

🔇 Additional comments (2)
.github/workflows/ci.yml (1)

85-85: LGTM!

Also applies to: 109-109, 129-129, 143-143, 158-158, 176-176

.github/workflows/deep-verification.yml (1)

1-93: LGTM!

📝 Walkthrough

Adds spawn-cleanup stress tests, scalable randomized tests, and command-line and environment-block fuzz targets. Expands CI with Windows and Linux verification jobs, and adds a scheduled workflow for longer stress, random-input, and fuzz runs.

Changes: Verification and CI

Layer / File(s) Summary
Spawn-cleanup stress test
tests/windows_spawn.rs, .github/workflows/ci.yml, .github/workflows/deep-verification.yml
Adds a 13-mode stress test that checks handle counts after repeated process spawns. CI runs 1,300 cases on x86_64 and i686; the scheduled workflow runs 100,000 x86_64 cases and 20,000 i686 cases.
Scaled randomized tests
tests/random/mod.rs, tests/argv_roundtrip.rs, tests/command_line_parsers.rs, .github/workflows/deep-verification.yml
Adds WINDOWS_SPAWN_RANDOM_SCALE to set the random-test iteration count. The argv round-trip test also propagates encoding and environment lookup errors and excludes PROCESSOR_ARCHITECTURE from environment comparisons.
Fuzz targets and support
fuzz/*, src/domain/command_line_rules.rs, src/domain/environment_rules.rs, Cargo.toml, REUSE.toml, xtask/src/gates.rs, .github/workflows/ci.yml, .github/workflows/deep-verification.yml
Adds command-line encoder/parser round-trip and environment-block build/scan fuzz targets. CI fuzzes both targets for ten minutes; the scheduled workflow runs each for up to five hours.
Verification jobs and documentation
.github/workflows/ci.yml, .github/workflows/deep-verification.yml, CONTRIBUTING.md, docs/adr/0017-long-careful-and-fuzzed-runs.md, src/command.rs
Adds Windows cargo-careful and ARM64 jobs, Linux Miri and AddressSanitizer jobs, and includes the new CI jobs in ci-required. Adds documentation for the deeper checks and Command::env_clear behavior.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Other

Merge Risk: ⚪ Minimal · up to 92e11

The expanded verification checks have no identified merge-blocking defect; the scheduled fuzz runs each have their own job.

Security architecture risk: 🔵 Low · up to 92e11

The expanded checks retain read-only repository permissions and reject ordinary verification failures, cancellations, and skips. No introduced privilege escalation was established. Cache isolation and enforcement of canceled or stale checks remain outside the available evidence.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — Pull-request authors can influence code executed by the added verification jobs. The visible exposure is runner execution, build caches, and failure-artifact production; the workflow additions do not declare deployment credentials or repository-write permissions. Organization-level runner and credential policies were not available.

Security Findings and Attack Paths

  • inferred — A potential PR-to-trusted-build cache path remains unverified: PR and scheduled/main verification use the same pinned cache action and corresponding target/workspace settings. Matching settings alone do not establish cross-branch cache consumption or poisoning; the decisive isolation contract is external to the inspected repository source.

Trust Boundaries and Controls

  • observed — The added PR workloads retain the pull_request trigger rather than introducing privileged PR-context execution. Scheduled/manual verification has separate triggers, read-only permissions, and no dependency into the required-status chain.

Resilience and Maintainability Implications

  • inferred — Ordinary dependency failure, cancellation, or skipping cannot produce successful ci-required aggregation. The final job's acceptance of a skipped ci-required result already existed at the base. Cancellation before aggregation starts, stale-result handling, and actual merge enforcement remain dependent on unverified platform and branch-protection behavior.
Pre-merge checks · Passed 6
Passed Passed checks (6 passed)
Check name Status Explanation
Title check Passed The title uses the required Conventional Commits format and accurately describes the added stress, fuzz, and extended spawn testing. The wording is somewhat informal but remains specific and related t…
Description check Passed The description includes Summary, Validation, and Checklist sections. It documents the main changes, exact validation commands, Windows versions, test results, documentation updates, and completed che…
Linked Issues check Passed Direct issue #38 has coding requirements for expanded validation. The PR adds the ignored handle-count stress test with configurable cases and the required spawn modes. It adds Windows cargo careful…
Out of Scope Changes check Passed The changes stay within issue #38. Workflow changes implement the requested validation jobs and extended runs. Fuzz targets, domain cfg changes, stress-test support, random scaling, documentation, a…
Behavior Verification Evidence Passed The PR provides relevant verification evidence. The diff adds a 13-mode handle-count stress test, parser-model fuzz targets, scaled random tests, ARM64, cargo-careful, Miri, and AddressSanitizer CI jo…
Public Interface Compatibility Passed No supported breaking interface change is introduced. The library diff only adds documentation to the existing Command::env_clear method; it does not change public signatures or implementation. The …
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
✨ Simplify code
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@P4suta
P4suta marked this pull request as ready for review October 13, 2026 13:48
coderabbitai[bot]
coderabbitai Bot previously approved these changes Oct 13, 2026
@P4suta
P4suta marked this pull request as draft October 13, 2026 14:08
@P4suta
P4suta marked this pull request as ready for review October 13, 2026 14:56
coderabbitai[bot]
coderabbitai Bot previously approved these changes Oct 13, 2026
@P4suta

P4suta commented Oct 13, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai pause

@coderabbitai

coderabbitai Bot commented Oct 13, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews paused.

@P4suta
P4suta marked this pull request as draft October 13, 2026 15:42
The ignored test `spawn_cleanup_stress` spawns children in thirteen modes, `WINDOWS_SPAWN_STRESS_CASES` times in all.
The modes cover both commits, a dropped suspended child, collected output, written input, a killed tree, transferred handles, a Job, an alternate parent, and two failed spawns.
It requires the process's handle count to end where it started, after a warm-up that runs each mode twice.
On Windows 11, 1300 spawns left the count at 86, where it started.

`WINDOWS_SPAWN_RANDOM_SCALE` multiplies the random command lines and environments, which keep their seeds.

`tests/argv_roundtrip.rs` propagates its errors instead of calling `expect`, and adopts handles without `as`.
The file-wide lint exception and its three registry entries go away.

Refs #38
A `fuzz` crate compiles `command_line_rules.rs` and `environment_rules.rs` from `src/domain`.
Its `command-line` target requires both C runtime parser models to read back the program name and every argument it encodes.
Its `environment-block` target requires a built block to end where `scan` finds its end and to read back as its variables, in order.
The parser models and the block scan compile under `cfg(fuzzing)` for them, and the models name the backslash pair they count.

The fuzz crate forms its own workspace, so the package, the MSRV, and the workspace lints leave it out.
The repository gate checks its targets, and `REUSE.toml` states the license of its files.
A broken encoder, which drops the backslashes before a closing quote, failed the `command-line` target within seconds.

Refs #38
Every PR now runs 1300 stress spawns on x64 and i686, the Windows tests under `cargo careful`, and `cargo xtask test` on Windows 11 ARM64.
It also runs Miri and AddressSanitizer over the platform-neutral decisions, and each fuzz target for ten minutes.
`required` waits for each of these jobs.

A nightly workflow runs the stress test 100000 times on x64 and 20000 times on i686.
It also runs the random cases at fifty times their size, and each fuzz target for five hours.
ADR 0017 records what each check covers and credits #14, and CONTRIBUTING shows how to run them.

Refs #38
…cess

The first ARM64 run showed that Windows on ARM64 gives every child `PROCESSOR_ARCHITECTURE`, even a child whose environment the command cleared.
The random environment test now leaves that variable out, as it leaves out the variables that `appverif.exe` and the profile runtime set.
`Command::env_clear` states the behavior.

Refs #38
The `cargo-fuzz` binary that `install-action` installs targets musl by default, where AddressSanitizer refuses the static C runtime.
Both workflows now name `x86_64-unknown-linux-gnu`, as #14 did.

Refs #38
zizmor reported the matrix values that the stress and fuzz steps expanded into their scripts.
The stress jobs now name their target through `CARGO_BUILD_TARGET`, and the fuzz jobs through `FUZZ_TARGET`, so no script expands a template.
The nightly workflow also runs one deep run at a time.

Refs #38
@P4suta
P4suta marked this pull request as ready for review October 13, 2026 16:11
@P4suta
P4suta merged commit 961eae8 into main Oct 13, 2026
62 of 91 checks passed
@P4suta
P4suta deleted the test/deep-checks branch October 13, 2026 16:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test: stress, fuzz, and run the spawn where bounded tests stop

1 participant