Skip to main content

agent_engine/tools/shell/
config.rs

1//! Shell session configuration — re-exported from `core::shell_config`.
2//! All existing paths (`tools::shell::config::ShellConfig`) remain valid.
3
4pub use crate::core::shell_config::ShellConfig;
5
6#[cfg(test)]
7mod tests {
8    use super::*;
9    use crate::core::config::load_config;
10    use serial_test::serial;
11    use std::time::Duration;
12
13    #[test]
14    fn test_shell_config_default() {
15        let config = ShellConfig::default();
16        assert_eq!(config.max_sessions, 5);
17        assert_eq!(config.idle_timeout, Duration::from_secs(600));
18        assert_eq!(config.readiness_timeout_ms, 300);
19        assert_eq!(config.max_readiness_timeout_ms, 10_000);
20        assert_eq!(config.default_rows, 24);
21        assert_eq!(config.default_cols, 80);
22        assert_eq!(config.prompt_patterns.len(), 19);
23    }
24
25    #[test]
26    // Keyed to the same lock as every other HOME/SYNAPS_BASE_DIR mutator:
27    // unkeyed `#[serial]` and `#[serial(synaps_base_dir)]` do NOT exclude
28    // each other, which produced cross-test races on base-dir resolution.
29    #[serial(synaps_base_dir)]
30    fn test_shell_config_from_file() {
31        // These tests must run sequentially since they mutate HOME env var.
32        // Combined into one test to avoid parallel races.
33
34        // --- Subtest 1: Full config parsing ---
35        {
36            let test_dir = std::path::PathBuf::from("/tmp/synaps-shell-test-1/.synaps-cli");
37            let _ = std::fs::create_dir_all(&test_dir);
38            let config_path = test_dir.join("config");
39
40            let config_content = "shell.max_sessions = 10\nshell.idle_timeout = 1200\nshell.readiness_timeout_ms = 500\nshell.max_readiness_timeout_ms = 20000\nshell.default_rows = 30\nshell.default_cols = 120\n";
41            std::fs::write(&config_path, config_content).unwrap();
42
43            let original_home = std::env::var("HOME").ok();
44            let original_base_dir = std::env::var("SYNAPS_BASE_DIR").ok();
45            std::env::remove_var("SYNAPS_BASE_DIR");
46            std::env::set_var("HOME", "/tmp/synaps-shell-test-1");
47            let config = load_config();
48            if let Some(home) = original_home {
49                std::env::set_var("HOME", home);
50            }
51            if let Some(base_dir) = original_base_dir {
52                std::env::set_var("SYNAPS_BASE_DIR", base_dir);
53            }
54            let _ = std::fs::remove_dir_all("/tmp/synaps-shell-test-1");
55
56            assert_eq!(config.shell.max_sessions, 10);
57            assert_eq!(config.shell.idle_timeout, Duration::from_secs(1200));
58            assert_eq!(config.shell.readiness_timeout_ms, 500);
59            assert_eq!(config.shell.max_readiness_timeout_ms, 20000);
60            assert_eq!(config.shell.default_rows, 30);
61            assert_eq!(config.shell.default_cols, 120);
62        }
63
64        // --- Subtest 2: Partial config — missing keys use defaults ---
65        {
66            let test_dir = std::path::PathBuf::from("/tmp/synaps-shell-test-2/.synaps-cli");
67            let _ = std::fs::create_dir_all(&test_dir);
68            let config_path = test_dir.join("config");
69
70            let config_content = "shell.max_sessions = 3\nshell.default_rows = 40\n";
71            std::fs::write(&config_path, config_content).unwrap();
72
73            let original_home = std::env::var("HOME").ok();
74            let original_base_dir = std::env::var("SYNAPS_BASE_DIR").ok();
75            std::env::remove_var("SYNAPS_BASE_DIR");
76            std::env::set_var("HOME", "/tmp/synaps-shell-test-2");
77            let config = load_config();
78            if let Some(home) = original_home {
79                std::env::set_var("HOME", home);
80            }
81            if let Some(base_dir) = original_base_dir {
82                std::env::set_var("SYNAPS_BASE_DIR", base_dir);
83            }
84            let _ = std::fs::remove_dir_all("/tmp/synaps-shell-test-2");
85
86            assert_eq!(config.shell.max_sessions, 3);
87            assert_eq!(config.shell.default_rows, 40);
88            assert_eq!(config.shell.idle_timeout, Duration::from_secs(600));
89            assert_eq!(config.shell.readiness_timeout_ms, 300);
90        }
91
92        // --- Subtest 3: Invalid values → defaults ---
93        {
94            let test_dir = std::path::PathBuf::from("/tmp/synaps-shell-test-3/.synaps-cli");
95            let _ = std::fs::create_dir_all(&test_dir);
96            let config_path = test_dir.join("config");
97
98            let config_content =
99                "shell.max_sessions = not_a_number\nshell.idle_timeout = invalid\n";
100            std::fs::write(&config_path, config_content).unwrap();
101
102            let original_home = std::env::var("HOME").ok();
103            let original_base_dir = std::env::var("SYNAPS_BASE_DIR").ok();
104            std::env::remove_var("SYNAPS_BASE_DIR");
105            std::env::set_var("HOME", "/tmp/synaps-shell-test-3");
106            let config = load_config();
107            if let Some(home) = original_home {
108                std::env::set_var("HOME", home);
109            }
110            if let Some(base_dir) = original_base_dir {
111                std::env::set_var("SYNAPS_BASE_DIR", base_dir);
112            }
113            let _ = std::fs::remove_dir_all("/tmp/synaps-shell-test-3");
114
115            assert_eq!(config.shell.max_sessions, 5);
116            assert_eq!(config.shell.idle_timeout, Duration::from_secs(600));
117        }
118    }
119}