tsoracle-failpoint
The one failpoint! macro shared across tsoracle — a thin wrapper over fail-rs that every crate re-uses instead of redefining its own copy.
Why it exists
Four crates (tsoracle-paxos-toolkit, tsoracle-openraft-toolkit, tsoracle-driver-file, tsoracle-server) each carried a byte-identical wrapper macro that forwarded to fail::fail_point! under a failpoints feature and expanded to () otherwise. Every change to failpoint semantics had to be made N times, and the macro had even drifted in name (fail_point! vs failpoint!). This crate is the single home for that wrapper.
What's in the box
failpoint!(name)/failpoint!(name, closure)— the macro consumers sprinkle into synchronous code paths. Inert (()) with thefailpointsfeature off; under the feature, forwards tofail::fail_point!so a test can arm apanic, an errorreturn, apause, or asleepat the named site.- A
failpoints-gated re-export offail(tsoracle_failpoint::fail), so test code arms the process-global registry through the same crate the macro lives in — consumers never namefaildirectly.
Quick reference
Opt in by declaring a feature on the consumer crate that flips tsoracle-failpoint/failpoints:
# consumer Cargo.toml
[]
= ["tsoracle-failpoint/failpoints"]
[]
= { = true }
Then at the source site:
failpoint!;
And in a test (with the feature on):
let _scenario = setup;
cfg.unwrap;
With failpoints off (production), the macro expands to nothing and fail is not linked.
Feature flags
failpoints(off by default) — enables the macro body, pulls infail, and enablesfail/failpoints. Production builds carry zero overhead.
Related
fail— the synchronous failpoint library this wraps.tsoracle-yieldpoint— the async analogue, for sites that must keep yielding their tokio worker while parked instead of blocking the thread.