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