Merge branch 'sg/test-atexit'
authorJunio C Hamano <gitster@pobox.com>
Thu, 25 Apr 2019 07:41:12 +0000 (16:41 +0900)
committerJunio C Hamano <gitster@pobox.com>
Thu, 25 Apr 2019 07:41:12 +0000 (16:41 +0900)
Test framework update to more robustly clean up leftover files and
processes after tests are done.

* sg/test-atexit:
t9811-git-p4-label-import: fix pipeline negation
git p4 test: disable '-x' tracing in the p4d watchdog loop
git p4 test: simplify timeout handling
git p4 test: clean up the p4d cleanup functions
git p4 test: use 'test_atexit' to kill p4d and the watchdog process
t0301-credential-cache: use 'test_atexit' to stop the credentials helper
tests: use 'test_atexit' to stop httpd
git-daemon: use 'test_atexit` to stop 'git-daemon'
test-lib: introduce 'test_atexit'
t/lib-git-daemon: make sure to kill the 'git-daemon' process
test-lib: fix interrupt handling with 'dash' and '--verbose-log -x'

68 files changed:
t/README
t/interop/i5500-git-daemon.sh
t/lib-git-daemon.sh
t/lib-git-p4.sh
t/lib-git-svn.sh
t/lib-httpd.sh
t/t0000-basic.sh
t/t0301-credential-cache.sh
t/t0410-partial-clone.sh
t/t5500-fetch-pack.sh
t/t5510-fetch.sh
t/t5537-fetch-shallow.sh
t/t5539-fetch-http-shallow.sh
t/t5540-http-push-webdav.sh
t/t5541-http-push-smart.sh
t/t5542-push-http-shallow.sh
t/t5545-push-options.sh
t/t5550-http-fetch-dumb.sh
t/t5551-http-fetch-smart.sh
t/t5561-http-backend.sh
t/t5570-git-daemon.sh
t/t5581-http-curl-verbose.sh
t/t5601-clone.sh
t/t5616-partial-clone.sh
t/t5700-protocol-v1.sh
t/t5702-protocol-v2.sh
t/t5703-upload-pack-ref-in-want.sh
t/t5812-proto-disable-http.sh
t/t9115-git-svn-dcommit-funky-renames.sh
t/t9118-git-svn-funky-branch-names.sh
t/t9120-git-svn-clone-with-percent-escapes.sh
t/t9142-git-svn-shallow-clone.sh
t/t9800-git-p4-basic.sh
t/t9801-git-p4-branch.sh
t/t9802-git-p4-filetype.sh
t/t9803-git-p4-shell-metachars.sh
t/t9804-git-p4-label.sh
t/t9805-git-p4-skip-submit-edit.sh
t/t9806-git-p4-options.sh
t/t9807-git-p4-submit.sh
t/t9808-git-p4-chdir.sh
t/t9809-git-p4-client-view.sh
t/t9810-git-p4-rcs.sh
t/t9811-git-p4-label-import.sh
t/t9812-git-p4-wildcards.sh
t/t9813-git-p4-preserve-users.sh
t/t9814-git-p4-rename.sh
t/t9815-git-p4-submit-fail.sh
t/t9816-git-p4-locked.sh
t/t9817-git-p4-exclude.sh
t/t9818-git-p4-block.sh
t/t9819-git-p4-case-folding.sh
t/t9820-git-p4-editor-handling.sh
t/t9821-git-p4-path-variations.sh
t/t9822-git-p4-path-encoding.sh
t/t9823-git-p4-mock-lfs.sh
t/t9824-git-p4-git-lfs.sh
t/t9825-git-p4-handle-utf16-without-bom.sh
t/t9826-git-p4-keep-empty-commits.sh
t/t9827-git-p4-change-filetype.sh
t/t9828-git-p4-map-user.sh
t/t9829-git-p4-jobs.sh
t/t9830-git-p4-symlink-dir.sh
t/t9831-git-p4-triggers.sh
t/t9832-unshelve.sh
t/t9833-errors.sh
t/test-lib-functions.sh
t/test-lib.sh
index af1243eb49efab5e5763c54e82697bf277be0adf..6404f33e19421c47999518138ed6f46a066921c0 100644 (file)
--- a/t/README
+++ b/t/README
@@ -871,6 +871,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.
index 1daf69420be1948cdc1eb97b4b4122e22674d43e..4d22e42f8422adac89c37ba4ef94f8a8ca66f413 100755 (executable)
@@ -37,5 +37,4 @@ test_expect_success "fetch with $VERSION_B" '
        test_cmp expect actual
 '
 
-stop_git_daemon
 test_done
index 79db3b7ae513c01b07422ed1a8d95f9f5b285cb5..7b3407134e1a776de7a030bce98f0248fe6cd42f 100644 (file)
@@ -13,7 +13,6 @@
 #
 #      test_expect_success ...
 #
-#      stop_git_daemon
 #      test_done
 
 test_tristate GIT_TEST_GIT_DAEMON
@@ -31,10 +30,12 @@ fi
 test_set_port LIB_GIT_DAEMON_PORT
 
 GIT_DAEMON_PID=
+GIT_DAEMON_PIDFILE="$PWD"/daemon.pid
 GIT_DAEMON_DOCUMENT_ROOT_PATH="$PWD"/repo
 GIT_DAEMON_HOST_PORT=127.0.0.1:$LIB_GIT_DAEMON_PORT
 GIT_DAEMON_URL=git://$GIT_DAEMON_HOST_PORT
 
+registered_stop_git_daemon_atexit_handler=
 start_git_daemon() {
        if test -n "$GIT_DAEMON_PID"
        then
@@ -43,13 +44,19 @@ start_git_daemon() {
 
        mkdir -p "$GIT_DAEMON_DOCUMENT_ROOT_PATH"
 
-       trap 'code=$?; stop_git_daemon; (exit $code); die' EXIT
+       # One of the test scripts stops and then re-starts 'git daemon'.
+       # Don't register and then run the same atexit handlers several times.
+       if test -z "$registered_stop_git_daemon_atexit_handler"
+       then
+               test_atexit 'stop_git_daemon'
+               registered_stop_git_daemon_atexit_handler=AlreadyDone
+       fi
 
        say >&3 "Starting git daemon ..."
        mkfifo git_daemon_output
        ${LIB_GIT_DAEMON_COMMAND:-git daemon} \
                --listen=127.0.0.1 --port="$LIB_GIT_DAEMON_PORT" \
-               --reuseaddr --verbose \
+               --reuseaddr --verbose --pid-file="$GIT_DAEMON_PIDFILE" \
                --base-path="$GIT_DAEMON_DOCUMENT_ROOT_PATH" \
                "$@" "$GIT_DAEMON_DOCUMENT_ROOT_PATH" \
                >&3 2>git_daemon_output &
@@ -65,7 +72,7 @@ start_git_daemon() {
        then
                kill "$GIT_DAEMON_PID"
                wait "$GIT_DAEMON_PID"
-               trap 'die' EXIT
+               unset GIT_DAEMON_PID
                test_skip_or_die $GIT_TEST_GIT_DAEMON \
                        "git daemon failed to start"
        fi
@@ -77,8 +84,6 @@ stop_git_daemon() {
                return
        fi
 
-       trap 'die' EXIT
-
        # kill git-daemon child of git
        say >&3 "Stopping git daemon ..."
        kill "$GIT_DAEMON_PID"
@@ -88,8 +93,9 @@ stop_git_daemon() {
        then
                error "git daemon exited with status: $ret"
        fi
+       kill "$(cat "$GIT_DAEMON_PIDFILE")" 2>/dev/null
        GIT_DAEMON_PID=
-       rm -f git_daemon_output
+       rm -f git_daemon_output "$GIT_DAEMON_PIDFILE"
 }
 
 # A stripped-down version of a netcat client, that connects to a "host:port"
index b3be3ba011a71ce11f11901c8472cb25ec21133a..547b9f88e1235a9248f6da9d1fa24dffd7cb0cd3 100644 (file)
@@ -44,15 +44,6 @@ native_path () {
        echo "$path"
 }
 
-# On Solaris the 'date +%s' function is not supported and therefore we
-# need this replacement.
-# Attention: This function is not safe again against time offset updates
-# at runtime (e.g. via NTP). The 'clock_gettime(CLOCK_MONOTONIC)'
-# function could fix that but it is not in Python until 3.3.
-time_in_seconds () {
-       (cd / && "$PYTHON_PATH" -c 'import time; print(int(time.time()))')
-}
-
 test_set_port P4DPORT
 
 P4PORT=localhost:$P4DPORT
@@ -67,14 +58,9 @@ cli="$TRASH_DIRECTORY/cli"
 git="$TRASH_DIRECTORY/git"
 pidfile="$TRASH_DIRECTORY/p4d.pid"
 
-# Sometimes "prove" seems to hang on exit because p4d is still running
-cleanup () {
-       if test -f "$pidfile"
-       then
-               kill -9 $(cat "$pidfile") 2>/dev/null && exit 255
-       fi
+stop_p4d_and_watchdog () {
+       kill -9 $p4d_pid $watchdog_pid
 }
-trap cleanup EXIT
 
 # git p4 submit generates a temp file, which will
 # not get cleaned up if the submission fails.  Don't
@@ -82,7 +68,16 @@ trap cleanup EXIT
 TMPDIR="$TRASH_DIRECTORY"
 export TMPDIR
 
+registered_stop_p4d_atexit_handler=
 start_p4d () {
+       # One of the test scripts stops and then re-starts p4d.
+       # Don't register and then run the same atexit handlers several times.
+       if test -z "$registered_stop_p4d_atexit_handler"
+       then
+               test_atexit 'stop_p4d_and_watchdog'
+               registered_stop_p4d_atexit_handler=AlreadyDone
+       fi
+
        mkdir -p "$db" "$cli" "$git" &&
        rm -f "$pidfile" &&
        (
@@ -92,6 +87,7 @@ start_p4d () {
                        echo $! >"$pidfile"
                }
        ) &&
+       p4d_pid=$(cat "$pidfile")
 
        # This gives p4d a long time to start up, as it can be
        # quite slow depending on the machine.  Set this environment
@@ -99,18 +95,18 @@ start_p4d () {
        # an automated test setup.  If the p4d process dies, that
        # will be caught with the "kill -0" check below.
        i=${P4D_START_PATIENCE:-300}
-       pid=$(cat "$pidfile")
 
-       timeout=$(($(time_in_seconds) + $P4D_TIMEOUT))
+       nr_tries_left=$P4D_TIMEOUT
        while true
        do
-               if test $(time_in_seconds) -gt $timeout
+               if test $nr_tries_left -eq 0
                then
-                       kill -9 $pid
+                       kill -9 $p4d_pid
                        exit 1
                fi
                sleep 1
-       done &
+               nr_tries_left=$(($nr_tries_left - 1))
+       done 2>/dev/null 4>&2 &
        watchdog_pid=$!
 
        ready=
@@ -123,7 +119,7 @@ start_p4d () {
                        break
                fi
                # fail if p4d died
-               kill -0 $pid 2>/dev/null || break
+               kill -0 $p4d_pid 2>/dev/null || break
                echo waiting for p4d to start
                sleep 1
                i=$(( $i - 1 ))
@@ -163,29 +159,18 @@ p4_add_job () {
 }
 
 retry_until_success () {
-       timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT))
-       until "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout
-       do
-               sleep 1
-       done
-}
-
-retry_until_fail () {
-       timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT))
-       until ! "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout
+       nr_tries_left=$RETRY_TIMEOUT
+       until "$@" 2>/dev/null || test $nr_tries_left -eq 0
        do
                sleep 1
+               nr_tries_left=$(($nr_tries_left - 1))
        done
 }
 
-kill_p4d () {
-       pid=$(cat "$pidfile")
-       retry_until_fail kill $pid
-       retry_until_fail kill -9 $pid
-       # complain if it would not die
-       test_must_fail kill $pid >/dev/null 2>&1 &&
-       rm -rf "$db" "$cli" "$pidfile" &&
-       retry_until_fail kill -9 $watchdog_pid
+stop_and_cleanup_p4d () {
+       kill -9 $p4d_pid $watchdog_pid
+       wait $p4d_pid
+       rm -rf "$db" "$cli" "$pidfile"
 }
 
 cleanup_git () {
index f3b478c307c99397fb180fb3d5688e1d6f257904..c1271d686372dfd46d640a84ebec3971933ed4f2 100644 (file)
@@ -76,11 +76,6 @@ maybe_start_httpd () {
                LIB_HTTPD_SVN="$loc"
                start_httpd
                ;;
-       *)
-               stop_httpd () {
-                       : noop
-               }
-               ;;
        esac
 }
 
index 0dfb48c2f6df78348c216bd34693758c0d22365d..b3cc62bd36f26f776b307607a941b01c547c404d 100644 (file)
@@ -14,7 +14,6 @@
 #
 #      test_expect_success ...
 #
-#      stop_httpd
 #      test_done
 #
 # Can be configured using the following variables.
@@ -176,7 +175,7 @@ prepare_httpd() {
 start_httpd() {
        prepare_httpd >&3 2>&4
 
-       trap 'code=$?; stop_httpd; (exit $code); die' EXIT
+       test_atexit stop_httpd
 
        "$LIB_HTTPD_PATH" -d "$HTTPD_ROOT_PATH" \
                -f "$TEST_PATH/apache.conf" $HTTPD_PARA \
@@ -184,15 +183,12 @@ start_httpd() {
                >&3 2>&4
        if test $? -ne 0
        then
-               trap 'die' EXIT
                cat "$HTTPD_ROOT_PATH"/error.log >&4 2>/dev/null
                test_skip_or_die $GIT_TEST_HTTPD "web server setup failed"
        fi
 }
 
 stop_httpd() {
-       trap 'die' EXIT
-
        "$LIB_HTTPD_PATH" -d "$HTTPD_ROOT_PATH" \
                -f "$TEST_PATH/apache.conf" $HTTPD_PARA -k stop
 }
index b6566003dd8704503305314767f84d516c170f7a..c03054c538a0f9220cb268ed4fa24ae963d06e84 100755 (executable)
@@ -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
 '
index fd92533acf488fd7d1aedd8152b9edaafc9bd87d..ebd5fa5249ca276b739977739e8dea27aa6728aa 100755 (executable)
@@ -10,7 +10,7 @@ test -z "$NO_UNIX_SOCKETS" || {
 }
 
 # don't leave a stale daemon running
-trap 'code=$?; git credential-cache exit; (exit $code); die' EXIT
+test_atexit 'git credential-cache exit'
 
 # test that the daemon works with no special setup
 helper_test cache
@@ -108,9 +108,4 @@ test_expect_success SYMLINKS 'use user socket if user directory is a symlink to
 
 helper_test_timeout cache --timeout=1
 
-# we can't rely on our "trap" above working after test_done,
-# as test_done will delete the trash directory containing
-# our socket, leaving us with no way to access the daemon.
-git credential-cache exit
-
 test_done
index bce02788e6e1b03b87911fb13594e0cf6f80fdab..5bd892f2f7a90ac9e35993c137e0addd10d17bde 100755 (executable)
@@ -518,6 +518,4 @@ test_expect_success 'fetching of missing objects from an HTTP server' '
        git verify-pack --verbose "$IDX" | grep "$HASH"
 '
 
-stop_httpd
-
 test_done
index 0ef4d6f20c226d544daa4ea62adf19e4ec946ce4..1c71c0ec770cd54505f65bf83eca91f153cdf785 100755 (executable)
@@ -920,7 +920,4 @@ test_expect_success 'fetch with --filter=blob:limit=0 and HTTP' '
        fetch_filter_blob_limit_zero "$HTTPD_DOCUMENT_ROOT_PATH/server" "$HTTPD_URL/smart/server"
 '
 
-stop_httpd
-
-
 test_done
index 3b7b30568cddd5d9ea1a8979e5366a262f81bf09..e98d90dd9baf644bf2013aea51a91eab4e9ef73c 100755 (executable)
@@ -978,6 +978,4 @@ test_expect_success '--negotiation-tip limits "have" lines sent with HTTP protoc
        check_negotiation_tip
 '
 
-stop_httpd
-
 test_done
index 6caf628efaaa400473ddfb46fdef0b847b4edd39..66f0b64d39273d9e2f6ae5c74e195e50e4b712c5 100755 (executable)
@@ -255,6 +255,4 @@ test_expect_success 'shallow fetches check connectivity before writing shallow f
        git -C client fsck
 '
 
-stop_httpd
-
 test_done
index cdb687b93aa1fe541a8c1b98a7dff0f4caf4c376..b4ad81f00635efc144a3b531a939e5fc34d5c14f 100755 (executable)
@@ -149,5 +149,4 @@ test_expect_success 'fetching deepen' '
        )
 '
 
-stop_httpd
 test_done
index 88ff5a49e4af38daca65c6e3a79ea4030b391c6b..a094fd5e71334bd16ac890234962485a7f9b7d24 100755 (executable)
@@ -176,6 +176,4 @@ test_expect_failure 'push to password-protected repository (no user in URL)' '
        test_cmp expect actual
 '
 
-stop_httpd
-
 test_done
index 0e3055ab98b94596eb5f7ac65e9dc35c58cd24c2..8ef8763e063cf30da8af4a80079458cf8e18c56d 100755 (executable)
@@ -383,5 +383,4 @@ test_expect_success 'colorize errors/hints' '
        test_i18ngrep ! "^hint: " decoded
 '
 
-stop_httpd
 test_done
index 51658331571611c568def54be28072f426c48e66..ddc1db722d43ce3cfbf80b46deea0a69a4973247 100755 (executable)
@@ -90,5 +90,4 @@ EOF
        )
 '
 
-stop_httpd
 test_done
index b47a95871cac3dd8593b3b9262d238be3914ac62..6d1d59c9b1af8c1ca7d6e78c8a589395ff971338 100755 (executable)
@@ -278,6 +278,4 @@ test_expect_success 'push options keep quoted characters intact (http)' '
        test_cmp expect "$HTTPD_DOCUMENT_ROOT_PATH"/upstream.git/hooks/pre-receive.push_options
 '
 
-stop_httpd
-
 test_done
index 694b77c8556d45ca594375683b1fd2209a346947..b811d89cfd6df25fb2e42db6f05a69cf0b7a6c3b 100755 (executable)
@@ -424,5 +424,4 @@ test_expect_success 'fetching via http alternates works' '
        git -c http.followredirects=true clone "$HTTPD_URL/dumb/alt-child.git"
 '
 
-stop_httpd
 test_done
index c760514716e37868feb1bd6be94b05912999df85..ac74626a7b667c3723569cfbca9c77bc264c6728 100755 (executable)
@@ -469,5 +469,4 @@ test_expect_success 'server-side error detected' '
        grep "server-side error" actual
 '
 
-stop_httpd
 test_done
index 1c49054595c23564cf762ac01ea0a1667a59f2f9..6eb0294978a03f35f5c246a6000a92fc377b02ed 100755 (executable)
@@ -132,5 +132,4 @@ test_expect_success 'server request log matches test results' '
        check_access_log exp
 '
 
-stop_httpd
 test_done
index 58ee7876853161087c256e56e687f0b341fde915..00fc612cacba4781975d066e01873e90e06050a8 100755 (executable)
@@ -198,5 +198,4 @@ test_expect_success FAKENC 'hostname interpolation works after LF-stripping' '
        test_cmp expect actual
 '
 
-stop_git_daemon
 test_done
index cd9283eeecd9d5d65ec5713b260d254679939fa8..5129b0724f703890c80c8dcbe7bd4347792963e3 100755 (executable)
@@ -23,6 +23,4 @@ test_expect_success 'failure in git-upload-pack is shown' '
        grep "< HTTP/1.1 500 Intentional Breakage" curl_log
 '
 
-stop_httpd
-
 test_done
index a454b143ea820392a8d41712d587cb144fc9a3df..23854cab263d467ba189879add1fb6b408e00792 100755 (executable)
@@ -733,6 +733,4 @@ test_expect_success 'partial clone using HTTP' '
        partial_clone "$HTTPD_DOCUMENT_ROOT_PATH/server" "$HTTPD_URL/smart/server"
 '
 
-stop_httpd
-
 test_done
index 9643acb1615fe0d28a7f0e386fa69a570a93dc8e..9a8f9886b3e2d82b5c10bf749d485f05bd364db6 100755 (executable)
@@ -331,6 +331,4 @@ test_expect_success 'when partial cloning, tolerate server not sending target of
        ! test -e "$HTTPD_ROOT_PATH/one-time-sed"
 '
 
-stop_httpd
-
 test_done
index d5ed196bfd096f1153c392f25a841aff3a84d7ca..7c9511c593c175b5065970b75319c6da03d68b31 100755 (executable)
@@ -292,6 +292,4 @@ test_expect_success 'push with http:// using protocol v1' '
        grep "git< version 1" log
 '
 
-stop_httpd
-
 test_done
index e112b6086c96e4cb0ad7bc10dcd685e7570d496f..a0896593375803eb79782705a21d673c72172c83 100755 (executable)
@@ -687,6 +687,4 @@ test_expect_success 'when server does not send "ready", expect FLUSH' '
        test_i18ngrep "expected no other sections to be sent after no .ready." err
 '
 
-stop_httpd
-
 test_done
index f87b2f6df329975e243ab9c00b510ee4cc588d0b..b6a995e8579c91874d2850ca579f87bf93f40561 100755 (executable)
@@ -257,8 +257,6 @@ test_expect_success 'server loses a ref - ref in want' '
        test_i18ngrep "fatal: remote error: unknown ref refs/heads/raster" err
 '
 
-stop_httpd
-
 REPO="$(pwd)/repo"
 LOCAL_PRISTINE="$(pwd)/local_pristine"
 
index 872788ac8ca4ecc0a54c14a04e3f72661306f1d3..af8772fadaa0d590370ba8a28b33c5b455164312 100755 (executable)
@@ -34,5 +34,4 @@ test_expect_success 'http can be limited to from-user' '
                clone "$HTTPD_URL/smart-redir-perm/repo.git" redir.git
 '
 
-stop_httpd
 test_done
index 64bb495834698c8438c8b8dde488873072abc1fd..9b44a44bc1f917e2a05956e3300e2cb673a3fec3 100755 (executable)
@@ -120,6 +120,4 @@ test_expect_success !MINGW,!UTF8_NFD_TO_NFC 'svn.pathnameencoding=cp932 rename o
        git svn dcommit
 '
 
-stop_httpd
-
 test_done
index 41a026637fa03174765d4e3facc3815bbf538e29..a159ff96b71882362eaa7d7856289561601674cf 100755 (executable)
@@ -87,6 +87,4 @@ test_expect_success 'test dcommit to trailing_dotlock branch' '
        )
        '
 
-stop_httpd
-
 test_done
index b28a1741e3f52296dcab35ed6d51fa01c2628652..40b714df31a20f5b6908ca69dd229d624bc775cc 100755 (executable)
@@ -74,6 +74,4 @@ test_expect_success 'test clone -s with unescaped space' '
        )
 '
 
-stop_httpd
-
 test_done
index 9ee23be64003ab22277c80a6c4b364c8cc36f902..a30730502d859408a3d59a1859e55a07eac0c6ce 100755 (executable)
@@ -26,6 +26,4 @@ test_expect_success 'clone trunk with "-r HEAD"' '
        ( cd g && git rev-parse --symbolic --verify HEAD )
 '
 
-stop_httpd
-
 test_done
index 729cd25770177aa52bade1100bb4ddae1456d269..5856563068c71280065c28d294a7c0a1149f6008 100755 (executable)
@@ -326,8 +326,4 @@ test_expect_success 'submit from worktree' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 6a86d6996b97de0bed0503021b76b33db8441029..38d6b9043b2039d97cdb634ac86658c45ec36abd 100755 (executable)
@@ -151,7 +151,7 @@ test_expect_success 'import depot, branch detection, branchList branch definitio
 '
 
 test_expect_success 'restart p4d' '
-       kill_p4d &&
+       stop_and_cleanup_p4d &&
        start_p4d
 '
 
@@ -505,7 +505,7 @@ test_expect_success 'use-client-spec detect-branches skips files in branches' '
 '
 
 test_expect_success 'restart p4d' '
-       kill_p4d &&
+       stop_and_cleanup_p4d &&
        start_p4d
 '
 
@@ -610,8 +610,4 @@ test_expect_success 'Update a file in git side and submit to P4 using client vie
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 9978352d7828dbd63d44d172b91193a20291c4d1..94edebe272691a72768cea14c1185c26113aad14 100755 (executable)
@@ -333,8 +333,4 @@ test_expect_success SYMLINKS 'empty symlink target' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index d5c367510049607ce33db73ffc1869a0652fe663..2913277013da56e98b9ad8b6ec3ea47ccbace103 100755 (executable)
@@ -105,8 +105,4 @@ test_expect_success 'branch with shell char' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index e30f80e617674967b1d474c1485a6570f1ef2903..32364571063d4c6001105d0929ca81fe50e2a87c 100755 (executable)
@@ -108,8 +108,4 @@ test_expect_failure 'two labels on the same changelist' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 5fbf904dc8f4df7de522d0eecbca133d7299259d..90ef647db7e610b825cc92d51ee2a5379dcf05b3 100755 (executable)
@@ -98,8 +98,4 @@ test_expect_success 'no config, edited' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 3f5291b85752e7bc78901da18c2bfa654134eb59..4e794a01bf556f97f94eaabf8cc259f333c75049 100755 (executable)
@@ -300,9 +300,4 @@ test_expect_success 'use --git-dir option and GIT_DIR' '
        test_path_is_file "$git"/cli_file2.t
 '
 
-
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 850d97911966fe78f22035dab78ac0556a82fd99..eaaae414a1ff22d127a51f047716800a8585d87a 100755 (executable)
@@ -593,8 +593,4 @@ test_expect_success 'update a shelve involving moved and copied files' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 11d2b5102cde384ad11540610a52f62c4732aa8c..58a9b3b71e6d88dfc9e3086fb515362e7c31e34a 100755 (executable)
@@ -83,8 +83,4 @@ test_expect_success SYMLINKS 'p4 client root symlink should stay symbolic' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 897b3c3034efcab3af88d8eddc4670e274361dd5..3cff1fce1b7464826412ece52ef394a551dce65e 100755 (executable)
@@ -836,8 +836,4 @@ test_expect_success 'quotes on both sides' '
        git_verify "cdir 1/file11" "cdir 1/file12"
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index cc53debe1955ece317f994b0e76f2b8470b0f4f6..57b533dc6fbaa9d9b82bdaf300b46a426c7b43b7 100755 (executable)
@@ -360,8 +360,4 @@ test_expect_failure 'Add keywords in git which do not match the default p4 value
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 602b0a5d5ceafcac6439491b463fee7867e7036f..c1446f26aba59e19b1610652a1db449e8bddca92 100755 (executable)
@@ -191,7 +191,7 @@ test_expect_success 'tag that cannot be exported' '
        (
                cd "$cli" &&
                p4 sync ... &&
-               !(p4 labels | grep GIT_TAG_ON_A_BRANCH)
+               ! p4 labels | grep GIT_TAG_ON_A_BRANCH
        )
 '
 
@@ -259,9 +259,4 @@ test_expect_success 'importing labels with missing revisions' '
        )
 '
 
-
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 0206771fbb91b734a626e628b21786805ebcfa22..254a7c244698a0140d6f5605d3013f72d9775310 100755 (executable)
@@ -211,8 +211,4 @@ test_expect_success 'wildcard files requiring keyword scrub' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 783c6ad1653142d174e4ddc6d49e1f631121be51..fd018c87a80636d7bb286fe596f299bbbbe6828b 100755 (executable)
@@ -138,8 +138,4 @@ test_expect_success 'not preserving user with mixed authorship' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 60baa06e27a0a6c45f580738e60f7fe8fa65373a..468767cbf4b93eb20f209fc25b46cc0f53d5b907 100755 (executable)
@@ -242,8 +242,4 @@ test_expect_success P4D_HAVE_CONFIGURABLE_RUN_MOVE_ALLOW \
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index eaf03a656329c7b4b9d0ed40c839232a81b310ac..9779dc0d11f33b6d8a6c5b8d8ffded834eddd8b2 100755 (executable)
@@ -422,8 +422,4 @@ test_expect_success 'cleanup chmod after submit cancel' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index d048bd33fa3c94402eb750b65553f72b955aa25f..932841003cfc4e3f6273087f8567d6c6a660bb0b 100755 (executable)
@@ -138,8 +138,4 @@ test_expect_failure 'move with lock taken' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index aac568eadfcab6198877d211d3e706cead68e302..96d25f0c02ccfb04391487b550a702751bf22a11 100755 (executable)
@@ -64,8 +64,4 @@ test_expect_success 'clone, then sync with exclude' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index ce7cb22ad37165c6976b4484f6b39a49747d4485..0db7ab99184add2c500f821659b09cc833c6a225 100755 (executable)
@@ -146,8 +146,4 @@ test_expect_success 'Clone repo with self-sizing block size' '
        test_line_count \> 10 log
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index d808c008c11700badffdcbbd34faba39428a47f1..600ce1e0b0d7edf193291a6a25450c92a5888475 100755 (executable)
@@ -53,8 +53,4 @@ test_expect_failure 'Clone UC repo with lc name' '
        test_must_fail git p4 clone //depot/uc/...
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 3c22f74bd436b7c6d94d5c29d5b2e3e3510d58e6..fa1bba1dd93614c8ad5c7f4a37c5b612440fd0eb 100755 (executable)
@@ -31,8 +31,4 @@ test_expect_success 'EDITOR with options' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 81e46acfa8ba10b8d0051acc1e7b19dc6b1de365..ef80f1690bcb9ad153df900e277ef48ce8e4e62e 100755 (executable)
@@ -193,8 +193,4 @@ test_expect_success 'Add a new file and clone path with new file (ignorecase)' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index c78477c19b4330f990c0cdd7d96997b8ed2ed02c..1bf7635016f54385912e7bd830eada93810a4bfc 100755 (executable)
@@ -67,8 +67,4 @@ test_expect_success 'Delete iso8859-1 encoded paths and clone' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 1f2dc369bfa96e767741484b421f42b56b3c0a18..88b76dc4d6c26fc99e32c91a11b2eb5bb7118e2c 100755 (executable)
@@ -185,8 +185,4 @@ test_expect_success 'Run git p4 submit in repo configured with large file system
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index ed80ca858c8f8352bd5a26b9a30e0c182d102ee9..a28dbbdd566ca69212f23958056d95b735a0127c 100755 (executable)
@@ -287,8 +287,4 @@ test_expect_success 'Add big files to repo and store files in LFS based on compr
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 1551845dc178e3cc57d31ac3e66f60db921be874..f049ff8229c6d38053dd3b3842e898e8473eaeb3 100755 (executable)
@@ -43,8 +43,4 @@ test_expect_failure 'clone depot with invalid UTF-16 file in non-verbose mode' '
        git p4 clone --dest="$git" //depot
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index fa8b9daf1fafba7498583e916cfea52d3c7207f5..fd64afe064e5a937b4a15d18f70e87cd524067c8 100755 (executable)
@@ -127,8 +127,4 @@ test_expect_success 'Clone repo subdir with all history' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 7433998f4779c7d1691e8c6fbb31fed3224c355d..d3670bd7a24dbf3cdc350939d6d130bd662f3e73 100755 (executable)
@@ -59,8 +59,4 @@ test_expect_success SYMLINKS 'change symbolic link to file' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index e20395c89f3dbc461516e22339f9fef47bd3426e..ca6c2942bdf200942cc4122e6172a120e0f1d1c1 100755 (executable)
@@ -54,8 +54,4 @@ test_expect_success 'Clone repo root path with all history' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 971aeeea1fb69ff5b73109d8b9496b5574317cd5..88cfb1fcd3f0a1401fd1cdb10f1fe697a5c4aaa3 100755 (executable)
@@ -92,8 +92,4 @@ test_expect_success 'check log message of changelist with more jobs' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 2ad1b0810df81ecaf5197e4cf860b3524d557c09..3fb6960c18fc0c2eb549f09c66d92b3f39822653 100755 (executable)
@@ -36,8 +36,4 @@ test_expect_success 'symlinked directory' '
 
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index be44c9751aefa5368d6f05d7b1c29f0c8354095f..d743ca33ee6ab29f97d328756663803824f105f5 100755 (executable)
@@ -96,8 +96,4 @@ test_expect_success 'submit description with extra info lines from verbose p4 ch
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
 test_done
index 41c09f11f4bf44ece085f952e8782d4dfe3fd169..1286a5b824b77d71061fb890d9f528b46ecc087d 100755 (executable)
@@ -174,8 +174,5 @@ test_expect_success 'unshelve specifying the origin' '
                test_path_is_file file_to_shelve
        )
 '
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
 
 test_done
index 47b312e1c9705af6f6ac6bb55ee81cb847f53d0c..e22369ccdf5f15840546269d0cdef9e8a54ce698 100755 (executable)
@@ -45,9 +45,4 @@ test_expect_success 'ticket logged out' '
        )
 '
 
-test_expect_success 'kill p4d' '
-       kill_p4d
-'
-
-
 test_done
index 681c41ba329a90db8c668fde4640025872f1e622..788ea1f18b99c5edacd9ae0ee81310141c799c6e 100644 (file)
@@ -943,6 +943,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 () {
index c14ebe68d3d1d1493ccf1aa220e0940597257ef8..38b157075a79bb7674394f4856a9781e2db22cae 100644 (file)
@@ -634,6 +634,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
@@ -645,7 +649,10 @@ die () {
 
 GIT_EXIT_OK=
 trap 'die' EXIT
-trap 'exit $?' INT TERM HUP
+# Disable '-x' tracing, because with some shells, notably dash, it
+# prevents running the cleanup commands when a test script run with
+# '--verbose-log -x' is interrupted.
+trap '{ code=$?; set +x; } 2>/dev/null; exit $code' INT TERM HUP
 
 # The user-facing functions are loaded from a separate file so that
 # test_perf subshells can have them too
@@ -1056,9 +1063,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" || {