apply-one-time-script.sh is a test helper that executes a "one-time-script" responsible for modifying the response normally returned by git-http-backend. apply-one-time-script.sh should run "one-time-script" once and return a modified response once. However, sometimes a race between multiple concurrent requests causes apply-one-time-script.sh to misbehave and return multiple modified responses or an empty response that results in: fatal: ... The requested URL returned error: 500 fatal: could not fetch <oid> from promisor remote This can be seen in the flaky failure of t5616.47 on the macOS CI runners. Fix the logic that checks if "one-time-script" has returned its modified response by chaining "rm one-time-script" with its execution. This ensures a racing script does not also have the opportunity to execute "one-time-script". Add t/t5567-one-time-script.sh to verify the race is fixed. Implement a stub "git-http-backend" that intentionally invokes a concurrent request, and check that only one modified response is returned without error. Signed-off-by: Michael Montalbo <mmontalbo@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
37 lines
1.2 KiB
Bash
37 lines
1.2 KiB
Bash
#!/bin/sh
|
|
|
|
# If "one-time-script" exists in $HTTPD_ROOT_PATH, run the script on the HTTP
|
|
# response. If the response was modified as a result, delete "one-time-script"
|
|
# so that subsequent HTTP responses are no longer modified.
|
|
#
|
|
# This can be used to simulate the effects of the repository changing in
|
|
# between HTTP request-response pairs.
|
|
test -f one-time-script || exec "$GIT_EXEC_PATH/git-http-backend"
|
|
|
|
LC_ALL=C
|
|
export LC_ALL
|
|
|
|
out=out.$$
|
|
modified=out-modified.$$
|
|
"$GIT_EXEC_PATH/git-http-backend" >"$out"
|
|
|
|
# Since Apache can execute this script for multiple requests
|
|
# concurrently, we chain "rm one-time-script" with the logic
|
|
# for generating a modified response. If the "rm" ran separately,
|
|
# a concurrent request could pass the "test -f" above and
|
|
# erroneously result in multiple modified responses or an empty
|
|
# body depending on the race state.
|
|
#
|
|
# We discard stderr for ./one-time-script since it is possible
|
|
# ./one-time-script has been removed already, which is expected
|
|
# sometimes. In this case, the unmodified response will be returned.
|
|
if ./one-time-script "$out" 2>/dev/null >"$modified" &&
|
|
! cmp -s "$out" "$modified" &&
|
|
rm one-time-script 2>/dev/null
|
|
then
|
|
cat "$modified"
|
|
else
|
|
cat "$out"
|
|
fi
|
|
rm -f "$out" "$modified"
|