Skip to content

Commit 65a68ca

Browse files
dschoGit for Windows Build Agent
authored and
Git for Windows Build Agent
committed
t/lib-httpd: avoid using BSD's sed
Among other differences relative to GNU sed, BSD sed always ends its output with a trailing newline, even if the input did not have such a trailing newline. Surprisingly, this makes three httpd-based tests fail on macOS: t5616, t5702 and t5703. ("Surprisingly" because those tests have been around for some time, but apparently nobody runs them on macOS with a working Apache2 setup.) The reason is that we use `sed` in those tests to filter the response of the web server. Apart from the fact that we use GNU constructs (such as using a space after the `c` command instead of a backslash and a newline), we have another problem: BSD sed LF-only newlines while webservers are supposed to use CR/LF ones. Even worse, t5616 uses `sed` to replace a binary part of the response with a new binary part (kind of hoping that the replaced binary part does not contain a 0x0a byte which would be interpreted as a newline). To that end, it calls on Perl to read the binary pack file and hex-encode it, then calls on `sed` to prefix every hex digit pair with a `\x` in order to construct the text that the `c` statement of the `sed` invocation is supposed to insert. So we call Perl and sed to construct a sed statement. The final nail in the coffin is that BSD sed does not even interpret those `\x<hex>` constructs. Let's just replace all of that by Perl snippets. With Perl, at least, we do not have to deal with GNU vs BSD semantics, we do not have to worry about unwanted trailing newlines, and we do not have to spawn commands to construct arguments for other commands to be spawned (i.e. we can avoid a whole lot of shell scripting complexity). The upshot is that this fixes t5616, t5702 and t5703 on macOS with Apache2. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 6196610 commit 65a68ca

8 files changed

+72
-59
lines changed

t/lib-httpd.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ prepare_httpd() {
132132
install_script broken-smart-http.sh
133133
install_script error-smart-http.sh
134134
install_script error.sh
135-
install_script apply-one-time-sed.sh
135+
install_script apply-one-time-perl.sh
136136

137137
ln -s "$LIB_HTTPD_MODULE_PATH" "$HTTPD_ROOT_PATH/modules"
138138

t/lib-httpd/apache.conf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ Alias /auth/dumb/ www/auth/dumb/
113113
SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
114114
SetEnv GIT_HTTP_EXPORT_ALL
115115
</LocationMatch>
116-
<LocationMatch /one_time_sed/>
116+
<LocationMatch /one_time_perl/>
117117
SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
118118
SetEnv GIT_HTTP_EXPORT_ALL
119119
</LocationMatch>
@@ -122,7 +122,7 @@ ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1
122122
ScriptAlias /broken_smart/ broken-smart-http.sh/
123123
ScriptAlias /error_smart/ error-smart-http.sh/
124124
ScriptAlias /error/ error.sh/
125-
ScriptAliasMatch /one_time_sed/(.*) apply-one-time-sed.sh/$1
125+
ScriptAliasMatch /one_time_perl/(.*) apply-one-time-perl.sh/$1
126126
<Directory ${GIT_EXEC_PATH}>
127127
Options FollowSymlinks
128128
</Directory>
@@ -135,7 +135,7 @@ ScriptAliasMatch /one_time_sed/(.*) apply-one-time-sed.sh/$1
135135
<Files error.sh>
136136
Options ExecCGI
137137
</Files>
138-
<Files apply-one-time-sed.sh>
138+
<Files apply-one-time-perl.sh>
139139
Options ExecCGI
140140
</Files>
141141
<Files ${GIT_EXEC_PATH}/git-http-backend>

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/bin/sh
2+
3+
# If "one-time-perl" exists in $HTTPD_ROOT_PATH, run perl on the HTTP response,
4+
# using the contents of "one-time-perl" as the perl command to be run. If the
5+
# response was modified as a result, delete "one-time-perl" 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 test -f one-time-perl
11+
then
12+
LC_ALL=C
13+
export LC_ALL
14+
15+
"$GIT_EXEC_PATH/git-http-backend" >out
16+
perl -pe "$(cat one-time-perl)" out >out_modified
17+
18+
echo "before applying one-time $(cat one-time-perl)" >&2
19+
hexdump -C out >&2
20+
echo "after applying one-time $(cat one-time-perl)" >&2
21+
hexdump -C out_modified >&2
22+
23+
if cmp -s out out_modified
24+
then
25+
cat out
26+
else
27+
cat out_modified
28+
# rm one-time-perl
29+
mv one-time-perl one-time-perl.$(($(ls one-time-perl.* 2>/dev/null | wc -l | tr -dc 0-9)+1))
30+
fi
31+
else
32+
"$GIT_EXEC_PATH/git-http-backend"
33+
fi

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

Lines changed: 0 additions & 24 deletions
This file was deleted.

t/t5537-fetch-shallow.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ test_expect_success 'shallow fetches check connectivity before writing shallow f
237237
git -C "$REPO" config protocol.version 2 &&
238238
git -C client config protocol.version 2 &&
239239
240-
git -C client fetch --depth=2 "$HTTPD_URL/one_time_sed/repo" master:a_branch &&
240+
git -C client fetch --depth=2 "$HTTPD_URL/one_time_perl/repo" master:a_branch &&
241241
242242
# Craft a situation in which the server sends back an unshallow request
243243
# with an empty packfile. This is done by refetching with a shorter
@@ -246,13 +246,13 @@ test_expect_success 'shallow fetches check connectivity before writing shallow f
246246
printf "$(test_oid sed)" \
247247
"$(git -C "$REPO" rev-parse HEAD)" \
248248
"$(git -C "$REPO" rev-parse HEAD^)" \
249-
>"$HTTPD_ROOT_PATH/one-time-sed" &&
249+
>"$HTTPD_ROOT_PATH/one-time-perl" &&
250250
test_must_fail env GIT_TEST_SIDEBAND_ALL=0 git -C client \
251-
fetch --depth=1 "$HTTPD_URL/one_time_sed/repo" \
251+
fetch --depth=1 "$HTTPD_URL/one_time_perl/repo" \
252252
master:a_branch &&
253253
254-
# Ensure that the one-time-sed script was used.
255-
! test -e "$HTTPD_ROOT_PATH/one-time-sed" &&
254+
# Ensure that the one-time-perl script was used.
255+
! test -e "$HTTPD_ROOT_PATH/one-time-perl" &&
256256
257257
# Ensure that the resulting repo is consistent, despite our failure to
258258
# fetch.

t/t5616-partial-clone.sh

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -429,14 +429,18 @@ intersperse () {
429429
sed 's/\(..\)/'$1'\1/g'
430430
}
431431

432-
# Create a one-time-sed command to replace the existing packfile with $1.
432+
# Create a one-time-perl command to replace the existing packfile with $1.
433433
replace_packfile () {
434434
# The protocol requires that the packfile be sent in sideband 1, hence
435435
# the extra \x01 byte at the beginning.
436-
printf "1,/packfile/!c %04x\\\\x01%s0000" \
437-
"$(($(wc -c <$1) + 5))" \
438-
"$(hex_unpack <$1 | intersperse '\\x')" \
439-
>"$HTTPD_ROOT_PATH/one-time-sed"
436+
cp $1 "$HTTPD_ROOT_PATH/one-time-pack" &&
437+
echo 'if (/packfile/) {
438+
print;
439+
my $length = -s "one-time-pack";
440+
printf "%04x\x01", $length + 5;
441+
print `cat one-time-pack` . "0000";
442+
last
443+
}' >"$HTTPD_ROOT_PATH/one-time-perl"
440444
}
441445

442446
test_expect_success 'upon cloning, check that all refs point to objects' '
@@ -460,16 +464,16 @@ test_expect_success 'upon cloning, check that all refs point to objects' '
460464
# \x01 byte at the beginning.
461465
replace_packfile incomplete.pack &&
462466
463-
# Use protocol v2 because the sed command looks for the "packfile"
467+
# Use protocol v2 because the perl command looks for the "packfile"
464468
# section header.
465469
test_config -C "$SERVER" protocol.version 2 &&
466470
test_must_fail git -c protocol.version=2 clone \
467-
--filter=blob:none $HTTPD_URL/one_time_sed/server repo 2>err &&
471+
--filter=blob:none $HTTPD_URL/one_time_perl/server repo 2>err &&
468472
469473
test_i18ngrep "did not send all necessary objects" err &&
470474
471-
# Ensure that the one-time-sed script was used.
472-
! test -e "$HTTPD_ROOT_PATH/one-time-sed"
475+
# Ensure that the one-time-perl script was used.
476+
! test -e "$HTTPD_ROOT_PATH/one-time-perl"
473477
'
474478

475479
test_expect_success 'when partial cloning, tolerate server not sending target of tag' '
@@ -500,17 +504,17 @@ test_expect_success 'when partial cloning, tolerate server not sending target of
500504
# \x01 byte at the beginning.
501505
replace_packfile incomplete.pack &&
502506
503-
# Use protocol v2 because the sed command looks for the "packfile"
507+
# Use protocol v2 because the perl command looks for the "packfile"
504508
# section header.
505509
test_config -C "$SERVER" protocol.version 2 &&
506510
507511
# Exercise to make sure it works.
508512
git -c protocol.version=2 clone \
509-
--filter=blob:none $HTTPD_URL/one_time_sed/server repo 2> err &&
513+
--filter=blob:none $HTTPD_URL/one_time_perl/server repo 2> err &&
510514
! grep "missing object referenced by" err &&
511515
512-
# Ensure that the one-time-sed script was used.
513-
! test -e "$HTTPD_ROOT_PATH/one-time-sed"
516+
# Ensure that the one-time-perl script was used.
517+
! test -e "$HTTPD_ROOT_PATH/one-time-perl"
514518
'
515519

516520
test_expect_success 'tolerate server sending REF_DELTA against missing promisor objects' '
@@ -533,7 +537,7 @@ test_expect_success 'tolerate server sending REF_DELTA against missing promisor
533537
534538
# Clone. The client has deltabase_have but not deltabase_missing.
535539
git -c protocol.version=2 clone --no-checkout \
536-
--filter=blob:none $HTTPD_URL/one_time_sed/server repo &&
540+
--filter=blob:none $HTTPD_URL/one_time_perl/server repo &&
537541
git -C repo hash-object -w -- "$SERVER/have.txt" &&
538542
539543
# Sanity check to ensure that the client does not have
@@ -574,7 +578,7 @@ test_expect_success 'tolerate server sending REF_DELTA against missing promisor
574578
575579
replace_packfile thin.pack &&
576580
577-
# Use protocol v2 because the sed command looks for the "packfile"
581+
# Use protocol v2 because the perl command looks for the "packfile"
578582
# section header.
579583
test_config -C "$SERVER" protocol.version 2 &&
580584
@@ -587,8 +591,8 @@ test_expect_success 'tolerate server sending REF_DELTA against missing promisor
587591
grep "want $(cat deltabase_missing)" trace &&
588592
! grep "want $(cat deltabase_have)" trace &&
589593
590-
# Ensure that the one-time-sed script was used.
591-
! test -e "$HTTPD_ROOT_PATH/one-time-sed"
594+
# Ensure that the one-time-perl script was used.
595+
! test -e "$HTTPD_ROOT_PATH/one-time-perl"
592596
'
593597

594598
# DO NOT add non-httpd-specific tests here, because the last part of this

t/t5702-protocol-v2.sh

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -712,11 +712,11 @@ test_expect_success 'when server sends "ready", expect DELIM' '
712712
713713
# After "ready" in the acknowledgments section, pretend that a FLUSH
714714
# (0000) was sent instead of a DELIM (0001).
715-
printf "/ready/,$ s/0001/0000/" \
716-
>"$HTTPD_ROOT_PATH/one-time-sed" &&
715+
printf "\$ready = 1 if /ready/; \$ready && s/0001/0000/" \
716+
>"$HTTPD_ROOT_PATH/one-time-perl" &&
717717
718718
test_must_fail git -C http_child -c protocol.version=2 \
719-
fetch "$HTTPD_URL/one_time_sed/http_parent" 2> err &&
719+
fetch "$HTTPD_URL/one_time_perl/http_parent" 2> err &&
720720
test_i18ngrep "expected packfile to be sent after .ready." err
721721
'
722722

@@ -737,12 +737,12 @@ test_expect_success 'when server does not send "ready", expect FLUSH' '
737737
738738
# After the acknowledgments section, pretend that a DELIM
739739
# (0001) was sent instead of a FLUSH (0000).
740-
printf "/acknowledgments/,$ s/0000/0001/" \
741-
>"$HTTPD_ROOT_PATH/one-time-sed" &&
740+
printf "\$ack = 1 if /acknowledgments/; \$ack && s/0000/0001/" \
741+
>"$HTTPD_ROOT_PATH/one-time-perl" &&
742742
743743
test_must_fail env GIT_TRACE_PACKET="$(pwd)/log" git -C http_child \
744744
-c protocol.version=2 \
745-
fetch "$HTTPD_URL/one_time_sed/http_parent" 2> err &&
745+
fetch "$HTTPD_URL/one_time_perl/http_parent" 2> err &&
746746
grep "fetch< .*acknowledgments" log &&
747747
! grep "fetch< .*ready" log &&
748748
test_i18ngrep "expected no other sections to be sent after no .ready." err

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ test_expect_success 'setup repos for change-while-negotiating test' '
314314
test_commit m3 &&
315315
git tag -d m2 m3
316316
) &&
317-
git -C "$LOCAL_PRISTINE" remote set-url origin "http://127.0.0.1:$LIB_HTTPD_PORT/one_time_sed/repo" &&
317+
git -C "$LOCAL_PRISTINE" remote set-url origin "http://127.0.0.1:$LIB_HTTPD_PORT/one_time_perl/repo" &&
318318
git -C "$LOCAL_PRISTINE" config protocol.version 2
319319
'
320320

@@ -327,7 +327,7 @@ inconsistency () {
327327
# RPCs during a single negotiation.
328328
oid1=$(git -C "$REPO" rev-parse $1) &&
329329
oid2=$(git -C "$REPO" rev-parse $2) &&
330-
echo "s/$oid1/$oid2/" >"$HTTPD_ROOT_PATH/one-time-sed"
330+
echo "s/$oid1/$oid2/" >"$HTTPD_ROOT_PATH/one-time-perl"
331331
}
332332

333333
test_expect_success 'server is initially ahead - no ref in want' '
@@ -379,7 +379,7 @@ test_expect_success 'server loses a ref - ref in want' '
379379
git -C "$REPO" config uploadpack.allowRefInWant true &&
380380
rm -rf local &&
381381
cp -r "$LOCAL_PRISTINE" local &&
382-
echo "s/master/raster/" >"$HTTPD_ROOT_PATH/one-time-sed" &&
382+
echo "s/master/raster/" >"$HTTPD_ROOT_PATH/one-time-perl" &&
383383
test_must_fail git -C local fetch 2>err &&
384384
385385
test_i18ngrep "fatal: remote error: unknown ref refs/heads/raster" err

0 commit comments

Comments
 (0)