1#!/bin/sh 2 3test_description="Test core.fsmonitor" 4 5. ./perf-lib.sh 6 7# 8# Performance test for the fsmonitor feature which enables git to talk to a 9# file system change monitor and avoid having to scan the working directory 10# for new or modified files. 11# 12# By default, the performance test will utilize the Watchman file system 13# monitor if it is installed. If Watchman is not installed, it will use a 14# dummy integration script that does not report any new or modified files. 15# The dummy script has very little overhead which provides optimistic results. 16# 17# The performance test will also use the untracked cache feature if it is 18# available as fsmonitor uses it to speed up scanning for untracked files. 19# 20# There are 3 environment variables that can be used to alter the default 21# behavior of the performance test: 22# 23# GIT_PERF_7519_UNTRACKED_CACHE: used to configure core.untrackedCache 24# GIT_PERF_7519_SPLIT_INDEX: used to configure core.splitIndex 25# GIT_PERF_7519_FSMONITOR: used to configure core.fsMonitor 26# 27# The big win for using fsmonitor is the elimination of the need to scan the 28# working directory looking for changed and untracked files. If the file 29# information is all cached in RAM, the benefits are reduced. 30# 31# GIT_PERF_7519_DROP_CACHE: if set, the OS caches are dropped between tests 32# 33 34test_perf_large_repo 35test_checkout_worktree 36 37test_lazy_prereq UNTRACKED_CACHE ' 38 { git update-index --test-untracked-cache; ret=$?; } && 39 test$ret-ne 1 40' 41 42test_lazy_prereq WATCHMAN ' 43 { command -v watchman >/dev/null 2>&1; ret=$?; } && 44 test$ret-ne 1 45' 46 47if test_have_prereq WATCHMAN 48then 49# Convert unix style paths to escaped Windows style paths for Watchman 50case"$(uname -s)"in 51 MSYS_NT*) 52 GIT_WORK_TREE="$(cygpath -aw "$PWD" | sed 's,\\,/,g')" 53;; 54*) 55 GIT_WORK_TREE="$PWD" 56;; 57esac 58fi 59 60iftest -n"$GIT_PERF_7519_DROP_CACHE" 61then 62# When using GIT_PERF_7519_DROP_CACHE, GIT_PERF_REPEAT_COUNT must be 1 to 63# generate valid results. Otherwise the caching that happens for the nth 64# run will negate the validity of the comparisons. 65iftest"$GIT_PERF_REPEAT_COUNT"-ne1 66then 67echo"warning: Setting GIT_PERF_REPEAT_COUNT=1">&2 68 GIT_PERF_REPEAT_COUNT=1 69fi 70fi 71 72test_expect_success "setup for fsmonitor"' 73 # set untrackedCache depending on the environment 74 if test -n "$GIT_PERF_7519_UNTRACKED_CACHE" 75 then 76 git config core.untrackedCache "$GIT_PERF_7519_UNTRACKED_CACHE" 77 else 78 if test_have_prereq UNTRACKED_CACHE 79 then 80 git config core.untrackedCache true 81 else 82 git config core.untrackedCache false 83 fi 84 fi && 85 86 # set core.splitindex depending on the environment 87 if test -n "$GIT_PERF_7519_SPLIT_INDEX" 88 then 89 git config core.splitIndex "$GIT_PERF_7519_SPLIT_INDEX" 90 fi && 91 92 # set INTEGRATION_SCRIPT depending on the environment 93 if test -n "$GIT_PERF_7519_FSMONITOR" 94 then 95 INTEGRATION_SCRIPT="$GIT_PERF_7519_FSMONITOR" 96 else 97 # 98 # Choose integration script based on existence of Watchman. 99 # If Watchman exists, watch the work tree and attempt a query. 100 # If everything succeeds, use Watchman integration script, 101 # else fall back to an empty integration script. 102 # 103 mkdir .git/hooks && 104 if test_have_prereq WATCHMAN 105 then 106 INTEGRATION_SCRIPT=".git/hooks/fsmonitor-watchman" && 107 cp "$TEST_DIRECTORY/../templates/hooks--fsmonitor-watchman.sample" "$INTEGRATION_SCRIPT" && 108 watchman watch "$GIT_WORK_TREE" && 109 watchman watch-list | grep -q -F "$GIT_WORK_TREE" 110 else 111 INTEGRATION_SCRIPT=".git/hooks/fsmonitor-empty" && 112 write_script "$INTEGRATION_SCRIPT"<<-\EOF 113 EOF 114 fi 115 fi && 116 117 git config core.fsmonitor "$INTEGRATION_SCRIPT" && 118 git update-index --fsmonitor 119' 120 121iftest -n"$GIT_PERF_7519_DROP_CACHE";then 122test-drop-caches 123fi 124 125test_perf "status (fsmonitor=$INTEGRATION_SCRIPT)"' 126 git status 127' 128 129iftest -n"$GIT_PERF_7519_DROP_CACHE";then 130test-drop-caches 131fi 132 133test_perf "status -uno (fsmonitor=$INTEGRATION_SCRIPT)"' 134 git status -uno 135' 136 137iftest -n"$GIT_PERF_7519_DROP_CACHE";then 138test-drop-caches 139fi 140 141test_perf "status -uall (fsmonitor=$INTEGRATION_SCRIPT)"' 142 git status -uall 143' 144 145test_expect_success "setup without fsmonitor"' 146 unset INTEGRATION_SCRIPT && 147 git config --unset core.fsmonitor && 148 git update-index --no-fsmonitor 149' 150 151iftest -n"$GIT_PERF_7519_DROP_CACHE";then 152test-drop-caches 153fi 154 155test_perf "status (fsmonitor=$INTEGRATION_SCRIPT)"' 156 git status 157' 158 159iftest -n"$GIT_PERF_7519_DROP_CACHE";then 160test-drop-caches 161fi 162 163test_perf "status -uno (fsmonitor=$INTEGRATION_SCRIPT)"' 164 git status -uno 165' 166 167iftest -n"$GIT_PERF_7519_DROP_CACHE";then 168test-drop-caches 169fi 170 171test_perf "status -uall (fsmonitor=$INTEGRATION_SCRIPT)"' 172 git status -uall 173' 174 175if test_have_prereq WATCHMAN 176then 177 watchman watch-del"$GIT_WORK_TREE">/dev/null 2>&1&& 178 179# Work around Watchman bug on Windows where it holds on to handles 180# preventing the removal of the trash directory 181 watchman shutdown-server>/dev/null 2>&1 182fi 183 184test_done