|
10 | 10 | use std::{ |
11 | 11 | io::Write, |
12 | 12 | process::{Command, Output, Stdio}, |
| 13 | + thread, |
| 14 | + time::Duration, |
13 | 15 | }; |
14 | 16 |
|
15 | 17 | use sysinfo::System; |
@@ -43,15 +45,33 @@ fn run_test_base(cmd: &str, args: &Vec<String>, stdin_data: &[u8]) -> (Output, i |
43 | 45 | .stdout(Stdio::piped()) |
44 | 46 | .stderr(Stdio::piped()) |
45 | 47 | .spawn() |
46 | | - .expect("failed to spawn head"); |
| 48 | + .expect(format!("failed to spawn command {}", cmd).as_str()); |
47 | 49 |
|
48 | 50 | let pgid = unsafe { libc::getpgid(child.id() as i32) }; |
49 | 51 |
|
50 | | - let stdin = child.stdin.as_mut().expect("failed to get stdin"); |
51 | | - stdin |
52 | | - .write_all(stdin_data) |
53 | | - .expect("failed to write to stdin"); |
| 52 | + // Separate the mutable borrow of stdin from the child process |
| 53 | + if let Some(mut stdin) = child.stdin.take() { |
| 54 | + let chunk_size = 1024; // Arbitrary chunk size, adjust if needed |
| 55 | + for chunk in stdin_data.chunks(chunk_size) { |
| 56 | + // Write each chunk |
| 57 | + if let Err(e) = stdin.write_all(chunk) { |
| 58 | + eprintln!("Error writing to stdin: {}", e); |
| 59 | + break; |
| 60 | + } |
| 61 | + // Flush after writing each chunk |
| 62 | + if let Err(e) = stdin.flush() { |
| 63 | + eprintln!("Error flushing stdin: {}", e); |
| 64 | + break; |
| 65 | + } |
| 66 | + |
| 67 | + // Sleep briefly to avoid CPU spinning |
| 68 | + thread::sleep(Duration::from_millis(10)); |
| 69 | + } |
| 70 | + // Explicitly drop stdin to close the pipe |
| 71 | + drop(stdin); |
| 72 | + } |
54 | 73 |
|
| 74 | + // Ensure we wait for the process to complete after writing to stdin |
55 | 75 | let output = child.wait_with_output().expect("failed to wait for child"); |
56 | 76 | (output, pgid) |
57 | 77 | } |
@@ -113,6 +133,7 @@ fn timeout_test_extended( |
113 | 133 | const TRUE: &'static str = "true"; |
114 | 134 | const SLEEP: &'static str = "sleep"; |
115 | 135 | const NON_EXECUTABLE: &'static str = "tests/timeout/non_executable.sh"; |
| 136 | +const WITH_ARGUMENT: &'static str = "tests/timeout/with_argument.sh"; |
116 | 137 | const SPAWN_CHILD: &'static str = "tests/timeout/spawn_child.sh"; |
117 | 138 |
|
118 | 139 | #[test] |
@@ -235,13 +256,7 @@ fn test_utility_not_found() { |
235 | 256 |
|
236 | 257 | #[test] |
237 | 258 | fn test_utility_error() { |
238 | | - let message: String = if cfg!(target_os = "macos") { |
239 | | - String::from("usage: sleep seconds\n") |
240 | | - } else { |
241 | | - String::from("/usr/bin/sleep: invalid time interval ‘invalid_value’\nTry '/usr/bin/sleep --help' for more information.\n") |
242 | | - }; |
243 | | - |
244 | | - timeout_test(&["1", SLEEP, "invalid_value"], &message, 1); |
| 259 | + timeout_test(&["1", WITH_ARGUMENT], "error: enter some argument\n", 1); |
245 | 260 | } |
246 | 261 |
|
247 | 262 | #[test] |
|
0 commit comments