@matheusbsbs / matheus-bagliano / commits / 38b9197a76
Fork 0

t5411: add basic test cases for proc-receive hook

Topic "proc-receive-hook" will change the workflow and output of git-push. Add some basic test cases in t5411 before introducing the new topic. Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jiang Xin committed Aug 27, 2020 at 11:45 UTC 38b9197a76a77671a8f48e423236739e7556c20d
6 files changed +521
t/t5411-proc-receive-hook.sh new
+108
@@ -0,0 +1,108 @@
1 +#!/bin/sh
2 +#
3 +# Copyright (c) 2020 Jiang Xin
4 +#
5 +
6 +test_description='Test proc-receive hook'
7 +
8 +. ./test-lib.sh
9 +
10 +. "$TEST_DIRECTORY"/t5411/common-functions.sh
11 +
12 +setup_upstream_and_workbench () {
13 + # Refs of upstream : master(A)
14 + # Refs of workbench: master(A) tags/v123
15 + test_expect_success "setup upstream and workbench" '
16 + rm -rf upstream.git &&
17 + rm -rf workbench &&
18 + git init --bare upstream.git &&
19 + git init workbench &&
20 + create_commits_in workbench A B &&
21 + (
22 + cd workbench &&
23 + # Try to make a stable fixed width for abbreviated commit ID,
24 + # this fixed-width oid will be replaced with "<OID>".
25 + git config core.abbrev 7 &&
26 + git tag -m "v123" v123 $A &&
27 + git remote add origin ../upstream.git &&
28 + git push origin master &&
29 + git update-ref refs/heads/master $A $B &&
30 + git -C ../upstream.git update-ref \
31 + refs/heads/master $A $B
32 + ) &&
33 + TAG=$(git -C workbench rev-parse v123) &&
34 +
35 + # setup pre-receive hook
36 + write_script upstream.git/hooks/pre-receive <<-\EOF &&
37 + exec >&2
38 + echo "# pre-receive hook"
39 + while read old new ref
40 + do
41 + echo "pre-receive< $old $new $ref"
42 + done
43 + EOF
44 +
45 + # setup post-receive hook
46 + write_script upstream.git/hooks/post-receive <<-\EOF &&
47 + exec >&2
48 + echo "# post-receive hook"
49 + while read old new ref
50 + do
51 + echo "post-receive< $old $new $ref"
52 + done
53 + EOF
54 +
55 + upstream=upstream.git
56 + '
57 +}
58 +
59 +run_proc_receive_hook_test() {
60 + case $1 in
61 + http)
62 + PROTOCOL="HTTP protocol"
63 + URL_PREFIX="http://.*"
64 + ;;
65 + local)
66 + PROTOCOL="builtin protocol"
67 + URL_PREFIX="\.\."
68 + ;;
69 + esac
70 +
71 + # Include test cases for both file and HTTP protocol
72 + for t in "$TEST_DIRECTORY"/t5411/test-*.sh
73 + do
74 + . "$t"
75 + done
76 +}
77 +
78 +# Initialize the upstream repository and local workbench.
79 +setup_upstream_and_workbench
80 +
81 +# Run test cases for 'proc-receive' hook on local file protocol.
82 +run_proc_receive_hook_test local
83 +
84 +ROOT_PATH="$PWD"
85 +. "$TEST_DIRECTORY"/lib-gpg.sh
86 +. "$TEST_DIRECTORY"/lib-httpd.sh
87 +. "$TEST_DIRECTORY"/lib-terminal.sh
88 +start_httpd
89 +
90 +# Re-initialize the upstream repository and local workbench.
91 +setup_upstream_and_workbench
92 +
93 +# Refs of upstream : master(A)
94 +# Refs of workbench: master(A) tags/v123
95 +test_expect_success "setup for HTTP protocol" '
96 + git -C upstream.git config http.receivepack true &&
97 + upstream="$HTTPD_DOCUMENT_ROOT_PATH/upstream.git" &&
98 + mv upstream.git "$upstream" &&
99 + git -C workbench remote set-url origin "$HTTPD_URL/auth-push/smart/upstream.git" &&
100 + set_askpass user@host pass@host
101 +'
102 +
103 +setup_askpass_helper
104 +
105 +# Run test cases for 'proc-receive' hook on HTTP protocol.
106 +run_proc_receive_hook_test http
107 +
108 +test_done
t/t5411/common-functions.sh new
+56
@@ -0,0 +1,56 @@
1 +# Create commits in <repo> and assign each commit's oid to shell variables
2 +# given in the arguments (A, B, and C). E.g.:
3 +#
4 +# create_commits_in <repo> A B C
5 +#
6 +# NOTE: Never calling this function from a subshell since variable
7 +# assignments will disappear when subshell exits.
8 +create_commits_in () {
9 + repo="$1" &&
10 + if ! parent=$(git -C "$repo" rev-parse HEAD^{} --)
11 + then
12 + parent=
13 + fi &&
14 + T=$(git -C "$repo" write-tree) &&
15 + shift &&
16 + while test $# -gt 0
17 + do
18 + name=$1 &&
19 + test_tick &&
20 + if test -z "$parent"
21 + then
22 + oid=$(echo $name | git -C "$repo" commit-tree $T)
23 + else
24 + oid=$(echo $name | git -C "$repo" commit-tree -p $parent $T)
25 + fi &&
26 + eval $name=$oid &&
27 + parent=$oid &&
28 + shift ||
29 + return 1
30 + done &&
31 + git -C "$repo" update-ref refs/heads/master $oid
32 +}
33 +
34 +# Format the output of git-push, git-show-ref and other commands to make a
35 +# user-friendly and stable text. We can easily prepare the expect text
36 +# without having to worry about future changes of the commit ID and spaces
37 +# of the output. Single quotes are replaced with double quotes, because
38 +# it is boring to prepare unquoted single quotes in expect text. We also
39 +# remove some locale error messages, which break test if we turn on
40 +# `GIT_TEST_GETTEXT_POISON=true` in order to test unintentional translations
41 +# on plumbing commands.
42 +make_user_friendly_and_stable_output () {
43 + sed \
44 + -e "s/ *\$//" \
45 + -e "s/ */ /g" \
46 + -e "s/'/\"/g" \
47 + -e "s/ / /g" \
48 + -e "s/$A/<COMMIT-A>/g" \
49 + -e "s/$B/<COMMIT-B>/g" \
50 + -e "s/$TAG/<TAG-v123>/g" \
51 + -e "s/$ZERO_OID/<ZERO-OID>/g" \
52 + -e "s/$(echo $A | cut -c1-7)[0-9a-f]*/<OID-A>/g" \
53 + -e "s/$(echo $B | cut -c1-7)[0-9a-f]*/<OID-B>/g" \
54 + -e "s#To $URL_PREFIX/upstream.git#To <URL/of/upstream.git>#" \
55 + -e "/^error: / d"
56 +}
t/t5411/test-0000-standard-git-push.sh new
+143
@@ -0,0 +1,143 @@
1 +# Refs of upstream : master(A)
2 +# Refs of workbench: master(A) tags/v123
3 +# git-push : master(B) next(A)
4 +test_expect_success "git-push ($PROTOCOL)" '
5 + git -C workbench push origin \
6 + $B:refs/heads/master \
7 + HEAD:refs/heads/next \
8 + >out 2>&1 &&
9 + make_user_friendly_and_stable_output <out >actual &&
10 + cat >expect <<-EOF &&
11 + remote: # pre-receive hook
12 + remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
13 + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
14 + remote: # post-receive hook
15 + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
16 + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
17 + To <URL/of/upstream.git>
18 + <OID-A>..<OID-B> <COMMIT-B> -> master
19 + * [new branch] HEAD -> next
20 + EOF
21 + test_cmp expect actual &&
22 + git -C "$upstream" show-ref >out &&
23 + make_user_friendly_and_stable_output <out >actual &&
24 + cat >expect <<-EOF &&
25 + <COMMIT-B> refs/heads/master
26 + <COMMIT-A> refs/heads/next
27 + EOF
28 + test_cmp expect actual
29 +'
30 +
31 +# Refs of upstream : master(B) next(A)
32 +# Refs of workbench: master(A) tags/v123
33 +# git-push --atomic: master(A) next(B)
34 +test_expect_success "git-push --atomic ($PROTOCOL)" '
35 + test_must_fail git -C workbench push --atomic origin \
36 + master \
37 + $B:refs/heads/next \
38 + >out 2>&1 &&
39 + make_user_friendly_and_stable_output <out |
40 + sed -n \
41 + -e "/^To / { s/ */ /g; p; }" \
42 + -e "/^ ! / { s/ */ /g; p; }" \
43 + >actual &&
44 + cat >expect <<-EOF &&
45 + To <URL/of/upstream.git>
46 + ! [rejected] master -> master (non-fast-forward)
47 + ! [rejected] <COMMIT-B> -> next (atomic push failed)
48 + EOF
49 + test_cmp expect actual &&
50 + git -C "$upstream" show-ref >out &&
51 + make_user_friendly_and_stable_output <out >actual &&
52 + cat >expect <<-EOF &&
53 + <COMMIT-B> refs/heads/master
54 + <COMMIT-A> refs/heads/next
55 + EOF
56 + test_cmp expect actual
57 +'
58 +
59 +# Refs of upstream : master(B) next(A)
60 +# Refs of workbench: master(A) tags/v123
61 +# git-push : master(A) next(B)
62 +test_expect_success "non-fast-forward git-push ($PROTOCOL)" '
63 + test_must_fail git \
64 + -C workbench \
65 + -c advice.pushUpdateRejected=false \
66 + push origin \
67 + master \
68 + $B:refs/heads/next \
69 + >out 2>&1 &&
70 + make_user_friendly_and_stable_output <out >actual &&
71 + cat >expect <<-EOF &&
72 + remote: # pre-receive hook
73 + remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/next
74 + remote: # post-receive hook
75 + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/next
76 + To <URL/of/upstream.git>
77 + <OID-A>..<OID-B> <COMMIT-B> -> next
78 + ! [rejected] master -> master (non-fast-forward)
79 + EOF
80 + test_cmp expect actual &&
81 + git -C "$upstream" show-ref >out &&
82 + make_user_friendly_and_stable_output <out >actual &&
83 + cat >expect <<-EOF &&
84 + <COMMIT-B> refs/heads/master
85 + <COMMIT-B> refs/heads/next
86 + EOF
87 + test_cmp expect actual
88 +'
89 +
90 +# Refs of upstream : master(B) next(B)
91 +# Refs of workbench: master(A) tags/v123
92 +# git-push -f : master(A) NULL tags/v123 refs/review/master/topic(A) a/b/c(A)
93 +test_expect_success "git-push -f ($PROTOCOL)" '
94 + git -C workbench push -f origin \
95 + refs/tags/v123 \
96 + :refs/heads/next \
97 + master \
98 + master:refs/review/master/topic \
99 + HEAD:refs/heads/a/b/c \
100 + >out 2>&1 &&
101 + make_user_friendly_and_stable_output <out >actual &&
102 + cat >expect <<-EOF &&
103 + remote: # pre-receive hook
104 + remote: pre-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
105 + remote: pre-receive< <COMMIT-B> <ZERO-OID> refs/heads/next
106 + remote: pre-receive< <ZERO-OID> <TAG-v123> refs/tags/v123
107 + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic
108 + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c
109 + remote: # post-receive hook
110 + remote: post-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
111 + remote: post-receive< <COMMIT-B> <ZERO-OID> refs/heads/next
112 + remote: post-receive< <ZERO-OID> <TAG-v123> refs/tags/v123
113 + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic
114 + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c
115 + To <URL/of/upstream.git>
116 + + <OID-B>...<OID-A> master -> master (forced update)
117 + - [deleted] next
118 + * [new tag] v123 -> v123
119 + * [new reference] master -> refs/review/master/topic
120 + * [new branch] HEAD -> a/b/c
121 + EOF
122 + test_cmp expect actual &&
123 + git -C "$upstream" show-ref >out &&
124 + make_user_friendly_and_stable_output <out >actual &&
125 + cat >expect <<-EOF &&
126 + <COMMIT-A> refs/heads/a/b/c
127 + <COMMIT-A> refs/heads/master
128 + <COMMIT-A> refs/review/master/topic
129 + <TAG-v123> refs/tags/v123
130 + EOF
131 + test_cmp expect actual
132 +'
133 +
134 +# Refs of upstream : master(A) tags/v123 refs/review/master/topic(A) a/b/c(A)
135 +# Refs of workbench: master(A) tags/v123
136 +test_expect_success "cleanup ($PROTOCOL)" '
137 + (
138 + cd "$upstream" &&
139 + git update-ref -d refs/review/master/topic &&
140 + git update-ref -d refs/tags/v123 &&
141 + git update-ref -d refs/heads/a/b/c
142 + )
143 +'
t/t5411/test-0001-standard-git-push--porcelain.sh new
+147
@@ -0,0 +1,147 @@
1 +# Refs of upstream : master(A)
2 +# Refs of workbench: master(A) tags/v123
3 +# git-push : master(B) next(A)
4 +test_expect_success "git-push ($PROTOCOL/porcelain)" '
5 + git -C workbench push --porcelain origin \
6 + $B:refs/heads/master \
7 + HEAD:refs/heads/next \
8 + >out 2>&1 &&
9 + make_user_friendly_and_stable_output <out >actual &&
10 + cat >expect <<-EOF &&
11 + remote: # pre-receive hook
12 + remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
13 + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
14 + remote: # post-receive hook
15 + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
16 + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
17 + To <URL/of/upstream.git>
18 + <COMMIT-B>:refs/heads/master <OID-A>..<OID-B>
19 + * HEAD:refs/heads/next [new branch]
20 + Done
21 + EOF
22 + test_cmp expect actual &&
23 + git -C "$upstream" show-ref >out &&
24 + make_user_friendly_and_stable_output <out >actual &&
25 + cat >expect <<-EOF &&
26 + <COMMIT-B> refs/heads/master
27 + <COMMIT-A> refs/heads/next
28 + EOF
29 + test_cmp expect actual
30 +'
31 +
32 +# Refs of upstream : master(B) next(A)
33 +# Refs of workbench: master(A) tags/v123
34 +# git-push --atomic: master(A) next(B)
35 +test_expect_success "git-push --atomic ($PROTOCOL/porcelain)" '
36 + test_must_fail git -C workbench push --atomic --porcelain origin \
37 + master \
38 + $B:refs/heads/next \
39 + >out 2>&1 &&
40 + make_user_friendly_and_stable_output <out |
41 + sed -n \
42 + -e "s/^# GETTEXT POISON #//" \
43 + -e "/^To / { s/ */ /g; p; }" \
44 + -e "/^! / { s/ */ /g; p; }" \
45 + >actual &&
46 + cat >expect <<-EOF &&
47 + To <URL/of/upstream.git>
48 + ! refs/heads/master:refs/heads/master [rejected] (non-fast-forward)
49 + ! <COMMIT-B>:refs/heads/next [rejected] (atomic push failed)
50 + EOF
51 + test_cmp expect actual &&
52 + git -C "$upstream" show-ref >out &&
53 + make_user_friendly_and_stable_output <out >actual &&
54 + cat >expect <<-EOF &&
55 + <COMMIT-B> refs/heads/master
56 + <COMMIT-A> refs/heads/next
57 + EOF
58 + test_cmp expect actual
59 +'
60 +
61 +# Refs of upstream : master(B) next(A)
62 +# Refs of workbench: master(A) tags/v123
63 +# git-push : master(A) next(B)
64 +test_expect_success "non-fast-forward git-push ($PROTOCOL/porcelain)" '
65 + test_must_fail git \
66 + -C workbench \
67 + -c advice.pushUpdateRejected=false \
68 + push --porcelain origin \
69 + master \
70 + $B:refs/heads/next \
71 + >out 2>&1 &&
72 + make_user_friendly_and_stable_output <out >actual &&
73 + cat >expect <<-EOF &&
74 + remote: # pre-receive hook
75 + remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/next
76 + remote: # post-receive hook
77 + remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/next
78 + To <URL/of/upstream.git>
79 + <COMMIT-B>:refs/heads/next <OID-A>..<OID-B>
80 + ! refs/heads/master:refs/heads/master [rejected] (non-fast-forward)
81 + Done
82 + EOF
83 + test_cmp expect actual &&
84 + git -C "$upstream" show-ref >out &&
85 + make_user_friendly_and_stable_output <out >actual &&
86 + cat >expect <<-EOF &&
87 + <COMMIT-B> refs/heads/master
88 + <COMMIT-B> refs/heads/next
89 + EOF
90 + test_cmp expect actual
91 +'
92 +
93 +# Refs of upstream : master(B) next(B)
94 +# Refs of workbench: master(A) tags/v123
95 +# git-push -f : master(A) NULL tags/v123 refs/review/master/topic(A) a/b/c(A)
96 +test_expect_success "git-push -f ($PROTOCOL/porcelain)" '
97 + git -C workbench push --porcelain -f origin \
98 + refs/tags/v123 \
99 + :refs/heads/next \
100 + master \
101 + master:refs/review/master/topic \
102 + HEAD:refs/heads/a/b/c \
103 + >out 2>&1 &&
104 + make_user_friendly_and_stable_output <out >actual &&
105 + cat >expect <<-EOF &&
106 + remote: # pre-receive hook
107 + remote: pre-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
108 + remote: pre-receive< <COMMIT-B> <ZERO-OID> refs/heads/next
109 + remote: pre-receive< <ZERO-OID> <TAG-v123> refs/tags/v123
110 + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic
111 + remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c
112 + remote: # post-receive hook
113 + remote: post-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
114 + remote: post-receive< <COMMIT-B> <ZERO-OID> refs/heads/next
115 + remote: post-receive< <ZERO-OID> <TAG-v123> refs/tags/v123
116 + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic
117 + remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c
118 + To <URL/of/upstream.git>
119 + + refs/heads/master:refs/heads/master <OID-B>...<OID-A> (forced update)
120 + - :refs/heads/next [deleted]
121 + * refs/tags/v123:refs/tags/v123 [new tag]
122 + * refs/heads/master:refs/review/master/topic [new reference]
123 + * HEAD:refs/heads/a/b/c [new branch]
124 + Done
125 + EOF
126 + test_cmp expect actual &&
127 + git -C "$upstream" show-ref >out &&
128 + make_user_friendly_and_stable_output <out >actual &&
129 + cat >expect <<-EOF &&
130 + <COMMIT-A> refs/heads/a/b/c
131 + <COMMIT-A> refs/heads/master
132 + <COMMIT-A> refs/review/master/topic
133 + <TAG-v123> refs/tags/v123
134 + EOF
135 + test_cmp expect actual
136 +'
137 +
138 +# Refs of upstream : master(A) tags/v123 refs/review/master/topic(A) a/b/c(A)
139 +# Refs of workbench: master(A) tags/v123
140 +test_expect_success "cleanup ($PROTOCOL/porcelain)" '
141 + (
142 + cd "$upstream" &&
143 + git update-ref -d refs/review/master/topic &&
144 + git update-ref -d refs/tags/v123 &&
145 + git update-ref -d refs/heads/a/b/c
146 + )
147 +'
t/t5411/test-0002-pre-receive-declined.sh new
+33
@@ -0,0 +1,33 @@
1 +test_expect_success "setup pre-receive hook ($PROTOCOL)" '
2 + mv "$upstream/hooks/pre-receive" "$upstream/hooks/pre-receive.ok" &&
3 + write_script "$upstream/hooks/pre-receive" <<-EOF
4 + exit 1
5 + EOF
6 +'
7 +
8 +# Refs of upstream : master(A)
9 +# Refs of workbench: master(A) tags/v123
10 +# git-push : master(B) next(A)
11 +test_expect_success "git-push is declined ($PROTOCOL)" '
12 + test_must_fail git -C workbench push origin \
13 + $B:refs/heads/master \
14 + HEAD:refs/heads/next \
15 + >out 2>&1 &&
16 + make_user_friendly_and_stable_output <out >actual &&
17 + cat >expect <<-EOF &&
18 + To <URL/of/upstream.git>
19 + ! [remote rejected] <COMMIT-B> -> master (pre-receive hook declined)
20 + ! [remote rejected] HEAD -> next (pre-receive hook declined)
21 + EOF
22 + test_cmp expect actual &&
23 + git -C "$upstream" show-ref >out &&
24 + make_user_friendly_and_stable_output <out >actual &&
25 + cat >expect <<-EOF &&
26 + <COMMIT-A> refs/heads/master
27 + EOF
28 + test_cmp expect actual
29 +'
30 +
31 +test_expect_success "cleanup ($PROTOCOL)" '
32 + mv "$upstream/hooks/pre-receive.ok" "$upstream/hooks/pre-receive"
33 +'
t/t5411/test-0003-pre-receive-declined--porcelain.sh new
+34
@@ -0,0 +1,34 @@
1 +test_expect_success "setup pre-receive hook ($PROTOCOL/porcelain)" '
2 + mv "$upstream/hooks/pre-receive" "$upstream/hooks/pre-receive.ok" &&
3 + write_script "$upstream/hooks/pre-receive" <<-EOF
4 + exit 1
5 + EOF
6 +'
7 +
8 +# Refs of upstream : master(A)
9 +# Refs of workbench: master(A) tags/v123
10 +# git-push : master(B) next(A)
11 +test_expect_success "git-push is declined ($PROTOCOL/porcelain)" '
12 + test_must_fail git -C workbench push --porcelain origin \
13 + $B:refs/heads/master \
14 + HEAD:refs/heads/next \
15 + >out 2>&1 &&
16 + make_user_friendly_and_stable_output <out >actual &&
17 + cat >expect <<-EOF &&
18 + To <URL/of/upstream.git>
19 + ! <COMMIT-B>:refs/heads/master [remote rejected] (pre-receive hook declined)
20 + ! HEAD:refs/heads/next [remote rejected] (pre-receive hook declined)
21 + Done
22 + EOF
23 + test_cmp expect actual &&
24 + git -C "$upstream" show-ref >out &&
25 + make_user_friendly_and_stable_output <out >actual &&
26 + cat >expect <<-EOF &&
27 + <COMMIT-A> refs/heads/master
28 + EOF
29 + test_cmp expect actual
30 +'
31 +
32 +test_expect_success "cleanup ($PROTOCOL/porcelain)" '
33 + mv "$upstream/hooks/pre-receive.ok" "$upstream/hooks/pre-receive"
34 +'