summaryrefslogtreecommitdiff
path: root/corebinutils/pwait/tests/test.sh
blob: 745a50f4ef43d465f12171c14a91f81b7e03ab7b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/bin/sh

# tests/test.sh for pwait Linux port

set -eu

# Fallbacks for paths
CC="${CC:-cc}"
PWAIT_BIN="${PWAIT_BIN:-$(pwd)/out/pwait}"

fail() {
	echo "FAIL: $*" >&2
	exit 1
}

assert_exit_code() {
	local expected=$1
	shift
	local cmd="$@"
	set +e
	eval "$cmd" > /tmp/pwait_test.out 2> /tmp/pwait_test.err
	local st=$?
	set -e
	if [ "$st" != "$expected" ]; then
		echo "Expected exit code $expected, got $st for: $cmd" >&2
		cat /tmp/pwait_test.out >&2
		cat /tmp/pwait_test.err >&2
		fail "exit code assertion failed"
	fi
}

assert_stdout() {
	local expected_str="$1"
	shift
	local cmd="$@"
	set +e
	eval "$cmd" > /tmp/pwait_test.out 2> /tmp/pwait_test.err
	local st=$?
	set -e
	local out=$(cat /tmp/pwait_test.out)
	if ! echo "$out" | grep -qF "$expected_str"; then
		echo "Expected stdout to contain '$expected_str' for: $cmd" >&2
		echo "Got stdout:" >&2
		cat /tmp/pwait_test.out >&2
		fail "stdout assertion failed"
	fi
}

assert_stderr() {
	local expected_str="$1"
	shift
	local cmd="$@"
	set +e
	eval "$cmd" > /tmp/pwait_test.out 2> /tmp/pwait_test.err
	local st=$?
	set -e
	local err=$(cat /tmp/pwait_test.err)
	if ! echo "$err" | grep -qF "$expected_str"; then
		echo "Expected stderr to contain '$expected_str' for: $cmd" >&2
		echo "Got stderr:" >&2
		cat /tmp/pwait_test.err >&2
		fail "stderr assertion failed"
	fi
}

echo "=== Basic tests ==="
sleep 1 &
p1=$!
sleep 3 &
p3=$!

assert_exit_code 0 timeout 10 "$PWAIT_BIN" $p1 $p3

echo "=== Timeout tests ==="
sleep 10 &
p10=$!

assert_exit_code 124 timeout 15 "$PWAIT_BIN" -t 1 $p10
assert_exit_code 0 timeout 15 "$PWAIT_BIN" -t 12 $p10

kill $p10 2>/dev/null || true
wait $p10 2>/dev/null || true

echo "=== OR (-o) tests ==="
sleep 1 &
p1=$!
sleep 10 &
p10=$!
assert_exit_code 0 timeout 4 "$PWAIT_BIN" -o $p1 $p10
# $p10 might still be running
kill $p10 2>/dev/null || true

echo "=== Missing PID tests ==="
# Give an invalid process ID, should err and consider it done
assert_stderr "999999" timeout 2 "$PWAIT_BIN" 999999
assert_exit_code 0 timeout 2 "$PWAIT_BIN" 999999

echo "=== -p (print remaining) tests ==="
sleep 1 &
p1=$!
sleep 10 &
p10=$!
# Wait for 3 sec, p1 finishes, p10 remains
assert_stdout "$p10" timeout 5 "$PWAIT_BIN" -t 3 -p $p1 $p10
kill $p10 2>/dev/null || true

echo "=== -v (verbose exit) tests ==="
sleep 1 &
p1=$!
# It's a child process because we started it from our shell script. However, pwait doesn't own it.
# So pwait will print `terminated.` instead of exact exit code.
assert_stdout "$p1: terminated" timeout 3 "$PWAIT_BIN" -v $p1

echo "=== ENOSYS (Mock failure) test ==="
# We can't easily mock ENOSYS for pidfd_open from shell.
# We'll skip it in automated tests for now unless we LD_PRELOAD.

echo "=== timeout=0 test ==="
sleep 2 &
p2=$!
assert_exit_code 124 timeout 2 "$PWAIT_BIN" -t 0 $p2
kill $p2 2>/dev/null || true

echo "=== Duplicate PID test ==="
sleep 1 &
p1=$!
# wait for duplicate PID, should just wait normally once
assert_exit_code 0 timeout 4 "$PWAIT_BIN" $p1 $p1

echo "=== Killed by signal test ==="
sleep 10 &
p10=$!
# We don't trace child signals for unrelated procs,
# but we can check if pwait returns successfully when the target dies from a signal.
kill -9 $p10 2>/dev/null || true
assert_exit_code 0 timeout 2 "$PWAIT_BIN" $p10

echo "=== Mixed valid/invalid test ==="
sleep 1 &
p1=$!
sleep 10 &
# 999999 invalid
assert_stderr "bad process id" timeout 2 "$PWAIT_BIN" abc xyz || true
assert_stderr "999999" timeout 2 "$PWAIT_BIN" 999999 $p1
# wait should still succeed as soon as valid process exits
assert_exit_code 0 timeout 4 "$PWAIT_BIN" 999999 $p1

echo "ALL TESTS PASSED."
exit 0