Skip to content

Commit 38b9197

Browse files
jiangxingitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 917c612 commit 38b9197

6 files changed

+521
-0
lines changed

t/t5411-proc-receive-hook.sh

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
'

0 commit comments

Comments
 (0)