Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bats/background-process: Close file descriptor 3 #227

Merged
merged 2 commits into from
Jun 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions lib/bats/background-process
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,25 @@
# These functions make it easier to write Bats test cases that validate the
# behavior of long-running processes such as servers:
#
# @test '$SUITE: my-server should start successfully' {
# @test "$SUITE: my-server should start successfully" {
# skip_if_missing_background_utilities
# run_in_background 'my-server'
# wait_for_background_output 'my-server is now ready'
# stop_background_run
# assert_...
# }
#
# @test "$SUITE: my-test-script should start successfully" {
# skip_if_missing_background_utilities
# run_in_test_script_in_background 'my-test-script' \
# 'sleep 1' \
# 'echo "Hello, World!"' \
# 'sleep 10'
# wait_for_background_output 'Hello, World!'
# stop_background_run
# assert_...
# }
#
# Call `skip_if_missing_background_utilities` at the beginning of each test case
# to skip it if the host system lacks any of the process management utilities
# required by the functions from this file.
Expand Down Expand Up @@ -64,7 +75,18 @@ run_in_background() {
export BATS_BACKGROUND_RUN_OUTPUT
BATS_BACKGROUND_RUN_OUTPUT="$BATS_TEST_ROOTDIR/background-run-output.txt"
printf '' >"$BATS_BACKGROUND_RUN_OUTPUT"
"$@" >"$BATS_BACKGROUND_RUN_OUTPUT" 2>&1 &

# 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:
# - https://github.com/sstephenson/bats/issues/80
# - https://github.com/mbland/go-script-bash/issues/226
"$@" >"$BATS_BACKGROUND_RUN_OUTPUT" 2>&1 3>&- &
export BATS_BACKGROUND_RUN_PID="$!"
restore_bats_shell_options
}
Expand Down
24 changes: 24 additions & 0 deletions tests/bats-background-process.bats
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,27 @@ kill_background_test_script() {
stop_background_run 'HUP'
assert_status "$((128 + $(kill -l HUP)))"
}

@test "$SUITE: bash -c command passes under run_in_background" {
skip_if_missing_background_utilities
mkdir "$BATS_TEST_ROOTDIR"

run_in_background bash -c 'echo "Oh hai, Mark."; sleep 60'
run wait_for_background_output 'Oh hai, Mark.' '0.25'
assert_success
}

@test "$SUITE: bash -c command fails under run_in_background without hanging" {
skip_if_missing_background_utilities
mkdir "$BATS_TEST_ROOTDIR"

run_in_background bash -c 'echo "Oh hai, Mark."; sleep 60'
run wait_for_background_output 'I did not do it! I did not!' '0.25'
assert_failure \
'Output did not match regular expression:' \
" 'I did not do it! I did not!'" \
'' \
'OUTPUT:' \
'------' \
'Oh hai, Mark.'
}