3894: Use gem install --user-install to avoid sudo/rvm requirement
[arvados-dev.git] / jenkins / run-tests.sh
index f4e729ab551a0c6ca5a4e462f78f48b6141ef501..44bb60392d2f015d698453f4568acd0007fd19d5 100755 (executable)
@@ -5,21 +5,86 @@
 # Exit non-zero if any tests fail.
 #
 # Arguments:
-# --skip FOO   Do not test the FOO component.
-# --only FOO   Do not test anything except the FOO component.
+# --skip FOO     Do not test the FOO component.
+# --only FOO     Do not test anything except the FOO component.
+# WORKSPACE=path Arvados source tree to test.
+# CONFIGSRC=path Dir with api server config files to copy into source tree.
+# envvar=value   Set $envvar to value
 #
 # Regardless of which components are tested, install all components in
 # the usual sequence. (Many test suites depend on other components
 # being installed.)
+#
+# To run a specific Ruby test, set $workbench_test, $apiserver_test or
+# $cli_test on the command line:
+#
+# $ run-tests.sh --only workbench workbench_test=TEST=test/integration/pipeline_instances_test.rb
+#
+#
+# To run a specific Python test set $python_sdk_test or $fuse_test.
+#
+# $ run-tests.sh --only python_sdk python_sdk_test="--test-suite tests.test_keep_locator"
+#
+#
+# You can also pass "export ARVADOS_DEBUG=1" to enable additional debugging output:
+#
+# $ run-tests.sh "export ARVADOS_DEBUG=1"
+#
+#
+# Finally, you can skip the installation steps on subsequent runs this way:
+#
+## First run
+# $ run-tests.sh --leave-temp
+#
+## Subsequent runs: record the values of VENVDIR and GOPATH from the first run, and
+# provide them on the command line in subsequent runs:
+#
+# $ run-tests.sh --skip-install VENVDIR="/tmp/tmp.y3tsTmigio" GOPATH="/tmp/tmp.3r4sSA9F3l"
 
-COLUMNS=80
 
-ARVADOS_API_HOST=qr1hi.arvadosapi.com
+# First make sure to remove any ARVADOS_ variables from the calling environment
+# that could interfer with the tests.
+unset $(env | cut -d= -f1 | grep \^ARVADOS_)
 
-export GOPATH=$(mktemp -d)
-VENVDIR=$(mktemp -d)
+COLUMNS=80
+
+GITDIR=
+GOPATH=
+VENVDIR=
+PYTHONPATH=
+cli_test=
+workbench_test=
+apiserver_test=
+python_sdk_test=
+ruby_sdk_test=
+fuse_test=
+leave_temp=
+skip_install=
+
+if [[ -f /etc/profile.d/rvm.sh ]]
+then
+    source /etc/profile.d/rvm.sh
+fi
 
-source /etc/profile.d/rvm.sh
+declare -A leave_temp
+clear_temp() {
+    leaving=""
+    for var in VENVDIR GOPATH GITDIR
+    do
+        if [[ -z "${leave_temp[$var]}" ]]
+        then
+            if [[ -n "${!var}" ]]
+            then
+                rm -rf "${!var}"
+            fi
+        else
+            leaving+=" $var=\"${!var}\""
+        fi
+    done
+    if [[ -z "$leaving" ]]; then
+        echo "Leaving behind temp dirs: $leaving"
+    fi
+}
 
 fatal() {
     clear_temp
@@ -27,18 +92,6 @@ fatal() {
     exit 1
 }
 
-# Sanity check
-echo "WORKSPACE=$WORKSPACE"
-[[ -n "$WORKSPACE" ]] || fatal "WORKSPACE not set"
-
-# Set up temporary install dirs
-mkdir -p "$GOPATH/src/git.curoverse.com"
-ln -sfn "$WORKSPACE" "$GOPATH/src/git.curoverse.com/arvados.git" \
-    || fatal "symlink failed"
-
-virtualenv --setuptools "$VENVDIR" || fatal "virtualenv $VENVDIR failed"
-PATH="$VENVDIR/bin:$PATH"
-
 declare -a failures
 declare -A skip
 
@@ -56,6 +109,16 @@ do
         --only)
             only="$1"; shift
             ;;
+        --skip-install)
+            skip_install=1
+            ;;
+        --leave-temp)
+            leave_temp[VENVDIR]=1
+            leave_temp[GOPATH]=1
+            ;;
+        *=*)
+            eval $(echo $arg | cut -d= -f1)=\"$(echo $arg | cut -d= -f2-)\"
+            ;;
         *)
             echo >&2 "$0: Unrecognized option: '$arg'"
             exit 1
@@ -63,19 +126,58 @@ do
     esac
 done
 
+# Sanity check
+echo "WORKSPACE=$WORKSPACE"
+[[ -n "$WORKSPACE" ]] || fatal "WORKSPACE not set"
+
+if [[ -n "$CONFIGSRC" ]]; then
+    if [[ -d "$HOME/arvados-api-server" ]]; then
+        # Jenkins expects us to use this by default.
+        CONFIGSRC="$HOME/arvados-api-server"
+    fi
+fi
+
+# Set up temporary install dirs (unless existing dirs were supplied)
+if [[ -n "$VENVDIR" ]]; then
+    leave_temp[VENVDIR]=1
+else
+    VENVDIR=$(mktemp -d)
+fi
+if [[ -n "$GOPATH" ]]; then
+    leave_temp[GOPATH]=1
+else
+    GOPATH=$(mktemp -d)
+fi
+export GOPATH
+mkdir -p "$GOPATH/src/git.curoverse.com"
+ln -sfn "$WORKSPACE" "$GOPATH/src/git.curoverse.com/arvados.git" \
+    || fatal "symlink failed"
+
+virtualenv --setuptools "$VENVDIR" || fatal "virtualenv $VENVDIR failed"
+PATH="$VENVDIR/bin:$PATH"
+
 checkexit() {
     if [[ "$?" != "0" ]]; then
         title "!!!!!! $1 FAILED !!!!!!"
-        failures+=("$1")
+        failures+=("$1 (`timer`)")
     else
-        successes+=("$1")
+        successes+=("$1 (`timer`)")
     fi
 }
 
+timer_reset() {
+    t0=$SECONDS
+}
+
+timer() {
+    echo -n "$(($SECONDS - $t0))s"
+}
+
 do_test() {
     if [[ -z "${skip[$1]}" ]] && ( [[ -z "$only" ]] || [[ "$only" == "$1" ]] )
     then
         title "Running $1 tests"
+        timer_reset
         if [[ "$2" == "go" ]]
         then
             go test "git.curoverse.com/arvados.git/$1"
@@ -83,22 +185,28 @@ do_test() {
             "test_$1"
         fi
         checkexit "$1 tests"
-        title "End of $1 tests"
+        title "End of $1 tests (`timer`)"
     else
         title "Skipping $1 tests"
     fi
 }
 
 do_install() {
-    title "Running $1 install"
-    if [[ "$2" == "go" ]]
+    if [[ -z "$skip_install" ]]
     then
-        go get -t "git.curoverse.com/arvados.git/$1"
+        title "Running $1 install"
+        timer_reset
+        if [[ "$2" == "go" ]]
+        then
+            go get -t "git.curoverse.com/arvados.git/$1"
+        else
+            "install_$1"
+        fi
+        checkexit "$1 install"
+        title "End of $1 install (`timer`)"
     else
-        "install_$1"
+        title "Skipping $1 install"
     fi
-    checkexit "$1 install"
-    title "End of $1 install"
 }
 
 title () {
@@ -106,24 +214,16 @@ title () {
     printf "\n%*s%s\n\n" $((($COLUMNS-${#txt})/2)) "" "$txt"
 }
 
-clear_temp() {
-    for t in "$VENVDIR" "$GOPATH"
-    do
-        if [[ -n "$t" ]]
-        then
-            rm -rf "$t"
-        fi
-    done
-}
-
-install_docs() {
+test_docs() {
     cd "$WORKSPACE/doc"
-    bundle install --deployment
+    bundle install --no-deployment
     rm -rf .site
     # Make sure python-epydoc is installed or the next line won't do much good!
+    ARVADOS_API_HOST=qr1hi.arvadosapi.com
     PYTHONPATH=$WORKSPACE/sdk/python/ bundle exec rake generate baseurl=file://$WORKSPACE/doc/.site/ arvados_workbench_host=workbench.$ARVADOS_API_HOST arvados_api_host=$ARVADOS_API_HOST
+    unset ARVADOS_API_HOST
 }
-do_install docs
+do_test docs
 
 test_doclinkchecker() {
     cd "$WORKSPACE/doc"
@@ -131,15 +231,50 @@ test_doclinkchecker() {
 }
 do_test doclinkchecker
 
+test_ruby_sdk() {
+    cd "$WORKSPACE/sdk/ruby" \
+        && bundle install --no-deployment \
+        && bundle exec rake test
+}
+do_test ruby_sdk
+
+install_ruby_sdk() {
+    cd "$WORKSPACE/sdk/ruby" \
+        && gem build arvados.gemspec \
+        && gem install --user-install --no-ri --no-rdoc `ls -t arvados-*.gem|head -n1`
+}
+do_install ruby_sdk
+
+install_cli() {
+    cd "$WORKSPACE/sdk/cli" \
+        && gem build arvados-cli.gemspec \
+        && gem install --user-install --no-ri --no-rdoc `ls -t arvados-cli-*.gem|head -n1`
+}
+do_install cli
+
+test_cli() {
+    title "Starting SDK CLI tests"
+    cd "$WORKSPACE/sdk/cli" \
+        && bundle install --no-deployment \
+        && mkdir -p /tmp/keep \
+        && KEEP_LOCAL_STORE=/tmp/keep bundle exec rake test $cli_test
+}
+do_test cli
+
 install_apiserver() {
     cd "$WORKSPACE/services/api"
-    bundle install --deployment
+    bundle install --no-deployment
 
     rm -f config/environments/test.rb
     cp config/environments/test.rb.example config/environments/test.rb
 
-    cp $HOME/arvados-api-server/database.yml config/ || fatal "database.yml"
-    cp $HOME/arvados-api-server/application.yml config/ || fatal "application.yml"
+    if [ -n "$CONFIGSRC" ]
+    then
+        for f in database.yml application.yml
+        do
+            cp "$CONFIGSRC/$f" config/ || fatal "$f"
+        done
+    fi
 
     # Fill in a random secret_token and blob_signing_key for testing
     SECRET_TOKEN=`echo 'puts rand(2**512).to_s(36)' |ruby`
@@ -151,7 +286,7 @@ install_apiserver() {
     export RAILS_ENV=test
 
     # Set up empty git repo (for git tests)
-    GITDIR="$WORKSPACE/tmpgit"
+    GITDIR=$(mktemp -d)
     sed -i'' -e "s:/var/cache/git:$GITDIR:" config/application.default.yml
 
     rm -rf $GITDIR
@@ -164,6 +299,10 @@ install_apiserver() {
         && git add tmp \
         && git commit -m 'initial commit'
 
+    # Clear out any lingering postgresql connections to arvados_test, so that we can drop it
+    # This assumes the current user is a postgresql superuser
+    psql arvados_test -c "SELECT pg_terminate_backend (pg_stat_activity.procpid::int) FROM pg_stat_activity WHERE pg_stat_activity.datname = 'arvados_test';" 2>/dev/null
+
     cd "$WORKSPACE/services/api" \
         && bundle exec rake db:drop \
         && bundle exec rake db:create \
@@ -173,16 +312,10 @@ do_install apiserver
 
 test_apiserver() {
     cd "$WORKSPACE/services/api"
-    bundle exec rake test
+    bundle exec rake test $apiserver_test
 }
 do_test apiserver
 
-install_cli() {
-    cd "$WORKSPACE/sdk/cli"
-    bundle install --deployment
-}
-do_install cli
-
 declare -a gostuff
 gostuff=(
     services/keepstore
@@ -209,12 +342,12 @@ install_python_sdk() {
 }
 do_install python_sdk
 
-test_fuse() {
+install_fuse() {
     cd "$WORKSPACE/services/fuse" \
         && python setup.py egg_info -b ".$(git log --format=format:%ct.%h -n1 .)" sdist rotate --keep=1 --match .tar.gz \
         && pip install dist/arvados_fuse-0.1.*.tar.gz
 }
-do_test fuse
+do_install fuse
 
 test_python_sdk() {
     # Python SDK. We test this before testing keepproxy: keepproxy runs
@@ -224,37 +357,34 @@ test_python_sdk() {
     # the .egg files that setup.py downloads.
 
     cd "$WORKSPACE/sdk/python" \
-        && python setup.py test \
-        && easy_install *.egg
+        && python setup.py test $python_sdk_test
+    r=$?
+    easy_install *.egg
+    return $r
 }
 do_test python_sdk
 
-install_fuse() {
+test_fuse() {
     # Install test dependencies here too, in case run_test_server needs them.
     cd "$WORKSPACE/services/fuse" \
-        && python setup.py test \
-        && easy_install *.egg
+        && python setup.py test $fuse_test
+    r=$?
+    easy_install *.egg
+    return $r
 }
+do_test fuse
 
 for g in "${gostuff[@]}"
 do
     do_test "$g" go
 done
 
-install_workbench() {
+test_workbench() {
     cd "$WORKSPACE/apps/workbench" \
-        && bundle install --deployment \
-        && bundle exec rake test
+        && bundle install --no-deployment \
+        && bundle exec rake test $workbench_test
 }
-
-test_cli() {
-    title "Starting SDK CLI tests"
-    cd "$WORKSPACE/sdk/cli" \
-        && bundle install --deployment \
-        && mkdir -p /tmp/keep \
-        && KEEP_LOCAL_STORE=/tmp/keep bundle exec rake test
-}
-do_test cli
+do_test workbench
 
 clear_temp