Merge branch 'tb/core-eol-fix' into maint
[gitweb.git] / t / lib-git-p4.sh
index 75482254a3e72a65640c6805abd028e2b7bd0e2f..012d40e74695f8c195236a22802fd3ca6d60a8d8 100644 (file)
@@ -6,6 +6,14 @@
 # a subdirectory called "$git"
 TEST_NO_CREATE_REPO=NoThanks
 
+# Some operations require multiple attempts to be successful. Define
+# here the maximal retry timeout in seconds.
+RETRY_TIMEOUT=60
+
+# Sometimes p4d seems to hang. Terminate the p4d process automatically after
+# the defined timeout in seconds.
+P4D_TIMEOUT=300
+
 . ./test-lib.sh
 
 if ! test_have_prereq PYTHON
@@ -36,6 +44,15 @@ native_path() {
        echo "$path"
 }
 
+# On Solaris the 'date +%s' function is not supported and therefore we
+# need this replacement.
+# Attention: This function is not safe again against time offset updates
+# at runtime (e.g. via NTP). The 'clock_gettime(CLOCK_MONOTONIC)'
+# function could fix that but it is not in Python until 3.3.
+time_in_seconds() {
+       (cd / && "$PYTHON_PATH" -c 'import time; print(int(time.time()))')
+}
+
 # Try to pick a unique port: guess a large number, then hope
 # no more than one of each test is running.
 #
@@ -57,6 +74,15 @@ cli="$TRASH_DIRECTORY/cli"
 git="$TRASH_DIRECTORY/git"
 pidfile="$TRASH_DIRECTORY/p4d.pid"
 
+# Sometimes "prove" seems to hang on exit because p4d is still running
+cleanup() {
+       if test -f "$pidfile"
+       then
+               kill -9 $(cat "$pidfile") 2>/dev/null && exit 255
+       fi
+}
+trap cleanup EXIT
+
 # git p4 submit generates a temp file, which will
 # not get cleaned up if the submission fails.  Don't
 # clutter up /tmp on the test machine.
@@ -81,6 +107,19 @@ start_p4d() {
        # will be caught with the "kill -0" check below.
        i=${P4D_START_PATIENCE:-300}
        pid=$(cat "$pidfile")
+
+       timeout=$(($(time_in_seconds) + $P4D_TIMEOUT))
+       while true
+       do
+               if test $(time_in_seconds) -gt $timeout
+               then
+                       kill -9 $pid
+                       exit 1
+               fi
+               sleep 1
+       done &
+       watchdog_pid=$!
+
        ready=
        while test $i -gt 0
        do
@@ -121,22 +160,36 @@ p4_add_user() {
        EOF
 }
 
+retry_until_success() {
+       timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT))
+       until "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout
+       do
+               sleep 1
+       done
+}
+
+retry_until_fail() {
+       timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT))
+       until ! "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout
+       do
+               sleep 1
+       done
+}
+
 kill_p4d() {
        pid=$(cat "$pidfile")
-       # it had better exist for the first kill
-       kill $pid &&
-       for i in 1 2 3 4 5 ; do
-               kill $pid >/dev/null 2>&1 || break
-               sleep 1
-       done &&
+       retry_until_fail kill $pid
+       retry_until_fail kill -9 $pid
        # complain if it would not die
        test_must_fail kill $pid >/dev/null 2>&1 &&
-       rm -rf "$db" "$cli" "$pidfile"
+       rm -rf "$db" "$cli" "$pidfile" &&
+       retry_until_fail kill -9 $watchdog_pid
 }
 
 cleanup_git() {
-       rm -rf "$git" &&
-       mkdir "$git"
+       retry_until_success rm -r "$git"
+       test_must_fail test -d "$git" &&
+       retry_until_success mkdir "$git"
 }
 
 marshal_dump() {
@@ -145,9 +198,10 @@ marshal_dump() {
        cat >"$TRASH_DIRECTORY/marshal-dump.py" <<-EOF &&
        import marshal
        import sys
+       instream = getattr(sys.stdin, 'buffer', sys.stdin)
        for i in range($line):
-           d = marshal.load(sys.stdin)
-       print d['$what']
+           d = marshal.load(instream)
+       print(d[b'$what'].decode('utf-8'))
        EOF
        "$PYTHON_PATH" "$TRASH_DIRECTORY/marshal-dump.py"
 }