Skip to content

Commit c34aa34

Browse files
committed
Merge branch 'jk/interop-test' into maint
Picking two versions of Git and running tests to make sure the older one and the newer one interoperate happily has now become possible. * jk/interop-test: t/interop: add test of old clients against modern git-daemon t: add an interoperability test harness
2 parents e0c74e6 + bd4d9d9 commit c34aa34

8 files changed

Lines changed: 270 additions & 1 deletion

File tree

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2249,6 +2249,9 @@ endif
22492249
ifdef GIT_PERF_MAKE_OPTS
22502250
@echo GIT_PERF_MAKE_OPTS=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_MAKE_OPTS)))'\' >>$@+
22512251
endif
2252+
ifdef GIT_INTEROP_MAKE_OPTS
2253+
@echo GIT_INTEROP_MAKE_OPTS=\''$(subst ','\'',$(subst ','\'',$(GIT_INTEROP_MAKE_OPTS)))'\' >>$@+
2254+
endif
22522255
ifdef TEST_GIT_INDEX_VERSION
22532256
@echo TEST_GIT_INDEX_VERSION=\''$(subst ','\'',$(subst ','\'',$(TEST_GIT_INDEX_VERSION)))'\' >>$@+
22542257
endif

t/interop/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/trash directory*/
2+
/test-results/
3+
/.prove/
4+
/build/

t/interop/Makefile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
-include ../../config.mak
2+
export GIT_TEST_OPTIONS
3+
4+
SHELL_PATH ?= $(SHELL)
5+
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
6+
T = $(sort $(wildcard i[0-9][0-9][0-9][0-9]-*.sh))
7+
8+
all: $(T)
9+
10+
$(T):
11+
@echo "*** $@ ***"; '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)
12+
13+
clean:
14+
rm -rf build "trash directory".* test-results
15+
16+
.PHONY: all clean $(T)

t/interop/README

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
Git version interoperability tests
2+
==================================
3+
4+
This directory has interoperability tests for git. Each script is
5+
similar to the normal test scripts found in t/, but with the added twist
6+
that two special versions of git, "git.a" and "git.b", are available in
7+
the PATH. Individual tests can then check the interaction between the
8+
two versions.
9+
10+
When you add a feature that handles backwards compatibility between git
11+
versions, it's encouraged to add a test here to make sure it behaves as
12+
you expect.
13+
14+
15+
Running Tests
16+
-------------
17+
18+
The easiest way to run tests is to say "make". This runs all
19+
the tests against their default versions.
20+
21+
You can run a single test like:
22+
23+
$ ./i0000-basic.sh
24+
ok 1 - bare git is forbidden
25+
ok 2 - git.a version (v1.6.6.3)
26+
ok 3 - git.b version (v2.11.1)
27+
# passed all 3 test(s)
28+
1..3
29+
30+
Each test contains default versions to run against. You may override
31+
these by setting `GIT_TEST_VERSION_A` and `GIT_TEST_VERSION_B` in the
32+
environment. Note that not all combinations will give sensible outcomes
33+
for all tests (e.g., a test checking for a specific old/new interaction
34+
may want something "old" enough" and something "new" enough; see
35+
individual tests for details).
36+
37+
Version names should be resolvable as revisions in the current
38+
repository. They will be exported and built as needed using the
39+
config.mak files found at the root of your working tree.
40+
41+
The exception is the special version "." which uses the currently-built
42+
contents of your working tree.
43+
44+
You can set the following variables (in the environment or in your config.mak):
45+
46+
GIT_INTEROP_MAKE_OPTS
47+
Options to pass to `make` when building a git version (e.g.,
48+
`-j8`).
49+
50+
You can also pass any command-line options taken by ordinary git tests (e.g.,
51+
"-v").
52+
53+
54+
Naming Tests
55+
------------
56+
57+
The interop test files are named like:
58+
59+
iNNNN-short-description.sh
60+
61+
where N is a decimal digit. The same conventions for choosing NNNN as
62+
for normal tests apply.
63+
64+
65+
Writing Tests
66+
-------------
67+
68+
An interop test script starts like a normal script, declaring a few
69+
variables and then including interop-lib.sh (which includes test-lib.sh).
70+
Besides test_description, you should also set the $VERSION_A and $VERSION_B
71+
variables to give the default versions to test against. See t0000-basic.sh for
72+
an example.
73+
74+
You can then use test_expect_success as usual, with a few differences:
75+
76+
1. The special commands "git.a" and "git.b" correspond to the
77+
two versions.
78+
79+
2. You cannot call a bare "git". This is to prevent accidents where
80+
you meant "git.a" or "git.b".
81+
82+
3. The trash directory is _not_ a git repository by default. You
83+
should create one with the appropriate version of git.
84+
85+
At the end of the script, call test_done as usual.

t/interop/i0000-basic.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/sh
2+
3+
# Note that this test only works on real version numbers,
4+
# as it depends on matching the output to "git version".
5+
VERSION_A=v1.6.6.3
6+
VERSION_B=v2.11.1
7+
8+
test_description='sanity test interop library'
9+
. ./interop-lib.sh
10+
11+
test_expect_success 'bare git is forbidden' '
12+
test_must_fail git version
13+
'
14+
15+
test_expect_success "git.a version ($VERSION_A)" '
16+
echo git version ${VERSION_A#v} >expect &&
17+
git.a version >actual &&
18+
test_cmp expect actual
19+
'
20+
21+
test_expect_success "git.b version ($VERSION_B)" '
22+
echo git version ${VERSION_B#v} >expect &&
23+
git.b version >actual &&
24+
test_cmp expect actual
25+
'
26+
27+
test_done

t/interop/i5500-git-daemon.sh

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/bin/sh
2+
3+
VERSION_A=.
4+
VERSION_B=v1.0.0
5+
6+
: ${LIB_GIT_DAEMON_PORT:=5500}
7+
LIB_GIT_DAEMON_COMMAND='git.a daemon'
8+
9+
test_description='clone and fetch by older client'
10+
. ./interop-lib.sh
11+
. "$TEST_DIRECTORY"/lib-git-daemon.sh
12+
13+
start_git_daemon --export-all
14+
15+
repo=$GIT_DAEMON_DOCUMENT_ROOT_PATH/repo
16+
17+
test_expect_success "create repo served by $VERSION_A" '
18+
git.a init "$repo" &&
19+
git.a -C "$repo" commit --allow-empty -m one
20+
'
21+
22+
test_expect_success "clone with $VERSION_B" '
23+
git.b clone "$GIT_DAEMON_URL/repo" child &&
24+
echo one >expect &&
25+
git.a -C child log -1 --format=%s >actual &&
26+
test_cmp expect actual
27+
'
28+
29+
test_expect_success "fetch with $VERSION_B" '
30+
git.a -C "$repo" commit --allow-empty -m two &&
31+
(
32+
cd child &&
33+
git.b fetch
34+
) &&
35+
echo two >expect &&
36+
git.a -C child log -1 --format=%s FETCH_HEAD >actual &&
37+
test_cmp expect actual
38+
'
39+
40+
stop_git_daemon
41+
test_done

t/interop/interop-lib.sh

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Interoperability testing framework. Each script should source
2+
# this after setting default $VERSION_A and $VERSION_B variables.
3+
4+
. ../../GIT-BUILD-OPTIONS
5+
INTEROP_ROOT=$(pwd)
6+
BUILD_ROOT=$INTEROP_ROOT/build
7+
8+
build_version () {
9+
if test -z "$1"
10+
then
11+
echo >&2 "error: test script did not set default versions"
12+
return 1
13+
fi
14+
15+
if test "$1" = "."
16+
then
17+
git rev-parse --show-toplevel
18+
return 0
19+
fi
20+
21+
sha1=$(git rev-parse "$1^{tree}") || return 1
22+
dir=$BUILD_ROOT/$sha1
23+
24+
if test -e "$dir/.built"
25+
then
26+
echo "$dir"
27+
return 0
28+
fi
29+
30+
echo >&2 "==> Building $1..."
31+
32+
mkdir -p "$dir" || return 1
33+
34+
(cd "$(git rev-parse --show-cdup)" && git archive --format=tar "$sha1") |
35+
(cd "$dir" && tar x) ||
36+
return 1
37+
38+
for config in config.mak config.mak.autogen config.status
39+
do
40+
if test -e "$INTEROP_ROOT/../../$config"
41+
then
42+
cp "$INTEROP_ROOT/../../$config" "$dir/" || return 1
43+
fi
44+
done
45+
46+
(
47+
cd "$dir" &&
48+
make $GIT_INTEROP_MAKE_OPTS >&2 &&
49+
touch .built
50+
) || return 1
51+
52+
echo "$dir"
53+
}
54+
55+
# Old versions of git don't have bin-wrappers, so let's give a rough emulation.
56+
wrap_git () {
57+
write_script "$1" <<-EOF
58+
GIT_EXEC_PATH="$2"
59+
export GIT_EXEC_PATH
60+
PATH="$2:\$PATH"
61+
export GIT_EXEC_PATH
62+
exec git "\$@"
63+
EOF
64+
}
65+
66+
generate_wrappers () {
67+
mkdir -p .bin &&
68+
wrap_git .bin/git.a "$DIR_A" &&
69+
wrap_git .bin/git.b "$DIR_B" &&
70+
write_script .bin/git <<-\EOF &&
71+
echo >&2 fatal: test tried to run generic git
72+
exit 1
73+
EOF
74+
PATH=$(pwd)/.bin:$PATH
75+
}
76+
77+
VERSION_A=${GIT_TEST_VERSION_A:-$VERSION_A}
78+
VERSION_B=${GIT_TEST_VERSION_B:-$VERSION_B}
79+
80+
if ! DIR_A=$(build_version "$VERSION_A") ||
81+
! DIR_B=$(build_version "$VERSION_B")
82+
then
83+
echo >&2 "fatal: unable to build git versions"
84+
exit 1
85+
fi
86+
87+
TEST_DIRECTORY=$INTEROP_ROOT/..
88+
TEST_OUTPUT_DIRECTORY=$INTEROP_ROOT
89+
TEST_NO_CREATE_REPO=t
90+
. "$TEST_DIRECTORY"/test-lib.sh
91+
92+
generate_wrappers || die "unable to set up interop test environment"

t/lib-git-daemon.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ start_git_daemon() {
4646

4747
say >&3 "Starting git daemon ..."
4848
mkfifo git_daemon_output
49-
git daemon --listen=127.0.0.1 --port="$LIB_GIT_DAEMON_PORT" \
49+
${LIB_GIT_DAEMON_COMMAND:-git daemon} \
50+
--listen=127.0.0.1 --port="$LIB_GIT_DAEMON_PORT" \
5051
--reuseaddr --verbose \
5152
--base-path="$GIT_DAEMON_DOCUMENT_ROOT_PATH" \
5253
"$@" "$GIT_DAEMON_DOCUMENT_ROOT_PATH" \

0 commit comments

Comments
 (0)