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 --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
32 Print more debug messages
33 envvar=value Set \$envvar to value. Primarily useful for WORKSPACE,
34 *_test, and other examples shown above.
36 Assuming --skip-install is not given, all components are installed
37 into \$GOPATH, \$VENDIR, and \$GEMHOME before running any tests. Many
38 test suites depend on other components being installed, and installing
39 everything tends to be quicker than debugging dependencies.
41 As a special concession to the current CI server config, CONFIGSRC
42 defaults to $HOME/arvados-api-server if that directory exists.
44 More information and background:
46 https://arvados.org/projects/arvados/wiki/Running_tests
51 apps/workbench_benchmark
52 apps/workbench_profile
60 services/arv-git-httpd
70 # First make sure to remove any ARVADOS_ variables from the calling
71 # environment that could interfere with the tests.
72 unset $(env | cut -d= -f1 | grep \^ARVADOS_)
74 # Reset other variables that could affect our [tests'] behavior by
90 for var in VENVDIR GOPATH GITDIR GEMHOME
92 if [[ -z "${leave_temp[$var]}" ]]
99 leaving+=" $var=\"${!var}\""
102 if [[ -n "$leaving" ]]; then
103 echo "Leaving behind temp dirs: $leaving"
109 echo >&2 "Fatal: $* in ${FUNCNAME[1]} at ${BASH_SOURCE[1]} line ${BASH_LINENO[0]}"
114 for x in "${successes[@]}"
119 if [[ ${#failures[@]} == 0 ]]
121 echo "All test suites passed."
123 echo "Failures (${#failures[@]}):"
124 for x in "${failures[@]}"
133 rotate_logfile "$WORKSPACE/apps/workbench/log/" "test.log"
135 rotate_logfile "$WORKSPACE/services/api/log/" "test.log"
142 # Make sure WORKSPACE is set
143 if ! [[ -n "$WORKSPACE" ]]; then
144 echo >&2 "$helpmessage"
146 echo >&2 "Error: WORKSPACE environment variable not set"
151 # Make sure virtualenv is installed
152 `virtualenv --help >/dev/null 2>&1`
154 if [[ "$?" != "0" ]]; then
156 echo >&2 "Error: virtualenv could not be found"
161 # Make sure go is installed
162 `go env >/dev/null 2>&1`
164 if [[ "$?" != "0" ]]; then
166 echo >&2 "Error: go could not be found"
171 # Make sure gcc is installed
172 `gcc --help >/dev/null 2>&1`
174 if [[ "$?" != "0" ]]; then
176 echo >&2 "Error: gcc could not be found"
183 # $BUILD_NUMBER is set by Jenkins if this script is being called as part of a Jenkins run
184 if [[ -f "$1/$2" ]]; then
185 THEDATE=`date +%Y%m%d%H%M%S`
186 mv "$1/$2" "$1/$THEDATE-$BUILD_NUMBER-$2"
187 gzip "$1/$THEDATE-$BUILD_NUMBER-$2"
194 skip[apps/workbench_profile]=1
201 echo >&2 "$helpmessage"
210 only="$1"; skip[$1]=""; shift
217 only_install="$1"; shift
220 leave_temp[VENVDIR]=1
222 leave_temp[GEMHOME]=1
228 suite="${arg%%_test=*}"
230 testargs["$suite"]="$args"
233 eval export $(echo $arg | cut -d= -f1)=\"$(echo $arg | cut -d= -f2-)\"
236 echo >&2 "$0: Unrecognized option: '$arg'. Try: $0 --help"
243 echo 'Starting API server...'
245 && eval $(python sdk/python/tests/run_test_server.py start --auth admin) \
246 && export ARVADOS_TEST_API_HOST="$ARVADOS_API_HOST" \
247 && export ARVADOS_TEST_API_INSTALLED="$$" \
248 && (env | egrep ^ARVADOS)
252 if [[ -n "$ARVADOS_TEST_API_HOST" ]]; then
253 unset ARVADOS_TEST_API_HOST
255 && python sdk/python/tests/run_test_server.py stop
260 failures+=("($(basename $0) interrupted)")
267 echo "WORKSPACE=$WORKSPACE"
269 if [[ -z "$CONFIGSRC" ]] && [[ -d "$HOME/arvados-api-server" ]]; then
270 # Jenkins expects us to use this by default.
271 CONFIGSRC="$HOME/arvados-api-server"
274 # Clean up .pyc files that may exist in the workspace
276 find -name '*.pyc' -delete
278 # Set up temporary install dirs (unless existing dirs were supplied)
279 for tmpdir in VENVDIR GOPATH GEMHOME
281 if [[ -n "${!tmpdir}" ]]; then
282 leave_temp[$tmpdir]=1
284 eval $tmpdir=$(mktemp -d)
288 setup_ruby_environment() {
289 if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
290 source "$HOME/.rvm/scripts/rvm"
292 elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
293 source "/usr/local/rvm/scripts/rvm"
299 if [[ "$using_rvm" == true ]]; then
300 # If rvm is in use, we can't just put separate "dependencies"
301 # and "gems-under-test" paths to GEM_PATH: passenger resets
302 # the environment to the "current gemset", which would lose
303 # our GEM_PATH and prevent our test suites from running ruby
304 # programs (for example, the Workbench test suite could not
305 # boot an API server or run arv). Instead, we have to make an
306 # rvm gemset and use it for everything.
308 [[ `type rvm | head -n1` == "rvm is a function" ]] \
311 # Put rvm's favorite path back in first place (overriding
312 # virtualenv, which just put itself there). Ignore rvm's
313 # complaint about not being in first place already.
314 rvm use @default 2>/dev/null
316 # Create (if needed) and switch to an @arvados-tests
317 # gemset. (Leave the choice of ruby to the caller.)
318 rvm use @arvados-tests --create \
319 || fatal 'rvm gemset setup'
323 # When our "bundle install"s need to install new gems to
324 # satisfy dependencies, we want them to go where "gem install
325 # --user-install" would put them. (However, if the caller has
326 # already set GEM_HOME, we assume that's where dependencies
327 # should be installed, and we should leave it alone.)
329 if [ -z "$GEM_HOME" ]; then
330 user_gempath="$(gem env gempath)"
331 export GEM_HOME="${user_gempath%%:*}"
333 PATH="$(gem env gemdir)/bin:$PATH"
335 # When we build and install our own gems, we install them in our
336 # $GEMHOME tmpdir, and we want them to be at the front of GEM_PATH and
337 # PATH so integration tests prefer them over other versions that
338 # happen to be installed in $user_gempath, system dirs, etc.
340 tmpdir_gem_home="$(env - PATH="$PATH" HOME="$GEMHOME" gem env gempath | cut -f1 -d:)"
341 PATH="$tmpdir_gem_home/bin:$PATH"
342 export GEM_PATH="$tmpdir_gem_home:$(gem env gempath)"
344 echo "Will install dependencies to $(gem env gemdir)"
345 echo "Will install arvados gems to $tmpdir_gem_home"
346 echo "Gem search path is GEM_PATH=$GEM_PATH"
351 if [[ "$using_rvm" == true ]]; then
354 GEM_HOME="$tmpdir_gem_home" "$@"
359 mkdir -p "$GOPATH/src/git.curoverse.com"
360 ln -sfn "$WORKSPACE" "$GOPATH/src/git.curoverse.com/arvados.git" \
361 || fatal "symlink failed"
363 virtualenv --setuptools "$VENVDIR" || fatal "virtualenv $VENVDIR failed"
364 . "$VENVDIR/bin/activate"
366 # When re-using $VENVDIR, upgrade any packages (except arvados) that are
368 pip install --quiet --upgrade `pip freeze | grep -v arvados | cut -f1 -d=`
370 # Note: this must be the last time we change PATH, otherwise rvm will
372 setup_ruby_environment
376 if ! which bundler >/dev/null
378 gem install --user-install bundler || fatal 'Could not install bundler'
381 # Needed for run_test_server.py which is used by certain (non-Python) tests.
382 echo "pip install -q PyYAML"
383 pip install --quiet PyYAML || fatal "pip install PyYAML failed"
386 if [[ "$1" != "0" ]]; then
387 title "!!!!!! $2 FAILED !!!!!!"
388 failures+=("$2 (`timer`)")
390 successes+=("$2 (`timer`)")
399 echo -n "$(($SECONDS - $t0))s"
403 while ! do_test_once ${@} && [[ "$retry" == 1 ]]
405 read -p 'Try again? [Y/n] ' x
406 if [[ "$x" != "y" ]] && [[ "$x" != "" ]]
414 if [[ -z "${skip[$1]}" ]] && ( [[ -z "$only" ]] || [[ "$only" == "$1" ]] )
416 title "Running $1 tests"
418 if [[ "$2" == "go" ]]
420 go test ${testargs[$1]} "git.curoverse.com/arvados.git/$1"
421 elif [[ "$2" == "pip" ]]
424 && python setup.py test ${testargs[$1]}
425 elif [[ "$2" != "" ]]
432 checkexit $result "$1 tests"
433 title "End of $1 tests (`timer`)"
436 title "Skipping $1 tests"
441 if [[ -z "$skip_install" || (-n "$only_install" && "$only_install" == "$1") ]]
443 title "Running $1 install"
445 if [[ "$2" == "go" ]]
447 go get -t "git.curoverse.com/arvados.git/$1"
448 elif [[ "$2" == "pip" ]]
450 # Need to change to a different directory after creating
451 # the source dist package to avoid a pip bug.
452 # see https://arvados.org/issues/5766 for details.
454 # Also need to install twice, because if it belives the package is
455 # already installed, pip it won't install it. So the first "pip
456 # install" ensures that the dependencies are met, the second "pip
457 # install" ensures that we've actually install the local package
460 && python setup.py sdist rotate --keep=1 --match .tar.gz \
462 && pip install --quiet "$WORKSPACE/$1/dist"/*.tar.gz \
463 && pip install --quiet --no-deps --ignore-installed "$WORKSPACE/$1/dist"/*.tar.gz
464 elif [[ "$2" != "" ]]
470 checkexit $? "$1 install"
471 title "End of $1 install (`timer`)"
473 title "Skipping $1 install"
478 txt="********** $1 **********"
479 printf "\n%*s%s\n\n" $((($COLUMNS-${#txt})/2)) "" "$txt"
482 bundle_install_trylocal() {
485 echo "(Running bundle install --local. 'could not find package' messages are OK.)"
486 if ! bundle install --local --no-deployment; then
487 echo "(Running bundle install again, without --local.)"
488 bundle install --no-deployment
495 cd "$WORKSPACE/doc" \
496 && bundle_install_trylocal \
502 with_test_gemset gem uninstall --force --all --executables arvados \
503 && cd "$WORKSPACE/sdk/ruby" \
504 && bundle_install_trylocal \
505 && gem build arvados.gemspec \
506 && with_test_gemset gem install --no-ri --no-rdoc `ls -t arvados-*.gem|head -n1`
508 do_install sdk/ruby ruby_sdk
511 with_test_gemset gem uninstall --force --all --executables arvados-cli \
512 && cd "$WORKSPACE/sdk/cli" \
513 && bundle_install_trylocal \
514 && gem build arvados-cli.gemspec \
515 && with_test_gemset gem install --no-ri --no-rdoc `ls -t arvados-cli-*.gem|head -n1`
517 do_install sdk/cli cli
519 # Install the Python SDK early. Various other test suites (like
520 # keepproxy) bring up run_test_server.py, which imports the arvados
521 # module. We can't actually *test* the Python SDK yet though, because
522 # its own test suite brings up some of those other programs (like
524 declare -a pythonstuff
530 for p in "${pythonstuff[@]}"
535 install_apiserver() {
536 cd "$WORKSPACE/services/api" \
537 && RAILS_ENV=test bundle_install_trylocal
539 rm -f config/environments/test.rb
540 cp config/environments/test.rb.example config/environments/test.rb
542 if [ -n "$CONFIGSRC" ]
544 for f in database.yml application.yml
546 cp "$CONFIGSRC/$f" config/ || fatal "$f"
550 # Fill in a random secret_token and blob_signing_key for testing
551 SECRET_TOKEN=`echo 'puts rand(2**512).to_s(36)' |ruby`
552 BLOB_SIGNING_KEY=`echo 'puts rand(2**512).to_s(36)' |ruby`
554 sed -i'' -e "s:SECRET_TOKEN:$SECRET_TOKEN:" config/application.yml
555 sed -i'' -e "s:BLOB_SIGNING_KEY:$BLOB_SIGNING_KEY:" config/application.yml
557 # Set up empty git repo (for git tests)
559 sed -i'' -e "s:/var/cache/git:$GITDIR:" config/application.default.yml
562 mkdir -p $GITDIR/test
565 && git config user.email "jenkins@ci.curoverse.com" \
566 && git config user.name "Jenkins, CI" \
569 && git commit -m 'initial commit'
571 # Clear out any lingering postgresql connections to arvados_test, so that we can drop it
572 # This assumes the current user is a postgresql superuser
573 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
575 cd "$WORKSPACE/services/api" \
576 && RAILS_ENV=test bundle exec rake db:drop \
577 && RAILS_ENV=test bundle exec rake db:setup \
578 && RAILS_ENV=test bundle exec rake db:fixtures:load
580 do_install services/api apiserver
584 services/arv-git-httpd
592 for g in "${gostuff[@]}"
597 install_workbench() {
598 cd "$WORKSPACE/apps/workbench" \
599 && mkdir -p tmp/cache \
600 && RAILS_ENV=test bundle_install_trylocal
602 do_install apps/workbench workbench
604 test_doclinkchecker() {
608 ARVADOS_API_HOST=qr1hi.arvadosapi.com
609 # Make sure python-epydoc is installed or the next line won't
611 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
614 do_test doc doclinkchecker
619 cd "$WORKSPACE/services/api" \
620 && RAILS_ENV=test bundle exec rake test TESTOPTS=-v ${testargs[services/api]}
622 do_test services/api apiserver
624 # Shortcut for when we're only running apiserver tests. This saves a bit of time,
625 # because we don't need to start up the api server for subsequent tests.
626 if [ ! -z "$only" ] && [ "$only" == "services/api" ]; then
627 rotate_logfile "$WORKSPACE/services/api/log/" "test.log"
634 cd "$WORKSPACE/sdk/ruby" \
635 && bundle exec rake test TESTOPTS=-v ${testargs[sdk/ruby]}
637 do_test sdk/ruby ruby_sdk
640 cd "$WORKSPACE/sdk/cli" \
641 && mkdir -p /tmp/keep \
642 && KEEP_LOCAL_STORE=/tmp/keep bundle exec rake test TESTOPTS=-v ${testargs[sdk/cli]}
646 for p in "${pythonstuff[@]}"
651 for g in "${gostuff[@]}"
657 cd "$WORKSPACE/apps/workbench" \
658 && RAILS_ENV=test bundle exec rake test TESTOPTS=-v ${testargs[apps/workbench]}
660 do_test apps/workbench workbench
662 test_workbench_benchmark() {
663 cd "$WORKSPACE/apps/workbench" \
664 && RAILS_ENV=test bundle exec rake test:benchmark ${testargs[apps/workbench_benchmark]}
666 do_test apps/workbench_benchmark workbench_benchmark
668 test_workbench_profile() {
669 cd "$WORKSPACE/apps/workbench" \
670 && RAILS_ENV=test bundle exec rake test:profile ${testargs[apps/workbench_profile]}
672 do_test apps/workbench_profile workbench_profile