Skip to content

Commit 92531af

Browse files
committed
bats/background-process: Close file descriptor 3
Closes #226. From the comment within `run_in_background`: Bats duplicates standard output as file descriptor 3 so that output from its framework functions isn't captured along with any output from the code under test. If the code under test contains a `sleep` or other blocking operation, this file descriptor will be held open until the process becomes unblocked, preventing Bats from exiting. Hence, we explicitly close file descriptor 3. Any other code running under Bats that opens a background process should close this file descriptor as well. See: sstephenson/bats#80 Much thanks to @marascio for discovering and researching the problem, and proposing the actual fix.
1 parent b8d7140 commit 92531af

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

lib/bats/background-process

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,25 @@
55
# These functions make it easier to write Bats test cases that validate the
66
# behavior of long-running processes such as servers:
77
#
8-
# @test '$SUITE: my-server should start successfully' {
8+
# @test "$SUITE: my-server should start successfully" {
99
# skip_if_missing_background_utilities
1010
# run_in_background 'my-server'
1111
# wait_for_background_output 'my-server is now ready'
1212
# stop_background_run
1313
# assert_...
1414
# }
1515
#
16+
# @test "$SUITE: my-test-script should start successfully" {
17+
# skip_if_missing_background_utilities
18+
# run_in_test_script_in_background 'my-test-script' \
19+
# 'sleep 1' \
20+
# 'echo "Hello, World!"' \
21+
# 'sleep 10'
22+
# wait_for_background_output 'Hello, World!'
23+
# stop_background_run
24+
# assert_...
25+
# }
26+
#
1627
# Call `skip_if_missing_background_utilities` at the beginning of each test case
1728
# to skip it if the host system lacks any of the process management utilities
1829
# required by the functions from this file.
@@ -64,7 +75,18 @@ run_in_background() {
6475
export BATS_BACKGROUND_RUN_OUTPUT
6576
BATS_BACKGROUND_RUN_OUTPUT="$BATS_TEST_ROOTDIR/background-run-output.txt"
6677
printf '' >"$BATS_BACKGROUND_RUN_OUTPUT"
67-
"$@" >"$BATS_BACKGROUND_RUN_OUTPUT" 2>&1 &
78+
79+
# Bats duplicates standard output as file descriptor 3 so that output from its
80+
# framework functions isn't captured along with any output from the code under
81+
# test. If the code under test contains a `sleep` or other blocking operation,
82+
# this file descriptor will be held open until the process becomes unblocked,
83+
# preventing Bats from exiting. Hence, we explicitly close file descriptor 3.
84+
#
85+
# Any other code running under Bats that opens a background process should
86+
# close this file descriptor as well. See:
87+
# - https://github.com/sstephenson/bats/issues/80
88+
# - https://github.com/mbland/go-script-bash/issues/226
89+
"$@" >"$BATS_BACKGROUND_RUN_OUTPUT" 2>&1 3>&- &
6890
export BATS_BACKGROUND_RUN_PID="$!"
6991
restore_bats_shell_options
7092
}

tests/bats-background-process.bats

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,27 @@ kill_background_test_script() {
163163
stop_background_run 'HUP'
164164
assert_status "$((128 + $(kill -l HUP)))"
165165
}
166+
167+
@test "$SUITE: bash -c command passes under run_in_background" {
168+
skip_if_missing_background_utilities
169+
mkdir "$BATS_TEST_ROOTDIR"
170+
171+
run_in_background bash -c 'echo "Oh hai, Mark."; sleep 60'
172+
run wait_for_background_output 'Oh hai, Mark.' '0.25'
173+
assert_success
174+
}
175+
176+
@test "$SUITE: bash -c command fails under run_in_background without hanging" {
177+
skip_if_missing_background_utilities
178+
mkdir "$BATS_TEST_ROOTDIR"
179+
180+
run_in_background bash -c 'echo "Oh hai, Mark."; sleep 60'
181+
run wait_for_background_output 'I did not do it! I did not!' '0.25'
182+
assert_failure \
183+
'Output did not match regular expression:' \
184+
" 'I did not do it! I did not!'" \
185+
'' \
186+
'OUTPUT:' \
187+
'------' \
188+
'Oh hai, Mark.'
189+
}

0 commit comments

Comments
 (0)