Skip to content

Commit bf2c50d

Browse files
Alonely0naoNao89
andcommitted
chore(timeout): Add and reinforce tests
Now tests time out, so we can track regressions in timeout. Also added one to track nested timeouts. Co-authored-by: naoNao89 <[email protected]>
1 parent 6958c54 commit bf2c50d

File tree

1 file changed

+53
-6
lines changed

1 file changed

+53
-6
lines changed

tests/by-util/test_timeout.rs

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use std::time::Duration;
1+
use std::time::{Duration, Instant};
2+
use uutests::util::TestScenario;
23

34
// This file is part of the uutils coreutils package.
45
//
@@ -52,11 +53,13 @@ fn test_command_with_args() {
5253
fn test_verbose() {
5354
for verbose_flag in ["-v", "--verbose"] {
5455
new_ucmd!()
55-
.args(&[verbose_flag, ".1", "sleep", "1"])
56+
.args(&[verbose_flag, ".1", "sleep", "10"])
57+
.timeout(Duration::from_secs(1))
5658
.fails()
5759
.stderr_only("timeout: sending signal TERM to command 'sleep'\n");
5860
new_ucmd!()
59-
.args(&[verbose_flag, "-s0", "-k.1", ".1", "sleep", "1"])
61+
.args(&[verbose_flag, "-s0", "-k.1", ".1", "sleep", "10"])
62+
.timeout(Duration::from_secs(1))
6063
.fails()
6164
.stderr_only("timeout: sending signal EXIT to command 'sleep'\ntimeout: sending signal KILL to command 'sleep'\n");
6265
}
@@ -107,22 +110,26 @@ fn test_preserve_status() {
107110
fn test_preserve_status_even_when_send_signal() {
108111
// When sending CONT signal, process doesn't get killed or stopped.
109112
// So, expected result is success and code 0.
113+
let time = Instant::now();
110114
for cont_spelling in ["CONT", "cOnT", "SIGcont"] {
111115
new_ucmd!()
112-
.args(&["-s", cont_spelling, "--preserve-status", ".1", "sleep", "1"])
116+
.args(&["-s", cont_spelling, "--preserve-status", ".1", "sleep", "2"])
113117
.succeeds()
114118
.no_output();
115119
}
120+
assert!(time.elapsed().as_secs() >= 6) // Assert they run for one second each.
116121
}
117122

118123
#[test]
119124
fn test_dont_overflow() {
120125
new_ucmd!()
121126
.args(&["9223372036854775808d", "sleep", "0"])
127+
.timeout(Duration::from_secs(2))
122128
.succeeds()
123129
.no_output();
124130
new_ucmd!()
125131
.args(&["-k", "9223372036854775808d", "10", "sleep", "0"])
132+
.timeout(Duration::from_secs(2))
126133
.succeeds()
127134
.no_output();
128135
}
@@ -183,11 +190,12 @@ fn test_kill_subprocess() {
183190
new_ucmd!()
184191
.args(&[
185192
// Make sure the CI can spawn the subprocess.
186-
"1",
193+
"5",
187194
"sh",
188195
"-c",
189-
"trap 'echo inside_trap' TERM; sleep 5",
196+
"trap 'echo inside_trap' TERM; sleep 30",
190197
])
198+
.timeout(Duration::from_secs(6)) // assert it exits when it times out.
191199
.fails_with_code(124)
192200
.stdout_contains("inside_trap");
193201
}
@@ -243,3 +251,42 @@ fn test_command_cannot_invoke() {
243251
// Try to execute a directory (should give permission denied or similar)
244252
new_ucmd!().args(&["1", "/"]).fails_with_code(126);
245253
}
254+
255+
fn test_cascaded_timeout_with_bash_trap() {
256+
// Use bash if available, otherwise skip
257+
if std::process::Command::new("bash")
258+
.arg("--version")
259+
.output()
260+
.is_err()
261+
{
262+
// Skip test if bash is not available
263+
return;
264+
}
265+
266+
// Test with bash explicitly to ensure SIGINT handlers work
267+
let script = r"
268+
trap 'echo bash_trap_fired; exit 0' INT
269+
sleep 10
270+
";
271+
272+
let ts = TestScenario::new("timeout");
273+
let timeout_bin = ts.bin_path.to_str().unwrap();
274+
275+
ts.ucmd()
276+
.args(&[
277+
"-s",
278+
"ALRM",
279+
"0.3",
280+
timeout_bin,
281+
"timeout",
282+
"-s",
283+
"INT",
284+
"5",
285+
"bash",
286+
"-c",
287+
script,
288+
])
289+
.timeout(Duration::from_secs(6))
290+
.fails_with_code(124)
291+
.stdout_contains("bash_trap_fired");
292+
}

0 commit comments

Comments
 (0)