Merge branch 'rs/sha1-file-close-mapped-file-on-error'
[git/git.git] / t / lib-git-p4.sh
CommitLineData
fc002330 1#
6ab1d76c 2# Library code for git p4 tests
fc002330
PW
3#
4
c88015a4
PW
5# p4 tests never use the top-level repo; always build/clone into
6# a subdirectory called "$git"
7TEST_NO_CREATE_REPO=NoThanks
8
23aee419
LS
9# Some operations require multiple attempts to be successful. Define
10# here the maximal retry timeout in seconds.
11RETRY_TIMEOUT=60
12
842addef
LS
13# Sometimes p4d seems to hang. Terminate the p4d process automatically after
14# the defined timeout in seconds.
15P4D_TIMEOUT=300
16
fc002330
PW
17. ./test-lib.sh
18
cfa96496
PW
19if ! test_have_prereq PYTHON
20then
6ab1d76c 21 skip_all='skipping git p4 tests; python not available'
fc002330
PW
22 test_done
23fi
24( p4 -h && p4d -h ) >/dev/null 2>&1 || {
6ab1d76c 25 skip_all='skipping git p4 tests; no p4 or p4d'
fc002330
PW
26 test_done
27}
28
cfa96496
PW
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.
a98772c6 36native_path () {
cfa96496
PW
37 path="$1" &&
38 if test_have_prereq CYGWIN && ! p4 -V | grep -q CYGWIN
39 then
40 path=$(cygpath --windows "$path")
41 else
b8d5cf4f 42 path=$(test-tool path-utils real_path "$path")
cfa96496
PW
43 fi &&
44 echo "$path"
45}
46
23aee419
LS
47# On Solaris the 'date +%s' function is not supported and therefore we
48# need this replacement.
49# Attention: This function is not safe again against time offset updates
50# at runtime (e.g. via NTP). The 'clock_gettime(CLOCK_MONOTONIC)'
51# function could fix that but it is not in Python until 3.3.
a98772c6 52time_in_seconds () {
1fb3fb4e 53 (cd / && "$PYTHON_PATH" -c 'import time; print(int(time.time()))')
23aee419
LS
54}
55
fc002330
PW
56# Try to pick a unique port: guess a large number, then hope
57# no more than one of each test is running.
58#
59# This does not handle the case where somebody else is running the
60# same tests and has chosen the same ports.
61testid=${this_test#t}
62git_p4_test_start=9800
63P4DPORT=$((10669 + ($testid - $git_p4_test_start)))
64
8c291350
PW
65P4PORT=localhost:$P4DPORT
66P4CLIENT=client
0055b56e 67P4USER=author
0cf1b72a 68P4EDITOR=true
79946031 69unset P4CHARSET
0055b56e 70export P4PORT P4CLIENT P4USER P4EDITOR P4CHARSET
fc002330
PW
71
72db="$TRASH_DIRECTORY/db"
cfa96496 73cli="$TRASH_DIRECTORY/cli"
fc002330
PW
74git="$TRASH_DIRECTORY/git"
75pidfile="$TRASH_DIRECTORY/p4d.pid"
76
dfe90e8b 77# Sometimes "prove" seems to hang on exit because p4d is still running
a98772c6 78cleanup () {
dfe90e8b
LS
79 if test -f "$pidfile"
80 then
81 kill -9 $(cat "$pidfile") 2>/dev/null && exit 255
82 fi
83}
84trap cleanup EXIT
85
0cf1b72a
PW
86# git p4 submit generates a temp file, which will
87# not get cleaned up if the submission fails. Don't
88# clutter up /tmp on the test machine.
89TMPDIR="$TRASH_DIRECTORY"
90export TMPDIR
91
a98772c6 92start_p4d () {
fc002330 93 mkdir -p "$db" "$cli" "$git" &&
f89f35a9 94 rm -f "$pidfile" &&
fc002330 95 (
6492a104
PW
96 cd "$db" &&
97 {
e80967b2 98 p4d -q -p $P4DPORT "$@" &
6492a104
PW
99 echo $! >"$pidfile"
100 }
fc002330 101 ) &&
f89f35a9
PW
102
103 # This gives p4d a long time to start up, as it can be
104 # quite slow depending on the machine. Set this environment
105 # variable to something smaller to fail faster in, say,
106 # an automated test setup. If the p4d process dies, that
107 # will be caught with the "kill -0" check below.
108 i=${P4D_START_PATIENCE:-300}
109 pid=$(cat "$pidfile")
842addef
LS
110
111 timeout=$(($(time_in_seconds) + $P4D_TIMEOUT))
112 while true
113 do
114 if test $(time_in_seconds) -gt $timeout
115 then
116 kill -9 $pid
117 exit 1
118 fi
119 sleep 1
120 done &
121 watchdog_pid=$!
122
f89f35a9
PW
123 ready=
124 while test $i -gt 0
125 do
126 # succeed when p4 client commands start to work
127 if p4 info >/dev/null 2>&1
128 then
129 ready=true
130 break
131 fi
132 # fail if p4d died
133 kill -0 $pid 2>/dev/null || break
134 echo waiting for p4d to start
fc002330 135 sleep 1
f89f35a9
PW
136 i=$(( $i - 1 ))
137 done
138
139 if test -z "$ready"
140 then
141 # p4d failed to start
142 return 1
143 fi
144
0055b56e
PW
145 # build a p4 user so author@example.com has an entry
146 p4_add_user author
147
f89f35a9 148 # build a client
daa38f4a
PW
149 client_view "//depot/... //client/..." &&
150
f89f35a9 151 return 0
fc002330
PW
152}
153
a98772c6 154p4_add_user () {
0055b56e
PW
155 name=$1 &&
156 p4 user -f -i <<-EOF
157 User: $name
158 Email: $name@example.com
159 FullName: Dr. $name
160 EOF
161}
162
26e6a27d
JD
163p4_add_job () {
164 p4 job -f -i <<-EOF
165 Job: $1
166 Status: open
167 User: dummy
168 Description:
169 EOF
170}
171
a98772c6 172retry_until_success () {
23aee419
LS
173 timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT))
174 until "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout
175 do
176 sleep 1
177 done
178}
179
a98772c6 180retry_until_fail () {
23aee419
LS
181 timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT))
182 until ! "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout
183 do
184 sleep 1
185 done
186}
187
a98772c6 188kill_p4d () {
fc002330 189 pid=$(cat "$pidfile")
23aee419
LS
190 retry_until_fail kill $pid
191 retry_until_fail kill -9 $pid
fc002330
PW
192 # complain if it would not die
193 test_must_fail kill $pid >/dev/null 2>&1 &&
842addef
LS
194 rm -rf "$db" "$cli" "$pidfile" &&
195 retry_until_fail kill -9 $watchdog_pid
fc002330
PW
196}
197
a98772c6 198cleanup_git () {
23aee419
LS
199 retry_until_success rm -r "$git"
200 test_must_fail test -d "$git" &&
201 retry_until_success mkdir "$git"
fc002330 202}
798d5980 203
a98772c6 204marshal_dump () {
798d5980
PW
205 what=$1 &&
206 line=${2:-1} &&
207 cat >"$TRASH_DIRECTORY/marshal-dump.py" <<-EOF &&
208 import marshal
209 import sys
84096814 210 instream = getattr(sys.stdin, 'buffer', sys.stdin)
798d5980 211 for i in range($line):
84096814
LD
212 d = marshal.load(instream)
213 print(d[b'$what'].decode('utf-8'))
798d5980
PW
214 EOF
215 "$PYTHON_PATH" "$TRASH_DIRECTORY/marshal-dump.py"
216}
d2018293
PW
217
218#
219# Construct a client with this list of View lines
220#
a98772c6 221client_view () {
d2018293
PW
222 (
223 cat <<-EOF &&
50038ba9
PW
224 Client: $P4CLIENT
225 Description: $P4CLIENT
d2018293 226 Root: $cli
cfa96496 227 AltRoots: $(native_path "$cli")
e93f8695 228 LineEnd: unix
d2018293
PW
229 View:
230 EOF
6112541b 231 printf "\t%s\n" "$@"
d2018293
PW
232 ) | p4 client -i
233}
e9df0f9c 234
a98772c6 235is_cli_file_writeable () {
e9df0f9c
PW
236 # cygwin version of p4 does not set read-only attr,
237 # will be marked 444 but -w is true
238 file="$1" &&
239 if test_have_prereq CYGWIN && p4 -V | grep -q CYGWIN
240 then
241 stat=$(stat --format=%a "$file") &&
242 test $stat = 644
243 else
244 test -w "$file"
245 fi
246}