Skip to content

Commit 5c8cdcf

Browse files
benpeartgitster
authored andcommitted
fsmonitor: add test cases for fsmonitor extension
Test the ability to add/remove the fsmonitor index extension via update-index. Test that dirty files returned from the integration script are properly represented in the index extension and verify that ls-files correctly reports their state. Test that ensure status results are correct when using the new fsmonitor extension. Test untracked, modified, and new files by ensuring the results are identical to when not using the extension. Test that if the fsmonitor extension doesn't tell git about a change, it doesn't discover it on its own. This ensures git is honoring the extension and that we get the performance benefits desired. Three test integration scripts are provided: fsmonitor-all - marks all files as dirty fsmonitor-none - marks no files as dirty fsmonitor-watchman - integrates with Watchman with debug logging To run tests in the test suite while utilizing fsmonitor: First copy t/t7519/fsmonitor-all to a location in your path and then set GIT_FORCE_PRELOAD_TEST=true and GIT_FSMONITOR_TEST=fsmonitor-all and run your tests. Note: currently when using the test script fsmonitor-watchman on Windows, many tests fail due to a reported but not yet fixed bug in Watchman where it holds on to handles for directories and files which prevents the test directory from being cleaned up properly. Signed-off-by: Ben Peart <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e692851 commit 5c8cdcf

File tree

4 files changed

+490
-0
lines changed

4 files changed

+490
-0
lines changed

t/t7519-status-fsmonitor.sh

Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
#!/bin/sh
2+
3+
test_description='git status with file system watcher'
4+
5+
. ./test-lib.sh
6+
7+
#
8+
# To run the entire git test suite using fsmonitor:
9+
#
10+
# copy t/t7519/fsmonitor-all to a location in your path and then set
11+
# GIT_FSMONITOR_TEST=fsmonitor-all and run your tests.
12+
#
13+
14+
# Note, after "git reset --hard HEAD" no extensions exist other than 'TREE'
15+
# "git update-index --fsmonitor" can be used to get the extension written
16+
# before testing the results.
17+
18+
clean_repo () {
19+
git reset --hard HEAD &&
20+
git clean -fd
21+
}
22+
23+
dirty_repo () {
24+
: >untracked &&
25+
: >dir1/untracked &&
26+
: >dir2/untracked &&
27+
echo 1 >modified &&
28+
echo 2 >dir1/modified &&
29+
echo 3 >dir2/modified &&
30+
echo 4 >new &&
31+
echo 5 >dir1/new &&
32+
echo 6 >dir2/new
33+
}
34+
35+
write_integration_script () {
36+
write_script .git/hooks/fsmonitor-test<<-\EOF
37+
if test "$#" -ne 2
38+
then
39+
echo "$0: exactly 2 arguments expected"
40+
exit 2
41+
fi
42+
if test "$1" != 1
43+
then
44+
echo "Unsupported core.fsmonitor hook version." >&2
45+
exit 1
46+
fi
47+
printf "untracked\0"
48+
printf "dir1/untracked\0"
49+
printf "dir2/untracked\0"
50+
printf "modified\0"
51+
printf "dir1/modified\0"
52+
printf "dir2/modified\0"
53+
printf "new\0"
54+
printf "dir1/new\0"
55+
printf "dir2/new\0"
56+
EOF
57+
}
58+
59+
test_lazy_prereq UNTRACKED_CACHE '
60+
{ git update-index --test-untracked-cache; ret=$?; } &&
61+
test $ret -ne 1
62+
'
63+
64+
test_expect_success 'setup' '
65+
mkdir -p .git/hooks &&
66+
: >tracked &&
67+
: >modified &&
68+
mkdir dir1 &&
69+
: >dir1/tracked &&
70+
: >dir1/modified &&
71+
mkdir dir2 &&
72+
: >dir2/tracked &&
73+
: >dir2/modified &&
74+
git -c core.fsmonitor= add . &&
75+
git -c core.fsmonitor= commit -m initial &&
76+
git config core.fsmonitor .git/hooks/fsmonitor-test &&
77+
cat >.gitignore <<-\EOF
78+
.gitignore
79+
expect*
80+
actual*
81+
marker*
82+
EOF
83+
'
84+
85+
# test that the fsmonitor extension is off by default
86+
test_expect_success 'fsmonitor extension is off by default' '
87+
test-dump-fsmonitor >actual &&
88+
grep "^no fsmonitor" actual
89+
'
90+
91+
# test that "update-index --fsmonitor" adds the fsmonitor extension
92+
test_expect_success 'update-index --fsmonitor" adds the fsmonitor extension' '
93+
git update-index --fsmonitor &&
94+
test-dump-fsmonitor >actual &&
95+
grep "^fsmonitor last update" actual
96+
'
97+
98+
# test that "update-index --no-fsmonitor" removes the fsmonitor extension
99+
test_expect_success 'update-index --no-fsmonitor" removes the fsmonitor extension' '
100+
git update-index --no-fsmonitor &&
101+
test-dump-fsmonitor >actual &&
102+
grep "^no fsmonitor" actual
103+
'
104+
105+
cat >expect <<EOF &&
106+
h dir1/modified
107+
H dir1/tracked
108+
h dir2/modified
109+
H dir2/tracked
110+
h modified
111+
H tracked
112+
EOF
113+
114+
# test that "update-index --fsmonitor-valid" sets the fsmonitor valid bit
115+
test_expect_success 'update-index --fsmonitor-valid" sets the fsmonitor valid bit' '
116+
git update-index --fsmonitor &&
117+
git update-index --fsmonitor-valid dir1/modified &&
118+
git update-index --fsmonitor-valid dir2/modified &&
119+
git update-index --fsmonitor-valid modified &&
120+
git ls-files -f >actual &&
121+
test_cmp expect actual
122+
'
123+
124+
cat >expect <<EOF &&
125+
H dir1/modified
126+
H dir1/tracked
127+
H dir2/modified
128+
H dir2/tracked
129+
H modified
130+
H tracked
131+
EOF
132+
133+
# test that "update-index --no-fsmonitor-valid" clears the fsmonitor valid bit
134+
test_expect_success 'update-index --no-fsmonitor-valid" clears the fsmonitor valid bit' '
135+
git update-index --no-fsmonitor-valid dir1/modified &&
136+
git update-index --no-fsmonitor-valid dir2/modified &&
137+
git update-index --no-fsmonitor-valid modified &&
138+
git ls-files -f >actual &&
139+
test_cmp expect actual
140+
'
141+
142+
cat >expect <<EOF &&
143+
H dir1/modified
144+
H dir1/tracked
145+
H dir2/modified
146+
H dir2/tracked
147+
H modified
148+
H tracked
149+
EOF
150+
151+
# test that all files returned by the script get flagged as invalid
152+
test_expect_success 'all files returned by integration script get flagged as invalid' '
153+
write_integration_script &&
154+
dirty_repo &&
155+
git update-index --fsmonitor &&
156+
git ls-files -f >actual &&
157+
test_cmp expect actual
158+
'
159+
160+
cat >expect <<EOF &&
161+
H dir1/modified
162+
h dir1/new
163+
H dir1/tracked
164+
H dir2/modified
165+
h dir2/new
166+
H dir2/tracked
167+
H modified
168+
h new
169+
H tracked
170+
EOF
171+
172+
# test that newly added files are marked valid
173+
test_expect_success 'newly added files are marked valid' '
174+
git add new &&
175+
git add dir1/new &&
176+
git add dir2/new &&
177+
git ls-files -f >actual &&
178+
test_cmp expect actual
179+
'
180+
181+
cat >expect <<EOF &&
182+
H dir1/modified
183+
h dir1/new
184+
h dir1/tracked
185+
H dir2/modified
186+
h dir2/new
187+
h dir2/tracked
188+
H modified
189+
h new
190+
h tracked
191+
EOF
192+
193+
# test that all unmodified files get marked valid
194+
test_expect_success 'all unmodified files get marked valid' '
195+
# modified files result in update-index returning 1
196+
test_must_fail git update-index --refresh --force-write-index &&
197+
git ls-files -f >actual &&
198+
test_cmp expect actual
199+
'
200+
201+
cat >expect <<EOF &&
202+
H dir1/modified
203+
h dir1/tracked
204+
h dir2/modified
205+
h dir2/tracked
206+
h modified
207+
h tracked
208+
EOF
209+
210+
# test that *only* files returned by the integration script get flagged as invalid
211+
test_expect_success '*only* files returned by the integration script get flagged as invalid' '
212+
write_script .git/hooks/fsmonitor-test<<-\EOF &&
213+
printf "dir1/modified\0"
214+
EOF
215+
clean_repo &&
216+
git update-index --refresh --force-write-index &&
217+
echo 1 >modified &&
218+
echo 2 >dir1/modified &&
219+
echo 3 >dir2/modified &&
220+
test_must_fail git update-index --refresh --force-write-index &&
221+
git ls-files -f >actual &&
222+
test_cmp expect actual
223+
'
224+
225+
# Ensure commands that call refresh_index() to move the index back in time
226+
# properly invalidate the fsmonitor cache
227+
test_expect_success 'refresh_index() invalidates fsmonitor cache' '
228+
write_script .git/hooks/fsmonitor-test<<-\EOF &&
229+
EOF
230+
clean_repo &&
231+
dirty_repo &&
232+
git add . &&
233+
git commit -m "to reset" &&
234+
git reset HEAD~1 &&
235+
git status >actual &&
236+
git -c core.fsmonitor= status >expect &&
237+
test_i18ncmp expect actual
238+
'
239+
240+
# test fsmonitor with and without preloadIndex
241+
preload_values="false true"
242+
for preload_val in $preload_values
243+
do
244+
test_expect_success "setup preloadIndex to $preload_val" '
245+
git config core.preloadIndex $preload_val &&
246+
if test $preload_val = true
247+
then
248+
GIT_FORCE_PRELOAD_TEST=$preload_val; export GIT_FORCE_PRELOAD_TEST
249+
else
250+
unset GIT_FORCE_PRELOAD_TEST
251+
fi
252+
'
253+
254+
# test fsmonitor with and without the untracked cache (if available)
255+
uc_values="false"
256+
test_have_prereq UNTRACKED_CACHE && uc_values="false true"
257+
for uc_val in $uc_values
258+
do
259+
test_expect_success "setup untracked cache to $uc_val" '
260+
git config core.untrackedcache $uc_val
261+
'
262+
263+
# Status is well tested elsewhere so we'll just ensure that the results are
264+
# the same when using core.fsmonitor.
265+
test_expect_success 'compare status with and without fsmonitor' '
266+
write_integration_script &&
267+
clean_repo &&
268+
dirty_repo &&
269+
git add new &&
270+
git add dir1/new &&
271+
git add dir2/new &&
272+
git status >actual &&
273+
git -c core.fsmonitor= status >expect &&
274+
test_i18ncmp expect actual
275+
'
276+
277+
# Make sure it's actually skipping the check for modified and untracked
278+
# (if enabled) files unless it is told about them.
279+
test_expect_success "status doesn't detect unreported modifications" '
280+
write_script .git/hooks/fsmonitor-test<<-\EOF &&
281+
:>marker
282+
EOF
283+
clean_repo &&
284+
git status &&
285+
test_path_is_file marker &&
286+
dirty_repo &&
287+
rm -f marker &&
288+
git status >actual &&
289+
test_path_is_file marker &&
290+
test_i18ngrep ! "Changes not staged for commit:" actual &&
291+
if test $uc_val = true
292+
then
293+
test_i18ngrep ! "Untracked files:" actual
294+
fi &&
295+
if test $uc_val = false
296+
then
297+
test_i18ngrep "Untracked files:" actual
298+
fi &&
299+
rm -f marker
300+
'
301+
done
302+
done
303+
304+
test_done

t/t7519/fsmonitor-all

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/sh
2+
#
3+
# An test hook script to integrate with git to test fsmonitor.
4+
#
5+
# The hook is passed a version (currently 1) and a time in nanoseconds
6+
# formatted as a string and outputs to stdout all files that have been
7+
# modified since the given time. Paths must be relative to the root of
8+
# the working tree and separated by a single NUL.
9+
#
10+
#echo "$0 $*" >&2
11+
12+
if test "$#" -ne 2
13+
then
14+
echo "$0: exactly 2 arguments expected" >&2
15+
exit 2
16+
fi
17+
18+
if test "$1" != 1
19+
then
20+
echo "Unsupported core.fsmonitor hook version." >&2
21+
exit 1
22+
fi
23+
24+
echo "/"

t/t7519/fsmonitor-none

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/bin/sh
2+
#
3+
# An test hook script to integrate with git to test fsmonitor.
4+
#
5+
# The hook is passed a version (currently 1) and a time in nanoseconds
6+
# formatted as a string and outputs to stdout all files that have been
7+
# modified since the given time. Paths must be relative to the root of
8+
# the working tree and separated by a single NUL.
9+
#
10+
#echo "$0 $*" >&2
11+
12+
if test "$#" -ne 2
13+
then
14+
echo "$0: exactly 2 arguments expected" >&2
15+
exit 2
16+
fi
17+
18+
if test "$1" != 1
19+
then
20+
echo "Unsupported core.fsmonitor hook version." >&2
21+
exit 1
22+
fi

0 commit comments

Comments
 (0)