aboutsummaryrefslogtreecommitdiff
path: root/tests/cli.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/cli.rs')
-rw-r--r--tests/cli.rs105
1 files changed, 61 insertions, 44 deletions
diff --git a/tests/cli.rs b/tests/cli.rs
index 37398e6..e99e876 100644
--- a/tests/cli.rs
+++ b/tests/cli.rs
@@ -32,7 +32,7 @@ fn test_version_output() {
32#[test] 32#[test]
33fn test_run_missing_command() { 33fn test_run_missing_command() {
34 let temp_dir = TempDir::new().unwrap(); 34 let temp_dir = TempDir::new().unwrap();
35 35
36 let mut cmd = Command::cargo_bin("demon").unwrap(); 36 let mut cmd = Command::cargo_bin("demon").unwrap();
37 cmd.current_dir(temp_dir.path()) 37 cmd.current_dir(temp_dir.path())
38 .args(&["run", "--id", "test"]) 38 .args(&["run", "--id", "test"])
@@ -44,19 +44,19 @@ fn test_run_missing_command() {
44#[test] 44#[test]
45fn test_run_creates_files() { 45fn test_run_creates_files() {
46 let temp_dir = TempDir::new().unwrap(); 46 let temp_dir = TempDir::new().unwrap();
47 47
48 let mut cmd = Command::cargo_bin("demon").unwrap(); 48 let mut cmd = Command::cargo_bin("demon").unwrap();
49 cmd.current_dir(temp_dir.path()) 49 cmd.current_dir(temp_dir.path())
50 .args(&["run", "--id", "test", "echo", "hello"]) 50 .args(&["run", "--id", "test", "echo", "hello"])
51 .assert() 51 .assert()
52 .success() 52 .success()
53 .stdout(predicate::str::contains("Started daemon 'test'")); 53 .stdout(predicate::str::contains("Started daemon 'test'"));
54 54
55 // Verify files were created 55 // Verify files were created
56 assert!(temp_dir.path().join("test.pid").exists()); 56 assert!(temp_dir.path().join("test.pid").exists());
57 assert!(temp_dir.path().join("test.stdout").exists()); 57 assert!(temp_dir.path().join("test.stdout").exists());
58 assert!(temp_dir.path().join("test.stderr").exists()); 58 assert!(temp_dir.path().join("test.stderr").exists());
59 59
60 // Check that stdout contains our output 60 // Check that stdout contains our output
61 let stdout_content = fs::read_to_string(temp_dir.path().join("test.stdout")).unwrap(); 61 let stdout_content = fs::read_to_string(temp_dir.path().join("test.stdout")).unwrap();
62 assert_eq!(stdout_content.trim(), "hello"); 62 assert_eq!(stdout_content.trim(), "hello");
@@ -65,14 +65,14 @@ fn test_run_creates_files() {
65#[test] 65#[test]
66fn test_run_duplicate_process() { 66fn test_run_duplicate_process() {
67 let temp_dir = TempDir::new().unwrap(); 67 let temp_dir = TempDir::new().unwrap();
68 68
69 // Start a long-running process 69 // Start a long-running process
70 let mut cmd = Command::cargo_bin("demon").unwrap(); 70 let mut cmd = Command::cargo_bin("demon").unwrap();
71 cmd.current_dir(temp_dir.path()) 71 cmd.current_dir(temp_dir.path())
72 .args(&["run", "--id", "long", "sleep", "30"]) 72 .args(&["run", "--id", "long", "sleep", "30"])
73 .assert() 73 .assert()
74 .success(); 74 .success();
75 75
76 // Try to start another with the same ID 76 // Try to start another with the same ID
77 let mut cmd = Command::cargo_bin("demon").unwrap(); 77 let mut cmd = Command::cargo_bin("demon").unwrap();
78 cmd.current_dir(temp_dir.path()) 78 cmd.current_dir(temp_dir.path())
@@ -80,7 +80,7 @@ fn test_run_duplicate_process() {
80 .assert() 80 .assert()
81 .failure() 81 .failure()
82 .stderr(predicate::str::contains("already running")); 82 .stderr(predicate::str::contains("already running"));
83 83
84 // Clean up the running process 84 // Clean up the running process
85 let mut cmd = Command::cargo_bin("demon").unwrap(); 85 let mut cmd = Command::cargo_bin("demon").unwrap();
86 cmd.current_dir(temp_dir.path()) 86 cmd.current_dir(temp_dir.path())
@@ -92,7 +92,7 @@ fn test_run_duplicate_process() {
92#[test] 92#[test]
93fn test_list_empty() { 93fn test_list_empty() {
94 let temp_dir = TempDir::new().unwrap(); 94 let temp_dir = TempDir::new().unwrap();
95 95
96 let mut cmd = Command::cargo_bin("demon").unwrap(); 96 let mut cmd = Command::cargo_bin("demon").unwrap();
97 cmd.current_dir(temp_dir.path()) 97 cmd.current_dir(temp_dir.path())
98 .args(&["list"]) 98 .args(&["list"])
@@ -107,14 +107,14 @@ fn test_list_empty() {
107#[test] 107#[test]
108fn test_list_with_processes() { 108fn test_list_with_processes() {
109 let temp_dir = TempDir::new().unwrap(); 109 let temp_dir = TempDir::new().unwrap();
110 110
111 // Start a process 111 // Start a process
112 let mut cmd = Command::cargo_bin("demon").unwrap(); 112 let mut cmd = Command::cargo_bin("demon").unwrap();
113 cmd.current_dir(temp_dir.path()) 113 cmd.current_dir(temp_dir.path())
114 .args(&["run", "--id", "test", "echo", "done"]) 114 .args(&["run", "--id", "test", "echo", "done"])
115 .assert() 115 .assert()
116 .success(); 116 .success();
117 117
118 // List processes 118 // List processes
119 let mut cmd = Command::cargo_bin("demon").unwrap(); 119 let mut cmd = Command::cargo_bin("demon").unwrap();
120 cmd.current_dir(temp_dir.path()) 120 cmd.current_dir(temp_dir.path())
@@ -128,17 +128,22 @@ fn test_list_with_processes() {
128#[test] 128#[test]
129fn test_cat_output() { 129fn test_cat_output() {
130 let temp_dir = TempDir::new().unwrap(); 130 let temp_dir = TempDir::new().unwrap();
131 131
132 // Create a process with output 132 // Create a process with output
133 let mut cmd = Command::cargo_bin("demon").unwrap(); 133 let mut cmd = Command::cargo_bin("demon").unwrap();
134 cmd.current_dir(temp_dir.path()) 134 cmd.current_dir(temp_dir.path())
135 .args(&[ 135 .args(&[
136 "run", "--id", "test", "--", 136 "run",
137 "sh", "-c", "echo 'stdout line'; echo 'stderr line' >&2" 137 "--id",
138 "test",
139 "--",
140 "sh",
141 "-c",
142 "echo 'stdout line'; echo 'stderr line' >&2",
138 ]) 143 ])
139 .assert() 144 .assert()
140 .success(); 145 .success();
141 146
142 // Cat the output 147 // Cat the output
143 let mut cmd = Command::cargo_bin("demon").unwrap(); 148 let mut cmd = Command::cargo_bin("demon").unwrap();
144 cmd.current_dir(temp_dir.path()) 149 cmd.current_dir(temp_dir.path())
@@ -152,17 +157,22 @@ fn test_cat_output() {
152#[test] 157#[test]
153fn test_cat_stdout_only() { 158fn test_cat_stdout_only() {
154 let temp_dir = TempDir::new().unwrap(); 159 let temp_dir = TempDir::new().unwrap();
155 160
156 // Create a process with output 161 // Create a process with output
157 let mut cmd = Command::cargo_bin("demon").unwrap(); 162 let mut cmd = Command::cargo_bin("demon").unwrap();
158 cmd.current_dir(temp_dir.path()) 163 cmd.current_dir(temp_dir.path())
159 .args(&[ 164 .args(&[
160 "run", "--id", "test", "--", 165 "run",
161 "sh", "-c", "echo 'stdout line'; echo 'stderr line' >&2" 166 "--id",
167 "test",
168 "--",
169 "sh",
170 "-c",
171 "echo 'stdout line'; echo 'stderr line' >&2",
162 ]) 172 ])
163 .assert() 173 .assert()
164 .success(); 174 .success();
165 175
166 // Cat only stdout 176 // Cat only stdout
167 let mut cmd = Command::cargo_bin("demon").unwrap(); 177 let mut cmd = Command::cargo_bin("demon").unwrap();
168 cmd.current_dir(temp_dir.path()) 178 cmd.current_dir(temp_dir.path())
@@ -176,7 +186,7 @@ fn test_cat_stdout_only() {
176#[test] 186#[test]
177fn test_status_nonexistent() { 187fn test_status_nonexistent() {
178 let temp_dir = TempDir::new().unwrap(); 188 let temp_dir = TempDir::new().unwrap();
179 189
180 let mut cmd = Command::cargo_bin("demon").unwrap(); 190 let mut cmd = Command::cargo_bin("demon").unwrap();
181 cmd.current_dir(temp_dir.path()) 191 cmd.current_dir(temp_dir.path())
182 .args(&["status", "--id", "nonexistent"]) 192 .args(&["status", "--id", "nonexistent"])
@@ -188,14 +198,14 @@ fn test_status_nonexistent() {
188#[test] 198#[test]
189fn test_status_dead_process() { 199fn test_status_dead_process() {
190 let temp_dir = TempDir::new().unwrap(); 200 let temp_dir = TempDir::new().unwrap();
191 201
192 // Create a short-lived process 202 // Create a short-lived process
193 let mut cmd = Command::cargo_bin("demon").unwrap(); 203 let mut cmd = Command::cargo_bin("demon").unwrap();
194 cmd.current_dir(temp_dir.path()) 204 cmd.current_dir(temp_dir.path())
195 .args(&["run", "--id", "dead", "echo", "hello"]) 205 .args(&["run", "--id", "dead", "echo", "hello"])
196 .assert() 206 .assert()
197 .success(); 207 .success();
198 208
199 // Check its status (should be dead) 209 // Check its status (should be dead)
200 let mut cmd = Command::cargo_bin("demon").unwrap(); 210 let mut cmd = Command::cargo_bin("demon").unwrap();
201 cmd.current_dir(temp_dir.path()) 211 cmd.current_dir(temp_dir.path())
@@ -208,7 +218,7 @@ fn test_status_dead_process() {
208#[test] 218#[test]
209fn test_stop_nonexistent() { 219fn test_stop_nonexistent() {
210 let temp_dir = TempDir::new().unwrap(); 220 let temp_dir = TempDir::new().unwrap();
211 221
212 let mut cmd = Command::cargo_bin("demon").unwrap(); 222 let mut cmd = Command::cargo_bin("demon").unwrap();
213 cmd.current_dir(temp_dir.path()) 223 cmd.current_dir(temp_dir.path())
214 .args(&["stop", "--id", "nonexistent"]) 224 .args(&["stop", "--id", "nonexistent"])
@@ -220,14 +230,14 @@ fn test_stop_nonexistent() {
220#[test] 230#[test]
221fn test_stop_process() { 231fn test_stop_process() {
222 let temp_dir = TempDir::new().unwrap(); 232 let temp_dir = TempDir::new().unwrap();
223 233
224 // Start a long-running process 234 // Start a long-running process
225 let mut cmd = Command::cargo_bin("demon").unwrap(); 235 let mut cmd = Command::cargo_bin("demon").unwrap();
226 cmd.current_dir(temp_dir.path()) 236 cmd.current_dir(temp_dir.path())
227 .args(&["run", "--id", "long", "sleep", "10"]) 237 .args(&["run", "--id", "long", "sleep", "10"])
228 .assert() 238 .assert()
229 .success(); 239 .success();
230 240
231 // Stop it 241 // Stop it
232 let mut cmd = Command::cargo_bin("demon").unwrap(); 242 let mut cmd = Command::cargo_bin("demon").unwrap();
233 cmd.current_dir(temp_dir.path()) 243 cmd.current_dir(temp_dir.path())
@@ -235,7 +245,7 @@ fn test_stop_process() {
235 .assert() 245 .assert()
236 .success() 246 .success()
237 .stdout(predicate::str::contains("terminated gracefully")); 247 .stdout(predicate::str::contains("terminated gracefully"));
238 248
239 // Verify PID file is gone 249 // Verify PID file is gone
240 assert!(!temp_dir.path().join("long.pid").exists()); 250 assert!(!temp_dir.path().join("long.pid").exists());
241} 251}
@@ -243,7 +253,7 @@ fn test_stop_process() {
243#[test] 253#[test]
244fn test_clean_no_orphans() { 254fn test_clean_no_orphans() {
245 let temp_dir = TempDir::new().unwrap(); 255 let temp_dir = TempDir::new().unwrap();
246 256
247 let mut cmd = Command::cargo_bin("demon").unwrap(); 257 let mut cmd = Command::cargo_bin("demon").unwrap();
248 cmd.current_dir(temp_dir.path()) 258 cmd.current_dir(temp_dir.path())
249 .args(&["clean"]) 259 .args(&["clean"])
@@ -255,14 +265,14 @@ fn test_clean_no_orphans() {
255#[test] 265#[test]
256fn test_clean_with_orphans() { 266fn test_clean_with_orphans() {
257 let temp_dir = TempDir::new().unwrap(); 267 let temp_dir = TempDir::new().unwrap();
258 268
259 // Create a dead process 269 // Create a dead process
260 let mut cmd = Command::cargo_bin("demon").unwrap(); 270 let mut cmd = Command::cargo_bin("demon").unwrap();
261 cmd.current_dir(temp_dir.path()) 271 cmd.current_dir(temp_dir.path())
262 .args(&["run", "--id", "dead", "echo", "hello"]) 272 .args(&["run", "--id", "dead", "echo", "hello"])
263 .assert() 273 .assert()
264 .success(); 274 .success();
265 275
266 // Clean up orphaned files 276 // Clean up orphaned files
267 let mut cmd = Command::cargo_bin("demon").unwrap(); 277 let mut cmd = Command::cargo_bin("demon").unwrap();
268 cmd.current_dir(temp_dir.path()) 278 cmd.current_dir(temp_dir.path())
@@ -271,7 +281,7 @@ fn test_clean_with_orphans() {
271 .success() 281 .success()
272 .stdout(predicate::str::contains("Cleaned up")) 282 .stdout(predicate::str::contains("Cleaned up"))
273 .stdout(predicate::str::contains("orphaned")); 283 .stdout(predicate::str::contains("orphaned"));
274 284
275 // Verify files are gone 285 // Verify files are gone
276 assert!(!temp_dir.path().join("dead.pid").exists()); 286 assert!(!temp_dir.path().join("dead.pid").exists());
277 assert!(!temp_dir.path().join("dead.stdout").exists()); 287 assert!(!temp_dir.path().join("dead.stdout").exists());
@@ -281,19 +291,24 @@ fn test_clean_with_orphans() {
281#[test] 291#[test]
282fn test_run_with_complex_command() { 292fn test_run_with_complex_command() {
283 let temp_dir = TempDir::new().unwrap(); 293 let temp_dir = TempDir::new().unwrap();
284 294
285 let mut cmd = Command::cargo_bin("demon").unwrap(); 295 let mut cmd = Command::cargo_bin("demon").unwrap();
286 cmd.current_dir(temp_dir.path()) 296 cmd.current_dir(temp_dir.path())
287 .args(&[ 297 .args(&[
288 "run", "--id", "complex", "--", 298 "run",
289 "sh", "-c", "for i in 1 2 3; do echo \"line $i\"; done" 299 "--id",
300 "complex",
301 "--",
302 "sh",
303 "-c",
304 "for i in 1 2 3; do echo \"line $i\"; done",
290 ]) 305 ])
291 .assert() 306 .assert()
292 .success(); 307 .success();
293 308
294 // Give the process a moment to complete 309 // Give the process a moment to complete
295 std::thread::sleep(Duration::from_millis(100)); 310 std::thread::sleep(Duration::from_millis(100));
296 311
297 // Check the output contains all lines 312 // Check the output contains all lines
298 let stdout_content = fs::read_to_string(temp_dir.path().join("complex.stdout")).unwrap(); 313 let stdout_content = fs::read_to_string(temp_dir.path().join("complex.stdout")).unwrap();
299 assert!(stdout_content.contains("line 1")); 314 assert!(stdout_content.contains("line 1"));
@@ -304,14 +319,14 @@ fn test_run_with_complex_command() {
304#[test] 319#[test]
305fn test_timeout_configuration() { 320fn test_timeout_configuration() {
306 let temp_dir = TempDir::new().unwrap(); 321 let temp_dir = TempDir::new().unwrap();
307 322
308 // Start a process 323 // Start a process
309 let mut cmd = Command::cargo_bin("demon").unwrap(); 324 let mut cmd = Command::cargo_bin("demon").unwrap();
310 cmd.current_dir(temp_dir.path()) 325 cmd.current_dir(temp_dir.path())
311 .args(&["run", "--id", "timeout-test", "sleep", "5"]) 326 .args(&["run", "--id", "timeout-test", "sleep", "5"])
312 .assert() 327 .assert()
313 .success(); 328 .success();
314 329
315 // Stop with custom timeout (should work normally since sleep responds to SIGTERM) 330 // Stop with custom timeout (should work normally since sleep responds to SIGTERM)
316 let mut cmd = Command::cargo_bin("demon").unwrap(); 331 let mut cmd = Command::cargo_bin("demon").unwrap();
317 cmd.current_dir(temp_dir.path()) 332 cmd.current_dir(temp_dir.path())
@@ -324,10 +339,10 @@ fn test_timeout_configuration() {
324#[test] 339#[test]
325fn test_invalid_process_id() { 340fn test_invalid_process_id() {
326 let temp_dir = TempDir::new().unwrap(); 341 let temp_dir = TempDir::new().unwrap();
327 342
328 // Create an invalid PID file 343 // Create an invalid PID file
329 fs::write(temp_dir.path().join("invalid.pid"), "not-a-number").unwrap(); 344 fs::write(temp_dir.path().join("invalid.pid"), "not-a-number").unwrap();
330 345
331 // Status should handle it gracefully 346 // Status should handle it gracefully
332 let mut cmd = Command::cargo_bin("demon").unwrap(); 347 let mut cmd = Command::cargo_bin("demon").unwrap();
333 cmd.current_dir(temp_dir.path()) 348 cmd.current_dir(temp_dir.path())
@@ -335,7 +350,7 @@ fn test_invalid_process_id() {
335 .assert() 350 .assert()
336 .success() 351 .success()
337 .stdout(predicate::str::contains("ERROR")); 352 .stdout(predicate::str::contains("ERROR"));
338 353
339 // Clean should remove it 354 // Clean should remove it
340 let mut cmd = Command::cargo_bin("demon").unwrap(); 355 let mut cmd = Command::cargo_bin("demon").unwrap();
341 cmd.current_dir(temp_dir.path()) 356 cmd.current_dir(temp_dir.path())
@@ -348,7 +363,7 @@ fn test_invalid_process_id() {
348#[test] 363#[test]
349fn test_list_quiet_mode() { 364fn test_list_quiet_mode() {
350 let temp_dir = TempDir::new().unwrap(); 365 let temp_dir = TempDir::new().unwrap();
351 366
352 // Test quiet mode with no processes 367 // Test quiet mode with no processes
353 let mut cmd = Command::cargo_bin("demon").unwrap(); 368 let mut cmd = Command::cargo_bin("demon").unwrap();
354 cmd.current_dir(temp_dir.path()) 369 cmd.current_dir(temp_dir.path())
@@ -356,14 +371,14 @@ fn test_list_quiet_mode() {
356 .assert() 371 .assert()
357 .success() 372 .success()
358 .stdout(predicate::str::is_empty()); 373 .stdout(predicate::str::is_empty());
359 374
360 // Create a process 375 // Create a process
361 let mut cmd = Command::cargo_bin("demon").unwrap(); 376 let mut cmd = Command::cargo_bin("demon").unwrap();
362 cmd.current_dir(temp_dir.path()) 377 cmd.current_dir(temp_dir.path())
363 .args(&["run", "--id", "quiet-test", "echo", "done"]) 378 .args(&["run", "--id", "quiet-test", "echo", "done"])
364 .assert() 379 .assert()
365 .success(); 380 .success();
366 381
367 // Test quiet mode with process - should output colon-separated format 382 // Test quiet mode with process - should output colon-separated format
368 let mut cmd = Command::cargo_bin("demon").unwrap(); 383 let mut cmd = Command::cargo_bin("demon").unwrap();
369 cmd.current_dir(temp_dir.path()) 384 cmd.current_dir(temp_dir.path())
@@ -384,7 +399,9 @@ fn test_llm_command() {
384 cmd.args(&["llm"]) 399 cmd.args(&["llm"])
385 .assert() 400 .assert()
386 .success() 401 .success()
387 .stdout(predicate::str::contains("# Demon - Daemon Process Management CLI")) 402 .stdout(predicate::str::contains(
403 "# Demon - Daemon Process Management CLI",
404 ))
388 .stdout(predicate::str::contains("## Available Commands")) 405 .stdout(predicate::str::contains("## Available Commands"))
389 .stdout(predicate::str::contains("demon run")) 406 .stdout(predicate::str::contains("demon run"))
390 .stdout(predicate::str::contains("demon stop")) 407 .stdout(predicate::str::contains("demon stop"))
@@ -396,4 +413,4 @@ fn test_llm_command() {
396 .stdout(predicate::str::contains("Common Workflows")) 413 .stdout(predicate::str::contains("Common Workflows"))
397 .stdout(predicate::str::contains("Best Practices")) 414 .stdout(predicate::str::contains("Best Practices"))
398 .stdout(predicate::str::contains("Integration Tips")); 415 .stdout(predicate::str::contains("Integration Tips"));
399} \ No newline at end of file 416}