| #!/bin/sh | 
 |  | 
 | test_description="Perf test for the builtin FSMonitor" | 
 |  | 
 | . ./perf-lib.sh | 
 |  | 
 | if ! test_have_prereq FSMONITOR_DAEMON | 
 | then | 
 | 	skip_all="fsmonitor--daemon is not supported on this platform" | 
 | 	test_done | 
 | fi | 
 |  | 
 | test_lazy_prereq UNTRACKED_CACHE ' | 
 | 	{ git update-index --test-untracked-cache; ret=$?; } && | 
 | 	test $ret -ne 1 | 
 | ' | 
 |  | 
 | # Lie to perf-lib and ask for a new empty repo and avoid | 
 | # the complaints about GIT_PERF_REPO not being big enough | 
 | # the perf hit when GIT_PERF_LARGE_REPO is copied into | 
 | # the trash directory. | 
 | # | 
 | # NEEDSWORK: It would be nice if perf-lib had an option to | 
 | # "borrow" an existing large repo (especially for gigantic | 
 | # monorepos) and use it in-place.  For now, fake it here. | 
 | # | 
 | test_perf_fresh_repo | 
 |  | 
 |  | 
 | # Use a generated synthetic monorepo.  If it doesn't exist, we will | 
 | # generate it.  If it does exist, we will put it in a known state | 
 | # before we start our timings. | 
 | # | 
 | PARAM_D=5 | 
 | PARAM_W=10 | 
 | PARAM_F=9 | 
 |  | 
 | PARAMS="$PARAM_D"."$PARAM_W"."$PARAM_F" | 
 |  | 
 | BALLAST_BR=p0006-ballast | 
 | export BALLAST_BR | 
 |  | 
 | TMP_BR=tmp_br | 
 | export TMP_BR | 
 |  | 
 | REPO=../repos/gen-many-files-"$PARAMS".git | 
 | export REPO | 
 |  | 
 | if ! test -d $REPO | 
 | then | 
 | 	(cd ../repos; ./many-files.sh -d $PARAM_D -w $PARAM_W -f $PARAM_F) | 
 | fi | 
 |  | 
 |  | 
 | enable_uc () { | 
 | 	git -C $REPO config core.untrackedcache true | 
 | 	git -C $REPO update-index --untracked-cache | 
 | 	git -C $REPO status >/dev/null 2>&1 | 
 | } | 
 |  | 
 | disable_uc () { | 
 | 	git -C $REPO config core.untrackedcache false | 
 | 	git -C $REPO update-index --no-untracked-cache | 
 | 	git -C $REPO status >/dev/null 2>&1 | 
 | } | 
 |  | 
 | start_fsm () { | 
 | 	git -C $REPO fsmonitor--daemon start | 
 | 	git -C $REPO fsmonitor--daemon status | 
 | 	git -C $REPO config core.fsmonitor true | 
 | 	git -C $REPO update-index --fsmonitor | 
 | 	git -C $REPO status >/dev/null 2>&1 | 
 | } | 
 |  | 
 | stop_fsm () { | 
 | 	git -C $REPO config --unset core.fsmonitor | 
 | 	git -C $REPO update-index --no-fsmonitor | 
 | 	test_might_fail git -C $REPO fsmonitor--daemon stop 2>/dev/null | 
 | 	git -C $REPO status >/dev/null 2>&1 | 
 | } | 
 |  | 
 |  | 
 | # Ensure that FSMonitor is turned off on the borrowed repo. | 
 | # | 
 | test_expect_success "Setup borrowed repo (fsm+uc)" " | 
 | 	stop_fsm && | 
 | 	disable_uc | 
 | " | 
 |  | 
 | # Also ensure that it starts in a known state. | 
 | # | 
 | # Because we assume that $GIT_PERF_REPEAT_COUNT > 1, we are not going to time | 
 | # the ballast checkout, since only the first invocation does any work and the | 
 | # subsequent ones just print "already on branch" and quit, so the reported | 
 | # time is not useful. | 
 | # | 
 | # Create a temp branch and do all work relative to it so that we don't | 
 | # accidentially alter the real ballast branch. | 
 | # | 
 | test_expect_success "Setup borrowed repo (temp ballast branch)" " | 
 | 	test_might_fail git -C $REPO checkout $BALLAST_BR && | 
 | 	test_might_fail git -C $REPO reset --hard && | 
 | 	git -C $REPO clean -d -f && | 
 | 	test_might_fail git -C $REPO branch -D $TMP_BR && | 
 | 	git -C $REPO branch $TMP_BR $BALLAST_BR && | 
 | 	git -C $REPO checkout $TMP_BR | 
 | " | 
 |  | 
 |  | 
 | echo Data >data.txt | 
 |  | 
 | # NEEDSWORK: We assume that $GIT_PERF_REPEAT_COUNT > 1.  With | 
 | # FSMonitor enabled, we can get a skewed view of status times, since | 
 | # the index MAY (or may not) be updated after the first invocation | 
 | # which will update the FSMonitor Token, so the subsequent invocations | 
 | # may get a smaller response from the daemon. | 
 | # | 
 | do_status () { | 
 | 	msg=$1 | 
 |  | 
 | 	test_perf "$msg" " | 
 | 		git -C $REPO status >/dev/null 2>&1 | 
 | 	" | 
 | } | 
 |  | 
 | do_matrix () { | 
 | 	uc=$1 | 
 | 	fsm=$2 | 
 |  | 
 | 	t="[uc $uc][fsm $fsm]" | 
 | 	MATRIX_BR="$TMP_BR-$uc-$fsm" | 
 |  | 
 | 	test_expect_success "$t Setup matrix branch" " | 
 | 		git -C $REPO clean -d -f && | 
 | 		git -C $REPO checkout $TMP_BR && | 
 | 		test_might_fail git -C $REPO branch -D $MATRIX_BR && | 
 | 		git -C $REPO branch $MATRIX_BR $TMP_BR && | 
 | 		git -C $REPO checkout $MATRIX_BR | 
 | 	" | 
 |  | 
 | 	if test $uc = true | 
 | 	then | 
 | 		enable_uc | 
 | 	else | 
 | 		disable_uc | 
 | 	fi | 
 |  | 
 | 	if test $fsm = true | 
 | 	then | 
 | 		start_fsm | 
 | 	else | 
 | 		stop_fsm | 
 | 	fi | 
 |  | 
 | 	do_status "$t status after checkout" | 
 |  | 
 | 	# Modify many files in the matrix branch. | 
 | 	# Stage them. | 
 | 	# Commit them. | 
 | 	# Rollback. | 
 | 	# | 
 | 	test_expect_success "$t modify tracked files" " | 
 | 		find $REPO -name file1 -exec cp data.txt {} \\; | 
 | 	" | 
 |  | 
 | 	do_status "$t status after big change" | 
 |  | 
 | 	# Don't bother timing the "add" because _REPEAT_COUNT | 
 | 	# issue described above. | 
 | 	# | 
 | 	test_expect_success "$t add all" " | 
 | 		git -C $REPO add -A | 
 | 	" | 
 |  | 
 | 	do_status "$t status after add all" | 
 |  | 
 | 	test_expect_success "$t add dot" " | 
 | 		git -C $REPO add . | 
 | 	" | 
 |  | 
 | 	do_status "$t status after add dot" | 
 |  | 
 | 	test_expect_success "$t commit staged" " | 
 | 		git -C $REPO commit -a -m data | 
 | 	" | 
 |  | 
 | 	do_status "$t status after commit" | 
 |  | 
 | 	test_expect_success "$t reset HEAD~1 hard" " | 
 | 		git -C $REPO reset --hard HEAD~1 >/dev/null 2>&1 | 
 | 	" | 
 |  | 
 | 	do_status "$t status after reset hard" | 
 |  | 
 | 	# Create some untracked files. | 
 | 	# | 
 | 	test_expect_success "$t create untracked files" " | 
 | 		cp -R $REPO/ballast/dir1 $REPO/ballast/xxx1 | 
 | 	" | 
 |  | 
 | 	do_status "$t status after create untracked files" | 
 |  | 
 | 	# Remove the new untracked files. | 
 | 	# | 
 | 	test_expect_success "$t clean -df" " | 
 | 		git -C $REPO clean -d -f | 
 | 	" | 
 |  | 
 | 	do_status "$t status after clean" | 
 |  | 
 | 	if test $fsm = true | 
 | 	then | 
 | 		stop_fsm | 
 | 	fi | 
 | } | 
 |  | 
 | # Begin testing each case in the matrix that we care about. | 
 | # | 
 | uc_values="false" | 
 | test_have_prereq UNTRACKED_CACHE && uc_values="false true" | 
 |  | 
 | fsm_values="false true" | 
 |  | 
 | for uc_val in $uc_values | 
 | do | 
 | 	for fsm_val in $fsm_values | 
 | 	do | 
 | 		do_matrix $uc_val $fsm_val | 
 | 	done | 
 | done | 
 |  | 
 | cleanup () { | 
 | 	uc=$1 | 
 | 	fsm=$2 | 
 |  | 
 | 	MATRIX_BR="$TMP_BR-$uc-$fsm" | 
 |  | 
 | 	test_might_fail git -C $REPO branch -D $MATRIX_BR | 
 | } | 
 |  | 
 |  | 
 | # We're borrowing this repo.  We should leave it in a clean state. | 
 | # | 
 | test_expect_success "Cleanup temp and matrix branches" " | 
 | 	git -C $REPO clean -d -f && | 
 | 	test_might_fail git -C $REPO checkout $BALLAST_BR && | 
 | 	test_might_fail git -C $REPO branch -D $TMP_BR && | 
 | 	for uc_val in $uc_values | 
 | 	do | 
 | 		for fsm_val in $fsm_values | 
 | 		do | 
 | 			cleanup $uc_val $fsm_val | 
 | 		done | 
 | 	done | 
 | " | 
 |  | 
 | test_done |