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
68 # First make sure to remove any ARVADOS_ variables from the calling
69 # environment that could interfere with the tests.
70 unset $(env | cut -d= -f1 | grep \^ARVADOS_)
72 # Reset other variables that could affect our [tests'] behavior by
88 for var in VENVDIR GOPATH GITDIR GEMHOME
90 if [[ -z "${leave_temp[$var]}" ]]
97 leaving+=" $var=\"${!var}\""
100 if [[ -n "$leaving" ]]; then
101 echo "Leaving behind temp dirs: $leaving"
107 echo >&2 "Fatal: $* in ${FUNCNAME[1]} at ${BASH_SOURCE[1]} line ${BASH_LINENO[0]}"
112 for x in "${successes[@]}"
117 if [[ ${#failures[@]} == 0 ]]
119 echo "All test suites passed."
121 echo "Failures (${#failures[@]}):"
122 for x in "${failures[@]}"
131 rotate_logfile "$WORKSPACE/apps/workbench/log/" "test.log"
133 rotate_logfile "$WORKSPACE/services/api/log/" "test.log"
140 # Make sure WORKSPACE is set
141 if ! [[ -n "$WORKSPACE" ]]; then
142 echo >&2 "$helpmessage"
144 echo >&2 "Error: WORKSPACE environment variable not set"
149 # Make sure virtualenv is installed
150 `virtualenv --help >/dev/null 2>&1`
152 if [[ "$?" != "0" ]]; then
154 echo >&2 "Error: virtualenv could not be found"
159 # Make sure go is installed
160 `go env >/dev/null 2>&1`
162 if [[ "$?" != "0" ]]; then
164 echo >&2 "Error: go could not be found"
169 # Make sure gcc is installed
170 `gcc --help >/dev/null 2>&1`
172 if [[ "$?" != "0" ]]; then
174 echo >&2 "Error: gcc could not be found"
181 # $BUILD_NUMBER is set by Jenkins if this script is being called as part of a Jenkins run
182 if [[ -f "$1/$2" ]]; then
183 THEDATE=`date +%Y%m%d%H%M%S`
184 mv "$1/$2" "$1/$THEDATE-$BUILD_NUMBER-$2"
185 gzip "$1/$THEDATE-$BUILD_NUMBER-$2"
192 skip[apps/workbench_profile]=1
199 echo >&2 "$helpmessage"
208 only="$1"; skip[$1]=""; shift
214 leave_temp[VENVDIR]=1
216 leave_temp[GEMHOME]=1
222 suite="${arg%%_test=*}"
224 testargs["$suite"]="$args"
227 eval export $(echo $arg | cut -d= -f1)=\"$(echo $arg | cut -d= -f2-)\"
230 echo >&2 "$0: Unrecognized option: '$arg'. Try: $0 --help"
237 echo 'Starting API server...'
239 && eval $(python sdk/python/tests/run_test_server.py start --auth admin) \
240 && export ARVADOS_TEST_API_HOST="$ARVADOS_API_HOST" \
241 && export ARVADOS_TEST_API_INSTALLED="$$" \
242 && (env | egrep ^ARVADOS)
246 if [[ -n "$ARVADOS_TEST_API_HOST" ]]; then
247 unset ARVADOS_TEST_API_HOST
249 && python sdk/python/tests/run_test_server.py stop
254 failures+=("($(basename $0) interrupted)")
261 echo "WORKSPACE=$WORKSPACE"
263 if [[ -z "$CONFIGSRC" ]] && [[ -d "$HOME/arvados-api-server" ]]; then
264 # Jenkins expects us to use this by default.
265 CONFIGSRC="$HOME/arvados-api-server"
268 # Clean up .pyc files that may exist in the workspace
270 find -name '*.pyc' -delete
272 # Set up temporary install dirs (unless existing dirs were supplied)
273 for tmpdir in VENVDIR GOPATH GEMHOME
275 if [[ -n "${!tmpdir}" ]]; then
276 leave_temp[$tmpdir]=1
278 eval $tmpdir=$(mktemp -d)
282 setup_ruby_environment() {
283 if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
284 source "$HOME/.rvm/scripts/rvm"
286 elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
287 source "/usr/local/rvm/scripts/rvm"
293 if [[ "$using_rvm" == true ]]; then
294 # If rvm is in use, we can't just put separate "dependencies"
295 # and "gems-under-test" paths to GEM_PATH: passenger resets
296 # the environment to the "current gemset", which would lose
297 # our GEM_PATH and prevent our test suites from running ruby
298 # programs (for example, the Workbench test suite could not
299 # boot an API server or run arv). Instead, we have to make an
300 # rvm gemset and use it for everything.
302 [[ `type rvm | head -n1` == "rvm is a function" ]] \
305 # Put rvm's favorite path back in first place (overriding
306 # virtualenv, which just put itself there). Ignore rvm's
307 # complaint about not being in first place already.
308 rvm use @default 2>/dev/null
310 # Create (if needed) and switch to an @arvados-tests
311 # gemset. (Leave the choice of ruby to the caller.)
312 rvm use @arvados-tests --create \
313 || fatal 'rvm gemset setup'
317 # When our "bundle install"s need to install new gems to
318 # satisfy dependencies, we want them to go where "gem install
319 # --user-install" would put them. (However, if the caller has
320 # already set GEM_HOME, we assume that's where dependencies
321 # should be installed, and we should leave it alone.)
323 if [ -z "$GEM_HOME" ]; then
324 user_gempath="$(gem env gempath)"
325 export GEM_HOME="${user_gempath%%:*}"
327 PATH="$(gem env gemdir)/bin:$PATH"
329 # When we build and install our own gems, we install them in our
330 # $GEMHOME tmpdir, and we want them to be at the front of GEM_PATH and
331 # PATH so integration tests prefer them over other versions that
332 # happen to be installed in $user_gempath, system dirs, etc.
334 tmpdir_gem_home="$(env - PATH="$PATH" HOME="$GEMHOME" gem env gempath | cut -f1 -d:)"
335 PATH="$tmpdir_gem_home/bin:$PATH"
336 export GEM_PATH="$tmpdir_gem_home:$(gem env gempath)"
338 echo "Will install dependencies to $(gem env gemdir)"
339 echo "Will install arvados gems to $tmpdir_gem_home"
340 echo "Gem search path is GEM_PATH=$GEM_PATH"
345 if [[ "$using_rvm" == true ]]; then
348 GEM_HOME="$tmpdir_gem_home" "$@"
353 mkdir -p "$GOPATH/src/git.curoverse.com"
354 ln -sfn "$WORKSPACE" "$GOPATH/src/git.curoverse.com/arvados.git" \
355 || fatal "symlink failed"
357 virtualenv --setuptools "$VENVDIR" || fatal "virtualenv $VENVDIR failed"
358 . "$VENVDIR/bin/activate"
360 # Note: this must be the last time we change PATH, otherwise rvm will
362 setup_ruby_environment
366 if ! which bundler >/dev/null
368 gem install --user-install bundler || fatal 'Could not install bundler'
371 # Needed for run_test_server.py which is used by certain (non-Python) tests.
372 echo "pip install -q PyYAML"
373 pip install -q PyYAML || fatal "pip install PyYAML failed"
376 if [[ "$1" != "0" ]]; then
377 title "!!!!!! $2 FAILED !!!!!!"
378 failures+=("$2 (`timer`)")
380 successes+=("$2 (`timer`)")
389 echo -n "$(($SECONDS - $t0))s"
393 while ! do_test_once ${@} && [[ "$retry" == 1 ]]
395 read -p 'Try again? [Y/n] ' x
396 if [[ "$x" != "y" ]] && [[ "$x" != "" ]]
404 if [[ -z "${skip[$1]}" ]] && ( [[ -z "$only" ]] || [[ "$only" == "$1" ]] )
406 title "Running $1 tests"
408 if [[ "$2" == "go" ]]
410 go test ${testargs[$1]} "git.curoverse.com/arvados.git/$1"
411 elif [[ "$2" == "pip" ]]
414 && python setup.py test ${testargs[$1]}
415 elif [[ "$2" != "" ]]
422 checkexit $result "$1 tests"
423 title "End of $1 tests (`timer`)"
426 title "Skipping $1 tests"
431 if [[ -z "$skip_install" ]]
433 title "Running $1 install"
435 if [[ "$2" == "go" ]]
437 go get -t "git.curoverse.com/arvados.git/$1"
438 elif [[ "$2" == "pip" ]]
441 && python setup.py sdist rotate --keep=1 --match .tar.gz \
442 && pip install -q --upgrade dist/*.tar.gz
443 elif [[ "$2" != "" ]]
449 checkexit $? "$1 install"
450 title "End of $1 install (`timer`)"
452 title "Skipping $1 install"
457 txt="********** $1 **********"
458 printf "\n%*s%s\n\n" $((($COLUMNS-${#txt})/2)) "" "$txt"
461 bundle_install_trylocal() {
464 echo "(Running bundle install --local. 'could not find package' messages are OK.)"
465 if ! bundle install --local --no-deployment; then
466 echo "(Running bundle install again, without --local.)"
467 bundle install --no-deployment
474 cd "$WORKSPACE/doc" \
475 && bundle_install_trylocal \
481 with_test_gemset gem uninstall --force --all --executables arvados \
482 && cd "$WORKSPACE/sdk/ruby" \
483 && bundle_install_trylocal \
484 && gem build arvados.gemspec \
485 && with_test_gemset gem install --no-ri --no-rdoc `ls -t arvados-*.gem|head -n1`
487 do_install sdk/ruby ruby_sdk
490 with_test_gemset gem uninstall --force --all --executables arvados-cli \
491 && cd "$WORKSPACE/sdk/cli" \
492 && bundle_install_trylocal \
493 && gem build arvados-cli.gemspec \
494 && with_test_gemset gem install --no-ri --no-rdoc `ls -t arvados-cli-*.gem|head -n1`
496 do_install sdk/cli cli
498 # Install the Python SDK early. Various other test suites (like
499 # keepproxy) bring up run_test_server.py, which imports the arvados
500 # module. We can't actually *test* the Python SDK yet though, because
501 # its own test suite brings up some of those other programs (like
503 declare -a pythonstuff
509 for p in "${pythonstuff[@]}"
514 install_apiserver() {
515 cd "$WORKSPACE/services/api" \
516 && RAILS_ENV=test bundle_install_trylocal
518 rm -f config/environments/test.rb
519 cp config/environments/test.rb.example config/environments/test.rb
521 if [ -n "$CONFIGSRC" ]
523 for f in database.yml application.yml
525 cp "$CONFIGSRC/$f" config/ || fatal "$f"
529 # Fill in a random secret_token and blob_signing_key for testing
530 SECRET_TOKEN=`echo 'puts rand(2**512).to_s(36)' |ruby`
531 BLOB_SIGNING_KEY=`echo 'puts rand(2**512).to_s(36)' |ruby`
533 sed -i'' -e "s:SECRET_TOKEN:$SECRET_TOKEN:" config/application.yml
534 sed -i'' -e "s:BLOB_SIGNING_KEY:$BLOB_SIGNING_KEY:" config/application.yml
536 # Set up empty git repo (for git tests)
538 sed -i'' -e "s:/var/cache/git:$GITDIR:" config/application.default.yml
541 mkdir -p $GITDIR/test
544 && git config user.email "jenkins@ci.curoverse.com" \
545 && git config user.name "Jenkins, CI" \
548 && git commit -m 'initial commit'
550 # Clear out any lingering postgresql connections to arvados_test, so that we can drop it
551 # This assumes the current user is a postgresql superuser
552 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
554 cd "$WORKSPACE/services/api" \
555 && RAILS_ENV=test bundle exec rake db:drop \
556 && RAILS_ENV=test bundle exec rake db:setup \
557 && RAILS_ENV=test bundle exec rake db:fixtures:load
559 do_install services/api apiserver
563 services/arv-git-httpd
571 for g in "${gostuff[@]}"
576 install_workbench() {
577 cd "$WORKSPACE/apps/workbench" \
578 && mkdir -p tmp/cache \
579 && RAILS_ENV=test bundle_install_trylocal
581 do_install apps/workbench workbench
583 test_doclinkchecker() {
587 ARVADOS_API_HOST=qr1hi.arvadosapi.com
588 # Make sure python-epydoc is installed or the next line won't
590 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
593 do_test doc doclinkchecker
598 cd "$WORKSPACE/services/api" \
599 && RAILS_ENV=test bundle exec rake test TESTOPTS=-v ${testargs[services/api]}
601 do_test services/api apiserver
603 # Shortcut for when we're only running apiserver tests. This saves a bit of time,
604 # because we don't need to start up the api server for subsequent tests.
605 if [ ! -z "$only" ] && [ "$only" == "services/api" ]; then
606 rotate_logfile "$WORKSPACE/services/api/log/" "test.log"
613 cd "$WORKSPACE/sdk/ruby" \
614 && bundle exec rake test TESTOPTS=-v ${testargs[sdk/ruby]}
616 do_test sdk/ruby ruby_sdk
619 cd "$WORKSPACE/sdk/cli" \
620 && mkdir -p /tmp/keep \
621 && KEEP_LOCAL_STORE=/tmp/keep bundle exec rake test TESTOPTS=-v ${testargs[sdk/cli]}
625 for p in "${pythonstuff[@]}"
630 for g in "${gostuff[@]}"
636 cd "$WORKSPACE/apps/workbench" \
637 && RAILS_ENV=test bundle exec rake test TESTOPTS=-v ${testargs[apps/workbench]}
639 do_test apps/workbench workbench
641 test_workbench_benchmark() {
642 cd "$WORKSPACE/apps/workbench" \
643 && RAILS_ENV=test bundle exec rake test:benchmark ${testargs[apps/workbench_benchmark]}
645 do_test apps/workbench_benchmark workbench_benchmark
647 test_workbench_profile() {
648 cd "$WORKSPACE/apps/workbench" \
649 && RAILS_ENV=test bundle exec rake test:profile ${testargs[apps/workbench_profile]}
651 do_test apps/workbench_profile workbench_profile