Add datamanager tests. refs #3408
[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         mkdir -p "${!tmpdir}"
291     else
292         eval "$tmpdir"='$(mktemp -d)'
293     fi
294 done
295
296 setup_ruby_environment() {
297     if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
298       source "$HOME/.rvm/scripts/rvm"
299       using_rvm=true
300     elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
301       source "/usr/local/rvm/scripts/rvm"
302       using_rvm=true
303     else
304       using_rvm=false
305     fi
306
307     if [[ "$using_rvm" == true ]]; then
308         # If rvm is in use, we can't just put separate "dependencies"
309         # and "gems-under-test" paths to GEM_PATH: passenger resets
310         # the environment to the "current gemset", which would lose
311         # our GEM_PATH and prevent our test suites from running ruby
312         # programs (for example, the Workbench test suite could not
313         # boot an API server or run arv). Instead, we have to make an
314         # rvm gemset and use it for everything.
315
316         [[ `type rvm | head -n1` == "rvm is a function" ]] \
317             || fatal 'rvm check'
318
319         # Put rvm's favorite path back in first place (overriding
320         # virtualenv, which just put itself there). Ignore rvm's
321         # complaint about not being in first place already.
322         rvm use @default 2>/dev/null
323
324         # Create (if needed) and switch to an @arvados-tests
325         # gemset. (Leave the choice of ruby to the caller.)
326         rvm use @arvados-tests --create \
327             || fatal 'rvm gemset setup'
328
329         rvm env
330     else
331         # When our "bundle install"s need to install new gems to
332         # satisfy dependencies, we want them to go where "gem install
333         # --user-install" would put them. (However, if the caller has
334         # already set GEM_HOME, we assume that's where dependencies
335         # should be installed, and we should leave it alone.)
336
337         if [ -z "$GEM_HOME" ]; then
338             user_gempath="$(gem env gempath)"
339             export GEM_HOME="${user_gempath%%:*}"
340         fi
341         PATH="$(gem env gemdir)/bin:$PATH"
342
343         # When we build and install our own gems, we install them in our
344         # $GEMHOME tmpdir, and we want them to be at the front of GEM_PATH and
345         # PATH so integration tests prefer them over other versions that
346         # happen to be installed in $user_gempath, system dirs, etc.
347
348         tmpdir_gem_home="$(env - PATH="$PATH" HOME="$GEMHOME" gem env gempath | cut -f1 -d:)"
349         PATH="$tmpdir_gem_home/bin:$PATH"
350         export GEM_PATH="$tmpdir_gem_home:$(gem env gempath)"
351
352         echo "Will install dependencies to $(gem env gemdir)"
353         echo "Will install arvados gems to $tmpdir_gem_home"
354         echo "Gem search path is GEM_PATH=$GEM_PATH"
355     fi
356 }
357
358 with_test_gemset() {
359     if [[ "$using_rvm" == true ]]; then
360         "$@"
361     else
362         GEM_HOME="$tmpdir_gem_home" GEM_PATH="$tmpdir_gem_home" "$@"
363     fi
364 }
365
366 gem_uninstall_if_exists() {
367     if gem list "$1\$" | egrep '^\w'; then
368         gem uninstall --force --all --executables "$1"
369     fi
370 }
371
372 export GOPATH
373 mkdir -p "$GOPATH/src/git.curoverse.com"
374 ln -sfn "$WORKSPACE" "$GOPATH/src/git.curoverse.com/arvados.git" \
375     || fatal "symlink failed"
376
377 virtualenv --setuptools "$VENVDIR" || fatal "virtualenv $VENVDIR failed"
378 . "$VENVDIR/bin/activate"
379
380 # Note: this must be the last time we change PATH, otherwise rvm will
381 # whine a lot.
382 setup_ruby_environment
383
384 echo "PATH is $PATH"
385
386 if ! which bundler >/dev/null
387 then
388     gem install --user-install bundler || fatal 'Could not install bundler'
389 fi
390
391 # Needed for run_test_server.py which is used by certain (non-Python) tests.
392 pip freeze 2>/dev/null | egrep ^PyYAML= \
393     || pip install PyYAML >/dev/null \
394     || fatal "pip install PyYAML failed"
395
396 # If Python 3 is available, set up its virtualenv in $VENV3DIR.
397 # Otherwise, skip dependent tests.
398 PYTHON3=$(which python3)
399 if [ "0" = "$?" ]; then
400     virtualenv --python "$PYTHON3" --setuptools "$VENV3DIR" \
401         || fatal "python3 virtualenv $VENV3DIR failed"
402 else
403     PYTHON3=
404     skip[services/dockercleaner]=1
405     cat >&2 <<EOF
406
407 Warning: python3 could not be found
408 services/dockercleaner install and tests will be skipped
409
410 EOF
411 fi
412
413 checkexit() {
414     if [[ "$1" != "0" ]]; then
415         title "!!!!!! $2 FAILED !!!!!!"
416         failures+=("$2 (`timer`)")
417     else
418         successes+=("$2 (`timer`)")
419     fi
420 }
421
422 timer_reset() {
423     t0=$SECONDS
424 }
425
426 timer() {
427     echo -n "$(($SECONDS - $t0))s"
428 }
429
430 do_test() {
431     while ! do_test_once ${@} && [[ "$retry" == 1 ]]
432     do
433         read -p 'Try again? [Y/n] ' x
434         if [[ "$x" != "y" ]] && [[ "$x" != "" ]]
435         then
436             break
437         fi
438     done
439 }
440
441 do_test_once() {
442     if [[ -z "${skip[$1]}" ]] && ( [[ -z "$only" ]] || [[ "$only" == "$1" ]] )
443     then
444         title "Running $1 tests"
445         timer_reset
446         if [[ "$2" == "go" ]]
447         then
448             if [[ -n "${testargs[$1]}" ]]
449             then
450                 # "go test -check.vv giturl" doesn't work, but this
451                 # does:
452                 cd "$WORKSPACE/$1" && go test ${testargs[$1]}
453             else
454                 # The above form gets verbose even when testargs is
455                 # empty, so use this form in such cases:
456                 go test "git.curoverse.com/arvados.git/$1"
457             fi
458         elif [[ "$2" == "pip" ]]
459         then
460             # $3 can name a path directory for us to use, including trailing
461             # slash; e.g., the bin/ subdirectory of a virtualenv.
462             cd "$WORKSPACE/$1" \
463                 && "${3}python" setup.py test ${testargs[$1]}
464         elif [[ "$2" != "" ]]
465         then
466             "test_$2"
467         else
468             "test_$1"
469         fi
470         result="$?"
471         checkexit $result "$1 tests"
472         title "End of $1 tests (`timer`)"
473         return $result
474     else
475         title "Skipping $1 tests"
476     fi
477 }
478
479 do_install() {
480     if [[ -z "$skip_install" || (-n "$only_install" && "$only_install" == "$1") ]]
481     then
482         title "Running $1 install"
483         timer_reset
484         if [[ "$2" == "go" ]]
485         then
486             go get -t "git.curoverse.com/arvados.git/$1"
487         elif [[ "$2" == "pip" ]]
488         then
489             # $3 can name a path directory for us to use, including trailing
490             # slash; e.g., the bin/ subdirectory of a virtualenv.
491
492             # Need to change to a different directory after creating
493             # the source dist package to avoid a pip bug.
494             # see https://arvados.org/issues/5766 for details.
495
496             # Also need to install twice, because if it belives the package is
497             # already installed, pip it won't install it.  So the first "pip
498             # install" ensures that the dependencies are met, the second "pip
499             # install" ensures that we've actually install the local package
500             # we just built.
501             cd "$WORKSPACE/$1" \
502                 && "${3}python" setup.py sdist rotate --keep=1 --match .tar.gz \
503                 && cd "$WORKSPACE" \
504                 && "${3}pip" install --quiet "$WORKSPACE/$1/dist"/*.tar.gz \
505                 && "${3}pip" install --quiet --no-deps --ignore-installed "$WORKSPACE/$1/dist"/*.tar.gz
506         elif [[ "$2" != "" ]]
507         then
508             "install_$2"
509         else
510             "install_$1"
511         fi
512         checkexit $? "$1 install"
513         title "End of $1 install (`timer`)"
514     else
515         title "Skipping $1 install"
516     fi
517 }
518
519 title () {
520     txt="********** $1 **********"
521     printf "\n%*s%s\n\n" $((($COLUMNS-${#txt})/2)) "" "$txt"
522 }
523
524 bundle_install_trylocal() {
525     (
526         set -e
527         echo "(Running bundle install --local. 'could not find package' messages are OK.)"
528         if ! bundle install --local --no-deployment; then
529             echo "(Running bundle install again, without --local.)"
530             bundle install --no-deployment
531         fi
532         bundle package --all
533     )
534 }
535
536 install_doc() {
537     cd "$WORKSPACE/doc" \
538         && bundle_install_trylocal \
539         && rm -rf .site
540 }
541 do_install doc
542
543 install_ruby_sdk() {
544     with_test_gemset gem_uninstall_if_exists arvados \
545         && cd "$WORKSPACE/sdk/ruby" \
546         && bundle_install_trylocal \
547         && gem build arvados.gemspec \
548         && with_test_gemset gem install --no-ri --no-rdoc `ls -t arvados-*.gem|head -n1`
549 }
550 do_install sdk/ruby ruby_sdk
551
552 install_cli() {
553     with_test_gemset gem_uninstall_if_exists arvados-cli \
554         && cd "$WORKSPACE/sdk/cli" \
555         && bundle_install_trylocal \
556         && gem build arvados-cli.gemspec \
557         && with_test_gemset gem install --no-ri --no-rdoc `ls -t arvados-cli-*.gem|head -n1`
558 }
559 do_install sdk/cli cli
560
561 # Install the Python SDK early. Various other test suites (like
562 # keepproxy) bring up run_test_server.py, which imports the arvados
563 # module. We can't actually *test* the Python SDK yet though, because
564 # its own test suite brings up some of those other programs (like
565 # keepproxy).
566 declare -a pythonstuff
567 pythonstuff=(
568     sdk/python
569     services/fuse
570     services/nodemanager
571     )
572 for p in "${pythonstuff[@]}"
573 do
574     do_install "$p" pip
575 done
576 if [ -n "$PYTHON3" ]; then
577     do_install services/dockercleaner pip "$VENV3DIR/bin/"
578 fi
579
580 install_apiserver() {
581     cd "$WORKSPACE/services/api" \
582         && RAILS_ENV=test bundle_install_trylocal
583
584     rm -f config/environments/test.rb
585     cp config/environments/test.rb.example config/environments/test.rb
586
587     if [ -n "$CONFIGSRC" ]
588     then
589         for f in database.yml application.yml
590         do
591             cp "$CONFIGSRC/$f" config/ || fatal "$f"
592         done
593     fi
594
595     # Fill in a random secret_token and blob_signing_key for testing
596     SECRET_TOKEN=`echo 'puts rand(2**512).to_s(36)' |ruby`
597     BLOB_SIGNING_KEY=`echo 'puts rand(2**512).to_s(36)' |ruby`
598
599     sed -i'' -e "s:SECRET_TOKEN:$SECRET_TOKEN:" config/application.yml
600     sed -i'' -e "s:BLOB_SIGNING_KEY:$BLOB_SIGNING_KEY:" config/application.yml
601
602     # Set up empty git repo (for git tests)
603     GITDIR=$(mktemp -d)
604     sed -i'' -e "s:/var/cache/git:$GITDIR:" config/application.default.yml
605
606     rm -rf $GITDIR
607     mkdir -p $GITDIR/test
608     cd $GITDIR/test \
609         && git init \
610         && git config user.email "jenkins@ci.curoverse.com" \
611         && git config user.name "Jenkins, CI" \
612         && touch tmp \
613         && git add tmp \
614         && git commit -m 'initial commit'
615
616     # Clear out any lingering postgresql connections to the test
617     # database, so that we can drop it. This assumes the current user
618     # is a postgresql superuser.
619     cd "$WORKSPACE/services/api" \
620         && test_database=$(python -c "import yaml; print yaml.load(file('config/database.yml'))['test']['database']") \
621         && 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
622
623     cd "$WORKSPACE/services/api" \
624         && RAILS_ENV=test bundle exec rake db:drop \
625         && RAILS_ENV=test bundle exec rake db:setup \
626         && RAILS_ENV=test bundle exec rake db:fixtures:load
627 }
628 do_install services/api apiserver
629
630 declare -a gostuff
631 gostuff=(
632     services/arv-git-httpd
633     services/crunchstat
634     services/keepstore
635     services/keepproxy
636     services/datamanager/summary
637     services/datamanager/collection
638     sdk/go/arvadosclient
639     sdk/go/keepclient
640     sdk/go/streamer
641     )
642 for g in "${gostuff[@]}"
643 do
644     do_install "$g" go
645 done
646
647 install_workbench() {
648     cd "$WORKSPACE/apps/workbench" \
649         && mkdir -p tmp/cache \
650         && RAILS_ENV=test bundle_install_trylocal
651 }
652 do_install apps/workbench workbench
653
654 test_doclinkchecker() {
655     (
656         set -e
657         cd "$WORKSPACE/doc"
658         ARVADOS_API_HOST=qr1hi.arvadosapi.com
659         # Make sure python-epydoc is installed or the next line won't
660         # do much good!
661         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
662     )
663 }
664 do_test doc doclinkchecker
665
666 stop_services
667
668 test_apiserver() {
669     cd "$WORKSPACE/services/api" \
670         && RAILS_ENV=test bundle exec rake test TESTOPTS=-v ${testargs[services/api]}
671 }
672 do_test services/api apiserver
673
674 # Shortcut for when we're only running apiserver tests. This saves a bit of time,
675 # because we don't need to start up the api server for subsequent tests.
676 if [ ! -z "$only" ] && [ "$only" == "services/api" ]; then
677   rotate_logfile "$WORKSPACE/services/api/log/" "test.log"
678   exit_cleanly
679 fi
680
681 start_api
682
683 test_ruby_sdk() {
684     cd "$WORKSPACE/sdk/ruby" \
685         && bundle exec rake test TESTOPTS=-v ${testargs[sdk/ruby]}
686 }
687 do_test sdk/ruby ruby_sdk
688
689 test_cli() {
690     cd "$WORKSPACE/sdk/cli" \
691         && mkdir -p /tmp/keep \
692         && KEEP_LOCAL_STORE=/tmp/keep bundle exec rake test TESTOPTS=-v ${testargs[sdk/cli]}
693 }
694 do_test sdk/cli cli
695
696 for p in "${pythonstuff[@]}"
697 do
698     do_test "$p" pip
699 done
700 do_test services/dockercleaner pip "$VENV3DIR/bin/"
701
702 for g in "${gostuff[@]}"
703 do
704     do_test "$g" go
705 done
706
707 test_workbench() {
708     start_nginx_proxy_services \
709         && cd "$WORKSPACE/apps/workbench" \
710         && RAILS_ENV=test bundle exec rake test TESTOPTS=-v ${testargs[apps/workbench]}
711 }
712 do_test apps/workbench workbench
713
714 test_workbench_benchmark() {
715     start_nginx_proxy_services \
716         && cd "$WORKSPACE/apps/workbench" \
717         && RAILS_ENV=test bundle exec rake test:benchmark ${testargs[apps/workbench_benchmark]}
718 }
719 do_test apps/workbench_benchmark workbench_benchmark
720
721 test_workbench_profile() {
722     start_nginx_proxy_services \
723         && cd "$WORKSPACE/apps/workbench" \
724         && RAILS_ENV=test bundle exec rake test:profile ${testargs[apps/workbench_profile]}
725 }
726 do_test apps/workbench_profile workbench_profile
727
728 exit_cleanly