clankers_testing/
context.rs1use std::path::PathBuf;
2
3use clankers_core::{LatencyStats, RobotResult};
4use clankers_data::{Replay, ReplayResult};
5
6pub struct ReplayContext {
8 pub mcap_path: PathBuf,
9 pub deterministic: bool,
10}
11
12#[derive(Debug, Clone)]
13pub struct ReplayTestResult {
14 pub replay: ReplayResult,
15 pub panics: u32,
16 pub topics_seen: Vec<String>,
17}
18
19impl ReplayContext {
20 pub fn new(mcap_path: impl Into<PathBuf>) -> Self {
21 Self {
22 mcap_path: mcap_path.into(),
23 deterministic: true,
24 }
25 }
26
27 pub async fn run_replay<F, Fut>(&self, mut handler: F) -> RobotResult<ReplayTestResult>
28 where
29 F: FnMut(clankers_data::McapRecord) -> Fut,
30 Fut: std::future::Future<Output = RobotResult<()>>,
31 {
32 let replay = Replay::from_mcap(&self.mcap_path)?;
33 let mut topics_seen = std::collections::HashSet::new();
34
35 let result = replay
36 .run(|msg| {
37 topics_seen.insert(msg.topic.clone());
38 handler(msg)
39 })
40 .await?;
41
42 let mut topics: Vec<_> = topics_seen.into_iter().collect();
43 topics.sort();
44
45 Ok(ReplayTestResult {
46 replay: result,
47 panics: 0,
48 topics_seen: topics,
49 })
50 }
51
52 pub fn latency(&self) -> &LatencyStats {
53 unimplemented!("call result.replay.latency after run_replay")
55 }
56}