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[@]}"
130 # Make sure WORKSPACE is set
131 if ! [[ -n "$WORKSPACE" ]]; then
132 echo >&2 "$helpmessage"
134 echo >&2 "Error: WORKSPACE environment variable not set"
139 # Make sure virtualenv is installed
140 `virtualenv --help >/dev/null 2>&1`
142 if [[ "$?" != "0" ]]; then
144 echo >&2 "Error: virtualenv could not be found"
149 # Make sure go is installed
150 `go env >/dev/null 2>&1`
152 if [[ "$?" != "0" ]]; then
154 echo >&2 "Error: go could not be found"
159 # Make sure gcc is installed
160 `gcc --help >/dev/null 2>&1`
162 if [[ "$?" != "0" ]]; then
164 echo >&2 "Error: gcc could not be found"
172 # $BUILD_NUMBER is set by Jenkins if this script is being called as part of a Jenkins run
173 if [[ -f "$1/$2" ]]; then
174 THEDATE=`date +%Y%m%d%H%M%S`
175 mv "$1/$2" "$1/$THEDATE-$BUILD_NUMBER-$2"
176 gzip "$1/$THEDATE-$BUILD_NUMBER-$2"
183 skip[apps/workbench_profile]=1
190 echo >&2 "$helpmessage"
199 only="$1"; skip[$1]=""; shift
205 leave_temp[VENVDIR]=1
207 leave_temp[GEMHOME]=1
210 suite="${arg%%_test=*}"
212 testargs["$suite"]="$args"
215 eval export $(echo $arg | cut -d= -f1)=\"$(echo $arg | cut -d= -f2-)\"
218 echo >&2 "$0: Unrecognized option: '$arg'. Try: $0 --help"
226 echo "WORKSPACE=$WORKSPACE"
228 if [[ -z "$CONFIGSRC" ]] && [[ -d "$HOME/arvados-api-server" ]]; then
229 # Jenkins expects us to use this by default.
230 CONFIGSRC="$HOME/arvados-api-server"
233 # Clean up .pyc files that may exist in the workspace
235 find -name '*.pyc' -delete
237 # Set up temporary install dirs (unless existing dirs were supplied)
238 for tmpdir in VENVDIR GOPATH GEMHOME
240 if [[ -n "${!tmpdir}" ]]; then
241 leave_temp[$tmpdir]=1
243 eval $tmpdir=$(mktemp -d)
247 setup_ruby_environment() {
248 if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
249 source "$HOME/.rvm/scripts/rvm"
251 elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
252 source "/usr/local/rvm/scripts/rvm"
258 if [[ "$using_rvm" == true ]]; then
259 # If rvm is in use, we can't just put separate "dependencies"
260 # and "gems-under-test" paths to GEM_PATH: passenger resets
261 # the environment to the "current gemset", which would lose
262 # our GEM_PATH and prevent our test suites from running ruby
263 # programs (for example, the Workbench test suite could not
264 # boot an API server or run arv). Instead, we have to make an
265 # rvm gemset and use it for everything.
267 [[ `type rvm | head -n1` == "rvm is a function" ]] \
270 # Put rvm's favorite path back in first place (overriding
271 # virtualenv, which just put itself there). Ignore rvm's
272 # complaint about not being in first place already.
273 rvm use @default 2>/dev/null
275 # Create (if needed) and switch to an @arvados-tests
276 # gemset. (Leave the choice of ruby to the caller.)
277 rvm use @arvados-tests --create \
278 || fatal 'rvm gemset setup'
282 # When our "bundle install"s need to install new gems to
283 # satisfy dependencies, we want them to go where "gem install
284 # --user-install" would put them. (However, if the caller has
285 # already set GEM_HOME, we assume that's where dependencies
286 # should be installed, and we should leave it alone.)
288 if [ -z "$GEM_HOME" ]; then
289 user_gempath="$(gem env gempath)"
290 export GEM_HOME="${user_gempath%%:*}"
292 PATH="$(gem env gemdir)/bin:$PATH"
294 # When we build and install our own gems, we install them in our
295 # $GEMHOME tmpdir, and we want them to be at the front of GEM_PATH and
296 # PATH so integration tests prefer them over other versions that
297 # happen to be installed in $user_gempath, system dirs, etc.
299 tmpdir_gem_home="$(env - PATH="$PATH" HOME="$GEMHOME" gem env gempath | cut -f1 -d:)"
300 PATH="$tmpdir_gem_home/bin:$PATH"
301 export GEM_PATH="$tmpdir_gem_home:$(gem env gempath)"
303 echo "Will install dependencies to $(gem env gemdir)"
304 echo "Will install arvados gems to $tmpdir_gem_home"
305 echo "Gem search path is GEM_PATH=$GEM_PATH"
310 if [[ "$using_rvm" == true ]]; then
313 GEM_HOME="$tmpdir_gem_home" "$@"
318 mkdir -p "$GOPATH/src/git.curoverse.com"
319 ln -sfn "$WORKSPACE" "$GOPATH/src/git.curoverse.com/arvados.git" \
320 || fatal "symlink failed"
322 virtualenv --setuptools "$VENVDIR" || fatal "virtualenv $VENVDIR failed"
323 . "$VENVDIR/bin/activate"
325 # Note: this must be the last time we change PATH, otherwise rvm will
327 setup_ruby_environment
331 if ! which bundler >/dev/null
333 gem install --user-install bundler || fatal 'Could not install bundler'
336 # Needed for run_test_server.py which is used by certain (non-Python) tests.
337 pip install PyYAML || fatal "pip install PyYAML failed"
339 # Needed for python-daemon 2.0.2, which breaks otherwise with
340 # "ImportError: No module named docutils.core"
341 pip install docutils || fatal "pip install docutils failed"
344 if [[ "$?" != "0" ]]; then
345 title "!!!!!! $1 FAILED !!!!!!"
346 failures+=("$1 (`timer`)")
348 successes+=("$1 (`timer`)")
357 echo -n "$(($SECONDS - $t0))s"
361 if [[ -z "${skip[$1]}" ]] && ( [[ -z "$only" ]] || [[ "$only" == "$1" ]] )
363 title "Running $1 tests"
365 if [[ "$2" == "go" ]]
367 go test ${testargs[$1]} "git.curoverse.com/arvados.git/$1"
368 elif [[ "$2" == "pip" ]]
371 && python setup.py test ${testargs[$1]}
372 elif [[ "$2" != "" ]]
379 title "End of $1 tests (`timer`)"
381 title "Skipping $1 tests"
386 if [[ -z "$skip_install" ]]
388 title "Running $1 install"
390 if [[ "$2" == "go" ]]
392 go get -t "git.curoverse.com/arvados.git/$1"
393 elif [[ "$2" == "pip" ]]
396 && python setup.py sdist rotate --keep=1 --match .tar.gz \
397 && pip install --upgrade dist/*.tar.gz
398 elif [[ "$2" != "" ]]
404 checkexit "$1 install"
405 title "End of $1 install (`timer`)"
407 title "Skipping $1 install"
412 txt="********** $1 **********"
413 printf "\n%*s%s\n\n" $((($COLUMNS-${#txt})/2)) "" "$txt"
417 cd "$WORKSPACE/doc" \
418 && (bundle install --local --no-deployment \
419 || bundle install --no-deployment) \
420 && bundle package --all \
426 with_test_gemset gem uninstall --force --all --executables arvados \
427 && cd "$WORKSPACE/sdk/ruby" \
428 && (bundle install --local --no-deployment \
429 || bundle install --no-deployment) \
430 && bundle package --all \
431 && gem build arvados.gemspec \
432 && with_test_gemset gem install --no-ri --no-rdoc `ls -t arvados-*.gem|head -n1`
434 do_install sdk/ruby ruby_sdk
437 with_test_gemset gem uninstall --force --all --executables arvados-cli \
438 && cd "$WORKSPACE/sdk/cli" \
439 && (bundle install --local --no-deployment \
440 || bundle install --no-deployment) \
441 && bundle package --all \
442 && gem build arvados-cli.gemspec \
443 && with_test_gemset gem install --no-ri --no-rdoc `ls -t arvados-cli-*.gem|head -n1`
445 do_install sdk/cli cli
447 # Install the Python SDK early. Various other test suites (like
448 # keepproxy) bring up run_test_server.py, which imports the arvados
449 # module. We can't actually *test* the Python SDK yet though, because
450 # its own test suite brings up some of those other programs (like
452 declare -a pythonstuff
458 for p in "${pythonstuff[@]}"
463 install_apiserver() {
464 cd "$WORKSPACE/services/api" \
465 && (RAILS_ENV=test bundle install --local --no-deployment \
466 || RAILS_ENV=test bundle install --no-deployment) \
467 && bundle package --all
469 rm -f config/environments/test.rb
470 cp config/environments/test.rb.example config/environments/test.rb
472 if [ -n "$CONFIGSRC" ]
474 for f in database.yml application.yml
476 cp "$CONFIGSRC/$f" config/ || fatal "$f"
480 # Fill in a random secret_token and blob_signing_key for testing
481 SECRET_TOKEN=`echo 'puts rand(2**512).to_s(36)' |ruby`
482 BLOB_SIGNING_KEY=`echo 'puts rand(2**512).to_s(36)' |ruby`
484 sed -i'' -e "s:SECRET_TOKEN:$SECRET_TOKEN:" config/application.yml
485 sed -i'' -e "s:BLOB_SIGNING_KEY:$BLOB_SIGNING_KEY:" config/application.yml
487 # Set up empty git repo (for git tests)
489 sed -i'' -e "s:/var/cache/git:$GITDIR:" config/application.default.yml
492 mkdir -p $GITDIR/test
495 && git config user.email "jenkins@ci.curoverse.com" \
496 && git config user.name "Jenkins, CI" \
499 && git commit -m 'initial commit'
501 # Clear out any lingering postgresql connections to arvados_test, so that we can drop it
502 # This assumes the current user is a postgresql superuser
503 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
505 cd "$WORKSPACE/services/api" \
506 && RAILS_ENV=test bundle exec rake db:drop \
507 && RAILS_ENV=test bundle exec rake db:setup \
508 && RAILS_ENV=test bundle exec rake db:fixtures:load
510 do_install services/api apiserver
521 for g in "${gostuff[@]}"
526 install_workbench() {
527 cd "$WORKSPACE/apps/workbench" \
528 && (RAILS_ENV=test bundle install --local --no-deployment \
529 || RAILS_ENV=test bundle install --no-deployment) \
530 && bundle package --all
532 do_install apps/workbench workbench
535 echo 'Starting API server...'
537 eval $(python sdk/python/tests/run_test_server.py start --auth admin) && \
538 export ARVADOS_TEST_API_HOST="$ARVADOS_API_HOST" && \
539 export ARVADOS_TEST_API_INSTALLED="$$" && \
540 (env | egrep ^ARVADOS)
544 unset ARVADOS_TEST_API_HOST
546 python sdk/python/tests/run_test_server.py stop
549 test_doclinkchecker() {
553 ARVADOS_API_HOST=qr1hi.arvadosapi.com
554 # Make sure python-epydoc is installed or the next line won't
556 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
559 do_test doc doclinkchecker
564 cd "$WORKSPACE/services/api"
565 RAILS_ENV=test bundle exec rake test ${testargs[services/api]}
567 do_test services/api apiserver
572 cd "$WORKSPACE/sdk/ruby" \
573 && bundle exec rake test ${testargs[sdk/ruby]}
575 do_test sdk/ruby ruby_sdk
578 cd "$WORKSPACE/sdk/cli" \
579 && mkdir -p /tmp/keep \
580 && KEEP_LOCAL_STORE=/tmp/keep bundle exec rake test ${testargs[sdk/cli]}
584 for p in "${pythonstuff[@]}"
589 for g in "${gostuff[@]}"
595 cd "$WORKSPACE/apps/workbench" \
596 && RAILS_ENV=test bundle exec rake test ${testargs[apps/workbench]}
598 do_test apps/workbench workbench
600 test_workbench_benchmark() {
601 cd "$WORKSPACE/apps/workbench" \
602 && RAILS_ENV=test bundle exec rake test:benchmark ${testargs[apps/workbench_benchmark]}
604 do_test apps/workbench_benchmark workbench_benchmark
606 test_workbench_profile() {
607 cd "$WORKSPACE/apps/workbench" \
608 && RAILS_ENV=test bundle exec rake test:profile ${testargs[apps/workbench_profile]}
610 do_test apps/workbench_profile workbench_profile
612 rotate_logfile "$WORKSPACE/apps/workbench/log/" "test.log"
615 rotate_logfile "$WORKSPACE/services/api/log/" "test.log"