From: Johannes Schindelin <johannes.schindelin@xxxxxx> When running the p4 daemon or `git daemon`, we want to kill it at the end of the test script. So far, we do this "manually". However, in the next few commits we want to teach the test suite to optionally re-run scripts with different options, therefore we will have to have a consistent way to stop daemons. 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 `--immediate` option is in effect). Signed-off-by: Johannes Schindelin <johannes.schindelin@xxxxxx> --- t/t0000-basic.sh | 18 ++++++++++++++++++ t/test-lib-functions.sh | 29 +++++++++++++++++++++++++++++ t/test-lib.sh | 4 ++++ 3 files changed, 51 insertions(+) diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index 391f910c6a..8c5faa6ce1 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -821,6 +821,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_exists 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 ' diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 78d8c3783b..d7dd0c1be9 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -891,6 +891,35 @@ 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 +# ' + +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" +} + +test_atexit_handler () { + test : != "$test_atexit_cleanup" || return 0 + + setup_malloc_check + test_eval_ "$test_atexit_cleanup" + test_atexit_cleanup=: + teardown_malloc_check +} + # Most tests can use the created repository, but some may need to create more. # Usage: test_create_repo <directory> test_create_repo () { diff --git a/t/test-lib.sh b/t/test-lib.sh index 7ed0013f6d..6f9c1f5300 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -413,6 +413,7 @@ test_external_has_tap=0 die () { code=$? + test_atexit_handler || code=$? if test -n "$GIT_EXIT_OK" then exit $code @@ -826,9 +827,12 @@ write_junit_xml_testcase () { junit_have_testcase=t } +test_atexit_cleanup=: test_done () { GIT_EXIT_OK=t + test -n "$immediate" || test_atexit_handler + if test -n "$write_junit_xml" && test -n "$junit_xml_path" then test -n "$junit_have_testcase" || { -- gitgitgadget