git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 4/8] parallel-checkout: add tests for basic operations

From
Matheus Tavares <matheus.bernardino@usp.br>
Date
Apr 30, 2021, 21:40 UTC
Message-ID
<f604c50dba723ae5f4c45e5292e1ba76e743ecce.1619818517.git.matheus.bernardino@usp.br>
In-Reply-To
<cover.1619818517.git.matheus.bernardino@usp.br>

Add tests to populate the working tree during clone and checkout using sequential and parallel mode, 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 they will also be used by other
parallel-checkout tests in the following patches.
Co-authored-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br>
---
 t/lib-parallel-checkout.sh          |  42 +++++
 t/t2080-parallel-checkout-basics.sh | 229 ++++++++++++++++++++++++++++
 2 files changed, 271 insertions(+)
 create mode 100644 t/lib-parallel-checkout.sh
 create mode 100755 t/t2080-parallel-checkout-basics.sh
diff --git a/t/lib-parallel-checkout.sh b/t/lib-parallel-checkout.sh
new file mode 100644
index 0000000000..f60b22ef34
--- /dev/null
+++ b/t/lib-parallel-checkout.sh
@@ -0,0 +1,42 @@
+# Helpers for tests invoking parallel-checkout
+
+set_checkout_config () {
+	if test $# -ne 2
+	then
+		BUG "usage: set_checkout_config <workers> <threshold>"
+	fi &&
+
+	test_config_global checkout.workers $1 &&
+	test_config_global checkout.thresholdForParallelism $2
+}
+
+# Run "${@:2}" and check that $1 checkout workers were used
+test_checkout_workers () {
+	if test $# -lt 2
+	then
+		BUG "too few arguments to test_checkout_workers"
+	fi &&
+
+	local expected_workers=$1 &&
+	shift &&
+
+	local trace_file=trace-test-checkout-workers &&
+	rm -f "$trace_file" &&
+	GIT_TRACE2="$(pwd)/$trace_file" "$@" &&
+
+	local workers=$(grep "child_start\[..*\] git checkout--worker" "$trace_file" | wc -l) &&
+	test $workers -eq $expected_workers &&
+	rm "$trace_file"
+}
+
+# Verify that both the working tree and the index were created correctly
+verify_checkout () {
+	if test $# -ne 1
+	then
+		BUG "usage: verify_checkout <repository path>"
+	fi &&
+
+	git -C "$1" diff-index --ignore-submodules=none --exit-code HEAD -- &&
+	git -C "$1" status --porcelain >"$1".status &&
+	test_must_be_empty "$1".status
+}
diff --git a/t/t2080-parallel-checkout-basics.sh b/t/t2080-parallel-checkout-basics.sh
new file mode 100755
index 0000000000..7087818550
--- /dev/null
+++ b/t/t2080-parallel-checkout-basics.sh
@@ -0,0 +1,229 @@
+#!/bin/sh
+
+test_description='parallel-checkout basics
+
+Ensure that parallel-checkout basically works on clone and checkout, spawning
+the required number of workers and correctly populating both the index and the
+working tree.
+'
+
+TEST_NO_CREATE_REPO=1
+. ./test-lib.sh
+. "$TEST_DIRECTORY/lib-parallel-checkout.sh"
+
+# Test parallel-checkout with a branch switch containing a variety of file
+# creations, deletions, and modifications, involving different entry types.
+# The branches B1 and B2 have the following paths:
+#
+#      B1                 B2
+#  a/a (file)         a   (file)
+#  b   (file)         b/b (file)
+#
+#  c/c (file)         c   (symlink)
+#  d   (symlink)      d/d (file)
+#
+#  e/e (file)         e   (submodule)
+#  f   (submodule)    f/f (file)
+#
+#  g   (submodule)    g   (symlink)
+#  h   (symlink)      h   (submodule)
+#
+# Additionally, the following paths are present on both branches, but with
+# different contents:
+#
+#  i   (file)         i   (file)
+#  j   (symlink)      j   (symlink)
+#  k   (submodule)    k   (submodule)
+#
+# And the following paths are only present in one of the branches:
+#
+#  l/l (file)         -
+#  -                  m/m (file)
+#
+test_expect_success 'setup repo for checkout with various types of changes' '
+	git init sub &&
+	(
+		cd sub &&
+		git checkout -b B2 &&
+		echo B2 >file &&
+		git add file &&
+		git commit -m file &&
+
+		git checkout -b B1 &&
+		echo B1 >file &&
+		git add file &&
+		git commit -m file
+	) &&
+
+	git init various &&
+	(
+		cd various &&
+
+		git checkout -b B1 &&
+		mkdir a c e &&
+		echo a/a >a/a &&
+		echo b >b &&
+		echo c/c >c/c &&
+		test_ln_s_add c d &&
+		echo e/e >e/e &&
+		git submodule add ../sub f &&
+		git submodule add ../sub g &&
+		test_ln_s_add c h &&
+
+		echo "B1 i" >i &&
+		test_ln_s_add c j &&
+		git submodule add -b B1 ../sub k &&
+		mkdir l &&
+		echo l/l >l/l &&
+
+		git add . &&
+		git commit -m B1 &&
+
+		git checkout -b B2 &&
+		git rm -rf :^.gitmodules :^k &&
+		mkdir b d f &&
+		echo a >a &&
+		echo b/b >b/b &&
+		test_ln_s_add b c &&
+		echo d/d >d/d &&
+		git submodule add ../sub e &&
+		echo f/f >f/f &&
+		test_ln_s_add b g &&
+		git submodule add ../sub h &&
+
+		echo "B2 i" >i &&
+		test_ln_s_add b j &&
+		git -C k checkout B2 &&
+		mkdir m &&
+		echo m/m >m/m &&
+
+		git add . &&
+		git commit -m B2 &&
+
+		git checkout --recurse-submodules B1
+	)
+'
+
+for mode in sequential parallel sequential-fallback
+do
+	case $mode in
+	sequential)          workers=1 threshold=0 expected_workers=0 ;;
+	parallel)            workers=2 threshold=0 expected_workers=2 ;;
+	sequential-fallback) workers=2 threshold=100 expected_workers=0 ;;
+	esac
+
+	test_expect_success "$mode checkout" '
+		repo=various_$mode &&
+		cp -R various $repo &&
+
+		# The just copied files have more recent timestamps than their
+		# associated index entries. So refresh the cached timestamps
+		# to avoid an "entry not up-to-date" error from `git checkout`.
+		# We only have to do this for the submodules as `git checkout`
+		# will already refresh the superproject index before performing
+		# the up-to-date check.
+		#
+		git -C $repo submodule foreach "git update-index --refresh" &&
+
+		set_checkout_config $workers $threshold &&
+		test_checkout_workers $expected_workers \
+			git -C $repo checkout --recurse-submodules B2 &&
+		verify_checkout $repo
+	'
+done
+
+for mode in parallel sequential-fallback
+do
+	case $mode in
+	parallel)            workers=2 threshold=0 expected_workers=2 ;;
+	sequential-fallback) workers=2 threshold=100 expected_workers=0 ;;
+	esac
+
+	test_expect_success "$mode checkout on clone" '
+		repo=various_${mode}_clone &&
+		set_checkout_config $workers $threshold &&
+		test_checkout_workers $expected_workers \
+			git clone --recurse-submodules --branch B2 various $repo &&
+		verify_checkout $repo
+	'
+done
+
+# Just to be paranoid, actually compare the working trees' contents directly.
+test_expect_success 'compare the working trees' '
+	rm -rf various_*/.git &&
+	rm -rf various_*/*/.git &&
+
+	# We use `git diff` instead of `diff -r` because the latter would
+	# follow symlinks, and not all `diff` implementations support the
+	# `--no-dereference` option.
+	#
+	git diff --no-index various_sequential various_parallel &&
+	git diff --no-index various_sequential various_parallel_clone &&
+	git diff --no-index various_sequential various_sequential-fallback &&
+	git diff --no-index various_sequential various_sequential-fallback_clone
+'
+
+# Currently, each submodule is checked out in a separated child process, but
+# these subprocesses must also be able to use parallel checkout workers to
+# write the submodules' entries.
+test_expect_success 'submodules can use parallel checkout' '
+	set_checkout_config 2 0 &&
+	git init super &&
+	(
+		cd super &&
+		git init sub &&
+		test_commit -C sub A &&
+		test_commit -C sub B &&
+		git submodule add ./sub &&
+		git commit -m sub &&
+		rm sub/* &&
+		test_checkout_workers 2 git checkout --recurse-submodules .
+	)
+'
+
+test_expect_success 'parallel checkout respects --[no]-force' '
+	set_checkout_config 2 0 &&
+	git init dirty &&
+	(
+		cd dirty &&
+		mkdir D &&
+		test_commit D/F &&
+		test_commit F &&
+
+		rm -rf D &&
+		echo changed >D &&
+		echo changed >F.t &&
+
+		# We expect 0 workers because there is nothing to be done
+		test_checkout_workers 0 git checkout HEAD &&
+		test_path_is_file D &&
+		grep changed D &&
+		grep changed F.t &&
+
+		test_checkout_workers 2 git checkout --force HEAD &&
+		test_path_is_dir D &&
+		grep D/F D/F.t &&
+		grep F F.t
+	)
+'
+
+test_expect_success SYMLINKS 'parallel checkout checks for symlinks in leading dirs' '
+	set_checkout_config 2 0 &&
+	git init symlinks &&
+	(
+		cd symlinks &&
+		mkdir D untracked &&
+		# Commit 2 files to have enough work for 2 parallel workers
+		test_commit D/A &&
+		test_commit D/B &&
+		rm -rf D &&
+		ln -s untracked D &&
+
+		test_checkout_workers 2 git checkout --force HEAD &&
+		! test -h D &&
+		grep D/A D/A.t &&
+		grep D/B D/B.t
+	)
+'
+
+test_done
-- 
2.30.1
Previous: Matheus Tavares BernardinoNext: Matheus Tavares
Message 27 of 50 in “Parallel Checkout (part 3)”
  1. 0/7 Parallel Checkout (part 3)Matheus Tavares, Apr 22, 2021
  2. 1/7 make_transient_cache_entry(): optionally alloc from mem_poolMatheus Tavares, Apr 22, 2021
  3. 2/7 builtin/checkout.c: complete parallel checkout supportMatheus Tavares, Apr 22, 2021
  4. Derrick StoleeApr 23, 2021
  5. Matheus Tavares BernardinoApr 26, 2021
  6. 3/7 checkout-index: add parallel checkout supportMatheus Tavares, Apr 22, 2021
  7. Derrick StoleeApr 23, 2021
  8. Matheus Tavares BernardinoApr 26, 2021
  9. 4/7 parallel-checkout: add tests for basic operationsMatheus Tavares, Apr 22, 2021
  10. Derrick StoleeApr 23, 2021
  11. Matheus Tavares BernardinoApr 27, 2021
  12. 5/7 parallel-checkout: add tests related to path collisionsMatheus Tavares, Apr 22, 2021
  13. 6/7 parallel-checkout: add tests related to .gitattributesMatheus Tavares, Apr 22, 2021
  14. Derrick StoleeApr 23, 2021
  15. 7/7 ci: run test round with parallel-checkout enabledMatheus Tavares, Apr 22, 2021
  16. Derrick StoleeApr 23, 2021
  17. 0/8 Parallel Checkout (part 3)Matheus Tavares, Apr 30, 2021
  18. 1/8 make_transient_cache_entry(): optionally alloc from mem_poolMatheus Tavares, Apr 30, 2021
  19. Christian CouderMay 1, 2021
  20. Matheus Tavares BernardinoMay 3, 2021
  21. 2/8 builtin/checkout.c: complete parallel checkout supportMatheus Tavares, Apr 30, 2021
  22. Christian CouderMay 1, 2021
  23. Matheus Tavares BernardinoMay 3, 2021
  24. 3/8 checkout-index: add parallel checkout supportMatheus Tavares, Apr 30, 2021
  25. Christian CouderMay 1, 2021
  26. Matheus Tavares BernardinoMay 3, 2021
  27. 4/8 parallel-checkout: add tests for basic operationsMatheus Tavares, Apr 30, 2021
  28. 5/8 parallel-checkout: add tests related to path collisionsMatheus Tavares, Apr 30, 2021
  29. Torsten BögershausenMay 2, 2021
  30. Matheus Tavares BernardinoMay 3, 2021
  31. 6/8 t0028: extract encoding helpers to lib-encoding.shMatheus Tavares, Apr 30, 2021
  32. 7/8 parallel-checkout: add tests related to .gitattributesMatheus Tavares, Apr 30, 2021
  33. 8/8 ci: run test round with parallel-checkout enabledMatheus Tavares, Apr 30, 2021
  34. Torsten BögershausenMay 2, 2021
  35. Matheus Tavares BernardinoMay 3, 2021
  36. 0/8 Parallel Checkout (part 3)Matheus Tavares, May 4, 2021
  37. 1/8 make_transient_cache_entry(): optionally alloc from mem_poolMatheus Tavares, May 4, 2021
  38. 2/8 builtin/checkout.c: complete parallel checkout supportMatheus Tavares, May 4, 2021
  39. Derrick StoleeMay 5, 2021
  40. 3/8 checkout-index: add parallel checkout supportMatheus Tavares, May 4, 2021
  41. 4/8 parallel-checkout: add tests for basic operationsMatheus Tavares, May 4, 2021
  42. AIX failures on parallel checkout (new in v2.32.0-rc*)Ævar Arnfjörð Bjarmason, May 26, 2021
  43. Matheus Tavares BernardinoMay 26, 2021
  44. Junio C HamanoMay 26, 2021
  45. 5/8 parallel-checkout: add tests related to path collisionsMatheus Tavares, May 4, 2021
  46. 6/8 t0028: extract encoding helpers to lib-encoding.shMatheus Tavares, May 4, 2021
  47. 7/8 parallel-checkout: add tests related to .gitattributesMatheus Tavares, May 4, 2021
  48. 8/8 ci: run test round with parallel-checkout enabledMatheus Tavares, May 4, 2021
  49. Derrick StoleeMay 5, 2021
  50. Junio C HamanoMay 6, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.