mirror of
https://github.com/git/git
synced 2024-08-25 10:45:59 +00:00
test-lib: introduce 'test_atexit'
When running Apache, 'git daemon', or p4d, we want to kill them at the end of the test script, otherwise a leftover daemon process will keep its port open indefinitely, and thus will interfere with subsequent executions of the same test script. So far, we stop these daemon processes "manually", i.e.: - by registering functions or commands in the trap on EXIT to stop the daemon while preserving the last seen exit code before the trap (to deal with a failure when run with '--immediate' or with interrupts by ctrl-C), - and by invoking these functions/commands last thing before 'test_done' (and sometimes restoring the test framework's default trap on EXIT, to prevent the daemons from being killed twice). On one hand, we do this inconsistently, e.g. 'git p4' tests invoke different functions in the trap on EXIT and in the last test before 'test_done', and they neither restore the test framework's default trap on EXIT nor preserve the last seen exit code. On the other hand, this is error prone, because, as shown in a previous patch in this series, any output from the cleanup commands in the trap on EXIT can prevent a proper cleanup when a test script run with '--verbose-log' and certain shells, notably 'dash', is interrupted. Let's introduce 'test_atexit', which is loosely modeled after 'test_when_finished', but has a broader scope: rather than running the commands after the current test case, run them when the test script finishes, and also run them when the test is interrupted, or exits early in case of a failure while the '--immediate' option is in effect. When running the cleanup commands at the end of a successful test, then they will be run in 'test_done' before it removes the trash directory, i.e. the cleanup commands will still be able to access any pidfiles or socket files in there. When running the cleanup commands after an interrupt or failure with '--immediate', then they will be run in the trap on EXIT. In both cases they will be run in 'test_eval_', i.e. both standard error and output of all cleanup commands will go where they should according to the '-v' or '--verbose-log' options, and thus won't cause any troubles when interrupting a test script run with '--verbose-log'. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
80a539acf6
commit
900721e15c
20
t/README
20
t/README
|
@ -862,6 +862,26 @@ library for your script to use.
|
|||
...
|
||||
'
|
||||
|
||||
- test_atexit <script>
|
||||
|
||||
Prepend <script> to a list of commands to run unconditionally to
|
||||
clean up before the test script exits, e.g. to stop a daemon:
|
||||
|
||||
test_expect_success 'test git daemon' '
|
||||
git daemon &
|
||||
daemon_pid=$! &&
|
||||
test_atexit 'kill $daemon_pid' &&
|
||||
hello world
|
||||
'
|
||||
|
||||
The commands will be executed before the trash directory is removed,
|
||||
i.e. the atexit commands will still be able to access any pidfiles or
|
||||
socket files.
|
||||
|
||||
Note that these commands will be run even when a test script run
|
||||
with '--immediate' fails. Be careful with your atexit commands to
|
||||
minimize any changes to the failed state.
|
||||
|
||||
- test_write_lines <lines>
|
||||
|
||||
Write <lines> on standard output, one line per argument.
|
||||
|
|
|
@ -825,6 +825,24 @@ test_expect_success 'tests clean up even on failures' "
|
|||
EOF
|
||||
"
|
||||
|
||||
test_expect_success 'test_atexit is run' "
|
||||
test_must_fail run_sub_test_lib_test \
|
||||
atexit-cleanup 'Run atexit commands' -i <<-\\EOF &&
|
||||
test_expect_success 'tests clean up even after a failure' '
|
||||
> ../../clean-atexit &&
|
||||
test_atexit rm ../../clean-atexit &&
|
||||
> ../../also-clean-atexit &&
|
||||
test_atexit rm ../../also-clean-atexit &&
|
||||
> ../../dont-clean-atexit &&
|
||||
(exit 1)
|
||||
'
|
||||
test_done
|
||||
EOF
|
||||
test_path_is_file dont-clean-atexit &&
|
||||
test_path_is_missing clean-atexit &&
|
||||
test_path_is_missing also-clean-atexit
|
||||
"
|
||||
|
||||
test_expect_success 'test_oid setup' '
|
||||
test_oid_init
|
||||
'
|
||||
|
|
|
@ -934,6 +934,34 @@ test_when_finished () {
|
|||
} && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"
|
||||
}
|
||||
|
||||
# This function can be used to schedule some commands to be run
|
||||
# unconditionally at the end of the test script, e.g. to stop a daemon:
|
||||
#
|
||||
# test_expect_success 'test git daemon' '
|
||||
# git daemon &
|
||||
# daemon_pid=$! &&
|
||||
# test_atexit 'kill $daemon_pid' &&
|
||||
# hello world
|
||||
# '
|
||||
#
|
||||
# The commands will be executed before the trash directory is removed,
|
||||
# i.e. the atexit commands will still be able to access any pidfiles or
|
||||
# socket files.
|
||||
#
|
||||
# Note that these commands will be run even when a test script run
|
||||
# with '--immediate' fails. Be careful with your atexit commands to
|
||||
# minimize any changes to the failed state.
|
||||
|
||||
test_atexit () {
|
||||
# We cannot detect when we are in a subshell in general, but by
|
||||
# doing so on Bash is better than nothing (the test will
|
||||
# silently pass on other shells).
|
||||
test "${BASH_SUBSHELL-0}" = 0 ||
|
||||
error "bug in test script: test_atexit does nothing in a subshell"
|
||||
test_atexit_cleanup="{ $*
|
||||
} && (exit \"\$eval_ret\"); eval_ret=\$?; $test_atexit_cleanup"
|
||||
}
|
||||
|
||||
# Most tests can use the created repository, but some may need to create more.
|
||||
# Usage: test_create_repo <directory>
|
||||
test_create_repo () {
|
||||
|
|
|
@ -620,6 +620,10 @@ test_external_has_tap=0
|
|||
|
||||
die () {
|
||||
code=$?
|
||||
# This is responsible for running the atexit commands even when a
|
||||
# test script run with '--immediate' fails, or when the user hits
|
||||
# ctrl-C, i.e. when 'test_done' is not invoked at all.
|
||||
test_atexit_handler || code=$?
|
||||
if test -n "$GIT_EXIT_OK"
|
||||
then
|
||||
exit $code
|
||||
|
@ -1045,9 +1049,28 @@ write_junit_xml_testcase () {
|
|||
junit_have_testcase=t
|
||||
}
|
||||
|
||||
test_atexit_cleanup=:
|
||||
test_atexit_handler () {
|
||||
# In a succeeding test script 'test_atexit_handler' is invoked
|
||||
# twice: first from 'test_done', then from 'die' in the trap on
|
||||
# EXIT.
|
||||
# This condition and resetting 'test_atexit_cleanup' below makes
|
||||
# sure that the registered cleanup commands are run only once.
|
||||
test : != "$test_atexit_cleanup" || return 0
|
||||
|
||||
setup_malloc_check
|
||||
test_eval_ "$test_atexit_cleanup"
|
||||
test_atexit_cleanup=:
|
||||
teardown_malloc_check
|
||||
}
|
||||
|
||||
test_done () {
|
||||
GIT_EXIT_OK=t
|
||||
|
||||
# Run the atexit commands _before_ the trash directory is
|
||||
# removed, so the commands can access pidfiles and socket files.
|
||||
test_atexit_handler
|
||||
|
||||
if test -n "$write_junit_xml" && test -n "$junit_xml_path"
|
||||
then
|
||||
test -n "$junit_have_testcase" || {
|
||||
|
|
Loading…
Reference in a new issue