Merge branch 'stable-3.1' into stable-3.2

* stable-3.1:
  fixup!: docker: Enable reruning tests without bringing down setup
  docker: Enable reruning tests without bringing down setup
  docker: Add support for "--preserve" option

Change-Id: I68cf619bb6f633bc758fc57dd855dd23f02ecae6
diff --git a/test/docker/lib_options.sh b/test/docker/lib_options.sh
new file mode 100755
index 0000000..87c77cd
--- /dev/null
+++ b/test/docker/lib_options.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+options_prefix() { # array_name option_name
+    local array_name=$1
+    local array_elements_name=$array_name[@]
+    local option=$2
+    local items=("${!array_elements_name}")
+    local item
+    eval "$array_name=()"
+    for item in "${items[@]}"; do
+        eval "$array_name"'+=("$option" "$item")'
+    done
+}
diff --git a/test/docker/run.sh b/test/docker/run.sh
index a57780b..75b9b3a 100755
--- a/test/docker/run.sh
+++ b/test/docker/run.sh
@@ -2,6 +2,8 @@
 
 readlink -f / &> /dev/null || readlink() { greadlink "$@" ; } # for MacOS
 MYDIR=$(dirname -- "$(readlink -f -- "$0")")
+MYPROG=$(basename -- "$0")
+source "$MYDIR/lib_options.sh"
 ARTIFACTS=$MYDIR/gerrit/artifacts
 
 die() { echo -e "\nERROR: $@" ; kill $$ ; exit 1 ; } # error_message
@@ -20,11 +22,9 @@
 }
 
 usage() { # [error_message]
-    local prog=$(basename -- "$0")
-
     cat <<-EOF
 Usage:
-    $prog [--task-plugin-jar|-t <FILE_PATH>] [--gerrit-war|-g <FILE_PATH>]
+    $MYPROG [--task-plugin-jar|-t <FILE_PATH>] [--gerrit-war|-g <FILE_PATH>]
 
     This tool runs the plugin functional tests in a Docker environment built
     from the gerritcodereview/gerrit base Docker image.
@@ -38,6 +38,7 @@
     --help|-h
     --gerrit-war|-g            path to Gerrit WAR file
     --task-plugin-jar|-t       path to task plugin JAR file
+    --preserve                 To preserve the docker setup for debugging
 
 EOF
 
@@ -60,19 +61,54 @@
         '/task/test/docker/run_tests/start.sh'
 }
 
-cleanup() {
-    docker-compose "${COMPOSE_ARGS[@]}" down -v --rmi local 2>/dev/null
+retest() {
+    docker-compose "${COMPOSE_ARGS[@]}" exec -T --user=gerrit_admin \
+        run_tests task/test/docker/run_tests/start.sh retest
+    RESULT=$?
+    cleanup
 }
 
+get_run_test_container() {
+    docker-compose "${COMPOSE_ARGS[@]}" ps | grep run_tests | awk '{ print $1 }'
+}
+
+cleanup() {
+    if [ "$PRESERVE" = "true" ] ; then
+        echo "Preserving the following docker setup"
+        docker-compose "${COMPOSE_ARGS[@]}" ps
+        echo ""
+        echo "To exec into runtests container, use following command:"
+        echo "docker exec -it $(get_run_test_container) /bin/bash"
+        echo ""
+        echo "Run the following command to bring down the setup:"
+        echo "docker-compose ${COMPOSE_ARGS[@]} down -v --rmi local"
+        echo ""
+        options_prefix "COMPOSE_ARGS" "--compose-arg"
+        echo "Use command below to re run tests after making changes to test scripts"
+        echo " $MYDIR/$MYPROG --retest --preserve ${COMPOSE_ARGS[@]}"
+    else
+        docker-compose "${COMPOSE_ARGS[@]}" down -v --rmi local 2>/dev/null
+    fi
+}
+
+PRESERVE="false"
+RETEST="false"
+COMPOSE_ARGS=()
 while (( "$#" )) ; do
     case "$1" in
         --help|-h)                usage ;;
         --gerrit-war|-g)          shift ; GERRIT_WAR=$1 ;;
         --task-plugin-jar|-t)     shift ; TASK_PLUGIN_JAR=$1 ;;
+        --preserve)               PRESERVE="true" ;;
+        --retest)                 RETEST="true" ;;
+        --compose-arg)            shift ; COMPOSE_ARGS+=("$1") ;;
         *)                        usage "invalid argument $1" ;;
     esac
     shift
 done
+
+[ "$RETEST" = "true" ] && { retest ; exit "$RESULT" ; }
+
 PROJECT_NAME="task_$$"
 COMPOSE_YAML="$MYDIR/docker-compose.yaml"
 COMPOSE_ARGS=(--project-name "$PROJECT_NAME" -f "$COMPOSE_YAML")
diff --git a/test/docker/run_tests/start.sh b/test/docker/run_tests/start.sh
index 9b40537..ac185d8 100755
--- a/test/docker/run_tests/start.sh
+++ b/test/docker/run_tests/start.sh
@@ -3,6 +3,11 @@
 USER_RUN_TESTS_DIR="$USER_HOME"/"$RUN_TESTS_DIR"
 cp -r /task "$USER_HOME"/
 
+if [ "$1" = "retest" ] ; then
+    cd "$USER_RUN_TESTS_DIR"/../../ && ./check_task_statuses.sh "$GERRIT_HOST"
+    exit $?
+fi
+
 ./"$USER_RUN_TESTS_DIR"/wait-for-it.sh "$GERRIT_HOST":29418 -t 60 -- echo "gerrit is up"
 
 echo "Creating a default user account ..."