cntryl_stress/
lib.rs

1//! # cntryl-stress
2//!
3//! A lightweight single-shot benchmark runner for system-level stress tests.
4//!
5//! Unlike Criterion (which uses statistical sampling), this crate is designed for
6//! expensive operations where each iteration matters: disk I/O, network calls,
7//! database transactions, compaction, recovery, etc.
8//!
9//! ## Quick Start (Attribute Style - Recommended)
10//!
11//! The easiest way to write stress tests is with the `#[stress_test]` attribute:
12//!
13//! ```rust,ignore
14//! use cntryl_stress::{stress_test, StressContext};
15//!
16//! #[stress_test]
17//! fn write_1mb_file(ctx: &mut StressContext) {
18//!     let data = vec![0u8; 1024 * 1024];
19//!     ctx.set_bytes(data.len() as u64);
20//!     
21//!     ctx.measure(|| {
22//!         std::fs::write("/tmp/test", &data).unwrap();
23//!     });
24//!     
25//!     std::fs::remove_file("/tmp/test").ok();
26//! }
27//!
28//! #[stress_test]
29//! fn database_insert(ctx: &mut StressContext) {
30//!     let db = setup_database();
31//!     ctx.measure(|| {
32//!         db.insert("key", "value");
33//!     });
34//! }
35//!
36//! // Generate main function
37//! cntryl_stress::stress_main!();
38//! # fn setup_database() -> FakeDb { FakeDb }
39//! # struct FakeDb;
40//! # impl FakeDb { fn insert(&self, _: &str, _: &str) {} }
41//! ```
42//!
43//! Then run with:
44//!
45//! ```bash
46//! cargo stress                          # Run all stress tests
47//! cargo stress --workload "database*"   # Run matching tests
48//! cargo stress --workload "*insert*"    # Glob patterns supported
49//! ```
50//!
51//! ## Manual Runner Style
52//!
53//! For more control, use the `BenchRunner` directly:
54//!
55//! ```rust,no_run
56//! use cntryl_stress::{BenchRunner, StressContext};
57//!
58//! let mut runner = BenchRunner::new("my_suite");
59//!
60//! runner.run("expensive_operation", |ctx| {
61//!     let data = prepare_data();
62//!     ctx.measure(|| {
63//!         expensive_operation(&data);
64//!     });
65//!     cleanup(&data);
66//! });
67//!
68//! runner.finish();
69//!
70//! fn prepare_data() -> Vec<u8> { vec![0; 1024] }
71//! fn expensive_operation(_: &[u8]) {}
72//! fn cleanup(_: &[u8]) {}
73//! ```
74//!
75//! ## Features
76//!
77//! - **Single-shot measurements** — no statistical sampling overhead
78//! - **Glob filtering** — run subsets with `--workload "pattern*"`
79
80mod config;
81mod context;
82mod harness;
83mod report;
84mod result;
85mod runner;
86
87pub use config::BenchRunnerConfig;
88pub use context::StressContext;
89/// Backwards compatibility alias
90#[doc(hidden)]
91#[deprecated(since = "0.2.0", note = "Use StressContext instead")]
92pub type BenchContext = StressContext;
93pub use report::{ConsoleReporter, JsonReporter, MultiReporter, Reporter};
94pub use result::{BenchResult, SuiteResult};
95pub use runner::BenchRunner;
96
97// Harness exports for auto-discovery
98pub use harness::{benchmark_count, list_benchmarks};
99pub use harness::{run_registered_benchmarks, run_with_options, StressRunnerOptions};
100
101// Entry point for stress binaries (called by stress_main! macro)
102pub use harness::stress_binary_main;
103
104// Re-export the proc macro
105pub use cntryl_stress_macros::{stress_main, stress_test};
106
107/// Private module for macro internals - do not use directly.
108#[doc(hidden)]
109pub mod __private {
110    pub use crate::harness::{linkme, BenchmarkEntry, STRESS_BENCHMARKS};
111}
112
113/// Prelude module for convenient imports.
114///
115/// ```rust,ignore
116/// use cntryl_stress::prelude::*;
117/// ```
118pub mod prelude {
119    pub use crate::{
120        stress_main, stress_test, BenchResult, BenchRunner, BenchRunnerConfig, StressContext,
121        StressRunnerOptions,
122    };
123}