Skip to content

test: inject Win32 failures to cover every error path - #23

Merged
P4suta merged 2 commits into
mainfrom
test/fault-injection
Sep 24, 2026
Merged

P4suta merged 2 commits into
mainfrom
test/fault-injection

Conversation

@P4suta

@P4suta P4suta commented Sep 24, 2026

Copy link
Copy Markdown
Owner

Summary

Closes the mutation findings the first rust-mutants run reported (ADR 0012).

  • sys::fault (tests only) fails the Nth fallible wrapper call on the current thread.
    failure_tests fails every call of every public operation in turn and requires the injected error back; an isolated run requires an unchanged handle count.
  • Real failures cover logic after Win32 calls: handles without the needed access, a full attribute list, an oversized attribute count, unterminated paths.
  • Stored handle duplicates are checked to be non-inheritable; more.com, application-directory, and NUL-path resolution are covered.
  • ConPTY probes check the console size, so a spawn missing the pseudoconsole attribute fails instead of hanging.
  • Isolated reruns carry their marker as an argument and a variable, so an environment mutant cannot make them recurse.
  • .rust-mutants.toml records each survivor no test can observe with its equivalence or unreachability, and skips three unreachable lines and one endless loop.

Validation

Windows 11 Pro build 26200, through domyjob:

  • cargo xtask test and the lib tests pass.
  • Mutation run: killed 558, survived 14 (all expected), waited 11, errored 2; before this PR, killed 438, survived 105, waited 24, unreached 20.
    Every waited mutant has a recorded failing test and is reported as waited only because a later test in the same process hangs; this and the two out-of-bounds panics reported as errored are with njutest.

macOS: cargo clippy --workspace --all-targets -- -D warnings for x86_64-pc-windows-msvc; cargo +1.75 check --workspace --all-targets.

Checklist

  • I ran the relevant local tests, including just ci and just coverage when applicable. (cargo xtask test on Windows; the rest is left to CI.)
  • I added or updated deterministic tests for behavior changes.
  • I documented new or changed ownership, safety, or cleanup contracts. (ADR 0012.)
  • I reviewed public API compatibility and updated the snapshot if needed. (Unchanged.)
  • I did not include secrets or public vulnerability details.
  • I kept this pull request focused and updated relevant documentation.

`sys::fault`, compiled only for tests, fails the Nth fallible wrapper call on the current thread; each wrapper checks it on entry (ADR 0012).
`failure_tests` fails every call of every public operation in turn and requires the injected error back, and an isolated run requires an unchanged handle count.

Other tests close the remaining gaps:

- Real failures cover logic after a Win32 call: handles without the needed access, a full attribute list, an oversized attribute count, unterminated paths.
- Stored handle duplicates are checked to be non-inheritable; `more.com`, application-directory, and NUL-path resolution are covered.
- ConPTY probes check the console size, so a spawn missing the pseudoconsole attribute fails instead of hanging.
- A test that runs first checks a running spawn is not suspended.
- Isolated reruns carry their marker as both an argument and a variable, so an environment mutant cannot make them recurse.

`.rust-mutants.toml` records the surviving mutants no test can observe, each with its equivalence or unreachability, and skips three unreachable lines and one endless loop.
`storage_words` uses `div_ceil` and can no longer fail.

On Windows the run now reports killed 558, survived 14 (all expected), waited 11, errored 2.
Every waited mutant has a recorded failing test; rust-mutants still reports it as waited because a later test hangs (reported upstream), as it does the two out-of-bounds panics.
@coderabbitai

coderabbitai Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 033d79b9-285e-4ed4-93bd-c1c90933aef8


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

The pipe operation read to EOF, so its number of reads depended on how the pipe split the output, and a failure index could miss.
It now writes and reads once each.

The pseudoconsole operation created and closed a console per run; ClosePseudoConsole can block on some Windows Server 2022 builds, and the blocked close threads held handles that the leak check counted.
One console now serves every run.
@P4suta
P4suta merged commit 2f5e6e9 into main Sep 24, 2026
15 checks passed
@P4suta
P4suta deleted the test/fault-injection branch September 24, 2026 18:56
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.

1 participant