Bash · 2850 bytes Raw Blame History
1 #!/bin/sh
2 TEST_PREFIX="[int-job-control]"
3 SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
4 SHELL_BIN="${SHELL_BIN:?ERROR: SHELL_BIN must be set}"
5 export SHELL_BIN
6 . "$SCRIPT_DIR/../test_harness.sh"
7
8 # Integration tests: job control, background processes, wait, kill
9 # TTY-dependent tests are skipped when not connected to a terminal
10
11 HAS_TTY=false
12 [ -t 0 ] && HAS_TTY=true
13
14 section "1. background execution"
15 compare_output "background and wait" 'echo bg & wait; echo done'
16 compare_output "background exit status via wait" 'true & wait $!; echo $?'
17 compare_output "background false status" 'false & wait $!; echo $?'
18 # Output order of concurrent background jobs is non-deterministic — sort to normalize
19 TEST_NUM=$((TEST_NUM + 1))
20 _jc_expected=$(run_with_timeout "$TEST_TIMEOUT" "$BASH_REF" -c 'echo a & echo b & wait; echo done' 2>&1 | sort)
21 _jc_actual=$(run_with_timeout "$TEST_TIMEOUT" "$SHELL_BIN" -c 'echo a & echo b & wait; echo done' 2>&1 | sort)
22 if [ "$_jc_expected" = "$_jc_actual" ]; then pass "multiple background wait all"
23 else fail "multiple background wait all" "$_jc_expected" "$_jc_actual"; fi
24 compare_output "background dollar-bang" 'sleep 0.01 & [ -n "$!" ] && echo has_pid'
25 compare_output "background preserves parent" 'X=before; (X=after) & wait; echo $X'
26
27 section "2. wait"
28 compare_output "wait specific pid" 'sleep 0.01 & PID=$!; wait $PID; echo $?'
29 compare_output "wait captures exit" 'false & wait $!; echo $?'
30 compare_output "wait for true" 'true & wait $!; echo $?'
31 compare_output "wait no children" 'wait 2>/dev/null; echo $?'
32 compare_output "wait nonexistent pid" 'wait 99999 2>/dev/null; echo $?'
33 compare_output "wait all children" 'sleep 0.01 & sleep 0.01 & wait; echo $?'
34
35 section "3. kill"
36 compare_output "kill background process" 'sleep 10 & PID=$!; kill $PID 2>/dev/null; wait $PID 2>/dev/null; echo done'
37 compare_output "kill -0 checks existence" 'sleep 10 & PID=$!; kill -0 $PID 2>/dev/null && echo alive; kill $PID 2>/dev/null; wait $PID 2>/dev/null'
38 compare_output "kill nonexistent pid" 'kill 99999 2>/dev/null; echo $?'
39 compare_output "kill -l lists signals" 'kill -l | head -1 | grep -q "[A-Z]" && echo has_signals'
40
41 section "4. job control (TTY-dependent)"
42 if $HAS_TTY; then
43 compare_output "jobs empty" 'jobs 2>/dev/null; echo $?'
44 else
45 skip "jobs empty" "no TTY"
46 skip "fg no jobs" "no TTY"
47 skip "bg no jobs" "no TTY"
48 fi
49
50 section "5. coproc"
51 compare_output "coproc with brace group" 'coproc { cat; }; echo hello >&${COPROC[1]}; sleep 0.1; read line <&${COPROC[0]}; echo $line'
52 compare_output "named coproc" 'coproc MYCAT { cat; }; echo test >&${MYCAT[1]}; sleep 0.1; read line <&${MYCAT[0]}; echo $line'
53 compare_output "coproc output" 'coproc { echo from_coproc; sleep 10; }; sleep 0.1; read line <&${COPROC[0]}; echo $line; kill $COPROC_PID 2>/dev/null; wait $COPROC_PID 2>/dev/null'
54
55 print_summary