Skip to content

Commit 3772cad

Browse files
committed
Fix a race; add a test to ensure the 'result' and 'stderr' files are
closed before continuing to run 'checkresult'.
1 parent 0847c00 commit 3772cad

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

scripts/runtests.in

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,41 @@ clean () {
5656
-print0 | xargs -0 rm -f
5757
}
5858

59+
wait_for_result_close() {
60+
# Test for the 'result' and 'stderr' files in the current testdir to be
61+
# closed. The 'checkresult' script cannot be run if these files are still
62+
# in use and would cause a race condition.
63+
# This function should be called with the test's directory as CWD.
64+
presult="$(realpath -e -q "./result")"
65+
pstderr="$(realpath -e -q "./stderr")"
66+
if [ -z "$presult" ] || [ -z "$pstderr" ]; then
67+
echo "Internal error: Missing 'result' or 'stderr' in wait_for_result_close()"
68+
exit 2
69+
fi
70+
timeoutcnt=0
71+
while true; do
72+
lsof -- "$presult" > /dev/null 2>&1; resresult=$?
73+
lsof -- "$pstderr" > /dev/null 2>&1; resstderr=$?
74+
if [ $resresult -ne 0 ] && [ $resstderr -ne 0 ]; then
75+
# Neither 'result' nor 'stderr' are open anymore
76+
break
77+
fi
78+
if [ $timeoutcnt -ge 30 ]; then
79+
if [ $resresult -eq 0 ]; then
80+
echo "*** Timeout waiting for 'result' file to close"
81+
fi
82+
if [ $resstderr -eq 0 ]; then
83+
echo "*** Timeout waiting for 'stderr' file to close"
84+
fi
85+
echo "*** Test results may be invalid when checked."
86+
return 1
87+
fi
88+
sleep 1
89+
timeoutcnt=$((timeoutcnt + 1))
90+
done
91+
return 0
92+
}
93+
5994
run_shell_script () {
6095
testname=$(basename "$1")
6196
testdir=$(dirname "$1")
@@ -67,6 +102,7 @@ run_shell_script () {
67102
bash -x "$testname" > result 2> stderr
68103
fi
69104
exitcode=$?
105+
wait_for_result_close
70106
popd > /dev/null || exit 2
71107
return "$exitcode"
72108
}
@@ -82,6 +118,7 @@ run_executable () {
82118
./"$testname" > result 2> stderr
83119
fi
84120
exitcode=$?
121+
wait_for_result_close
85122
popd > /dev/null || exit 2
86123
return "$exitcode"
87124
}
@@ -99,6 +136,7 @@ run_without_overruns () {
99136
halrun -f "$testname" > result 2> stderr
100137
fi
101138
exitcode=$?
139+
wait_for_result_close
102140
popd > /dev/null || exit 2
103141

104142
if ! grep -q '^overrun$' "$testdir/result"; then return "$exitcode"; fi

0 commit comments

Comments
 (0)