3 read -rd "\000" helpmessage <<EOF
4 $(basename $0): Install and test Arvados components.
6 Exit non-zero if any tests fail.
9 $(basename $0) WORKSPACE=/path/to/arvados [options]
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 WORKSPACE=path Arvados source tree to test.
22 CONFIGSRC=path Dir with api server config files to copy into source tree.
23 (If none given, leave config files alone in source tree.)
24 services/api_test="TEST=test/functional/arvados/v1/collections_controller_test.rb"
25 Restrict apiserver tests to the given file
26 sdk/python_test="--test-suite test.test_keep_locator"
27 Restrict Python SDK tests to the given class
28 apps/workbench_test="TEST=test/integration/pipeline_instances_test.rb"
29 Restrict Workbench tests to the given file
31 Print more debug messages
32 envvar=value Set \$envvar to value. Primarily useful for WORKSPACE,
33 *_test, and other examples shown above.
35 Assuming --skip-install is not given, all components are installed
36 into \$GOPATH, \$VENDIR, and \$GEMHOME before running any tests. Many
37 test suites depend on other components being installed, and installing
38 everything tends to be quicker than debugging dependencies.
40 As a special concession to the current CI server config, CONFIGSRC
41 defaults to $HOME/arvados-api-server if that directory exists.
43 More information and background:
45 https://arvados.org/projects/arvados/wiki/Running_tests
50 apps/workbench_benchmark
51 apps/workbench_profile
59 services/arv-git-httpd
69 # First make sure to remove any ARVADOS_ variables from the calling
70 # environment that could interfere with the tests.
71 unset $(env | cut -d= -f1 | grep \^ARVADOS_)
73 # Reset other variables that could affect our [tests'] behavior by
89 for var in VENVDIR GOPATH GITDIR GEMHOME
91 if [[ -z "${leave_temp[$var]}" ]]
98 leaving+=" $var=\"${!var}\""
101 if [[ -n "$leaving" ]]; then
102 echo "Leaving behind temp dirs: $leaving"
108 echo >&2 "Fatal: $* in ${FUNCNAME[1]} at ${BASH_SOURCE[1]} line ${BASH_LINENO[0]}"
113 for x in "${successes[@]}"
118 if [[ ${#failures[@]} == 0 ]]
120 echo "All test suites passed."
122 echo "Failures (${#failures[@]}):"
123 for x in "${failures[@]}"
132 rotate_logfile "$WORKSPACE/apps/workbench/log/" "test.log"
134 rotate_logfile "$WORKSPACE/services/api/log/" "test.log"
141 # Make sure WORKSPACE is set
142 if ! [[ -n "$WORKSPACE" ]]; then
143 echo >&2 "$helpmessage"
145 echo >&2 "Error: WORKSPACE environment variable not set"
150 # Make sure virtualenv is installed
151 `virtualenv --help >/dev/null 2>&1`
153 if [[ "$?" != "0" ]]; then
155 echo >&2 "Error: virtualenv could not be found"
160 # Make sure go is installed
161 `go env >/dev/null 2>&1`
163 if [[ "$?" != "0" ]]; then
165 echo >&2 "Error: go could not be found"
170 # Make sure gcc is installed
171 `gcc --help >/dev/null 2>&1`
173 if [[ "$?" != "0" ]]; then
175 echo >&2 "Error: gcc could not be found"
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"
193 skip[apps/workbench_profile]=1
200 echo >&2 "$helpmessage"
209 only="$1"; skip[$1]=""; shift
215 leave_temp[VENVDIR]=1
217 leave_temp[GEMHOME]=1
223 suite="${arg%%_test=*}"
225 testargs["$suite"]="$args"
228 eval export $(echo $arg | cut -d= -f1)=\"$(echo $arg | cut -d= -f2-)\"
231 echo >&2 "$0: Unrecognized option: '$arg'. Try: $0 --help"
238 echo 'Starting API server...'
240 && eval $(python sdk/python/tests/run_test_server.py start --auth admin) \
241 && export ARVADOS_TEST_API_HOST="$ARVADOS_API_HOST" \
242 && export ARVADOS_TEST_API_INSTALLED="$$" \
243 && (env | egrep ^ARVADOS)
247 if [[ -n "$ARVADOS_TEST_API_HOST" ]]; then
248 unset ARVADOS_TEST_API_HOST
250 && python sdk/python/tests/run_test_server.py stop
255 failures+=("($(basename $0) interrupted)")
262 echo "WORKSPACE=$WORKSPACE"
264 if [[ -z "$CONFIGSRC" ]] && [[ -d "$HOME/arvados-api-server" ]]; then
265 # Jenkins expects us to use this by default.
266 CONFIGSRC="$HOME/arvados-api-server"
269 # Clean up .pyc files that may exist in the workspace
271 find -name '*.pyc' -delete
273 # Set up temporary install dirs (unless existing dirs were supplied)
274 for tmpdir in VENVDIR GOPATH GEMHOME
276 if [[ -n "${!tmpdir}" ]]; then
277 leave_temp[$tmpdir]=1
279 eval $tmpdir=$(mktemp -d)
283 setup_ruby_environment() {
284 if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
285 source "$HOME/.rvm/scripts/rvm"
287 elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
288 source "/usr/local/rvm/scripts/rvm"
294 if [[ "$using_rvm" == true ]]; then
295 # If rvm is in use, we can't just put separate "dependencies"
296 # and "gems-under-test" paths to GEM_PATH: passenger resets
297 # the environment to the "current gemset", which would lose
298 # our GEM_PATH and prevent our test suites from running ruby
299 # programs (for example, the Workbench test suite could not
300 # boot an API server or run arv). Instead, we have to make an
301 # rvm gemset and use it for everything.
303 [[ `type rvm | head -n1` == "rvm is a function" ]] \
306 # Put rvm's favorite path back in first place (overriding
307 # virtualenv, which just put itself there). Ignore rvm's
308 # complaint about not being in first place already.
309 rvm use @default 2>/dev/null
311 # Create (if needed) and switch to an @arvados-tests
312 # gemset. (Leave the choice of ruby to the caller.)
313 rvm use @arvados-tests --create \
314 || fatal 'rvm gemset setup'
318 # When our "bundle install"s need to install new gems to
319 # satisfy dependencies, we want them to go where "gem install
320 # --user-install" would put them. (However, if the caller has
321 # already set GEM_HOME, we assume that's where dependencies
322 # should be installed, and we should leave it alone.)
324 if [ -z "$GEM_HOME" ]; then
325 user_gempath="$(gem env gempath)"
326 export GEM_HOME="${user_gempath%%:*}"
328 PATH="$(gem env gemdir)/bin:$PATH"
330 # When we build and install our own gems, we install them in our
331 # $GEMHOME tmpdir, and we want them to be at the front of GEM_PATH and
332 # PATH so integration tests prefer them over other versions that
333 # happen to be installed in $user_gempath, system dirs, etc.
335 tmpdir_gem_home="$(env - PATH="$PATH" HOME="$GEMHOME" gem env gempath | cut -f1 -d:)"
336 PATH="$tmpdir_gem_home/bin:$PATH"
337 export GEM_PATH="$tmpdir_gem_home:$(gem env gempath)"
339 echo "Will install dependencies to $(gem env gemdir)"
340 echo "Will install arvados gems to $tmpdir_gem_home"
341 echo "Gem search path is GEM_PATH=$GEM_PATH"
346 if [[ "$using_rvm" == true ]]; then
349 GEM_HOME="$tmpdir_gem_home" "$@"
354 mkdir -p "$GOPATH/src/git.curoverse.com"
355 ln -sfn "$WORKSPACE" "$GOPATH/src/git.curoverse.com/arvados.git" \
356 || fatal "symlink failed"
358 virtualenv --setuptools "$VENVDIR" || fatal "virtualenv $VENVDIR failed"
359 . "$VENVDIR/bin/activate"
361 # Note: this must be the last time we change PATH, otherwise rvm will
363 setup_ruby_environment
367 if ! which bundler >/dev/null
369 gem install --user-install bundler || fatal 'Could not install bundler'
372 # Needed for run_test_server.py which is used by certain (non-Python) tests.
373 echo "pip install -q PyYAML"
374 pip install -q PyYAML || fatal "pip install PyYAML failed"
377 if [[ "$1" != "0" ]]; then
378 title "!!!!!! $2 FAILED !!!!!!"
379 failures+=("$2 (`timer`)")
381 successes+=("$2 (`timer`)")
390 echo -n "$(($SECONDS - $t0))s"
394 while ! do_test_once ${@} && [[ "$retry" == 1 ]]
396 read -p 'Try again? [Y/n] ' x
397 if [[ "$x" != "y" ]] && [[ "$x" != "" ]]
405 if [[ -z "${skip[$1]}" ]] && ( [[ -z "$only" ]] || [[ "$only" == "$1" ]] )
407 title "Running $1 tests"
409 if [[ "$2" == "go" ]]
411 go test ${testargs[$1]} "git.curoverse.com/arvados.git/$1"
412 elif [[ "$2" == "pip" ]]
415 && python setup.py test ${testargs[$1]}
416 elif [[ "$2" != "" ]]
423 checkexit $result "$1 tests"
424 title "End of $1 tests (`timer`)"
427 title "Skipping $1 tests"
432 if [[ -z "$skip_install" ]]
434 title "Running $1 install"
436 if [[ "$2" == "go" ]]
438 go get -t "git.curoverse.com/arvados.git/$1"
439 elif [[ "$2" == "pip" ]]
442 && python setup.py sdist rotate --keep=1 --match .tar.gz \
443 && pip install -q --upgrade dist/*.tar.gz
444 elif [[ "$2" != "" ]]
450 checkexit $? "$1 install"
451 title "End of $1 install (`timer`)"
453 title "Skipping $1 install"
458 txt="********** $1 **********"
459 printf "\n%*s%s\n\n" $((($COLUMNS-${#txt})/2)) "" "$txt"
462 bundle_install_trylocal() {
465 echo "(Running bundle install --local. 'could not find package' messages are OK.)"
466 if ! bundle install --local --no-deployment; then
467 echo "(Running bundle install again, without --local.)"
468 bundle install --no-deployment
475 cd "$WORKSPACE/doc" \
476 && bundle_install_trylocal \
482 with_test_gemset gem uninstall --force --all --executables arvados \
483 && cd "$WORKSPACE/sdk/ruby" \
484 && bundle_install_trylocal \
485 && gem build arvados.gemspec \
486 && with_test_gemset gem install --no-ri --no-rdoc `ls -t arvados-*.gem|head -n1`
488 do_install sdk/ruby ruby_sdk
491 with_test_gemset gem uninstall --force --all --executables arvados-cli \
492 && cd "$WORKSPACE/sdk/cli" \
493 && bundle_install_trylocal \
494 && gem build arvados-cli.gemspec \
495 && with_test_gemset gem install --no-ri --no-rdoc `ls -t arvados-cli-*.gem|head -n1`
497 do_install sdk/cli cli
499 # Install the Python SDK early. Various other test suites (like
500 # keepproxy) bring up run_test_server.py, which imports the arvados
501 # module. We can't actually *test* the Python SDK yet though, because
502 # its own test suite brings up some of those other programs (like
504 declare -a pythonstuff
510 for p in "${pythonstuff[@]}"
515 install_apiserver() {
516 cd "$WORKSPACE/services/api" \
517 && RAILS_ENV=test bundle_install_trylocal
519 rm -f config/environments/test.rb
520 cp config/environments/test.rb.example config/environments/test.rb
522 if [ -n "$CONFIGSRC" ]
524 for f in database.yml application.yml
526 cp "$CONFIGSRC/$f" config/ || fatal "$f"
530 # Fill in a random secret_token and blob_signing_key for testing
531 SECRET_TOKEN=`echo 'puts rand(2**512).to_s(36)' |ruby`
532 BLOB_SIGNING_KEY=`echo 'puts rand(2**512).to_s(36)' |ruby`
534 sed -i'' -e "s:SECRET_TOKEN:$SECRET_TOKEN:" config/application.yml
535 sed -i'' -e "s:BLOB_SIGNING_KEY:$BLOB_SIGNING_KEY:" config/application.yml
537 # Set up empty git repo (for git tests)
539 sed -i'' -e "s:/var/cache/git:$GITDIR:" config/application.default.yml
542 mkdir -p $GITDIR/test
545 && git config user.email "jenkins@ci.curoverse.com" \
546 && git config user.name "Jenkins, CI" \
549 && git commit -m 'initial commit'
551 # Clear out any lingering postgresql connections to arvados_test, so that we can drop it
552 # This assumes the current user is a postgresql superuser
553 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
555 cd "$WORKSPACE/services/api" \
556 && RAILS_ENV=test bundle exec rake db:drop \
557 && RAILS_ENV=test bundle exec rake db:setup \
558 && RAILS_ENV=test bundle exec rake db:fixtures:load
560 do_install services/api apiserver
564 services/arv-git-httpd
572 for g in "${gostuff[@]}"
577 install_workbench() {
578 cd "$WORKSPACE/apps/workbench" \
579 && mkdir -p tmp/cache \
580 && RAILS_ENV=test bundle_install_trylocal
582 do_install apps/workbench workbench
584 test_doclinkchecker() {
588 ARVADOS_API_HOST=qr1hi.arvadosapi.com
589 # Make sure python-epydoc is installed or the next line won't
591 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
594 do_test doc doclinkchecker
599 cd "$WORKSPACE/services/api" \
600 && RAILS_ENV=test bundle exec rake test TESTOPTS=-v ${testargs[services/api]}
602 do_test services/api apiserver
604 # Shortcut for when we're only running apiserver tests. This saves a bit of time,
605 # because we don't need to start up the api server for subsequent tests.
606 if [ ! -z "$only" ] && [ "$only" == "services/api" ]; then
607 rotate_logfile "$WORKSPACE/services/api/log/" "test.log"
614 cd "$WORKSPACE/sdk/ruby" \
615 && bundle exec rake test TESTOPTS=-v ${testargs[sdk/ruby]}
617 do_test sdk/ruby ruby_sdk
620 cd "$WORKSPACE/sdk/cli" \
621 && mkdir -p /tmp/keep \
622 && KEEP_LOCAL_STORE=/tmp/keep bundle exec rake test TESTOPTS=-v ${testargs[sdk/cli]}
626 for p in "${pythonstuff[@]}"
631 for g in "${gostuff[@]}"
637 cd "$WORKSPACE/apps/workbench" \
638 && RAILS_ENV=test bundle exec rake test TESTOPTS=-v ${testargs[apps/workbench]}
640 do_test apps/workbench workbench
642 test_workbench_benchmark() {
643 cd "$WORKSPACE/apps/workbench" \
644 && RAILS_ENV=test bundle exec rake test:benchmark ${testargs[apps/workbench_benchmark]}
646 do_test apps/workbench_benchmark workbench_benchmark
648 test_workbench_profile() {
649 cd "$WORKSPACE/apps/workbench" \
650 && RAILS_ENV=test bundle exec rake test:profile ${testargs[apps/workbench_profile]}
652 do_test apps/workbench_profile workbench_profile