Skip to content

Commit 682569c

Browse files
matheustavaresgitster
authored andcommitted
parallel-checkout: add tests for basic operations
Add tests to populate the working tree during clone and checkout using the sequential and parallel modes, to confirm that they produce identical results. Also test basic checkout mechanics, such as checking for symlinks in the leading directories and the abidance to --force. Note: some helper functions are added to a common lib file which is only included by t2080 for now. But it will also be used by another parallel-checkout test in a following patch. Original-patch-by: Jeff Hostetler <[email protected]> Signed-off-by: Jeff Hostetler <[email protected]> Signed-off-by: Matheus Tavares <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d4eccdb commit 682569c

File tree

2 files changed

+236
-0
lines changed

2 files changed

+236
-0
lines changed

t/lib-parallel-checkout.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Helpers for t208* tests
2+
3+
# Runs `git -c checkout.workers=$1 -c checkout.thesholdForParallelism=$2 ${@:4}`
4+
# and checks that the number of workers spawned is equal to $3.
5+
git_pc()
6+
{
7+
if test $# -lt 4
8+
then
9+
BUG "too few arguments to git_pc()"
10+
fi
11+
12+
workers=$1 threshold=$2 expected_workers=$3 &&
13+
shift && shift && shift &&
14+
15+
rm -f trace &&
16+
GIT_TRACE2="$(pwd)/trace" git \
17+
-c checkout.workers=$workers \
18+
-c checkout.thresholdForParallelism=$threshold \
19+
-c advice.detachedHead=0 \
20+
$@ &&
21+
22+
# Check that the expected number of workers has been used. Note that it
23+
# can be different than the requested number in two cases: when the
24+
# quantity of entries to be checked out is less than the number of
25+
# workers; and when the threshold has not been reached.
26+
#
27+
local workers_in_trace=$(grep "child_start\[.\+\] git checkout--helper" trace | wc -l) &&
28+
test $workers_in_trace -eq $expected_workers &&
29+
rm -f trace
30+
}
31+
32+
# Verify that both the working tree and the index were created correctly
33+
verify_checkout()
34+
{
35+
git -C $1 diff-index --quiet HEAD -- &&
36+
git -C $1 diff-index --quiet --cached HEAD -- &&
37+
git -C $1 status --porcelain >$1.status &&
38+
test_must_be_empty $1.status
39+
}

t/t2080-parallel-checkout-basics.sh

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
#!/bin/sh
2+
3+
test_description='parallel-checkout basics
4+
5+
Ensure that parallel-checkout basically works on clone and checkout, spawning
6+
the required number of workers and correctly populating both the index and
7+
working tree.
8+
'
9+
10+
TEST_NO_CREATE_REPO=1
11+
. ./test-lib.sh
12+
. "$TEST_DIRECTORY/lib-parallel-checkout.sh"
13+
14+
# NEEDSWORK: cloning a SHA1 repo with GIT_TEST_DEFAULT_HASH set to "sha256"
15+
# currently produces a wrong result (See
16+
# https://lore.kernel.org/git/[email protected]/).
17+
# So we skip the "parallel-checkout during clone" tests when this test flag is
18+
# set to "sha256". Remove this when the bug is fixed.
19+
#
20+
if test "$GIT_TEST_DEFAULT_HASH" = "sha256"
21+
then
22+
skip_all="t2080 currently don't work with GIT_TEST_DEFAULT_HASH=sha256"
23+
test_done
24+
fi
25+
26+
R_BASE=$GIT_BUILD_DIR
27+
28+
test_expect_success 'sequential clone' '
29+
git_pc 1 0 0 clone --quiet -- $R_BASE r_sequential &&
30+
verify_checkout r_sequential
31+
'
32+
33+
test_expect_success 'parallel clone' '
34+
git_pc 2 0 2 clone --quiet -- $R_BASE r_parallel &&
35+
verify_checkout r_parallel
36+
'
37+
38+
test_expect_success 'fallback to sequential clone (threshold)' '
39+
git -C $R_BASE ls-files >files &&
40+
nr_files=$(wc -l <files) &&
41+
threshold=$(($nr_files + 1)) &&
42+
43+
git_pc 2 $threshold 0 clone --quiet -- $R_BASE r_sequential_fallback &&
44+
verify_checkout r_sequential_fallback
45+
'
46+
47+
# Just to be paranoid, actually compare the contents of the worktrees directly.
48+
test_expect_success 'compare working trees from clones' '
49+
rm -rf r_sequential/.git &&
50+
rm -rf r_parallel/.git &&
51+
rm -rf r_sequential_fallback/.git &&
52+
diff -qr r_sequential r_parallel &&
53+
diff -qr r_sequential r_sequential_fallback
54+
'
55+
56+
# Test parallel-checkout with different operations (creation, deletion,
57+
# modification) and entry types. A branch switch from B1 to B2 will contain:
58+
#
59+
# - a (file): modified
60+
# - e/x (file): deleted
61+
# - b (symlink): deleted
62+
# - b/f (file): created
63+
# - e (symlink): created
64+
# - d (submodule): created
65+
#
66+
test_expect_success SYMLINKS 'setup repo for checkout with various operations' '
67+
git init various &&
68+
(
69+
cd various &&
70+
git checkout -b B1 &&
71+
echo a>a &&
72+
mkdir e &&
73+
echo e/x >e/x &&
74+
ln -s e b &&
75+
git add -A &&
76+
git commit -m B1 &&
77+
78+
git checkout -b B2 &&
79+
echo modified >a &&
80+
rm -rf e &&
81+
rm b &&
82+
mkdir b &&
83+
echo b/f >b/f &&
84+
ln -s b e &&
85+
git init d &&
86+
test_commit -C d f &&
87+
git submodule add ./d &&
88+
git add -A &&
89+
git commit -m B2 &&
90+
91+
git checkout --recurse-submodules B1
92+
)
93+
'
94+
95+
test_expect_success SYMLINKS 'sequential checkout' '
96+
cp -R various various_sequential &&
97+
git_pc 1 0 0 -C various_sequential checkout --recurse-submodules B2 &&
98+
verify_checkout various_sequential
99+
'
100+
101+
test_expect_success SYMLINKS 'parallel checkout' '
102+
cp -R various various_parallel &&
103+
git_pc 2 0 2 -C various_parallel checkout --recurse-submodules B2 &&
104+
verify_checkout various_parallel
105+
'
106+
107+
test_expect_success SYMLINKS 'fallback to sequential checkout (threshold)' '
108+
cp -R various various_sequential_fallback &&
109+
git_pc 2 100 0 -C various_sequential_fallback checkout --recurse-submodules B2 &&
110+
verify_checkout various_sequential_fallback
111+
'
112+
113+
test_expect_success SYMLINKS 'compare working trees from checkouts' '
114+
rm -rf various_sequential/.git &&
115+
rm -rf various_parallel/.git &&
116+
rm -rf various_sequential_fallback/.git &&
117+
diff -qr various_sequential various_parallel &&
118+
diff -qr various_sequential various_sequential_fallback
119+
'
120+
121+
test_cmp_str()
122+
{
123+
echo "$1" >tmp &&
124+
test_cmp tmp "$2"
125+
}
126+
127+
test_expect_success 'parallel checkout respects --[no]-force' '
128+
git init dirty &&
129+
(
130+
cd dirty &&
131+
mkdir D &&
132+
test_commit D/F &&
133+
test_commit F &&
134+
135+
echo changed >F.t &&
136+
rm -rf D &&
137+
echo changed >D &&
138+
139+
# We expect 0 workers because there is nothing to be updated
140+
git_pc 2 0 0 checkout HEAD &&
141+
test_path_is_file D &&
142+
test_cmp_str changed D &&
143+
test_cmp_str changed F.t &&
144+
145+
git_pc 2 0 2 checkout --force HEAD &&
146+
test_path_is_dir D &&
147+
test_cmp_str D/F D/F.t &&
148+
test_cmp_str F F.t
149+
)
150+
'
151+
152+
test_expect_success SYMLINKS 'parallel checkout checks for symlinks in leading dirs' '
153+
git init symlinks &&
154+
(
155+
cd symlinks &&
156+
mkdir D E &&
157+
158+
# Create two entries in D to have enough work for 2 parallel
159+
# workers
160+
test_commit D/A &&
161+
test_commit D/B &&
162+
test_commit E/C &&
163+
rm -rf D &&
164+
ln -s E D &&
165+
166+
git_pc 2 0 2 checkout --force HEAD &&
167+
! test -L D &&
168+
test_cmp_str D/A D/A.t &&
169+
test_cmp_str D/B D/B.t
170+
)
171+
'
172+
173+
test_expect_success SYMLINKS,CASE_INSENSITIVE_FS 'symlink colliding with leading dir' '
174+
git init colliding-symlink &&
175+
(
176+
cd colliding-symlink &&
177+
file_hex=$(git hash-object -w --stdin </dev/null) &&
178+
file_oct=$(echo $file_hex | hex2oct) &&
179+
180+
sym_hex=$(echo "./D" | git hash-object -w --stdin) &&
181+
sym_oct=$(echo $sym_hex | hex2oct) &&
182+
183+
printf "100644 D/A\0${file_oct}" >tree &&
184+
printf "100644 E/B\0${file_oct}" >>tree &&
185+
printf "120000 e\0${sym_oct}" >>tree &&
186+
187+
tree_hex=$(git hash-object -w -t tree --stdin <tree) &&
188+
commit_hex=$(git commit-tree -m collisions $tree_hex) &&
189+
git update-ref refs/heads/colliding-symlink $commit_hex &&
190+
191+
git_pc 2 0 2 checkout colliding-symlink &&
192+
test_path_is_dir D &&
193+
test_path_is_missing D/B
194+
)
195+
'
196+
197+
test_done

0 commit comments

Comments
 (0)