3c9ad9adcf34e66e7d203ce3a9397a8a61394573
   1#
   2# Library code for git p4 tests
   3#
   4
   5# p4 tests never use the top-level repo; always build/clone into
   6# a subdirectory called "$git"
   7TEST_NO_CREATE_REPO=NoThanks
   8
   9# Some operations require multiple attempts to be successful. Define
  10# here the maximal retry timeout in seconds.
  11RETRY_TIMEOUT=60
  12
  13. ./test-lib.sh
  14
  15if ! test_have_prereq PYTHON
  16then
  17        skip_all='skipping git p4 tests; python not available'
  18        test_done
  19fi
  20( p4 -h && p4d -h ) >/dev/null 2>&1 || {
  21        skip_all='skipping git p4 tests; no p4 or p4d'
  22        test_done
  23}
  24
  25# On cygwin, the NT version of Perforce can be used.  When giving
  26# it paths, either on the command-line or in client specifications,
  27# be sure to use the native windows form.
  28#
  29# Older versions of perforce were available compiled natively for
  30# cygwin.  Those do not accept native windows paths, so make sure
  31# not to convert for them.
  32native_path() {
  33        path="$1" &&
  34        if test_have_prereq CYGWIN && ! p4 -V | grep -q CYGWIN
  35        then
  36                path=$(cygpath --windows "$path")
  37        else
  38                path=$(test-path-utils real_path "$path")
  39        fi &&
  40        echo "$path"
  41}
  42
  43# On Solaris the 'date +%s' function is not supported and therefore we
  44# need this replacement.
  45# Attention: This function is not safe again against time offset updates
  46# at runtime (e.g. via NTP). The 'clock_gettime(CLOCK_MONOTONIC)'
  47# function could fix that but it is not in Python until 3.3.
  48time_in_seconds() {
  49        python -c 'import time; print int(time.time())'
  50}
  51
  52# Try to pick a unique port: guess a large number, then hope
  53# no more than one of each test is running.
  54#
  55# This does not handle the case where somebody else is running the
  56# same tests and has chosen the same ports.
  57testid=${this_test#t}
  58git_p4_test_start=9800
  59P4DPORT=$((10669 + ($testid - $git_p4_test_start)))
  60
  61P4PORT=localhost:$P4DPORT
  62P4CLIENT=client
  63P4USER=author
  64P4EDITOR=true
  65unset P4CHARSET
  66export P4PORT P4CLIENT P4USER P4EDITOR P4CHARSET
  67
  68db="$TRASH_DIRECTORY/db"
  69cli="$TRASH_DIRECTORY/cli"
  70git="$TRASH_DIRECTORY/git"
  71pidfile="$TRASH_DIRECTORY/p4d.pid"
  72
  73# git p4 submit generates a temp file, which will
  74# not get cleaned up if the submission fails.  Don't
  75# clutter up /tmp on the test machine.
  76TMPDIR="$TRASH_DIRECTORY"
  77export TMPDIR
  78
  79start_p4d() {
  80        mkdir -p "$db" "$cli" "$git" &&
  81        rm -f "$pidfile" &&
  82        (
  83                cd "$db" &&
  84                {
  85                        p4d -q -p $P4DPORT "$@" &
  86                        echo $! >"$pidfile"
  87                }
  88        ) &&
  89
  90        # This gives p4d a long time to start up, as it can be
  91        # quite slow depending on the machine.  Set this environment
  92        # variable to something smaller to fail faster in, say,
  93        # an automated test setup.  If the p4d process dies, that
  94        # will be caught with the "kill -0" check below.
  95        i=${P4D_START_PATIENCE:-300}
  96        pid=$(cat "$pidfile")
  97        ready=
  98        while test $i -gt 0
  99        do
 100                # succeed when p4 client commands start to work
 101                if p4 info >/dev/null 2>&1
 102                then
 103                        ready=true
 104                        break
 105                fi
 106                # fail if p4d died
 107                kill -0 $pid 2>/dev/null || break
 108                echo waiting for p4d to start
 109                sleep 1
 110                i=$(( $i - 1 ))
 111        done
 112
 113        if test -z "$ready"
 114        then
 115                # p4d failed to start
 116                return 1
 117        fi
 118
 119        # build a p4 user so author@example.com has an entry
 120        p4_add_user author
 121
 122        # build a client
 123        client_view "//depot/... //client/..." &&
 124
 125        return 0
 126}
 127
 128p4_add_user() {
 129        name=$1 &&
 130        p4 user -f -i <<-EOF
 131        User: $name
 132        Email: $name@example.com
 133        FullName: Dr. $name
 134        EOF
 135}
 136
 137retry_until_success() {
 138        timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT))
 139        until "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout
 140        do
 141                sleep 1
 142        done
 143}
 144
 145retry_until_fail() {
 146        timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT))
 147        until ! "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout
 148        do
 149                sleep 1
 150        done
 151}
 152
 153kill_p4d() {
 154        pid=$(cat "$pidfile")
 155        retry_until_fail kill $pid
 156        retry_until_fail kill -9 $pid
 157        # complain if it would not die
 158        test_must_fail kill $pid >/dev/null 2>&1 &&
 159        rm -rf "$db" "$cli" "$pidfile"
 160}
 161
 162cleanup_git() {
 163        retry_until_success rm -r "$git"
 164        test_must_fail test -d "$git" &&
 165        retry_until_success mkdir "$git"
 166}
 167
 168marshal_dump() {
 169        what=$1 &&
 170        line=${2:-1} &&
 171        cat >"$TRASH_DIRECTORY/marshal-dump.py" <<-EOF &&
 172        import marshal
 173        import sys
 174        for i in range($line):
 175            d = marshal.load(sys.stdin)
 176        print d['$what']
 177        EOF
 178        "$PYTHON_PATH" "$TRASH_DIRECTORY/marshal-dump.py"
 179}
 180
 181#
 182# Construct a client with this list of View lines
 183#
 184client_view() {
 185        (
 186                cat <<-EOF &&
 187                Client: $P4CLIENT
 188                Description: $P4CLIENT
 189                Root: $cli
 190                AltRoots: $(native_path "$cli")
 191                LineEnd: unix
 192                View:
 193                EOF
 194                printf "\t%s\n" "$@"
 195        ) | p4 client -i
 196}
 197
 198is_cli_file_writeable() {
 199        # cygwin version of p4 does not set read-only attr,
 200        # will be marked 444 but -w is true
 201        file="$1" &&
 202        if test_have_prereq CYGWIN && p4 -V | grep -q CYGWIN
 203        then
 204                stat=$(stat --format=%a "$file") &&
 205                test $stat = 644
 206        else
 207                test -w "$file"
 208        fi
 209}