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# Sometimes p4d seems to hang. Terminate the p4d process automatically after 14# the defined timeout in seconds. 15P4D_TIMEOUT=300 16 17. ./test-lib.sh 18 19if ! test_have_prereq PYTHON 20then 21 skip_all='skipping git p4 tests; python not available' 22 test_done 23fi 24( p4 -h && p4d -h ) >/dev/null 2>&1 || { 25 skip_all='skipping git p4 tests; no p4 or p4d' 26 test_done 27} 28 29# On cygwin, the NT version of Perforce can be used. When giving 30# it paths, either on the command-line or in client specifications, 31# be sure to use the native windows form. 32# 33# Older versions of perforce were available compiled natively for 34# cygwin. Those do not accept native windows paths, so make sure 35# not to convert for them. 36native_path () { 37 path="$1" && 38 if test_have_prereq CYGWIN && ! p4 -V | grep -q CYGWIN 39 then 40 path=$(cygpath --windows "$path") 41 else 42 path=$(test-tool path-utils real_path "$path") 43 fi && 44 echo "$path" 45} 46 47test_set_port P4DPORT 48 49P4PORT=localhost:$P4DPORT 50P4CLIENT=client 51P4USER=author 52P4EDITOR=true 53unset P4CHARSET 54export P4PORT P4CLIENT P4USER P4EDITOR P4CHARSET 55 56db="$TRASH_DIRECTORY/db" 57cli="$TRASH_DIRECTORY/cli" 58git="$TRASH_DIRECTORY/git" 59pidfile="$TRASH_DIRECTORY/p4d.pid" 60 61stop_p4d_and_watchdog () { 62 kill -9 $p4d_pid $watchdog_pid 63} 64 65# git p4 submit generates a temp file, which will 66# not get cleaned up if the submission fails. Don't 67# clutter up /tmp on the test machine. 68TMPDIR="$TRASH_DIRECTORY" 69export TMPDIR 70 71registered_stop_p4d_atexit_handler= 72start_p4d () { 73 # One of the test scripts stops and then re-starts p4d. 74 # Don't register and then run the same atexit handlers several times. 75 if test -z "$registered_stop_p4d_atexit_handler" 76 then 77 test_atexit 'stop_p4d_and_watchdog' 78 registered_stop_p4d_atexit_handler=AlreadyDone 79 fi 80 81 mkdir -p "$db" "$cli" "$git" && 82 rm -f "$pidfile" && 83 ( 84 cd "$db" && 85 { 86 p4d -q -p $P4DPORT "$@" & 87 echo $! >"$pidfile" 88 } 89 ) && 90 p4d_pid=$(cat "$pidfile") 91 92 # This gives p4d a long time to start up, as it can be 93 # quite slow depending on the machine. Set this environment 94 # variable to something smaller to fail faster in, say, 95 # an automated test setup. If the p4d process dies, that 96 # will be caught with the "kill -0" check below. 97 i=${P4D_START_PATIENCE:-300} 98 99 nr_tries_left=$P4D_TIMEOUT 100 while true 101 do 102 if test $nr_tries_left -eq 0 103 then 104 kill -9 $p4d_pid 105 exit 1 106 fi 107 sleep 1 108 nr_tries_left=$(($nr_tries_left - 1)) 109 done & 110 watchdog_pid=$! 111 112 ready= 113 while test $i -gt 0 114 do 115 # succeed when p4 client commands start to work 116 if p4 info >/dev/null 2>&1 117 then 118 ready=true 119 break 120 fi 121 # fail if p4d died 122 kill -0 $p4d_pid 2>/dev/null || break 123 echo waiting for p4d to start 124 sleep 1 125 i=$(( $i - 1 )) 126 done 127 128 if test -z "$ready" 129 then 130 # p4d failed to start 131 return 1 132 fi 133 134 # build a p4 user so author@example.com has an entry 135 p4_add_user author 136 137 # build a client 138 client_view "//depot/... //client/..." && 139 140 return 0 141} 142 143p4_add_user () { 144 name=$1 && 145 p4 user -f -i <<-EOF 146 User: $name 147 Email: $name@example.com 148 FullName: Dr. $name 149 EOF 150} 151 152p4_add_job () { 153 p4 job -f -i <<-EOF 154 Job: $1 155 Status: open 156 User: dummy 157 Description: 158 EOF 159} 160 161retry_until_success () { 162 nr_tries_left=$RETRY_TIMEOUT 163 until "$@" 2>/dev/null || test $nr_tries_left -eq 0 164 do 165 sleep 1 166 nr_tries_left=$(($nr_tries_left - 1)) 167 done 168} 169 170stop_and_cleanup_p4d () { 171 kill -9 $p4d_pid $watchdog_pid 172 wait $p4d_pid 173 rm -rf "$db" "$cli" "$pidfile" 174} 175 176cleanup_git () { 177 retry_until_success rm -r "$git" 178 test_must_fail test -d "$git" && 179 retry_until_success mkdir "$git" 180} 181 182marshal_dump () { 183 what=$1 && 184 line=${2:-1} && 185 cat >"$TRASH_DIRECTORY/marshal-dump.py" <<-EOF && 186 import marshal 187 import sys 188 instream = getattr(sys.stdin, 'buffer', sys.stdin) 189 for i in range($line): 190 d = marshal.load(instream) 191 print(d[b'$what'].decode('utf-8')) 192 EOF 193 "$PYTHON_PATH" "$TRASH_DIRECTORY/marshal-dump.py" 194} 195 196# 197# Construct a client with this list of View lines 198# 199client_view () { 200 ( 201 cat <<-EOF && 202 Client: $P4CLIENT 203 Description: $P4CLIENT 204 Root: $cli 205 AltRoots: $(native_path "$cli") 206 LineEnd: unix 207 View: 208 EOF 209 printf "\t%s\n" "$@" 210 ) | p4 client -i 211} 212 213is_cli_file_writeable () { 214 # cygwin version of p4 does not set read-only attr, 215 # will be marked 444 but -w is true 216 file="$1" && 217 if test_have_prereq CYGWIN && p4 -V | grep -q CYGWIN 218 then 219 stat=$(stat --format=%a "$file") && 220 test $stat = 644 221 else 222 test -w "$file" 223 fi 224}