clankers_testing/lib.rs
1//! # Replay-based testing
2//!
3//! Run node logic against recorded MCAP fixtures and assert on topics, latency,
4//! and dropped messages.
5//!
6//! Use the [`clankers::replay_test`](https://docs.rs/clankers/latest/clankers/attr.replay_test.html)
7//! attribute macro from the facade, or call [`ReplayContext`] directly in `#[tokio::test]`:
8//!
9//! ```
10//! use std::time::Duration;
11//! use clankers_testing::{
12//! assert_max_latency, assert_no_panics, assert_topic_exists, ReplayContext,
13//! };
14//!
15//! #[tokio::test]
16//! async fn camera_log_replays_cleanly() {
17//! let ctx = ReplayContext::new("tests/fixtures/camera_log.mcap");
18//! let result = ctx.run_replay(|_msg| async { Ok(()) }).await.unwrap();
19//!
20//! assert_no_panics(&result).unwrap();
21//! assert_topic_exists(&result, "/camera/image_raw").unwrap();
22//! assert_max_latency(&result, Duration::from_secs(10)).unwrap();
23//! }
24//! ```
25//!
26//! ## Assertion helpers
27//!
28//! | Function | Checks |
29//! |----------|--------|
30//! | [`assert_topic_exists`] | A topic appeared during replay |
31//! | [`assert_no_panics`] | Handler completed without panics |
32//! | [`assert_dropped_messages`] | Drop count within budget |
33//! | [`assert_max_latency`] | p99 latency under a ceiling |
34
35pub mod assertions;
36pub mod context;
37
38pub use assertions::{
39 assert_dropped_messages, assert_max_latency, assert_no_panics, assert_topic_exists,
40};
41pub use context::{AggregatedInferenceStats, ReplayContext, ReplayTestResult};