mockforge_test/
config.rs

1//! Configuration for MockForge test servers
2
3use std::path::PathBuf;
4use std::time::Duration;
5
6/// Configuration for a MockForge test server
7#[derive(Debug, Clone)]
8pub struct ServerConfig {
9    /// HTTP server port (default: auto-assigned)
10    pub http_port: u16,
11
12    /// WebSocket server port (optional)
13    pub ws_port: Option<u16>,
14
15    /// gRPC server port (optional)
16    pub grpc_port: Option<u16>,
17
18    /// Admin UI port (optional)
19    pub admin_port: Option<u16>,
20
21    /// Metrics/Prometheus port (optional)
22    pub metrics_port: Option<u16>,
23
24    /// Path to OpenAPI specification file (optional)
25    pub spec_file: Option<PathBuf>,
26
27    /// Path to workspace directory (optional)
28    pub workspace_dir: Option<PathBuf>,
29
30    /// Profile name for configuration (optional)
31    pub profile: Option<String>,
32
33    /// Enable admin UI (default: false)
34    pub enable_admin: bool,
35
36    /// Enable metrics endpoint (default: false)
37    pub enable_metrics: bool,
38
39    /// Additional CLI arguments
40    pub extra_args: Vec<String>,
41
42    /// Health check timeout (default: 30 seconds)
43    pub health_timeout: Duration,
44
45    /// Health check interval (default: 100ms)
46    pub health_interval: Duration,
47
48    /// Working directory for the server process (optional)
49    pub working_dir: Option<PathBuf>,
50
51    /// Environment variables for the server process
52    pub env_vars: Vec<(String, String)>,
53
54    /// Path to mockforge binary (optional, will search PATH if not provided)
55    pub binary_path: Option<PathBuf>,
56}
57
58impl Default for ServerConfig {
59    fn default() -> Self {
60        Self {
61            http_port: 0, // 0 means auto-assign
62            ws_port: None,
63            grpc_port: None,
64            admin_port: None,
65            metrics_port: None,
66            spec_file: None,
67            workspace_dir: None,
68            profile: None,
69            enable_admin: false,
70            enable_metrics: false,
71            extra_args: Vec::new(),
72            health_timeout: Duration::from_secs(30),
73            health_interval: Duration::from_millis(100),
74            working_dir: None,
75            env_vars: Vec::new(),
76            binary_path: None,
77        }
78    }
79}
80
81impl ServerConfig {
82    /// Create a new builder for ServerConfig
83    pub fn builder() -> ServerConfigBuilder {
84        ServerConfigBuilder::default()
85    }
86}
87
88/// Builder for ServerConfig
89#[derive(Debug, Default)]
90pub struct ServerConfigBuilder {
91    config: ServerConfig,
92}
93
94impl ServerConfigBuilder {
95    /// Set HTTP port (0 for auto-assign)
96    pub fn http_port(mut self, port: u16) -> Self {
97        self.config.http_port = port;
98        self
99    }
100
101    /// Set WebSocket port
102    pub fn ws_port(mut self, port: u16) -> Self {
103        self.config.ws_port = Some(port);
104        self
105    }
106
107    /// Set gRPC port
108    pub fn grpc_port(mut self, port: u16) -> Self {
109        self.config.grpc_port = Some(port);
110        self
111    }
112
113    /// Set admin UI port
114    pub fn admin_port(mut self, port: u16) -> Self {
115        self.config.admin_port = Some(port);
116        self
117    }
118
119    /// Set metrics port
120    pub fn metrics_port(mut self, port: u16) -> Self {
121        self.config.metrics_port = Some(port);
122        self
123    }
124
125    /// Set OpenAPI specification file
126    pub fn spec_file<P: Into<PathBuf>>(mut self, path: P) -> Self {
127        self.config.spec_file = Some(path.into());
128        self
129    }
130
131    /// Set workspace directory
132    pub fn workspace_dir<P: Into<PathBuf>>(mut self, path: P) -> Self {
133        self.config.workspace_dir = Some(path.into());
134        self
135    }
136
137    /// Set profile name
138    pub fn profile<S: Into<String>>(mut self, profile: S) -> Self {
139        self.config.profile = Some(profile.into());
140        self
141    }
142
143    /// Enable admin UI
144    pub fn enable_admin(mut self, enable: bool) -> Self {
145        self.config.enable_admin = enable;
146        self
147    }
148
149    /// Enable metrics endpoint
150    pub fn enable_metrics(mut self, enable: bool) -> Self {
151        self.config.enable_metrics = enable;
152        self
153    }
154
155    /// Add extra CLI argument
156    pub fn extra_arg<S: Into<String>>(mut self, arg: S) -> Self {
157        self.config.extra_args.push(arg.into());
158        self
159    }
160
161    /// Add multiple extra CLI arguments
162    pub fn extra_args<I, S>(mut self, args: I) -> Self
163    where
164        I: IntoIterator<Item = S>,
165        S: Into<String>,
166    {
167        self.config.extra_args.extend(args.into_iter().map(Into::into));
168        self
169    }
170
171    /// Set health check timeout
172    pub fn health_timeout(mut self, timeout: Duration) -> Self {
173        self.config.health_timeout = timeout;
174        self
175    }
176
177    /// Set health check interval
178    pub fn health_interval(mut self, interval: Duration) -> Self {
179        self.config.health_interval = interval;
180        self
181    }
182
183    /// Set working directory
184    pub fn working_dir<P: Into<PathBuf>>(mut self, path: P) -> Self {
185        self.config.working_dir = Some(path.into());
186        self
187    }
188
189    /// Add environment variable
190    pub fn env_var<K, V>(mut self, key: K, value: V) -> Self
191    where
192        K: Into<String>,
193        V: Into<String>,
194    {
195        self.config.env_vars.push((key.into(), value.into()));
196        self
197    }
198
199    /// Set path to mockforge binary
200    pub fn binary_path<P: Into<PathBuf>>(mut self, path: P) -> Self {
201        self.config.binary_path = Some(path.into());
202        self
203    }
204
205    /// Build the ServerConfig
206    pub fn build(self) -> ServerConfig {
207        self.config
208    }
209}
210
211#[cfg(test)]
212mod tests {
213    use super::*;
214
215    #[test]
216    fn test_default_config() {
217        let config = ServerConfig::default();
218        assert_eq!(config.http_port, 0);
219        assert!(config.ws_port.is_none());
220        assert!(!config.enable_admin);
221    }
222
223    #[test]
224    fn test_builder() {
225        let config = ServerConfig::builder()
226            .http_port(3000)
227            .ws_port(3001)
228            .grpc_port(3002)
229            .admin_port(3003)
230            .enable_admin(true)
231            .enable_metrics(true)
232            .profile("test")
233            .extra_arg("--verbose")
234            .build();
235
236        assert_eq!(config.http_port, 3000);
237        assert_eq!(config.ws_port, Some(3001));
238        assert_eq!(config.grpc_port, Some(3002));
239        assert_eq!(config.admin_port, Some(3003));
240        assert!(config.enable_admin);
241        assert!(config.enable_metrics);
242        assert_eq!(config.profile, Some("test".to_string()));
243        assert_eq!(config.extra_args, vec!["--verbose"]);
244    }
245}