t/perf/p7527: add perf test for builtin FSMonitor

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff Hostetler committed May 26, 2022 at 21:47 UTC 7667f9d2ae944dbea85aeda7093af5c87904245c
1 file changed +257
t/perf/p7527-builtin-fsmonitor.sh new
+257
@@ -0,0 +1,257 @@
1 +#!/bin/sh
2 +
3 +test_description="Perf test for the builtin FSMonitor"
4 +
5 +. ./perf-lib.sh
6 +
7 +if ! test_have_prereq FSMONITOR_DAEMON
8 +then
9 + skip_all="fsmonitor--daemon is not supported on this platform"
10 + test_done
11 +fi
12 +
13 +test_lazy_prereq UNTRACKED_CACHE '
14 + { git update-index --test-untracked-cache; ret=$?; } &&
15 + test $ret -ne 1
16 +'
17 +
18 +# Lie to perf-lib and ask for a new empty repo and avoid
19 +# the complaints about GIT_PERF_REPO not being big enough
20 +# the perf hit when GIT_PERF_LARGE_REPO is copied into
21 +# the trash directory.
22 +#
23 +# NEEDSWORK: It would be nice if perf-lib had an option to
24 +# "borrow" an existing large repo (especially for gigantic
25 +# monorepos) and use it in-place. For now, fake it here.
26 +#
27 +test_perf_fresh_repo
28 +
29 +
30 +# Use a generated synthetic monorepo. If it doesn't exist, we will
31 +# generate it. If it does exist, we will put it in a known state
32 +# before we start our timings.
33 +#
34 +PARAM_D=5
35 +PARAM_W=10
36 +PARAM_F=9
37 +
38 +PARAMS="$PARAM_D"."$PARAM_W"."$PARAM_F"
39 +
40 +BALLAST_BR=p0006-ballast
41 +export BALLAST_BR
42 +
43 +TMP_BR=tmp_br
44 +export TMP_BR
45 +
46 +REPO=../repos/gen-many-files-"$PARAMS".git
47 +export REPO
48 +
49 +if ! test -d $REPO
50 +then
51 + (cd ../repos; ./many-files.sh -d $PARAM_D -w $PARAM_W -f $PARAM_F)
52 +fi
53 +
54 +
55 +enable_uc () {
56 + git -C $REPO config core.untrackedcache true
57 + git -C $REPO update-index --untracked-cache
58 + git -C $REPO status >/dev/null 2>&1
59 +}
60 +
61 +disable_uc () {
62 + git -C $REPO config core.untrackedcache false
63 + git -C $REPO update-index --no-untracked-cache
64 + git -C $REPO status >/dev/null 2>&1
65 +}
66 +
67 +start_fsm () {
68 + git -C $REPO fsmonitor--daemon start
69 + git -C $REPO fsmonitor--daemon status
70 + git -C $REPO config core.fsmonitor true
71 + git -C $REPO update-index --fsmonitor
72 + git -C $REPO status >/dev/null 2>&1
73 +}
74 +
75 +stop_fsm () {
76 + git -C $REPO config --unset core.fsmonitor
77 + git -C $REPO update-index --no-fsmonitor
78 + test_might_fail git -C $REPO fsmonitor--daemon stop 2>/dev/null
79 + git -C $REPO status >/dev/null 2>&1
80 +}
81 +
82 +
83 +# Ensure that FSMonitor is turned off on the borrowed repo.
84 +#
85 +test_expect_success "Setup borrowed repo (fsm+uc)" "
86 + stop_fsm &&
87 + disable_uc
88 +"
89 +
90 +# Also ensure that it starts in a known state.
91 +#
92 +# Because we assume that $GIT_PERF_REPEAT_COUNT > 1, we are not going to time
93 +# the ballast checkout, since only the first invocation does any work and the
94 +# subsequent ones just print "already on branch" and quit, so the reported
95 +# time is not useful.
96 +#
97 +# Create a temp branch and do all work relative to it so that we don't
98 +# accidentially alter the real ballast branch.
99 +#
100 +test_expect_success "Setup borrowed repo (temp ballast branch)" "
101 + test_might_fail git -C $REPO checkout $BALLAST_BR &&
102 + test_might_fail git -C $REPO reset --hard &&
103 + git -C $REPO clean -d -f &&
104 + test_might_fail git -C $REPO branch -D $TMP_BR &&
105 + git -C $REPO branch $TMP_BR $BALLAST_BR &&
106 + git -C $REPO checkout $TMP_BR
107 +"
108 +
109 +
110 +echo Data >data.txt
111 +
112 +# NEEDSWORK: We assume that $GIT_PERF_REPEAT_COUNT > 1. With
113 +# FSMonitor enabled, we can get a skewed view of status times, since
114 +# the index MAY (or may not) be updated after the first invocation
115 +# which will update the FSMonitor Token, so the subsequent invocations
116 +# may get a smaller response from the daemon.
117 +#
118 +do_status () {
119 + msg=$1
120 +
121 + test_perf "$msg" "
122 + git -C $REPO status >/dev/null 2>&1
123 + "
124 +}
125 +
126 +do_matrix () {
127 + uc=$1
128 + fsm=$2
129 +
130 + t="[uc $uc][fsm $fsm]"
131 + MATRIX_BR="$TMP_BR-$uc-$fsm"
132 +
133 + test_expect_success "$t Setup matrix branch" "
134 + git -C $REPO clean -d -f &&
135 + git -C $REPO checkout $TMP_BR &&
136 + test_might_fail git -C $REPO branch -D $MATRIX_BR &&
137 + git -C $REPO branch $MATRIX_BR $TMP_BR &&
138 + git -C $REPO checkout $MATRIX_BR
139 + "
140 +
141 + if test $uc = true
142 + then
143 + enable_uc
144 + else
145 + disable_uc
146 + fi
147 +
148 + if test $fsm = true
149 + then
150 + start_fsm
151 + else
152 + stop_fsm
153 + fi
154 +
155 + do_status "$t status after checkout"
156 +
157 + # Modify many files in the matrix branch.
158 + # Stage them.
159 + # Commit them.
160 + # Rollback.
161 + #
162 + test_expect_success "$t modify tracked files" "
163 + find $REPO -name file1 -exec cp data.txt {} \\;
164 + "
165 +
166 + do_status "$t status after big change"
167 +
168 + # Don't bother timing the "add" because _REPEAT_COUNT
169 + # issue described above.
170 + #
171 + test_expect_success "$t add all" "
172 + git -C $REPO add -A
173 + "
174 +
175 + do_status "$t status after add all"
176 +
177 + test_expect_success "$t add dot" "
178 + git -C $REPO add .
179 + "
180 +
181 + do_status "$t status after add dot"
182 +
183 + test_expect_success "$t commit staged" "
184 + git -C $REPO commit -a -m data
185 + "
186 +
187 + do_status "$t status after commit"
188 +
189 + test_expect_success "$t reset HEAD~1 hard" "
190 + git -C $REPO reset --hard HEAD~1 >/dev/null 2>&1
191 + "
192 +
193 + do_status "$t status after reset hard"
194 +
195 + # Create some untracked files.
196 + #
197 + test_expect_success "$t create untracked files" "
198 + cp -R $REPO/ballast/dir1 $REPO/ballast/xxx1
199 + "
200 +
201 + do_status "$t status after create untracked files"
202 +
203 + # Remove the new untracked files.
204 + #
205 + test_expect_success "$t clean -df" "
206 + git -C $REPO clean -d -f
207 + "
208 +
209 + do_status "$t status after clean"
210 +
211 + if test $fsm = true
212 + then
213 + stop_fsm
214 + fi
215 +}
216 +
217 +# Begin testing each case in the matrix that we care about.
218 +#
219 +uc_values="false"
220 +test_have_prereq UNTRACKED_CACHE && uc_values="false true"
221 +
222 +fsm_values="false true"
223 +
224 +for uc_val in $uc_values
225 +do
226 + for fsm_val in $fsm_values
227 + do
228 + do_matrix $uc_val $fsm_val
229 + done
230 +done
231 +
232 +cleanup () {
233 + uc=$1
234 + fsm=$2
235 +
236 + MATRIX_BR="$TMP_BR-$uc-$fsm"
237 +
238 + test_might_fail git -C $REPO branch -D $MATRIX_BR
239 +}
240 +
241 +
242 +# We're borrowing this repo. We should leave it in a clean state.
243 +#
244 +test_expect_success "Cleanup temp and matrix branches" "
245 + git -C $REPO clean -d -f &&
246 + test_might_fail git -C $REPO checkout $BALLAST_BR &&
247 + test_might_fail git -C $REPO branch -D $TMP_BR &&
248 + for uc_val in $uc_values
249 + do
250 + for fsm_val in $fsm_values
251 + do
252 + cleanup $uc_val $fsm_val
253 + done
254 + done
255 +"
256 +
257 +test_done