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
31 services/arv-git-httpd_test="-check.vv"
32 Show all log messages, even when tests pass (also works
33 with services/keepstore_test etc.)
35 Print more debug messages
36 envvar=value Set \$envvar to value. Primarily useful for WORKSPACE,
37 *_test, and other examples shown above.
39 Assuming --skip-install is not given, all components are installed
40 into \$GOPATH, \$VENDIR, and \$GEMHOME before running any tests. Many
41 test suites depend on other components being installed, and installing
42 everything tends to be quicker than debugging dependencies.
44 As a special concession to the current CI server config, CONFIGSRC
45 defaults to $HOME/arvados-api-server if that directory exists.
47 More information and background:
49 https://arvados.org/projects/arvados/wiki/Running_tests
54 apps/workbench_benchmark
55 apps/workbench_profile
59 services/dockercleaner
64 services/arv-git-httpd
74 # First make sure to remove any ARVADOS_ variables from the calling
75 # environment that could interfere with the tests.
76 unset $(env | cut -d= -f1 | grep \^ARVADOS_)
78 # Reset other variables that could affect our [tests'] behavior by
95 for var in VENVDIR VENV3DIR GOPATH GITDIR GEMHOME
97 if [[ -z "${leave_temp[$var]}" ]]
104 leaving+=" $var=\"${!var}\""
107 if [[ -n "$leaving" ]]; then
108 echo "Leaving behind temp dirs: $leaving"
114 echo >&2 "Fatal: $* in ${FUNCNAME[1]} at ${BASH_SOURCE[1]} line ${BASH_LINENO[0]}"
119 for x in "${successes[@]}"
124 if [[ ${#failures[@]} == 0 ]]
126 echo "All test suites passed."
128 echo "Failures (${#failures[@]}):"
129 for x in "${failures[@]}"
138 rotate_logfile "$WORKSPACE/apps/workbench/log/" "test.log"
140 rotate_logfile "$WORKSPACE/services/api/log/" "test.log"
147 # Make sure WORKSPACE is set
148 if ! [[ -n "$WORKSPACE" ]]; then
149 echo >&2 "$helpmessage"
151 echo >&2 "Error: WORKSPACE environment variable not set"
156 # Make sure virtualenv is installed
157 `virtualenv --help >/dev/null 2>&1`
159 if [[ "$?" != "0" ]]; then
161 echo >&2 "Error: virtualenv could not be found"
166 # Make sure go is installed
167 `go env >/dev/null 2>&1`
169 if [[ "$?" != "0" ]]; then
171 echo >&2 "Error: go could not be found"
176 # Make sure gcc is installed
177 `gcc --help >/dev/null 2>&1`
179 if [[ "$?" != "0" ]]; then
181 echo >&2 "Error: gcc could not be found"
188 # $BUILD_NUMBER is set by Jenkins if this script is being called as part of a Jenkins run
189 if [[ -f "$1/$2" ]]; then
190 THEDATE=`date +%Y%m%d%H%M%S`
191 mv "$1/$2" "$1/$THEDATE-$BUILD_NUMBER-$2"
192 gzip "$1/$THEDATE-$BUILD_NUMBER-$2"
199 skip[apps/workbench_profile]=1
206 echo >&2 "$helpmessage"
215 only="$1"; skip[$1]=""; shift
222 only_install="$1"; shift
225 leave_temp[VENVDIR]=1
226 leave_temp[VENV3DIR]=1
228 leave_temp[GEMHOME]=1
234 suite="${arg%%_test=*}"
236 testargs["$suite"]="$args"
239 eval export $(echo $arg | cut -d= -f1)=\"$(echo $arg | cut -d= -f2-)\"
242 echo >&2 "$0: Unrecognized option: '$arg'. Try: $0 --help"
249 echo 'Starting API server...'
251 && eval $(python sdk/python/tests/run_test_server.py start --auth admin) \
252 && export ARVADOS_TEST_API_HOST="$ARVADOS_API_HOST" \
253 && export ARVADOS_TEST_API_INSTALLED="$$" \
254 && (env | egrep ^ARVADOS)
257 start_nginx_proxy_services() {
258 echo 'Starting keepproxy, arv-git-httpd, and nginx ssl proxy...'
260 && python sdk/python/tests/run_test_server.py start_keep_proxy \
261 && python sdk/python/tests/run_test_server.py start_arv-git-httpd \
262 && python sdk/python/tests/run_test_server.py start_nginx \
263 && export ARVADOS_TEST_PROXY_SERVICES=1
267 if [[ -n "$ARVADOS_TEST_PROXY_SERVICES" ]]; then
268 unset ARVADOS_TEST_PROXY_SERVICES
270 && python sdk/python/tests/run_test_server.py stop_nginx \
271 && python sdk/python/tests/run_test_server.py stop_arv-git-httpd \
272 && python sdk/python/tests/run_test_server.py stop_keep_proxy
274 if [[ -n "$ARVADOS_TEST_API_HOST" ]]; then
275 unset ARVADOS_TEST_API_HOST
277 && python sdk/python/tests/run_test_server.py stop
282 failures+=("($(basename $0) interrupted)")
289 echo "WORKSPACE=$WORKSPACE"
291 if [[ -z "$CONFIGSRC" ]] && [[ -d "$HOME/arvados-api-server" ]]; then
292 # Jenkins expects us to use this by default.
293 CONFIGSRC="$HOME/arvados-api-server"
296 # Clean up .pyc files that may exist in the workspace
298 find -name '*.pyc' -delete
300 # Set up temporary install dirs (unless existing dirs were supplied)
301 for tmpdir in VENVDIR VENV3DIR GOPATH GEMHOME
303 if [[ -n "${!tmpdir}" ]]; then
304 leave_temp[$tmpdir]=1
306 eval $tmpdir=$(mktemp -d)
310 setup_ruby_environment() {
311 if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
312 source "$HOME/.rvm/scripts/rvm"
314 elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
315 source "/usr/local/rvm/scripts/rvm"
321 if [[ "$using_rvm" == true ]]; then
322 # If rvm is in use, we can't just put separate "dependencies"
323 # and "gems-under-test" paths to GEM_PATH: passenger resets
324 # the environment to the "current gemset", which would lose
325 # our GEM_PATH and prevent our test suites from running ruby
326 # programs (for example, the Workbench test suite could not
327 # boot an API server or run arv). Instead, we have to make an
328 # rvm gemset and use it for everything.
330 [[ `type rvm | head -n1` == "rvm is a function" ]] \
333 # Put rvm's favorite path back in first place (overriding
334 # virtualenv, which just put itself there). Ignore rvm's
335 # complaint about not being in first place already.
336 rvm use @default 2>/dev/null
338 # Create (if needed) and switch to an @arvados-tests
339 # gemset. (Leave the choice of ruby to the caller.)
340 rvm use @arvados-tests --create \
341 || fatal 'rvm gemset setup'
345 # When our "bundle install"s need to install new gems to
346 # satisfy dependencies, we want them to go where "gem install
347 # --user-install" would put them. (However, if the caller has
348 # already set GEM_HOME, we assume that's where dependencies
349 # should be installed, and we should leave it alone.)
351 if [ -z "$GEM_HOME" ]; then
352 user_gempath="$(gem env gempath)"
353 export GEM_HOME="${user_gempath%%:*}"
355 PATH="$(gem env gemdir)/bin:$PATH"
357 # When we build and install our own gems, we install them in our
358 # $GEMHOME tmpdir, and we want them to be at the front of GEM_PATH and
359 # PATH so integration tests prefer them over other versions that
360 # happen to be installed in $user_gempath, system dirs, etc.
362 tmpdir_gem_home="$(env - PATH="$PATH" HOME="$GEMHOME" gem env gempath | cut -f1 -d:)"
363 PATH="$tmpdir_gem_home/bin:$PATH"
364 export GEM_PATH="$tmpdir_gem_home:$(gem env gempath)"
366 echo "Will install dependencies to $(gem env gemdir)"
367 echo "Will install arvados gems to $tmpdir_gem_home"
368 echo "Gem search path is GEM_PATH=$GEM_PATH"
373 if [[ "$using_rvm" == true ]]; then
376 GEM_HOME="$tmpdir_gem_home" "$@"
381 mkdir -p "$GOPATH/src/git.curoverse.com"
382 ln -sfn "$WORKSPACE" "$GOPATH/src/git.curoverse.com/arvados.git" \
383 || fatal "symlink failed"
385 virtualenv --setuptools "$VENVDIR" || fatal "virtualenv $VENVDIR failed"
386 . "$VENVDIR/bin/activate"
388 # When re-using $VENVDIR, upgrade any packages (except arvados) that are
390 pip install --quiet --upgrade `pip freeze | grep -v arvados | cut -f1 -d=`
392 # Note: this must be the last time we change PATH, otherwise rvm will
394 setup_ruby_environment
398 if ! which bundler >/dev/null
400 gem install --user-install bundler || fatal 'Could not install bundler'
403 # Needed for run_test_server.py which is used by certain (non-Python) tests.
404 echo "pip install -q PyYAML"
405 pip install --quiet PyYAML || fatal "pip install PyYAML failed"
407 # If Python 3 is available, set up its virtualenv in $VENV3DIR.
408 # Otherwise, skip dependent tests.
409 PYTHON3=$(which python3)
410 if [ "0" = "$?" ]; then
411 virtualenv --python "$PYTHON3" --setuptools "$VENV3DIR" \
412 || fatal "python3 virtualenv $VENV3DIR failed"
415 skip[services/dockercleaner]=1
418 Warning: python3 could not be found
419 services/dockercleaner install and tests will be skipped
425 if [[ "$1" != "0" ]]; then
426 title "!!!!!! $2 FAILED !!!!!!"
427 failures+=("$2 (`timer`)")
429 successes+=("$2 (`timer`)")
438 echo -n "$(($SECONDS - $t0))s"
442 while ! do_test_once ${@} && [[ "$retry" == 1 ]]
444 read -p 'Try again? [Y/n] ' x
445 if [[ "$x" != "y" ]] && [[ "$x" != "" ]]
453 if [[ -z "${skip[$1]}" ]] && ( [[ -z "$only" ]] || [[ "$only" == "$1" ]] )
455 title "Running $1 tests"
457 if [[ "$2" == "go" ]]
459 if [[ -n "${testargs[$1]}" ]]
461 # "go test -check.vv giturl" doesn't work, but this
463 cd "$WORKSPACE/$1" && go test ${testargs[$1]}
465 # The above form gets verbose even when testargs is
466 # empty, so use this form in such cases:
467 go test "git.curoverse.com/arvados.git/$1"
469 elif [[ "$2" == "pip" ]]
471 # $3 can name a path directory for us to use, including trailing
472 # slash; e.g., the bin/ subdirectory of a virtualenv.
474 && "${3}python" setup.py test ${testargs[$1]}
475 elif [[ "$2" != "" ]]
482 checkexit $result "$1 tests"
483 title "End of $1 tests (`timer`)"
486 title "Skipping $1 tests"
491 if [[ -z "$skip_install" || (-n "$only_install" && "$only_install" == "$1") ]]
493 title "Running $1 install"
495 if [[ "$2" == "go" ]]
497 go get -t "git.curoverse.com/arvados.git/$1"
498 elif [[ "$2" == "pip" ]]
500 # $3 can name a path directory for us to use, including trailing
501 # slash; e.g., the bin/ subdirectory of a virtualenv.
503 # Need to change to a different directory after creating
504 # the source dist package to avoid a pip bug.
505 # see https://arvados.org/issues/5766 for details.
507 # Also need to install twice, because if it belives the package is
508 # already installed, pip it won't install it. So the first "pip
509 # install" ensures that the dependencies are met, the second "pip
510 # install" ensures that we've actually install the local package
513 && "${3}python" setup.py sdist rotate --keep=1 --match .tar.gz \
515 && "${3}pip" install --quiet "$WORKSPACE/$1/dist"/*.tar.gz \
516 && "${3}pip" install --quiet --no-deps --ignore-installed "$WORKSPACE/$1/dist"/*.tar.gz
517 elif [[ "$2" != "" ]]
523 checkexit $? "$1 install"
524 title "End of $1 install (`timer`)"
526 title "Skipping $1 install"
531 txt="********** $1 **********"
532 printf "\n%*s%s\n\n" $((($COLUMNS-${#txt})/2)) "" "$txt"
535 bundle_install_trylocal() {
538 echo "(Running bundle install --local. 'could not find package' messages are OK.)"
539 if ! bundle install --local --no-deployment; then
540 echo "(Running bundle install again, without --local.)"
541 bundle install --no-deployment
548 cd "$WORKSPACE/doc" \
549 && bundle_install_trylocal \
555 with_test_gemset gem uninstall --force --all --executables arvados \
556 && cd "$WORKSPACE/sdk/ruby" \
557 && bundle_install_trylocal \
558 && gem build arvados.gemspec \
559 && with_test_gemset gem install --no-ri --no-rdoc `ls -t arvados-*.gem|head -n1`
561 do_install sdk/ruby ruby_sdk
564 with_test_gemset gem uninstall --force --all --executables arvados-cli \
565 && cd "$WORKSPACE/sdk/cli" \
566 && bundle_install_trylocal \
567 && gem build arvados-cli.gemspec \
568 && with_test_gemset gem install --no-ri --no-rdoc `ls -t arvados-cli-*.gem|head -n1`
570 do_install sdk/cli cli
572 # Install the Python SDK early. Various other test suites (like
573 # keepproxy) bring up run_test_server.py, which imports the arvados
574 # module. We can't actually *test* the Python SDK yet though, because
575 # its own test suite brings up some of those other programs (like
577 declare -a pythonstuff
583 for p in "${pythonstuff[@]}"
587 if [ -n "$PYTHON3" ]; then
588 do_install services/dockercleaner pip "$VENV3DIR/bin/"
591 install_apiserver() {
592 cd "$WORKSPACE/services/api" \
593 && RAILS_ENV=test bundle_install_trylocal
595 rm -f config/environments/test.rb
596 cp config/environments/test.rb.example config/environments/test.rb
598 if [ -n "$CONFIGSRC" ]
600 for f in database.yml application.yml
602 cp "$CONFIGSRC/$f" config/ || fatal "$f"
606 # Fill in a random secret_token and blob_signing_key for testing
607 SECRET_TOKEN=`echo 'puts rand(2**512).to_s(36)' |ruby`
608 BLOB_SIGNING_KEY=`echo 'puts rand(2**512).to_s(36)' |ruby`
610 sed -i'' -e "s:SECRET_TOKEN:$SECRET_TOKEN:" config/application.yml
611 sed -i'' -e "s:BLOB_SIGNING_KEY:$BLOB_SIGNING_KEY:" config/application.yml
613 # Set up empty git repo (for git tests)
615 sed -i'' -e "s:/var/cache/git:$GITDIR:" config/application.default.yml
618 mkdir -p $GITDIR/test
621 && git config user.email "jenkins@ci.curoverse.com" \
622 && git config user.name "Jenkins, CI" \
625 && git commit -m 'initial commit'
627 # Clear out any lingering postgresql connections to the test
628 # database, so that we can drop it. This assumes the current user
629 # is a postgresql superuser.
630 test_database=$(python -c "import yaml; print yaml.load(file('config/database.yml'))['test']['database']")
631 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
633 cd "$WORKSPACE/services/api" \
634 && RAILS_ENV=test bundle exec rake db:drop \
635 && RAILS_ENV=test bundle exec rake db:setup \
636 && RAILS_ENV=test bundle exec rake db:fixtures:load
638 do_install services/api apiserver
642 services/arv-git-httpd
650 for g in "${gostuff[@]}"
655 install_workbench() {
656 cd "$WORKSPACE/apps/workbench" \
657 && mkdir -p tmp/cache \
658 && RAILS_ENV=test bundle_install_trylocal
660 do_install apps/workbench workbench
662 test_doclinkchecker() {
666 ARVADOS_API_HOST=qr1hi.arvadosapi.com
667 # Make sure python-epydoc is installed or the next line won't
669 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
672 do_test doc doclinkchecker
677 cd "$WORKSPACE/services/api" \
678 && RAILS_ENV=test bundle exec rake test TESTOPTS=-v ${testargs[services/api]}
680 do_test services/api apiserver
682 # Shortcut for when we're only running apiserver tests. This saves a bit of time,
683 # because we don't need to start up the api server for subsequent tests.
684 if [ ! -z "$only" ] && [ "$only" == "services/api" ]; then
685 rotate_logfile "$WORKSPACE/services/api/log/" "test.log"
692 cd "$WORKSPACE/sdk/ruby" \
693 && bundle exec rake test TESTOPTS=-v ${testargs[sdk/ruby]}
695 do_test sdk/ruby ruby_sdk
698 cd "$WORKSPACE/sdk/cli" \
699 && mkdir -p /tmp/keep \
700 && KEEP_LOCAL_STORE=/tmp/keep bundle exec rake test TESTOPTS=-v ${testargs[sdk/cli]}
704 for p in "${pythonstuff[@]}"
708 do_test services/dockercleaner pip "$VENV3DIR/bin/"
710 for g in "${gostuff[@]}"
716 start_nginx_proxy_services \
717 && cd "$WORKSPACE/apps/workbench" \
718 && RAILS_ENV=test bundle exec rake test TESTOPTS=-v ${testargs[apps/workbench]}
720 do_test apps/workbench workbench
722 test_workbench_benchmark() {
723 start_nginx_proxy_services \
724 && cd "$WORKSPACE/apps/workbench" \
725 && RAILS_ENV=test bundle exec rake test:benchmark ${testargs[apps/workbench_benchmark]}
727 do_test apps/workbench_benchmark workbench_benchmark
729 test_workbench_profile() {
730 start_nginx_proxy_services \
731 && cd "$WORKSPACE/apps/workbench" \
732 && RAILS_ENV=test bundle exec rake test:profile ${testargs[apps/workbench_profile]}
734 do_test apps/workbench_profile workbench_profile