clnrm_core/backend/
mock.rs1use crate::backend::{Backend, Cmd, RunResult};
7use crate::error::Result;
8use std::collections::HashMap;
9
10#[derive(Debug, Clone)]
13pub struct MockBackend {
14 responses: HashMap<String, MockResponse>,
16}
17
18#[derive(Debug, Clone)]
19pub struct MockResponse {
20 stdout: String,
21 stderr: String,
22 exit_code: i32,
23}
24
25impl MockBackend {
26 pub fn new() -> Self {
28 let mut responses = HashMap::new();
29
30 responses.insert(
32 "echo".to_string(),
33 MockResponse {
34 stdout: "mock echo output".to_string(),
35 stderr: "".to_string(),
36 exit_code: 0,
37 },
38 );
39
40 responses.insert(
41 "cat".to_string(),
42 MockResponse {
43 stdout: "mock file content".to_string(),
44 stderr: "".to_string(),
45 exit_code: 0,
46 },
47 );
48
49 responses.insert(
50 "test".to_string(),
51 MockResponse {
52 stdout: "".to_string(),
53 stderr: "".to_string(),
54 exit_code: 1, },
56 );
57
58 responses.insert(
59 "uname".to_string(),
60 MockResponse {
61 stdout: "Linux\n".to_string(),
62 stderr: "".to_string(),
63 exit_code: 0,
64 },
65 );
66
67 responses.insert(
68 "whoami".to_string(),
69 MockResponse {
70 stdout: "root\n".to_string(),
71 stderr: "".to_string(),
72 exit_code: 0,
73 },
74 );
75
76 responses.insert("env".to_string(), MockResponse {
77 stdout: "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\nHOSTNAME=mock-container\nHOME=/root\n".to_string(),
78 stderr: "".to_string(),
79 exit_code: 0,
80 });
81
82 responses.insert("ls".to_string(), MockResponse {
83 stdout: "bin\nboot\ndev\netc\nhome\nlib\nlib64\nmedia\nmnt\nopt\nproc\nroot\nrun\nsbin\nsrv\nsys\ntmp\nusr\nvar\n".to_string(),
84 stderr: "".to_string(),
85 exit_code: 0,
86 });
87
88 Self { responses }
89 }
90
91 pub fn add_response(mut self, command: &str, response: MockResponse) -> Self {
93 self.responses.insert(command.to_string(), response);
94 self
95 }
96
97 fn execute_mock_cmd(&self, cmd: &Cmd) -> Result<RunResult> {
99 let cmd_key = cmd.bin.clone();
100
101 if let Some(response) = self.responses.get(&cmd_key) {
103 Ok(RunResult {
104 exit_code: response.exit_code,
105 stdout: response.stdout.clone(),
106 stderr: response.stderr.clone(),
107 duration_ms: 1, steps: Vec::new(),
109 redacted_env: Vec::new(),
110 backend: "mock".to_string(),
111 concurrent: false,
112 step_order: Vec::new(),
113 })
114 } else {
115 Ok(RunResult {
117 exit_code: 0,
118 stdout: format!("mock output for: {}", cmd.bin),
119 stderr: "".to_string(),
120 duration_ms: 1,
121 steps: Vec::new(),
122 redacted_env: Vec::new(),
123 backend: "mock".to_string(),
124 concurrent: false,
125 step_order: Vec::new(),
126 })
127 }
128 }
129}
130
131impl Backend for MockBackend {
132 fn run_cmd(&self, cmd: Cmd) -> Result<RunResult> {
134 self.execute_mock_cmd(&cmd)
135 }
136
137 fn name(&self) -> &str {
139 "mock"
140 }
141
142 fn is_available(&self) -> bool {
144 true
145 }
146
147 fn supports_hermetic(&self) -> bool {
149 true
150 }
151
152 fn supports_deterministic(&self) -> bool {
154 true
155 }
156}
157
158impl Default for MockBackend {
159 fn default() -> Self {
160 Self::new()
161 }
162}