Git 2.23
[gitweb.git] / t / lib-git-p4.sh
index 75482254a3e72a65640c6805abd028e2b7bd0e2f..547b9f88e1235a9248f6da9d1fa24dffd7cb0cd3 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
@@ -25,25 +33,18 @@ fi
 # Older versions of perforce were available compiled natively for
 # cygwin.  Those do not accept native windows paths, so make sure
 # not to convert for them.
-native_path() {
+native_path () {
        path="$1" &&
        if test_have_prereq CYGWIN && ! p4 -V | grep -q CYGWIN
        then
                path=$(cygpath --windows "$path")
        else
-               path=$(test-path-utils real_path "$path")
+               path=$(test-tool path-utils real_path "$path")
        fi &&
        echo "$path"
 }
 
-# Try to pick a unique port: guess a large number, then hope
-# no more than one of each test is running.
-#
-# This does not handle the case where somebody else is running the
-# same tests and has chosen the same ports.
-testid=${this_test#t}
-git_p4_test_start=9800
-P4DPORT=$((10669 + ($testid - $git_p4_test_start)))
+test_set_port P4DPORT
 
 P4PORT=localhost:$P4DPORT
 P4CLIENT=client
@@ -57,13 +58,26 @@ cli="$TRASH_DIRECTORY/cli"
 git="$TRASH_DIRECTORY/git"
 pidfile="$TRASH_DIRECTORY/p4d.pid"
 
+stop_p4d_and_watchdog () {
+       kill -9 $p4d_pid $watchdog_pid
+}
+
 # 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.
 TMPDIR="$TRASH_DIRECTORY"
 export TMPDIR
 
-start_p4d() {
+registered_stop_p4d_atexit_handler=
+start_p4d () {
+       # One of the test scripts stops and then re-starts p4d.
+       # Don't register and then run the same atexit handlers several times.
+       if test -z "$registered_stop_p4d_atexit_handler"
+       then
+               test_atexit 'stop_p4d_and_watchdog'
+               registered_stop_p4d_atexit_handler=AlreadyDone
+       fi
+
        mkdir -p "$db" "$cli" "$git" &&
        rm -f "$pidfile" &&
        (
@@ -73,6 +87,7 @@ start_p4d() {
                        echo $! >"$pidfile"
                }
        ) &&
+       p4d_pid=$(cat "$pidfile")
 
        # This gives p4d a long time to start up, as it can be
        # quite slow depending on the machine.  Set this environment
@@ -80,7 +95,20 @@ start_p4d() {
        # an automated test setup.  If the p4d process dies, that
        # will be caught with the "kill -0" check below.
        i=${P4D_START_PATIENCE:-300}
-       pid=$(cat "$pidfile")
+
+       nr_tries_left=$P4D_TIMEOUT
+       while true
+       do
+               if test $nr_tries_left -eq 0
+               then
+                       kill -9 $p4d_pid
+                       exit 1
+               fi
+               sleep 1
+               nr_tries_left=$(($nr_tries_left - 1))
+       done 2>/dev/null 4>&2 &
+       watchdog_pid=$!
+
        ready=
        while test $i -gt 0
        do
@@ -91,7 +119,7 @@ start_p4d() {
                        break
                fi
                # fail if p4d died
-               kill -0 $pid 2>/dev/null || break
+               kill -0 $p4d_pid 2>/dev/null || break
                echo waiting for p4d to start
                sleep 1
                i=$(( $i - 1 ))
@@ -112,7 +140,7 @@ start_p4d() {
        return 0
 }
 
-p4_add_user() {
+p4_add_user () {
        name=$1 &&
        p4 user -f -i <<-EOF
        User: $name
@@ -121,33 +149,46 @@ p4_add_user() {
        EOF
 }
 
-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
+p4_add_job () {
+       p4 job -f -i <<-EOF
+       Job: $1
+       Status: open
+       User: dummy
+       Description:
+       EOF
+}
+
+retry_until_success () {
+       nr_tries_left=$RETRY_TIMEOUT
+       until "$@" 2>/dev/null || test $nr_tries_left -eq 0
+       do
                sleep 1
-       done &&
-       # complain if it would not die
-       test_must_fail kill $pid >/dev/null 2>&1 &&
+               nr_tries_left=$(($nr_tries_left - 1))
+       done
+}
+
+stop_and_cleanup_p4d () {
+       kill -9 $p4d_pid $watchdog_pid
+       wait $p4d_pid
        rm -rf "$db" "$cli" "$pidfile"
 }
 
-cleanup_git() {
-       rm -rf "$git" &&
-       mkdir "$git"
+cleanup_git () {
+       retry_until_success rm -r "$git"
+       test_must_fail test -d "$git" &&
+       retry_until_success mkdir "$git"
 }
 
-marshal_dump() {
+marshal_dump () {
        what=$1 &&
        line=${2:-1} &&
        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"
 }
@@ -155,7 +196,7 @@ marshal_dump() {
 #
 # Construct a client with this list of View lines
 #
-client_view() {
+client_view () {
        (
                cat <<-EOF &&
                Client: $P4CLIENT
@@ -169,7 +210,7 @@ client_view() {
        ) | p4 client -i
 }
 
-is_cli_file_writeable() {
+is_cli_file_writeable () {
        # cygwin version of p4 does not set read-only attr,
        # will be marked 444 but -w is true
        file="$1" &&