Merge branch '6592-test-perl' refs #6592
[arvados-dev.git] / jenkins / run-tests.sh
1 #!/bin/bash
2
3 read -rd "\000" helpmessage <<EOF
4 $(basename $0): Install and test Arvados components.
5
6 Exit non-zero if any tests fail.
7
8 Syntax:
9         $(basename $0) WORKSPACE=/path/to/arvados [options]
10
11 Options:
12
13 --skip FOO     Do not test the FOO component.
14 --only FOO     Do not test anything except the FOO component.
15 --leave-temp   Do not remove GOPATH, virtualenv, and other temp dirs at exit.
16                Instead, show which directories were used this time so they
17                can be reused in subsequent invocations.
18 --skip-install Do not run any install steps. Just run tests.
19                You should provide GOPATH, GEMHOME, and VENVDIR options
20                from a previous invocation if you use this option.
21 --only-install Run specific install step
22 WORKSPACE=path Arvados source tree to test.
23 CONFIGSRC=path Dir with api server config files to copy into source tree.
24                (If none given, leave config files alone in source tree.)
25 services/api_test="TEST=test/functional/arvados/v1/collections_controller_test.rb"
26                Restrict apiserver tests to the given file
27 sdk/python_test="--test-suite test.test_keep_locator"
28                Restrict Python SDK tests to the given class
29 apps/workbench_test="TEST=test/integration/pipeline_instances_test.rb"
30                Restrict Workbench tests to the given file
31 services/arv-git-httpd_test="-check.vv"
32                Show all log messages, even when tests pass (also works
33                with services/keepstore_test etc.)
34 ARVADOS_DEBUG=1
35                Print more debug messages
36 envvar=value   Set \$envvar to value. Primarily useful for WORKSPACE,
37                *_test, and other examples shown above.
38
39 Assuming --skip-install is not given, all components are installed
40 into \$GOPATH, \$VENDIR, and \$GEMHOME before running any tests. Many
41 test suites depend on other components being installed, and installing
42 everything tends to be quicker than debugging dependencies.
43
44 As a special concession to the current CI server config, CONFIGSRC
45 defaults to $HOME/arvados-api-server if that directory exists.
46
47 More information and background:
48
49 https://arvados.org/projects/arvados/wiki/Running_tests
50
51 Available tests:
52
53 apps/workbench
54 apps/workbench_benchmark
55 apps/workbench_profile
56 doc
57 services/api
58 services/crunchstat
59 services/dockercleaner
60 services/fuse
61 services/keepproxy
62 services/keepstore
63 services/nodemanager
64 services/arv-git-httpd
65 sdk/cli
66 sdk/python
67 sdk/ruby
68 sdk/go/arvadosclient
69 sdk/go/keepclient
70 sdk/go/streamer
71
72 EOF
73
74 # First make sure to remove any ARVADOS_ variables from the calling
75 # environment that could interfere with the tests.
76 unset $(env | cut -d= -f1 | grep \^ARVADOS_)
77
78 # Reset other variables that could affect our [tests'] behavior by
79 # accident.
80 GITDIR=
81 GOPATH=
82 VENVDIR=
83 VENV3DIR=
84 PYTHONPATH=
85 GEMHOME=
86 PERLINSTALLBASE=
87
88 COLUMNS=80
89
90 leave_temp=
91 skip_install=
92
93 declare -A leave_temp
94 clear_temp() {
95     leaving=""
96     for var in VENVDIR VENV3DIR GOPATH GITDIR GEMHOME PERLINSTALLBASE
97     do
98         if [[ -z "${leave_temp[$var]}" ]]
99         then
100             if [[ -n "${!var}" ]]
101             then
102                 rm -rf "${!var}"
103             fi
104         else
105             leaving+=" $var=\"${!var}\""
106         fi
107     done
108     if [[ -n "$leaving" ]]; then
109         echo "Leaving behind temp dirs: $leaving"
110     fi
111 }
112
113 fatal() {
114     clear_temp
115     echo >&2 "Fatal: $* (encountered in ${FUNCNAME[1]} at ${BASH_SOURCE[1]} line ${BASH_LINENO[0]})"
116     exit 1
117 }
118
119 report_outcomes() {
120     for x in "${successes[@]}"
121     do
122         echo "Pass: $x"
123     done
124
125     if [[ ${#failures[@]} == 0 ]]
126     then
127         echo "All test suites passed."
128     else
129         echo "Failures (${#failures[@]}):"
130         for x in "${failures[@]}"
131         do
132             echo "Fail: $x"
133         done
134     fi
135 }
136
137 exit_cleanly() {
138     trap - INT
139     create-plot-data-from-log.sh $BUILD_NUMBER "$WORKSPACE/apps/workbench/log/test.log" "$WORKSPACE/apps/workbench/log/"
140     rotate_logfile "$WORKSPACE/apps/workbench/log/" "test.log"
141     stop_services
142     rotate_logfile "$WORKSPACE/services/api/log/" "test.log"
143     report_outcomes
144     clear_temp
145     exit ${#failures}
146 }
147
148 sanity_checks() {
149     ( [[ -n "$WORKSPACE" ]] && [[ -d "$WORKSPACE/services" ]] ) \
150         || fatal "WORKSPACE environment variable not set to a source directory (see: $0 --help)"
151     echo Checking dependencies:
152     echo -n 'virtualenv: '
153     virtualenv --version \
154         || fatal "No virtualenv. Try: apt-get install virtualenv"
155     echo -n 'go: '
156     go version \
157         || fatal "No go binary. See http://golang.org/doc/install"
158     echo -n 'gcc: '
159     gcc --version | egrep ^gcc \
160         || fatal "No gcc. Try: apt-get install build-essential"
161     echo -n 'fuse.h: '
162     find /usr/include -wholename '*fuse/fuse.h' \
163         || fatal "No fuse/fuse.h. Try: apt-get install libfuse-dev"
164     echo -n 'pyconfig.h: '
165     find /usr/include -name pyconfig.h | egrep --max-count=1 . \
166         || fatal "No pyconfig.h. Try: apt-get install python-dev"
167     echo -n 'nginx: '
168     PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin" nginx -v \
169         || fatal "No nginx. Try: apt-get install nginx"
170     echo -n 'perl: '
171     perl -v | grep version \
172         || fatal "No perl. Try: apt-get install perl"
173     for mod in ExtUtils::MakeMaker JSON LWP Net::SSL; do
174         echo -n "perl $mod: "
175         perl -e "use $mod; print \"\$$mod::VERSION\\n\"" \
176             || fatal "No $mod. Try: apt-get install perl-modules libcrypt-ssleay-perl libjson-perl"
177     done
178 }
179
180 rotate_logfile() {
181   # i.e.  rotate_logfile "$WORKSPACE/apps/workbench/log/" "test.log"
182   # $BUILD_NUMBER is set by Jenkins if this script is being called as part of a Jenkins run
183   if [[ -f "$1/$2" ]]; then
184     THEDATE=`date +%Y%m%d%H%M%S`
185     mv "$1/$2" "$1/$THEDATE-$BUILD_NUMBER-$2"
186     gzip "$1/$THEDATE-$BUILD_NUMBER-$2"
187   fi
188 }
189
190 declare -a failures
191 declare -A skip
192 declare -A testargs
193 skip[apps/workbench_profile]=1
194
195 while [[ -n "$1" ]]
196 do
197     arg="$1"; shift
198     case "$arg" in
199         --help)
200             echo >&2 "$helpmessage"
201             echo >&2
202             exit 1
203             ;;
204         --skip)
205             skipwhat="$1"; shift
206             skip[$skipwhat]=1
207             ;;
208         --only)
209             only="$1"; skip[$1]=""; shift
210             ;;
211         --skip-install)
212             skip_install=1
213             ;;
214         --only-install)
215             skip_install=1
216             only_install="$1"; shift
217             ;;
218         --leave-temp)
219             leave_temp[VENVDIR]=1
220             leave_temp[VENV3DIR]=1
221             leave_temp[GOPATH]=1
222             leave_temp[GEMHOME]=1
223             leave_temp[PERLINSTALLBASE]=1
224             ;;
225         --retry)
226             retry=1
227             ;;
228         *_test=*)
229             suite="${arg%%_test=*}"
230             args="${arg#*=}"
231             testargs["$suite"]="$args"
232             ;;
233         *=*)
234             eval export $(echo $arg | cut -d= -f1)=\"$(echo $arg | cut -d= -f2-)\"
235             ;;
236         *)
237             echo >&2 "$0: Unrecognized option: '$arg'. Try: $0 --help"
238             exit 1
239             ;;
240     esac
241 done
242
243 start_api() {
244     echo 'Starting API server...'
245     cd "$WORKSPACE" \
246         && eval $(python sdk/python/tests/run_test_server.py start --auth admin) \
247         && export ARVADOS_TEST_API_HOST="$ARVADOS_API_HOST" \
248         && export ARVADOS_TEST_API_INSTALLED="$$" \
249         && (env | egrep ^ARVADOS)
250 }
251
252 start_nginx_proxy_services() {
253     echo 'Starting keepproxy, arv-git-httpd, and nginx ssl proxy...'
254     cd "$WORKSPACE" \
255         && python sdk/python/tests/run_test_server.py start_keep_proxy \
256         && python sdk/python/tests/run_test_server.py start_arv-git-httpd \
257         && python sdk/python/tests/run_test_server.py start_nginx \
258         && export ARVADOS_TEST_PROXY_SERVICES=1
259 }
260
261 stop_services() {
262     if [[ -n "$ARVADOS_TEST_PROXY_SERVICES" ]]; then
263         unset ARVADOS_TEST_PROXY_SERVICES
264         cd "$WORKSPACE" \
265             && python sdk/python/tests/run_test_server.py stop_nginx \
266             && python sdk/python/tests/run_test_server.py stop_arv-git-httpd \
267             && python sdk/python/tests/run_test_server.py stop_keep_proxy
268     fi
269     if [[ -n "$ARVADOS_TEST_API_HOST" ]]; then
270         unset ARVADOS_TEST_API_HOST
271         cd "$WORKSPACE" \
272             && python sdk/python/tests/run_test_server.py stop
273     fi
274 }
275
276 interrupt() {
277     failures+=("($(basename $0) interrupted)")
278     exit_cleanly
279 }
280 trap interrupt INT
281
282 sanity_checks
283
284 echo "WORKSPACE=$WORKSPACE"
285
286 if [[ -z "$CONFIGSRC" ]] && [[ -d "$HOME/arvados-api-server" ]]; then
287     # Jenkins expects us to use this by default.
288     CONFIGSRC="$HOME/arvados-api-server"
289 fi
290
291 # Clean up .pyc files that may exist in the workspace
292 cd "$WORKSPACE"
293 find -name '*.pyc' -delete
294
295 # Set up temporary install dirs (unless existing dirs were supplied)
296 for tmpdir in VENVDIR VENV3DIR GOPATH GEMHOME PERLINSTALLBASE
297 do
298     if [[ -n "${!tmpdir}" ]]; then
299         leave_temp[$tmpdir]=1
300         mkdir -p "${!tmpdir}"
301     else
302         eval "$tmpdir"='$(mktemp -d)'
303     fi
304 done
305
306 setup_ruby_environment() {
307     if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
308       source "$HOME/.rvm/scripts/rvm"
309       using_rvm=true
310     elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
311       source "/usr/local/rvm/scripts/rvm"
312       using_rvm=true
313     else
314       using_rvm=false
315     fi
316
317     if [[ "$using_rvm" == true ]]; then
318         # If rvm is in use, we can't just put separate "dependencies"
319         # and "gems-under-test" paths to GEM_PATH: passenger resets
320         # the environment to the "current gemset", which would lose
321         # our GEM_PATH and prevent our test suites from running ruby
322         # programs (for example, the Workbench test suite could not
323         # boot an API server or run arv). Instead, we have to make an
324         # rvm gemset and use it for everything.
325
326         [[ `type rvm | head -n1` == "rvm is a function" ]] \
327             || fatal 'rvm check'
328
329         # Put rvm's favorite path back in first place (overriding
330         # virtualenv, which just put itself there). Ignore rvm's
331         # complaint about not being in first place already.
332         rvm use @default 2>/dev/null
333
334         # Create (if needed) and switch to an @arvados-tests
335         # gemset. (Leave the choice of ruby to the caller.)
336         rvm use @arvados-tests --create \
337             || fatal 'rvm gemset setup'
338
339         rvm env
340     else
341         # When our "bundle install"s need to install new gems to
342         # satisfy dependencies, we want them to go where "gem install
343         # --user-install" would put them. (However, if the caller has
344         # already set GEM_HOME, we assume that's where dependencies
345         # should be installed, and we should leave it alone.)
346
347         if [ -z "$GEM_HOME" ]; then
348             user_gempath="$(gem env gempath)"
349             export GEM_HOME="${user_gempath%%:*}"
350         fi
351         PATH="$(gem env gemdir)/bin:$PATH"
352
353         # When we build and install our own gems, we install them in our
354         # $GEMHOME tmpdir, and we want them to be at the front of GEM_PATH and
355         # PATH so integration tests prefer them over other versions that
356         # happen to be installed in $user_gempath, system dirs, etc.
357
358         tmpdir_gem_home="$(env - PATH="$PATH" HOME="$GEMHOME" gem env gempath | cut -f1 -d:)"
359         PATH="$tmpdir_gem_home/bin:$PATH"
360         export GEM_PATH="$tmpdir_gem_home:$(gem env gempath)"
361
362         echo "Will install dependencies to $(gem env gemdir)"
363         echo "Will install arvados gems to $tmpdir_gem_home"
364         echo "Gem search path is GEM_PATH=$GEM_PATH"
365     fi
366 }
367
368 with_test_gemset() {
369     if [[ "$using_rvm" == true ]]; then
370         "$@"
371     else
372         GEM_HOME="$tmpdir_gem_home" GEM_PATH="$tmpdir_gem_home" "$@"
373     fi
374 }
375
376 gem_uninstall_if_exists() {
377     if gem list "$1\$" | egrep '^\w'; then
378         gem uninstall --force --all --executables "$1"
379     fi
380 }
381
382 export PERLINSTALLBASE
383 export PERLLIB="$PERLINSTALLBASE/lib/perl5:${PERLLIB:+$PERLLIB}"
384
385 export GOPATH
386 mkdir -p "$GOPATH/src/git.curoverse.com"
387 ln -sfn "$WORKSPACE" "$GOPATH/src/git.curoverse.com/arvados.git" \
388     || fatal "symlink failed"
389
390 virtualenv --setuptools "$VENVDIR" || fatal "virtualenv $VENVDIR failed"
391 . "$VENVDIR/bin/activate"
392
393 # Note: this must be the last time we change PATH, otherwise rvm will
394 # whine a lot.
395 setup_ruby_environment
396
397 echo "PATH is $PATH"
398
399 if ! which bundler >/dev/null
400 then
401     gem install --user-install bundler || fatal 'Could not install bundler'
402 fi
403
404 # Needed for run_test_server.py which is used by certain (non-Python) tests.
405 pip freeze 2>/dev/null | egrep ^PyYAML= \
406     || pip install PyYAML >/dev/null \
407     || fatal "pip install PyYAML failed"
408
409 # If Python 3 is available, set up its virtualenv in $VENV3DIR.
410 # Otherwise, skip dependent tests.
411 PYTHON3=$(which python3)
412 if [ "0" = "$?" ]; then
413     virtualenv --python "$PYTHON3" --setuptools "$VENV3DIR" \
414         || fatal "python3 virtualenv $VENV3DIR failed"
415 else
416     PYTHON3=
417     skip[services/dockercleaner]=1
418     cat >&2 <<EOF
419
420 Warning: python3 could not be found
421 services/dockercleaner install and tests will be skipped
422
423 EOF
424 fi
425
426 checkexit() {
427     if [[ "$1" != "0" ]]; then
428         title "!!!!!! $2 FAILED !!!!!!"
429         failures+=("$2 (`timer`)")
430     else
431         successes+=("$2 (`timer`)")
432     fi
433 }
434
435 timer_reset() {
436     t0=$SECONDS
437 }
438
439 timer() {
440     echo -n "$(($SECONDS - $t0))s"
441 }
442
443 do_test() {
444     while ! do_test_once ${@} && [[ "$retry" == 1 ]]
445     do
446         read -p 'Try again? [Y/n] ' x
447         if [[ "$x" != "y" ]] && [[ "$x" != "" ]]
448         then
449             break
450         fi
451     done
452 }
453
454 do_test_once() {
455     if [[ -z "${skip[$1]}" ]] && ( [[ -z "$only" ]] || [[ "$only" == "$1" ]] )
456     then
457         title "Running $1 tests"
458         timer_reset
459         if [[ "$2" == "go" ]]
460         then
461             if [[ -n "${testargs[$1]}" ]]
462             then
463                 # "go test -check.vv giturl" doesn't work, but this
464                 # does:
465                 cd "$WORKSPACE/$1" && go test ${testargs[$1]}
466             else
467                 # The above form gets verbose even when testargs is
468                 # empty, so use this form in such cases:
469                 go test "git.curoverse.com/arvados.git/$1"
470             fi
471         elif [[ "$2" == "pip" ]]
472         then
473             # $3 can name a path directory for us to use, including trailing
474             # slash; e.g., the bin/ subdirectory of a virtualenv.
475             cd "$WORKSPACE/$1" \
476                 && "${3}python" setup.py test ${testargs[$1]}
477         elif [[ "$2" != "" ]]
478         then
479             "test_$2"
480         else
481             "test_$1"
482         fi
483         result="$?"
484         checkexit $result "$1 tests"
485         title "End of $1 tests (`timer`)"
486         return $result
487     else
488         title "Skipping $1 tests"
489     fi
490 }
491
492 do_install() {
493     if [[ -z "$skip_install" || (-n "$only_install" && "$only_install" == "$1") ]]
494     then
495         title "Running $1 install"
496         timer_reset
497         if [[ "$2" == "go" ]]
498         then
499             go get -t "git.curoverse.com/arvados.git/$1"
500         elif [[ "$2" == "pip" ]]
501         then
502             # $3 can name a path directory for us to use, including trailing
503             # slash; e.g., the bin/ subdirectory of a virtualenv.
504
505             # Need to change to a different directory after creating
506             # the source dist package to avoid a pip bug.
507             # see https://arvados.org/issues/5766 for details.
508
509             # Also need to install twice, because if it belives the package is
510             # already installed, pip it won't install it.  So the first "pip
511             # install" ensures that the dependencies are met, the second "pip
512             # install" ensures that we've actually install the local package
513             # we just built.
514             cd "$WORKSPACE/$1" \
515                 && "${3}python" setup.py sdist rotate --keep=1 --match .tar.gz \
516                 && cd "$WORKSPACE" \
517                 && "${3}pip" install --quiet "$WORKSPACE/$1/dist"/*.tar.gz \
518                 && "${3}pip" install --quiet --no-deps --ignore-installed "$WORKSPACE/$1/dist"/*.tar.gz
519         elif [[ "$2" != "" ]]
520         then
521             "install_$2"
522         else
523             "install_$1"
524         fi
525         checkexit $? "$1 install"
526         title "End of $1 install (`timer`)"
527     else
528         title "Skipping $1 install"
529     fi
530 }
531
532 title () {
533     txt="********** $1 **********"
534     printf "\n%*s%s\n\n" $((($COLUMNS-${#txt})/2)) "" "$txt"
535 }
536
537 bundle_install_trylocal() {
538     (
539         set -e
540         echo "(Running bundle install --local. 'could not find package' messages are OK.)"
541         if ! bundle install --local --no-deployment; then
542             echo "(Running bundle install again, without --local.)"
543             bundle install --no-deployment
544         fi
545         bundle package --all
546     )
547 }
548
549 install_doc() {
550     cd "$WORKSPACE/doc" \
551         && bundle_install_trylocal \
552         && rm -rf .site
553 }
554 do_install doc
555
556 install_ruby_sdk() {
557     with_test_gemset gem_uninstall_if_exists arvados \
558         && cd "$WORKSPACE/sdk/ruby" \
559         && bundle_install_trylocal \
560         && gem build arvados.gemspec \
561         && with_test_gemset gem install --no-ri --no-rdoc `ls -t arvados-*.gem|head -n1`
562 }
563 do_install sdk/ruby ruby_sdk
564
565 install_perl_sdk() {
566     cd "$WORKSPACE/sdk/perl" \
567         && perl Makefile.PL INSTALL_BASE="$PERLINSTALLBASE" \
568         && make install INSTALLDIRS=perl
569 }
570 do_install sdk/perl perl_sdk
571
572 install_cli() {
573     with_test_gemset gem_uninstall_if_exists arvados-cli \
574         && cd "$WORKSPACE/sdk/cli" \
575         && bundle_install_trylocal \
576         && gem build arvados-cli.gemspec \
577         && with_test_gemset gem install --no-ri --no-rdoc `ls -t arvados-cli-*.gem|head -n1`
578 }
579 do_install sdk/cli cli
580
581 # Install the Python SDK early. Various other test suites (like
582 # keepproxy) bring up run_test_server.py, which imports the arvados
583 # module. We can't actually *test* the Python SDK yet though, because
584 # its own test suite brings up some of those other programs (like
585 # keepproxy).
586 declare -a pythonstuff
587 pythonstuff=(
588     sdk/python
589     services/fuse
590     services/nodemanager
591     )
592 for p in "${pythonstuff[@]}"
593 do
594     do_install "$p" pip
595 done
596 if [ -n "$PYTHON3" ]; then
597     do_install services/dockercleaner pip "$VENV3DIR/bin/"
598 fi
599
600 install_apiserver() {
601     cd "$WORKSPACE/services/api" \
602         && RAILS_ENV=test bundle_install_trylocal
603
604     rm -f config/environments/test.rb
605     cp config/environments/test.rb.example config/environments/test.rb
606
607     if [ -n "$CONFIGSRC" ]
608     then
609         for f in database.yml application.yml
610         do
611             cp "$CONFIGSRC/$f" config/ || fatal "$f"
612         done
613     fi
614
615     # Fill in a random secret_token and blob_signing_key for testing
616     SECRET_TOKEN=`echo 'puts rand(2**512).to_s(36)' |ruby`
617     BLOB_SIGNING_KEY=`echo 'puts rand(2**512).to_s(36)' |ruby`
618
619     sed -i'' -e "s:SECRET_TOKEN:$SECRET_TOKEN:" config/application.yml
620     sed -i'' -e "s:BLOB_SIGNING_KEY:$BLOB_SIGNING_KEY:" config/application.yml
621
622     # Set up empty git repo (for git tests)
623     GITDIR=$(mktemp -d)
624     sed -i'' -e "s:/var/cache/git:$GITDIR:" config/application.default.yml
625
626     rm -rf $GITDIR
627     mkdir -p $GITDIR/test
628     cd $GITDIR/test \
629         && git init \
630         && git config user.email "jenkins@ci.curoverse.com" \
631         && git config user.name "Jenkins, CI" \
632         && touch tmp \
633         && git add tmp \
634         && git commit -m 'initial commit'
635
636     # Clear out any lingering postgresql connections to the test
637     # database, so that we can drop it. This assumes the current user
638     # is a postgresql superuser.
639     cd "$WORKSPACE/services/api" \
640         && test_database=$(python -c "import yaml; print yaml.load(file('config/database.yml'))['test']['database']") \
641         && psql "$test_database" -c "SELECT pg_terminate_backend (pg_stat_activity.procpid::int) FROM pg_stat_activity WHERE pg_stat_activity.datname = '$test_database';" 2>/dev/null
642
643     cd "$WORKSPACE/services/api" \
644         && RAILS_ENV=test bundle exec rake db:drop \
645         && RAILS_ENV=test bundle exec rake db:setup \
646         && RAILS_ENV=test bundle exec rake db:fixtures:load
647 }
648 do_install services/api apiserver
649
650 declare -a gostuff
651 gostuff=(
652     services/arv-git-httpd
653     services/crunchstat
654     services/keepstore
655     services/keepproxy
656     services/datamanager/summary
657     services/datamanager/collection
658     sdk/go/arvadosclient
659     sdk/go/keepclient
660     sdk/go/streamer
661     )
662 for g in "${gostuff[@]}"
663 do
664     do_install "$g" go
665 done
666
667 install_workbench() {
668     cd "$WORKSPACE/apps/workbench" \
669         && mkdir -p tmp/cache \
670         && RAILS_ENV=test bundle_install_trylocal
671 }
672 do_install apps/workbench workbench
673
674 test_doclinkchecker() {
675     (
676         set -e
677         cd "$WORKSPACE/doc"
678         ARVADOS_API_HOST=qr1hi.arvadosapi.com
679         # Make sure python-epydoc is installed or the next line won't
680         # do much good!
681         PYTHONPATH=$WORKSPACE/sdk/python/ bundle exec rake linkchecker baseurl=file://$WORKSPACE/doc/.site/ arvados_workbench_host=https://workbench.$ARVADOS_API_HOST arvados_api_host=$ARVADOS_API_HOST
682     )
683 }
684 do_test doc doclinkchecker
685
686 stop_services
687
688 test_apiserver() {
689     cd "$WORKSPACE/services/api" \
690         && RAILS_ENV=test bundle exec rake test TESTOPTS=-v ${testargs[services/api]}
691 }
692 do_test services/api apiserver
693
694 # Shortcut for when we're only running apiserver tests. This saves a bit of time,
695 # because we don't need to start up the api server for subsequent tests.
696 if [ ! -z "$only" ] && [ "$only" == "services/api" ]; then
697   rotate_logfile "$WORKSPACE/services/api/log/" "test.log"
698   exit_cleanly
699 fi
700
701 start_api
702
703 test_ruby_sdk() {
704     cd "$WORKSPACE/sdk/ruby" \
705         && bundle exec rake test TESTOPTS=-v ${testargs[sdk/ruby]}
706 }
707 do_test sdk/ruby ruby_sdk
708
709 test_cli() {
710     cd "$WORKSPACE/sdk/cli" \
711         && mkdir -p /tmp/keep \
712         && KEEP_LOCAL_STORE=/tmp/keep bundle exec rake test TESTOPTS=-v ${testargs[sdk/cli]}
713 }
714 do_test sdk/cli cli
715
716 for p in "${pythonstuff[@]}"
717 do
718     do_test "$p" pip
719 done
720 do_test services/dockercleaner pip "$VENV3DIR/bin/"
721
722 for g in "${gostuff[@]}"
723 do
724     do_test "$g" go
725 done
726
727 test_workbench() {
728     start_nginx_proxy_services \
729         && cd "$WORKSPACE/apps/workbench" \
730         && RAILS_ENV=test bundle exec rake test TESTOPTS=-v ${testargs[apps/workbench]}
731 }
732 do_test apps/workbench workbench
733
734 test_workbench_benchmark() {
735     start_nginx_proxy_services \
736         && cd "$WORKSPACE/apps/workbench" \
737         && RAILS_ENV=test bundle exec rake test:benchmark ${testargs[apps/workbench_benchmark]}
738 }
739 do_test apps/workbench_benchmark workbench_benchmark
740
741 test_workbench_profile() {
742     start_nginx_proxy_services \
743         && cd "$WORKSPACE/apps/workbench" \
744         && RAILS_ENV=test bundle exec rake test:profile ${testargs[apps/workbench_profile]}
745 }
746 do_test apps/workbench_profile workbench_profile
747
748 exit_cleanly