t / perf / p7519-fsmonitor.shon commit Merge branch 'jk/fewer-pack-rescan' (79bafd2)
   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
  50        case "$(uname -s)" in
  51        MSYS_NT*)
  52          GIT_WORK_TREE="$(cygpath -aw "$PWD" | sed 's,\\,/,g')"
  53          ;;
  54        *)
  55          GIT_WORK_TREE="$PWD"
  56          ;;
  57        esac
  58fi
  59
  60if test -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.
  65        if test "$GIT_PERF_REPEAT_COUNT" -ne 1
  66        then
  67                echo "warning: Setting GIT_PERF_REPEAT_COUNT=1" >&2
  68                GIT_PERF_REPEAT_COUNT=1
  69        fi
  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
 121if test -n "$GIT_PERF_7519_DROP_CACHE"; then
 122        test-drop-caches
 123fi
 124
 125test_perf "status (fsmonitor=$INTEGRATION_SCRIPT)" '
 126        git status
 127'
 128
 129if test -n "$GIT_PERF_7519_DROP_CACHE"; then
 130        test-drop-caches
 131fi
 132
 133test_perf "status -uno (fsmonitor=$INTEGRATION_SCRIPT)" '
 134        git status -uno
 135'
 136
 137if test -n "$GIT_PERF_7519_DROP_CACHE"; then
 138        test-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
 151if test -n "$GIT_PERF_7519_DROP_CACHE"; then
 152        test-drop-caches
 153fi
 154
 155test_perf "status (fsmonitor=$INTEGRATION_SCRIPT)" '
 156        git status
 157'
 158
 159if test -n "$GIT_PERF_7519_DROP_CACHE"; then
 160        test-drop-caches
 161fi
 162
 163test_perf "status -uno (fsmonitor=$INTEGRATION_SCRIPT)" '
 164        git status -uno
 165'
 166
 167if test -n "$GIT_PERF_7519_DROP_CACHE"; then
 168        test-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