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)
246 start_nginx_proxy_services() {
247 echo 'Starting keepproxy, arv-git-httpd, and nginx ssl proxy...'
249 && python sdk/python/tests/run_test_server.py start_keep_proxy \
250 && python sdk/python/tests/run_test_server.py start_arv-git-httpd \
251 && python sdk/python/tests/run_test_server.py start_nginx \
252 && export ARVADOS_TEST_PROXY_SERVICES=1
256 if [[ -n "$ARVADOS_TEST_PROXY_SERVICES" ]]; then
257 unset ARVADOS_TEST_PROXY_SERVICES
259 && python sdk/python/tests/run_test_server.py stop_nginx \
260 && python sdk/python/tests/run_test_server.py stop_arv-git-httpd \
261 && python sdk/python/tests/run_test_server.py stop_keep_proxy
263 if [[ -n "$ARVADOS_TEST_API_HOST" ]]; then
264 unset ARVADOS_TEST_API_HOST
266 && python sdk/python/tests/run_test_server.py stop
271 failures+=("($(basename $0) interrupted)")
278 echo "WORKSPACE=$WORKSPACE"
280 if [[ -z "$CONFIGSRC" ]] && [[ -d "$HOME/arvados-api-server" ]]; then
281 # Jenkins expects us to use this by default.
282 CONFIGSRC="$HOME/arvados-api-server"
285 # Clean up .pyc files that may exist in the workspace
287 find -name '*.pyc' -delete
289 # Set up temporary install dirs (unless existing dirs were supplied)
290 for tmpdir in VENVDIR GOPATH GEMHOME
292 if [[ -n "${!tmpdir}" ]]; then
293 leave_temp[$tmpdir]=1
295 eval $tmpdir=$(mktemp -d)
299 setup_ruby_environment() {
300 if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
301 source "$HOME/.rvm/scripts/rvm"
303 elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
304 source "/usr/local/rvm/scripts/rvm"
310 if [[ "$using_rvm" == true ]]; then
311 # If rvm is in use, we can't just put separate "dependencies"
312 # and "gems-under-test" paths to GEM_PATH: passenger resets
313 # the environment to the "current gemset", which would lose
314 # our GEM_PATH and prevent our test suites from running ruby
315 # programs (for example, the Workbench test suite could not
316 # boot an API server or run arv). Instead, we have to make an
317 # rvm gemset and use it for everything.
319 [[ `type rvm | head -n1` == "rvm is a function" ]] \
322 # Put rvm's favorite path back in first place (overriding
323 # virtualenv, which just put itself there). Ignore rvm's
324 # complaint about not being in first place already.
325 rvm use @default 2>/dev/null
327 # Create (if needed) and switch to an @arvados-tests
328 # gemset. (Leave the choice of ruby to the caller.)
329 rvm use @arvados-tests --create \
330 || fatal 'rvm gemset setup'
334 # When our "bundle install"s need to install new gems to
335 # satisfy dependencies, we want them to go where "gem install
336 # --user-install" would put them. (However, if the caller has
337 # already set GEM_HOME, we assume that's where dependencies
338 # should be installed, and we should leave it alone.)
340 if [ -z "$GEM_HOME" ]; then
341 user_gempath="$(gem env gempath)"
342 export GEM_HOME="${user_gempath%%:*}"
344 PATH="$(gem env gemdir)/bin:$PATH"
346 # When we build and install our own gems, we install them in our
347 # $GEMHOME tmpdir, and we want them to be at the front of GEM_PATH and
348 # PATH so integration tests prefer them over other versions that
349 # happen to be installed in $user_gempath, system dirs, etc.
351 tmpdir_gem_home="$(env - PATH="$PATH" HOME="$GEMHOME" gem env gempath | cut -f1 -d:)"
352 PATH="$tmpdir_gem_home/bin:$PATH"
353 export GEM_PATH="$tmpdir_gem_home:$(gem env gempath)"
355 echo "Will install dependencies to $(gem env gemdir)"
356 echo "Will install arvados gems to $tmpdir_gem_home"
357 echo "Gem search path is GEM_PATH=$GEM_PATH"
362 if [[ "$using_rvm" == true ]]; then
365 GEM_HOME="$tmpdir_gem_home" "$@"
370 mkdir -p "$GOPATH/src/git.curoverse.com"
371 ln -sfn "$WORKSPACE" "$GOPATH/src/git.curoverse.com/arvados.git" \
372 || fatal "symlink failed"
374 virtualenv --setuptools "$VENVDIR" || fatal "virtualenv $VENVDIR failed"
375 . "$VENVDIR/bin/activate"
377 # Note: this must be the last time we change PATH, otherwise rvm will
379 setup_ruby_environment
383 if ! which bundler >/dev/null
385 gem install --user-install bundler || fatal 'Could not install bundler'
388 # Needed for run_test_server.py which is used by certain (non-Python) tests.
389 echo "pip install -q PyYAML"
390 pip install -q PyYAML || fatal "pip install PyYAML failed"
393 if [[ "$1" != "0" ]]; then
394 title "!!!!!! $2 FAILED !!!!!!"
395 failures+=("$2 (`timer`)")
397 successes+=("$2 (`timer`)")
406 echo -n "$(($SECONDS - $t0))s"
410 while ! do_test_once ${@} && [[ "$retry" == 1 ]]
412 read -p 'Try again? [Y/n] ' x
413 if [[ "$x" != "y" ]] && [[ "$x" != "" ]]
421 if [[ -z "${skip[$1]}" ]] && ( [[ -z "$only" ]] || [[ "$only" == "$1" ]] )
423 title "Running $1 tests"
425 if [[ "$2" == "go" ]]
427 go test ${testargs[$1]} "git.curoverse.com/arvados.git/$1"
428 elif [[ "$2" == "pip" ]]
431 && python setup.py test ${testargs[$1]}
432 elif [[ "$2" != "" ]]
439 checkexit $result "$1 tests"
440 title "End of $1 tests (`timer`)"
443 title "Skipping $1 tests"
448 if [[ -z "$skip_install" ]]
450 title "Running $1 install"
452 if [[ "$2" == "go" ]]
454 go get -t "git.curoverse.com/arvados.git/$1"
455 elif [[ "$2" == "pip" ]]
458 && python setup.py sdist rotate --keep=1 --match .tar.gz \
459 && pip install -q --upgrade dist/*.tar.gz
460 elif [[ "$2" != "" ]]
466 checkexit $? "$1 install"
467 title "End of $1 install (`timer`)"
469 title "Skipping $1 install"
474 txt="********** $1 **********"
475 printf "\n%*s%s\n\n" $((($COLUMNS-${#txt})/2)) "" "$txt"
478 bundle_install_trylocal() {
481 echo "(Running bundle install --local. 'could not find package' messages are OK.)"
482 if ! bundle install --local --no-deployment; then
483 echo "(Running bundle install again, without --local.)"
484 bundle install --no-deployment
491 cd "$WORKSPACE/doc" \
492 && bundle_install_trylocal \
498 with_test_gemset gem uninstall --force --all --executables arvados \
499 && cd "$WORKSPACE/sdk/ruby" \
500 && bundle_install_trylocal \
501 && gem build arvados.gemspec \
502 && with_test_gemset gem install --no-ri --no-rdoc `ls -t arvados-*.gem|head -n1`
504 do_install sdk/ruby ruby_sdk
507 with_test_gemset gem uninstall --force --all --executables arvados-cli \
508 && cd "$WORKSPACE/sdk/cli" \
509 && bundle_install_trylocal \
510 && gem build arvados-cli.gemspec \
511 && with_test_gemset gem install --no-ri --no-rdoc `ls -t arvados-cli-*.gem|head -n1`
513 do_install sdk/cli cli
515 # Install the Python SDK early. Various other test suites (like
516 # keepproxy) bring up run_test_server.py, which imports the arvados
517 # module. We can't actually *test* the Python SDK yet though, because
518 # its own test suite brings up some of those other programs (like
520 declare -a pythonstuff
526 for p in "${pythonstuff[@]}"
531 install_apiserver() {
532 cd "$WORKSPACE/services/api" \
533 && RAILS_ENV=test bundle_install_trylocal
535 rm -f config/environments/test.rb
536 cp config/environments/test.rb.example config/environments/test.rb
538 if [ -n "$CONFIGSRC" ]
540 for f in database.yml application.yml
542 cp "$CONFIGSRC/$f" config/ || fatal "$f"
546 # Fill in a random secret_token and blob_signing_key for testing
547 SECRET_TOKEN=`echo 'puts rand(2**512).to_s(36)' |ruby`
548 BLOB_SIGNING_KEY=`echo 'puts rand(2**512).to_s(36)' |ruby`
550 sed -i'' -e "s:SECRET_TOKEN:$SECRET_TOKEN:" config/application.yml
551 sed -i'' -e "s:BLOB_SIGNING_KEY:$BLOB_SIGNING_KEY:" config/application.yml
553 # Set up empty git repo (for git tests)
555 sed -i'' -e "s:/var/cache/git:$GITDIR:" config/application.default.yml
558 mkdir -p $GITDIR/test
561 && git config user.email "jenkins@ci.curoverse.com" \
562 && git config user.name "Jenkins, CI" \
565 && git commit -m 'initial commit'
567 # Clear out any lingering postgresql connections to the test
568 # database, so that we can drop it. This assumes the current user
569 # is a postgresql superuser.
570 test_database=$(python -c "import yaml; print yaml.load(file('config/database.yml'))['test']['database']")
571 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
573 cd "$WORKSPACE/services/api" \
574 && RAILS_ENV=test bundle exec rake db:drop \
575 && RAILS_ENV=test bundle exec rake db:setup \
576 && RAILS_ENV=test bundle exec rake db:fixtures:load
578 do_install services/api apiserver
582 services/arv-git-httpd
590 for g in "${gostuff[@]}"
595 install_workbench() {
596 cd "$WORKSPACE/apps/workbench" \
597 && mkdir -p tmp/cache \
598 && RAILS_ENV=test bundle_install_trylocal
600 do_install apps/workbench workbench
602 test_doclinkchecker() {
606 ARVADOS_API_HOST=qr1hi.arvadosapi.com
607 # Make sure python-epydoc is installed or the next line won't
609 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
612 do_test doc doclinkchecker
617 cd "$WORKSPACE/services/api" \
618 && RAILS_ENV=test bundle exec rake test TESTOPTS=-v ${testargs[services/api]}
620 do_test services/api apiserver
622 # Shortcut for when we're only running apiserver tests. This saves a bit of time,
623 # because we don't need to start up the api server for subsequent tests.
624 if [ ! -z "$only" ] && [ "$only" == "services/api" ]; then
625 rotate_logfile "$WORKSPACE/services/api/log/" "test.log"
632 cd "$WORKSPACE/sdk/ruby" \
633 && bundle exec rake test TESTOPTS=-v ${testargs[sdk/ruby]}
635 do_test sdk/ruby ruby_sdk
638 cd "$WORKSPACE/sdk/cli" \
639 && mkdir -p /tmp/keep \
640 && KEEP_LOCAL_STORE=/tmp/keep bundle exec rake test TESTOPTS=-v ${testargs[sdk/cli]}
644 for p in "${pythonstuff[@]}"
649 for g in "${gostuff[@]}"
655 start_nginx_proxy_services \
656 && cd "$WORKSPACE/apps/workbench" \
657 && RAILS_ENV=test bundle exec rake test TESTOPTS=-v ${testargs[apps/workbench]}
659 do_test apps/workbench workbench
661 test_workbench_benchmark() {
662 start_nginx_proxy_services \
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 start_nginx_proxy_services \
670 && cd "$WORKSPACE/apps/workbench" \
671 && RAILS_ENV=test bundle exec rake test:profile ${testargs[apps/workbench_profile]}
673 do_test apps/workbench_profile workbench_profile