Skip to content

Commit 3374292

Browse files
bmwillgitster
authored andcommitted
upload-pack: test negotiation with changing repository
Add tests to check the behavior of fetching from a repository which changes between rounds of negotiation (for example, when different servers in a load-balancing agreement participate in the same stateless RPC negotiation). This forms a baseline of comparison to the ref-in-want functionality (which will be introduced to the client in subsequent commits), and ensures that subsequent commits do not change existing behavior. As part of this effort, a mechanism to substitute strings in a single HTTP response is added. Signed-off-by: Brandon Williams <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 516e2b7 commit 3374292

File tree

4 files changed

+99
-0
lines changed

4 files changed

+99
-0
lines changed

t/lib-httpd.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ prepare_httpd() {
132132
cp "$TEST_PATH"/passwd "$HTTPD_ROOT_PATH"
133133
install_script broken-smart-http.sh
134134
install_script error.sh
135+
install_script apply-one-time-sed.sh
135136

136137
ln -s "$LIB_HTTPD_MODULE_PATH" "$HTTPD_ROOT_PATH/modules"
137138

t/lib-httpd/apache.conf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,14 @@ Alias /auth/dumb/ www/auth/dumb/
111111
SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
112112
SetEnv GIT_HTTP_EXPORT_ALL
113113
</LocationMatch>
114+
<LocationMatch /one_time_sed/>
115+
SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
116+
SetEnv GIT_HTTP_EXPORT_ALL
117+
</LocationMatch>
114118
ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1
115119
ScriptAlias /broken_smart/ broken-smart-http.sh/
116120
ScriptAlias /error/ error.sh/
121+
ScriptAliasMatch /one_time_sed/(.*) apply-one-time-sed.sh/$1
117122
<Directory ${GIT_EXEC_PATH}>
118123
Options FollowSymlinks
119124
</Directory>
@@ -123,6 +128,9 @@ ScriptAlias /error/ error.sh/
123128
<Files error.sh>
124129
Options ExecCGI
125130
</Files>
131+
<Files apply-one-time-sed.sh>
132+
Options ExecCGI
133+
</Files>
126134
<Files ${GIT_EXEC_PATH}/git-http-backend>
127135
Options ExecCGI
128136
</Files>

t/lib-httpd/apply-one-time-sed.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/bin/sh
2+
3+
# If "one-time-sed" exists in $HTTPD_ROOT_PATH, run sed on the HTTP response,
4+
# using the contents of "one-time-sed" as the sed command to be run. If the
5+
# response was modified as a result, delete "one-time-sed" so that subsequent
6+
# HTTP responses are no longer modified.
7+
#
8+
# This can be used to simulate the effects of the repository changing in
9+
# between HTTP request-response pairs.
10+
if [ -e one-time-sed ]; then
11+
"$GIT_EXEC_PATH/git-http-backend" >out
12+
sed "$(cat one-time-sed)" <out >out_modified
13+
14+
if diff out out_modified >/dev/null; then
15+
cat out
16+
else
17+
cat out_modified
18+
rm one-time-sed
19+
fi
20+
else
21+
"$GIT_EXEC_PATH/git-http-backend"
22+
fi

t/t5703-upload-pack-ref-in-want.sh

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,72 @@ test_expect_success 'want-ref with ref we already have commit for' '
157157
check_output
158158
'
159159

160+
. "$TEST_DIRECTORY"/lib-httpd.sh
161+
start_httpd
162+
163+
REPO="$HTTPD_DOCUMENT_ROOT_PATH/repo"
164+
LOCAL_PRISTINE="$(pwd)/local_pristine"
165+
166+
test_expect_success 'setup repos for change-while-negotiating test' '
167+
(
168+
git init "$REPO" &&
169+
cd "$REPO" &&
170+
>.git/git-daemon-export-ok &&
171+
test_commit m1 &&
172+
git tag -d m1 &&
173+
174+
# Local repo with many commits (so that negotiation will take
175+
# more than 1 request/response pair)
176+
git clone "http://127.0.0.1:$LIB_HTTPD_PORT/smart/repo" "$LOCAL_PRISTINE" &&
177+
cd "$LOCAL_PRISTINE" &&
178+
git checkout -b side &&
179+
for i in $(seq 1 33); do test_commit s$i; done &&
180+
181+
# Add novel commits to upstream
182+
git checkout master &&
183+
cd "$REPO" &&
184+
test_commit m2 &&
185+
test_commit m3 &&
186+
git tag -d m2 m3
187+
) &&
188+
git -C "$LOCAL_PRISTINE" remote set-url origin "http://127.0.0.1:$LIB_HTTPD_PORT/one_time_sed/repo" &&
189+
git -C "$LOCAL_PRISTINE" config protocol.version 2
190+
'
191+
192+
inconsistency () {
193+
# Simulate that the server initially reports $2 as the ref
194+
# corresponding to $1, and after that, $1 as the ref corresponding to
195+
# $1. This corresponds to the real-life situation where the server's
196+
# repository appears to change during negotiation, for example, when
197+
# different servers in a load-balancing arrangement serve (stateless)
198+
# RPCs during a single negotiation.
199+
printf "s/%s/%s/" \
200+
$(git -C "$REPO" rev-parse $1 | tr -d "\n") \
201+
$(git -C "$REPO" rev-parse $2 | tr -d "\n") \
202+
>"$HTTPD_ROOT_PATH/one-time-sed"
203+
}
204+
205+
test_expect_success 'server is initially ahead - no ref in want' '
206+
git -C "$REPO" config uploadpack.allowRefInWant false &&
207+
rm -rf local &&
208+
cp -r "$LOCAL_PRISTINE" local &&
209+
inconsistency master 1234567890123456789012345678901234567890 &&
210+
test_must_fail git -C local fetch 2>err &&
211+
grep "ERR upload-pack: not our ref" err
212+
'
213+
214+
test_expect_success 'server is initially behind - no ref in want' '
215+
git -C "$REPO" config uploadpack.allowRefInWant false &&
216+
rm -rf local &&
217+
cp -r "$LOCAL_PRISTINE" local &&
218+
inconsistency master "master^" &&
219+
git -C local fetch &&
220+
221+
git -C "$REPO" rev-parse --verify "master^" >expected &&
222+
git -C local rev-parse --verify refs/remotes/origin/master >actual &&
223+
test_cmp expected actual
224+
'
225+
226+
stop_httpd
227+
160228
test_done

0 commit comments

Comments
 (0)