]> git.ipfire.org Git - thirdparty/git.git/commitdiff
test-lib-functions: add and use a "test_hook" wrapper
authorÆvar Arnfjörð Bjarmason <avarab@gmail.com>
Thu, 17 Mar 2022 10:13:06 +0000 (11:13 +0100)
committerJunio C Hamano <gitster@pobox.com>
Thu, 17 Mar 2022 15:40:25 +0000 (08:40 -0700)
Add a "test_hook" wrapper similar to the existing "test_config"
wrapper added in d960c47a881 (test-lib: add helper functions for
config, 2011-08-17).

This wrapper:

 - Will clean up the hook with "test_when_finished", unless --setup is
   provided.

 - Will error if we clobber a hook, unless --clobber is provided.

 - Takes a name like "update" instead of ".git/hooks/update".

 - Accepts -C <dir>, like "test_config" and "test_commit".

By using a wrapper we'll be able to easily change all the hook-related
code that assumes that the template-created ".git/hooks" directory is
created by "init", "clone" etc. once another topic follows-up and
changes the test suite to stop creating trash directories using those
templates.

In addition this will make it easy to have the hooks configured using
the "configuration-based hooks" topic, once we get around to
integrating that. I.e. we'll be able to run the tests in a mode where
we sometimes create a .git/hooks/<name>, and other times create a
script in another location, and point the relevant configuration
snippet to it.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
13 files changed:
t/t1416-ref-transaction-hooks.sh
t/t1800-hook.sh
t/t5401-update-hooks.sh
t/t5406-remote-rejects.sh
t/t5409-colorize-remote-messages.sh
t/t5411-proc-receive-hook.sh
t/t5503-tagfollow.sh
t/t5510-fetch.sh
t/t5521-pull-options.sh
t/t5547-push-quarantine.sh
t/t5548-push-porcelain.sh
t/t7519-status-fsmonitor.sh
t/test-lib-functions.sh

index 4e1e84a91f365b1a625273a552a87ddb937be1b6..6fca1f08d9a11e374c686fdfd23581aa3da83a55 100755 (executable)
@@ -16,9 +16,8 @@ test_expect_success setup '
 '
 
 test_expect_success 'hook allows updating ref if successful' '
-       test_when_finished "rm .git/hooks/reference-transaction" &&
        git reset --hard PRE &&
-       write_script .git/hooks/reference-transaction <<-\EOF &&
+       test_hook reference-transaction <<-\EOF &&
                echo "$*" >>actual
        EOF
        cat >expect <<-EOF &&
@@ -30,9 +29,8 @@ test_expect_success 'hook allows updating ref if successful' '
 '
 
 test_expect_success 'hook aborts updating ref in prepared state' '
-       test_when_finished "rm .git/hooks/reference-transaction" &&
        git reset --hard PRE &&
-       write_script .git/hooks/reference-transaction <<-\EOF &&
+       test_hook reference-transaction <<-\EOF &&
                if test "$1" = prepared
                then
                        exit 1
@@ -43,9 +41,9 @@ test_expect_success 'hook aborts updating ref in prepared state' '
 '
 
 test_expect_success 'hook gets all queued updates in prepared state' '
-       test_when_finished "rm .git/hooks/reference-transaction actual" &&
+       test_when_finished "rm actual" &&
        git reset --hard PRE &&
-       write_script .git/hooks/reference-transaction <<-\EOF &&
+       test_hook reference-transaction <<-\EOF &&
                if test "$1" = prepared
                then
                        while read -r line
@@ -66,9 +64,9 @@ test_expect_success 'hook gets all queued updates in prepared state' '
 '
 
 test_expect_success 'hook gets all queued updates in committed state' '
-       test_when_finished "rm .git/hooks/reference-transaction actual" &&
+       test_when_finished "rm actual" &&
        git reset --hard PRE &&
-       write_script .git/hooks/reference-transaction <<-\EOF &&
+       test_hook reference-transaction <<-\EOF &&
                if test "$1" = committed
                then
                        while read -r line
@@ -86,9 +84,9 @@ test_expect_success 'hook gets all queued updates in committed state' '
 '
 
 test_expect_success 'hook gets all queued updates in aborted state' '
-       test_when_finished "rm .git/hooks/reference-transaction actual" &&
+       test_when_finished "rm actual" &&
        git reset --hard PRE &&
-       write_script .git/hooks/reference-transaction <<-\EOF &&
+       test_hook reference-transaction <<-\EOF &&
                if test "$1" = aborted
                then
                        while read -r line
@@ -115,11 +113,11 @@ test_expect_success 'interleaving hook calls succeed' '
 
        git init --bare target-repo.git &&
 
-       write_script target-repo.git/hooks/reference-transaction <<-\EOF &&
+       test_hook -C target-repo.git reference-transaction <<-\EOF &&
                echo $0 "$@" >>actual
        EOF
 
-       write_script target-repo.git/hooks/update <<-\EOF &&
+       test_hook -C target-repo.git update <<-\EOF &&
                echo $0 "$@" >>actual
        EOF
 
@@ -140,7 +138,7 @@ test_expect_success 'hook does not get called on packing refs' '
        # Pack references first such that we are in a known state.
        git pack-refs --all &&
 
-       write_script .git/hooks/reference-transaction <<-\EOF &&
+       test_hook reference-transaction <<-\EOF &&
                echo "$@" >>actual
                cat >>actual
        EOF
@@ -166,7 +164,7 @@ test_expect_success 'deleting packed ref calls hook once' '
        git update-ref refs/heads/to-be-deleted $POST_OID &&
        git pack-refs --all &&
 
-       write_script .git/hooks/reference-transaction <<-\EOF &&
+       test_hook reference-transaction <<-\EOF &&
                echo "$@" >>actual
                cat >>actual
        EOF
index 29718aa99137edbf3a350352cfeecd50bb1df8c3..93540b1fa1256dc6faf36746462a119f32c4ef57 100755 (executable)
@@ -27,7 +27,7 @@ test_expect_success 'git hook run: nonexistent hook with --ignore-missing' '
 '
 
 test_expect_success 'git hook run: basic' '
-       write_script .git/hooks/test-hook <<-EOF &&
+       test_hook test-hook <<-EOF &&
        echo Test hook
        EOF
 
@@ -39,7 +39,7 @@ test_expect_success 'git hook run: basic' '
 '
 
 test_expect_success 'git hook run: stdout and stderr both write to our stderr' '
-       write_script .git/hooks/test-hook <<-EOF &&
+       test_hook test-hook <<-EOF &&
        echo >&1 Will end up on stderr
        echo >&2 Will end up on stderr
        EOF
@@ -84,7 +84,7 @@ test_expect_success 'git hook run arg u ments without -- is not allowed' '
 '
 
 test_expect_success 'git hook run -- pass arguments' '
-       write_script .git/hooks/test-hook <<-\EOF &&
+       test_hook test-hook <<-\EOF &&
        echo $1
        echo $2
        EOF
@@ -99,7 +99,7 @@ test_expect_success 'git hook run -- pass arguments' '
 '
 
 test_expect_success 'git hook run -- out-of-repo runs excluded' '
-       write_script .git/hooks/test-hook <<-EOF &&
+       test_hook test-hook <<-EOF &&
        echo Test hook
        EOF
 
@@ -120,6 +120,10 @@ test_expect_success 'git -c core.hooksPath=<PATH> hook run' '
        Hook ran four
        EOF
 
+       test_hook test-hook <<-EOF &&
+       echo Test hook
+       EOF
+
        # Test various ways of specifying the path. See also
        # t1350-config-hooks-path.sh
        >actual &&
index 6012cc8172a6bd6e9acad5fc84ddb87cb67815b9..799349a416c90ec37781332bf25981bbb925923d 100755 (executable)
@@ -136,7 +136,7 @@ test_expect_success 'send-pack stderr contains hook messages' '
 '
 
 test_expect_success 'pre-receive hook that forgets to read its input' '
-       write_script victim.git/hooks/pre-receive <<-\EOF &&
+       test_hook --clobber -C victim.git pre-receive <<-\EOF &&
        exit 0
        EOF
        rm -f victim.git/hooks/update victim.git/hooks/post-update &&
index 5c509db6fc378ebf646833d349ef12fd192f2774..dcbeb42082791ba0bb2683e9f78b545250d380fc 100755 (executable)
@@ -5,7 +5,7 @@ test_description='remote push rejects are reported by client'
 . ./test-lib.sh
 
 test_expect_success 'setup' '
-       write_script .git/hooks/update <<-\EOF &&
+       test_hook update <<-\EOF &&
        exit 1
        EOF
        echo 1 >file &&
index 9f1a483f426ea954af03029eafd1e573fd99cd29..fa5de4500a4f50d48067ef6b1c05491b360a11f4 100755 (executable)
@@ -5,7 +5,7 @@ test_description='remote messages are colorized on the client'
 . ./test-lib.sh
 
 test_expect_success 'setup' '
-       write_script .git/hooks/update <<-\EOF &&
+       test_hook --setup update <<-\EOF &&
        echo error: error
        echo ERROR: also highlighted
        echo hint: hint
index 98b0e81208293b10a57cf8e20a8f3a621ae1f4d1..92cf52c6d4a32c401680a068f9d892950e13d99a 100755 (executable)
@@ -36,7 +36,7 @@ setup_upstream_and_workbench () {
                TAG=$(git -C workbench rev-parse v123) &&
 
                # setup pre-receive hook
-               write_script upstream.git/hooks/pre-receive <<-\EOF &&
+               test_hook --setup -C upstream.git pre-receive <<-\EOF &&
                exec >&2
                echo "# pre-receive hook"
                while read old new ref
@@ -46,7 +46,7 @@ setup_upstream_and_workbench () {
                EOF
 
                # setup post-receive hook
-               write_script upstream.git/hooks/post-receive <<-\EOF &&
+               test_hook --setup -C upstream.git post-receive <<-\EOF &&
                exec >&2
                echo "# post-receive hook"
                while read old new ref
index a3c01014b7ee445d7e51c6735faea36f46833bfb..acdb731edfe816fede94fc2cdcb5f9f04c60a110 100755 (executable)
@@ -169,7 +169,7 @@ test_expect_success 'atomic fetch with failing backfill' '
        # one of both fails to update correctly.
        #
        # To trigger failure we simply abort when backfilling a tag.
-       write_script clone3/.git/hooks/reference-transaction <<-\EOF &&
+       test_hook -C clone3 reference-transaction <<-\EOF &&
                while read oldrev newrev reference
                do
                        if test "$reference" = refs/tags/tag1
@@ -201,7 +201,7 @@ test_expect_success 'atomic fetch with backfill should use single transaction' '
                $ZERO_OID $T refs/tags/tag1
        EOF
 
-       write_script clone4/.git/hooks/reference-transaction <<-\EOF &&
+       test_hook -C clone4 reference-transaction <<-\EOF &&
                ( echo "$*" && cat ) >>actual
        EOF
 
index 48e14e2dab1dc38055370655237ade6ff2fc1bd9..6f38a69fbb2c2d4fc0f7479971e880be211bb186 100755 (executable)
@@ -273,7 +273,7 @@ test_expect_success 'fetch --atomic executes a single reference transaction only
        EOF
 
        rm -f atomic/actual &&
-       write_script atomic/.git/hooks/reference-transaction <<-\EOF &&
+       test_hook -C atomic reference-transaction <<-\EOF &&
                ( echo "$*" && cat ) >>actual
        EOF
 
@@ -306,7 +306,7 @@ test_expect_success 'fetch --atomic aborts all reference updates if hook aborts'
        EOF
 
        rm -f atomic/actual &&
-       write_script atomic/.git/hooks/reference-transaction <<-\EOF &&
+       test_hook -C atomic/.git reference-transaction <<-\EOF &&
                ( echo "$*" && cat ) >>actual
                exit 1
        EOF
@@ -334,7 +334,7 @@ test_expect_success 'fetch --atomic --append appends to FETCH_HEAD' '
        test_line_count = 2 atomic/.git/FETCH_HEAD &&
        cp atomic/.git/FETCH_HEAD expected &&
 
-       write_script atomic/.git/hooks/reference-transaction <<-\EOF &&
+       test_hook -C atomic reference-transaction <<-\EOF &&
                exit 1
        EOF
 
@@ -364,7 +364,7 @@ test_expect_success 'fetch --atomic --prune executes a single reference transact
                $ZERO_OID $head_oid refs/remotes/origin/new-branch
        EOF
 
-       write_script atomic/.git/hooks/reference-transaction <<-\EOF &&
+       test_hook -C atomic reference-transaction <<-\EOF &&
                ( echo "$*" && cat ) >>actual
        EOF
 
index 66cfcb09c552c9122e648ec01b9ff4793de6ca7c..264de29c35c11cbe09d31d57629aabaae0423b35 100755 (executable)
@@ -233,7 +233,7 @@ test_expect_success 'git pull --no-verify flag passed to merge' '
        git init src &&
        test_commit -C src one &&
        git clone src dst &&
-       write_script dst/.git/hooks/commit-msg <<-\EOF &&
+       test_hook -C dst commit-msg <<-\EOF &&
        false
        EOF
        test_commit -C src two &&
@@ -245,7 +245,7 @@ test_expect_success 'git pull --no-verify --verify passed to merge' '
        git init src &&
        test_commit -C src one &&
        git clone src dst &&
-       write_script dst/.git/hooks/commit-msg <<-\EOF &&
+       test_hook -C dst commit-msg <<-\EOF &&
        false
        EOF
        test_commit -C src two &&
index faaa51ccc562545c18180410e68483019a80832d..1876fb34e51a09f8b3d7f6d82d174044c9a16c84 100755 (executable)
@@ -5,7 +5,7 @@ test_description='check quarantine of objects during push'
 
 test_expect_success 'create picky dest repo' '
        git init --bare dest.git &&
-       write_script dest.git/hooks/pre-receive <<-\EOF
+       test_hook --setup -C dest.git pre-receive <<-\EOF
        while read old new ref; do
                test "$(git log -1 --format=%s $new)" = reject && exit 1
        done
@@ -60,7 +60,7 @@ test_expect_success 'push to repo path with path separator (colon)' '
 
 test_expect_success 'updating a ref from quarantine is forbidden' '
        git init --bare update.git &&
-       write_script update.git/hooks/pre-receive <<-\EOF &&
+       test_hook -C update.git pre-receive <<-\EOF &&
        read old new refname
        git update-ref refs/heads/unrelated $new
        exit 1
index f11ff57e5499a1724841d27cd09c61e18108ce8f..6282728eaf3e7871d99fea48357298f6b14c9fd2 100755 (executable)
@@ -168,7 +168,7 @@ run_git_push_porcelain_output_test() {
        '
 
        test_expect_success "prepare pre-receive hook ($PROTOCOL)" '
-               write_script "$upstream/hooks/pre-receive" <<-EOF
+               test_hook --setup -C "$upstream" pre-receive <<-EOF
                exit 1
                EOF
        '
index fffc57120d651fa530bd4c8d1ba54a85fdedf396..4c7c00c94f17313a8d29fb02aead763a45afb1d6 100755 (executable)
@@ -26,7 +26,7 @@ dirty_repo () {
 }
 
 write_integration_script () {
-       write_script .git/hooks/fsmonitor-test<<-\EOF
+       test_hook --setup --clobber fsmonitor-test<<-\EOF
        if test "$#" -ne 2
        then
                echo "$0: exactly 2 arguments expected"
@@ -108,7 +108,7 @@ EOF
 
 # test that "update-index --fsmonitor-valid" sets the fsmonitor valid bit
 test_expect_success 'update-index --fsmonitor-valid" sets the fsmonitor valid bit' '
-       write_script .git/hooks/fsmonitor-test<<-\EOF &&
+       test_hook fsmonitor-test<<-\EOF &&
                printf "last_update_token\0"
        EOF
        git update-index --fsmonitor &&
@@ -169,7 +169,7 @@ EOF
 
 # test that newly added files are marked valid
 test_expect_success 'newly added files are marked valid' '
-       write_script .git/hooks/fsmonitor-test<<-\EOF &&
+       test_hook --setup --clobber fsmonitor-test<<-\EOF &&
                printf "last_update_token\0"
        EOF
        git add new &&
@@ -210,7 +210,7 @@ EOF
 
 # test that *only* files returned by the integration script get flagged as invalid
 test_expect_success '*only* files returned by the integration script get flagged as invalid' '
-       write_script .git/hooks/fsmonitor-test<<-\EOF &&
+       test_hook --clobber fsmonitor-test<<-\EOF &&
        printf "last_update_token\0"
        printf "dir1/modified\0"
        EOF
@@ -231,7 +231,7 @@ test_expect_success 'refresh_index() invalidates fsmonitor cache' '
        dirty_repo &&
        write_integration_script &&
        git add . &&
-       write_script .git/hooks/fsmonitor-test<<-\EOF &&
+       test_hook --clobber fsmonitor-test<<-\EOF &&
        EOF
        git commit -m "to reset" &&
        git reset HEAD~1 &&
@@ -280,7 +280,7 @@ do
                # Make sure it's actually skipping the check for modified and untracked
                # (if enabled) files unless it is told about them.
                test_expect_success "status doesn't detect unreported modifications" '
-                       write_script .git/hooks/fsmonitor-test<<-\EOF &&
+                       test_hook --clobber fsmonitor-test<<-\EOF &&
                        printf "last_update_token\0"
                        :>marker
                        EOF
@@ -414,14 +414,14 @@ test_expect_success 'status succeeds with sparse index' '
                git -C sparse sparse-checkout init --cone --sparse-index &&
                git -C sparse sparse-checkout set dir1 dir2 &&
 
-               write_script .git/hooks/fsmonitor-test <<-\EOF &&
+               test_hook --clobber fsmonitor-test <<-\EOF &&
                        printf "last_update_token\0"
                EOF
                git -C full config core.fsmonitor ../.git/hooks/fsmonitor-test &&
                git -C sparse config core.fsmonitor ../.git/hooks/fsmonitor-test &&
                check_sparse_index_behavior ! &&
 
-               write_script .git/hooks/fsmonitor-test <<-\EOF &&
+               test_hook --clobber fsmonitor-test <<-\EOF &&
                        printf "last_update_token\0"
                        printf "dir1/modified\0"
                EOF
@@ -439,7 +439,7 @@ test_expect_success 'status succeeds with sparse index' '
 
                # This one modifies outside the sparse-checkout definition
                # and hence we expect to expand the sparse-index.
-               write_script .git/hooks/fsmonitor-test <<-\EOF &&
+               test_hook --clobber fsmonitor-test <<-\EOF &&
                        printf "last_update_token\0"
                        printf "dir1a/modified\0"
                EOF
index 0f439c99d6109110786db0492111ebdb945342a6..6c9c61c79c2dd3b813c460a49297d5f46b5bcfe7 100644 (file)
@@ -551,6 +551,58 @@ write_script () {
        chmod +x "$1"
 }
 
+# Usage: test_hook [options] <hook-name> <<-\EOF
+#
+#   -C <dir>:
+#      Run all git commands in directory <dir>
+#   --setup
+#      Setup a hook for subsequent tests, i.e. don't remove it in a
+#      "test_when_finished"
+#   --clobber
+#      Overwrite an existing <hook-name>, if it exists. Implies
+#      --setup (i.e. the "test_when_finished" is assumed to have been
+#      set up already).
+test_hook () {
+       setup= &&
+       clobber= &&
+       indir= &&
+       while test $# != 0
+       do
+               case "$1" in
+               -C)
+                       indir="$2" &&
+                       shift
+                       ;;
+               --setup)
+                       setup=t
+                       ;;
+               --clobber)
+                       clobber=t
+                       ;;
+               -*)
+                       BUG "invalid argument: $1"
+                       ;;
+               *)
+                       break
+                       ;;
+               esac &&
+               shift
+       done &&
+
+       git_dir=$(git -C "$indir" rev-parse --absolute-git-dir) &&
+       hook_dir="$git_dir/hooks" &&
+       hook_file="$hook_dir/$1" &&
+       if test -z "$clobber"
+       then
+               test_path_is_missing "$hook_file"
+       fi &&
+       if test -z "$setup$clobber"
+       then
+               test_when_finished "rm \"$hook_file\""
+       fi &&
+       write_script "$hook_file"
+}
+
 # Use test_set_prereq to tell that a particular prerequisite is available.
 # The prerequisite can later be checked for in two ways:
 #