cu_profiler_core/backend/
recorded.rs1use std::collections::HashMap;
8
9use crate::Result;
10use crate::backend::{ExecutionBackend, SimulationOutput};
11use crate::error::Error;
12use crate::metadata::BackendKind;
13use crate::scenario::Scenario;
14
15#[derive(Debug, Default, Clone)]
17pub struct RecordedLogsBackend {
18 by_scenario: HashMap<String, SimulationOutput>,
19}
20
21impl RecordedLogsBackend {
22 #[must_use]
24 pub fn new() -> Self {
25 Self::default()
26 }
27
28 pub fn insert(&mut self, scenario: impl Into<String>, logs: Vec<String>, success: bool) {
30 self.by_scenario
31 .insert(scenario.into(), SimulationOutput { logs, success });
32 }
33
34 pub fn insert_blob(&mut self, scenario: impl Into<String>, blob: &str, success: bool) {
36 let logs = blob.lines().map(str::to_string).collect();
37 self.insert(scenario, logs, success);
38 }
39}
40
41impl ExecutionBackend for RecordedLogsBackend {
42 fn kind(&self) -> BackendKind {
43 BackendKind::Recorded
44 }
45
46 fn is_deterministic(&self) -> bool {
48 true
49 }
50
51 fn run(&self, scenario: &Scenario) -> Result<SimulationOutput> {
52 self.by_scenario
53 .get(&scenario.name)
54 .cloned()
55 .ok_or_else(|| {
56 Error::Simulation(format!(
57 "no recorded logs registered for scenario `{}`",
58 scenario.name
59 ))
60 })
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67
68 #[test]
69 fn replays_registered_logs() {
70 let mut backend = RecordedLogsBackend::new();
71 backend.insert_blob("swap", "Program X invoke [1]\nProgram X success", true);
72 let out = backend.run(&Scenario::new("swap")).unwrap();
73 assert_eq!(out.logs.len(), 2);
74 assert!(out.success);
75 }
76
77 #[test]
78 fn missing_scenario_errors_clearly() {
79 let backend = RecordedLogsBackend::new();
80 let err = backend.run(&Scenario::new("nope")).unwrap_err();
81 assert!(err.to_string().contains("no recorded logs"));
82 }
83}