t / perf / p7519-fsmonitor.shon commit Merge branch 'nd/checkout-m' (4a3ed2b)
   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
  44'
  45
  46if test_have_prereq WATCHMAN
  47then
  48        # Convert unix style paths to escaped Windows style paths for Watchman
  49        case "$(uname -s)" in
  50        MSYS_NT*)
  51          GIT_WORK_TREE="$(cygpath -aw "$PWD" | sed 's,\\,/,g')"
  52          ;;
  53        *)
  54          GIT_WORK_TREE="$PWD"
  55          ;;
  56        esac
  57fi
  58
  59if test -n "$GIT_PERF_7519_DROP_CACHE"
  60then
  61        # When using GIT_PERF_7519_DROP_CACHE, GIT_PERF_REPEAT_COUNT must be 1 to
  62        # generate valid results. Otherwise the caching that happens for the nth
  63        # run will negate the validity of the comparisons.
  64        if test "$GIT_PERF_REPEAT_COUNT" -ne 1
  65        then
  66                echo "warning: Setting GIT_PERF_REPEAT_COUNT=1" >&2
  67                GIT_PERF_REPEAT_COUNT=1
  68        fi
  69fi
  70
  71test_expect_success "setup for fsmonitor" '
  72        # set untrackedCache depending on the environment
  73        if test -n "$GIT_PERF_7519_UNTRACKED_CACHE"
  74        then
  75                git config core.untrackedCache "$GIT_PERF_7519_UNTRACKED_CACHE"
  76        else
  77                if test_have_prereq UNTRACKED_CACHE
  78                then
  79                        git config core.untrackedCache true
  80                else
  81                        git config core.untrackedCache false
  82                fi
  83        fi &&
  84
  85        # set core.splitindex depending on the environment
  86        if test -n "$GIT_PERF_7519_SPLIT_INDEX"
  87        then
  88                git config core.splitIndex "$GIT_PERF_7519_SPLIT_INDEX"
  89        fi &&
  90
  91        # set INTEGRATION_SCRIPT depending on the environment
  92        if test -n "$GIT_PERF_7519_FSMONITOR"
  93        then
  94                INTEGRATION_SCRIPT="$GIT_PERF_7519_FSMONITOR"
  95        else
  96                #
  97                # Choose integration script based on existence of Watchman.
  98                # If Watchman exists, watch the work tree and attempt a query.
  99                # If everything succeeds, use Watchman integration script,
 100                # else fall back to an empty integration script.
 101                #
 102                mkdir .git/hooks &&
 103                if test_have_prereq WATCHMAN
 104                then
 105                        INTEGRATION_SCRIPT=".git/hooks/fsmonitor-watchman" &&
 106                        cp "$TEST_DIRECTORY/../templates/hooks--fsmonitor-watchman.sample" "$INTEGRATION_SCRIPT" &&
 107                        watchman watch "$GIT_WORK_TREE" &&
 108                        watchman watch-list | grep -q -F "$GIT_WORK_TREE"
 109                else
 110                        INTEGRATION_SCRIPT=".git/hooks/fsmonitor-empty" &&
 111                        write_script "$INTEGRATION_SCRIPT"<<-\EOF
 112                        EOF
 113                fi
 114        fi &&
 115
 116        git config core.fsmonitor "$INTEGRATION_SCRIPT" &&
 117        git update-index --fsmonitor
 118'
 119
 120if test -n "$GIT_PERF_7519_DROP_CACHE"; then
 121        test-tool drop-caches
 122fi
 123
 124test_perf "status (fsmonitor=$INTEGRATION_SCRIPT)" '
 125        git status
 126'
 127
 128if test -n "$GIT_PERF_7519_DROP_CACHE"; then
 129        test-tool drop-caches
 130fi
 131
 132test_perf "status -uno (fsmonitor=$INTEGRATION_SCRIPT)" '
 133        git status -uno
 134'
 135
 136if test -n "$GIT_PERF_7519_DROP_CACHE"; then
 137        test-tool drop-caches
 138fi
 139
 140test_perf "status -uall (fsmonitor=$INTEGRATION_SCRIPT)" '
 141        git status -uall
 142'
 143
 144test_expect_success "setup without fsmonitor" '
 145        unset INTEGRATION_SCRIPT &&
 146        git config --unset core.fsmonitor &&
 147        git update-index --no-fsmonitor
 148'
 149
 150if test -n "$GIT_PERF_7519_DROP_CACHE"; then
 151        test-tool drop-caches
 152fi
 153
 154test_perf "status (fsmonitor=$INTEGRATION_SCRIPT)" '
 155        git status
 156'
 157
 158if test -n "$GIT_PERF_7519_DROP_CACHE"; then
 159        test-tool drop-caches
 160fi
 161
 162test_perf "status -uno (fsmonitor=$INTEGRATION_SCRIPT)" '
 163        git status -uno
 164'
 165
 166if test -n "$GIT_PERF_7519_DROP_CACHE"; then
 167        test-tool drop-caches
 168fi
 169
 170test_perf "status -uall (fsmonitor=$INTEGRATION_SCRIPT)" '
 171        git status -uall
 172'
 173
 174if test_have_prereq WATCHMAN
 175then
 176        watchman watch-del "$GIT_WORK_TREE" >/dev/null 2>&1 &&
 177
 178        # Work around Watchman bug on Windows where it holds on to handles
 179        # preventing the removal of the trash directory
 180        watchman shutdown-server >/dev/null 2>&1
 181fi
 182
 183test_done