From be990991928b3e2a3aefea15614eca009253c276 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 14 Sep 2018 14:42:13 -0500 Subject: [PATCH] tests: introduce `test_atexit` 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 --- 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 b6566003dd..156732f3b3 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -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_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 6b3bbf99e4..c4da13a390 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -927,6 +927,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 test_create_repo () { diff --git a/t/test-lib.sh b/t/test-lib.sh index b8414d7aec..ca1acd61d1 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -470,6 +470,7 @@ test_external_has_tap=0 die () { code=$? + test_atexit_handler || code=$? if test -n "$GIT_EXIT_OK" then exit $code @@ -883,9 +884,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" || {