2881: Skip Node Manager tests for now.
[arvados.git] / jenkins / run-tests.sh
1 #!/bin/bash
2
3 read -rd "\000" helpmessage <<EOF
4 $(basename $0): Install and test Arvados components.
5
6 Exit non-zero if any tests fail.
7
8 Syntax:
9         $(basename $0) WORKSPACE=/path/to/arvados [options]
10
11 Options:
12
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 apiserver_test="TEST=test/functional/arvados/v1/collections_test.rb"
25                Restrict apiserver tests to the given file
26 python_sdk_test="--test-suite test.test_keep_locator"
27                Restrict Python SDK tests to the given class
28 workbench_test="TEST=test/integration/pipeline_instances_test.rb"
29                Restrict Workbench tests to the given file
30 ARVADOS_DEBUG=1
31                Print more debug messages
32 envvar=value   Set \$envvar to value. Primarily useful for WORKSPACE,
33                *_test, and other examples shown above.
34
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.
39
40 As a special concession to the current CI server config, CONFIGSRC
41 defaults to $HOME/arvados-api-server if that directory exists.
42
43 More information and background:
44
45 https://arvados.org/projects/arvados/wiki/Running_tests
46 EOF
47
48 # First make sure to remove any ARVADOS_ variables from the calling
49 # environment that could interfere with the tests.
50 unset $(env | cut -d= -f1 | grep \^ARVADOS_)
51
52 # Reset other variables that could affect our [tests'] behavior by
53 # accident.
54 GITDIR=
55 GOPATH=
56 VENVDIR=
57 PYTHONPATH=
58 GEMHOME=
59
60 COLUMNS=80
61
62 cli_test=
63 workbench_test=
64 apiserver_test=
65 python_sdk_test=
66 ruby_sdk_test=
67 fuse_test=
68 leave_temp=
69 skip_install=
70
71 if [[ -f /etc/profile.d/rvm.sh ]]
72 then
73     source /etc/profile.d/rvm.sh
74 fi
75
76 declare -A leave_temp
77 clear_temp() {
78     leaving=""
79     for var in VENVDIR GOPATH GITDIR GEMHOME
80     do
81         if [[ -z "${leave_temp[$var]}" ]]
82         then
83             if [[ -n "${!var}" ]]
84             then
85                 rm -rf "${!var}"
86             fi
87         else
88             leaving+=" $var=\"${!var}\""
89         fi
90     done
91     if [[ -n "$leaving" ]]; then
92         echo "Leaving behind temp dirs: $leaving"
93     fi
94 }
95
96 fatal() {
97     clear_temp
98     echo >&2 "Fatal: $* in ${FUNCNAME[1]} at ${BASH_SOURCE[1]} line ${BASH_LINENO[0]}"
99     exit 1
100 }
101
102 report_outcomes() {
103     for x in "${successes[@]}"
104     do
105         echo "Pass: $x"
106     done
107
108     if [[ ${#failures[@]} == 0 ]]
109     then
110         echo "All test suites passed."
111     else
112         echo "Failures (${#failures[@]}):"
113         for x in "${failures[@]}"
114         do
115             echo "Fail: $x"
116         done
117     fi
118 }
119 declare -a failures
120 declare -A skip
121
122 # Always skip CLI tests. They don't know how to use run_test_server.py.
123 skip[cli]=1
124
125 # Skip Node Manager tests.  Because these tests are multithreaded, their
126 # performance is a little unpredictable, and Jenkins regularly has trouble
127 # with them.  Brett has a plan for making them more robust, but it's going
128 # to take a little time to implement.  -2014-10-10
129 skip[nodemanager]=1
130
131 while [[ -n "$1" ]]
132 do
133     arg="$1"; shift
134     case "$arg" in
135         --help)
136             echo >&2 "$helpmessage"
137             echo >&2
138             exit 1
139             ;;
140         --skip)
141             skipwhat="$1"; shift
142             skip[$skipwhat]=1
143             ;;
144         --only)
145             only="$1"; shift
146             ;;
147         --skip-install)
148             skip_install=1
149             ;;
150         --leave-temp)
151             leave_temp[VENVDIR]=1
152             leave_temp[GOPATH]=1
153             leave_temp[GEMHOME]=1
154             ;;
155         *=*)
156             eval $(echo $arg | cut -d= -f1)=\"$(echo $arg | cut -d= -f2-)\"
157             ;;
158         *)
159             echo >&2 "$0: Unrecognized option: '$arg'. Try: $0 --help"
160             exit 1
161             ;;
162     esac
163 done
164
165 # Sanity check
166 echo "WORKSPACE=$WORKSPACE"
167 [[ -n "$WORKSPACE" ]] || fatal "WORKSPACE not set"
168
169 if [[ -z "$CONFIGSRC" ]] && [[ -d "$HOME/arvados-api-server" ]]; then
170     # Jenkins expects us to use this by default.
171     CONFIGSRC="$HOME/arvados-api-server"
172 fi
173
174 # Set up temporary install dirs (unless existing dirs were supplied)
175 for tmpdir in VENVDIR GOPATH GEMHOME
176 do
177     if [[ -n "${!tmpdir}" ]]; then
178         leave_temp[$tmpdir]=1
179     else
180         eval $tmpdir=$(mktemp -d)
181     fi
182 done
183 PATH="$GEMHOME/.gem/ruby/2.1.0/bin:$PATH"
184 export GOPATH
185 mkdir -p "$GOPATH/src/git.curoverse.com"
186 ln -sfn "$WORKSPACE" "$GOPATH/src/git.curoverse.com/arvados.git" \
187     || fatal "symlink failed"
188
189 virtualenv --setuptools "$VENVDIR" || fatal "virtualenv $VENVDIR failed"
190 . "$VENVDIR/bin/activate"
191
192 checkexit() {
193     if [[ "$?" != "0" ]]; then
194         title "!!!!!! $1 FAILED !!!!!!"
195         failures+=("$1 (`timer`)")
196     else
197         successes+=("$1 (`timer`)")
198     fi
199 }
200
201 timer_reset() {
202     t0=$SECONDS
203 }
204
205 timer() {
206     echo -n "$(($SECONDS - $t0))s"
207 }
208
209 do_test() {
210     if [[ -z "${skip[$1]}" ]] && ( [[ -z "$only" ]] || [[ "$only" == "$1" ]] )
211     then
212         title "Running $1 tests"
213         timer_reset
214         if [[ "$2" == "go" ]]
215         then
216             go test "git.curoverse.com/arvados.git/$1"
217         else
218             "test_$1"
219         fi
220         checkexit "$1 tests"
221         title "End of $1 tests (`timer`)"
222     else
223         title "Skipping $1 tests"
224     fi
225 }
226
227 do_install() {
228     if [[ -z "$skip_install" ]]
229     then
230         title "Running $1 install"
231         timer_reset
232         if [[ "$2" == "go" ]]
233         then
234             go get -t "git.curoverse.com/arvados.git/$1"
235         else
236             "install_$1"
237         fi
238         checkexit "$1 install"
239         title "End of $1 install (`timer`)"
240     else
241         title "Skipping $1 install"
242     fi
243 }
244
245 title () {
246     txt="********** $1 **********"
247     printf "\n%*s%s\n\n" $((($COLUMNS-${#txt})/2)) "" "$txt"
248 }
249
250 install_docs() {
251     cd "$WORKSPACE/doc"
252     HOME="$GEMHOME" bundle install --no-deployment
253     rm -rf .site
254     # Make sure python-epydoc is installed or the next line won't do much good!
255     ARVADOS_API_HOST=qr1hi.arvadosapi.com
256     PYTHONPATH=$WORKSPACE/sdk/python/ HOME="$GEMHOME" bundle exec rake generate baseurl=file://$WORKSPACE/doc/.site/ arvados_workbench_host=workbench.$ARVADOS_API_HOST arvados_api_host=$ARVADOS_API_HOST
257     unset ARVADOS_API_HOST
258 }
259 do_install docs
260
261 install_ruby_sdk() {
262     cd "$WORKSPACE/sdk/ruby" \
263         && HOME="$GEMHOME" bundle install --no-deployment \
264         && gem build arvados.gemspec \
265         && HOME="$GEMHOME" gem install --user-install --no-ri --no-rdoc `ls -t arvados-*.gem|head -n1`
266 }
267 do_install ruby_sdk
268
269 install_cli() {
270     cd "$WORKSPACE/sdk/cli" \
271         && gem build arvados-cli.gemspec \
272         && HOME="$GEMHOME" gem install --user-install --no-ri --no-rdoc `ls -t arvados-cli-*.gem|head -n1`
273 }
274 do_install cli
275
276 install_python_sdk() {
277     # Install the Python SDK early. Various other test suites (like
278     # keepproxy) bring up run_test_server.py, which imports the arvados
279     # module. We can't actually *test* the Python SDK yet though, because
280     # its own test suite brings up some of those other programs (like
281     # keepproxy).
282
283     cd "$WORKSPACE/sdk/python" \
284         && python setup.py sdist rotate --keep=1 --match .tar.gz \
285         && pip install dist/arvados-python-client-0.1.*.tar.gz
286 }
287 do_install python_sdk
288
289 install_fuse() {
290     cd "$WORKSPACE/services/fuse" \
291         && python setup.py sdist rotate --keep=1 --match .tar.gz \
292         && pip install dist/arvados_fuse-0.1.*.tar.gz
293 }
294 do_install fuse
295
296 install_apiserver() {
297     cd "$WORKSPACE/services/api"
298     export RAILS_ENV=test
299     HOME="$GEMHOME" bundle install --no-deployment
300
301     rm -f config/environments/test.rb
302     cp config/environments/test.rb.example config/environments/test.rb
303
304     if [ -n "$CONFIGSRC" ]
305     then
306         for f in database.yml application.yml
307         do
308             cp "$CONFIGSRC/$f" config/ || fatal "$f"
309         done
310     fi
311
312     # Fill in a random secret_token and blob_signing_key for testing
313     SECRET_TOKEN=`echo 'puts rand(2**512).to_s(36)' |ruby`
314     BLOB_SIGNING_KEY=`echo 'puts rand(2**512).to_s(36)' |ruby`
315
316     sed -i'' -e "s:SECRET_TOKEN:$SECRET_TOKEN:" config/application.yml
317     sed -i'' -e "s:BLOB_SIGNING_KEY:$BLOB_SIGNING_KEY:" config/application.yml
318
319     # Set up empty git repo (for git tests)
320     GITDIR=$(mktemp -d)
321     sed -i'' -e "s:/var/cache/git:$GITDIR:" config/application.default.yml
322
323     rm -rf $GITDIR
324     mkdir -p $GITDIR/test
325     cd $GITDIR/test \
326         && git init \
327         && git config user.email "jenkins@ci.curoverse.com" \
328         && git config user.name "Jenkins, CI" \
329         && touch tmp \
330         && git add tmp \
331         && git commit -m 'initial commit'
332
333     # Clear out any lingering postgresql connections to arvados_test, so that we can drop it
334     # This assumes the current user is a postgresql superuser
335     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
336
337     cd "$WORKSPACE/services/api" \
338         && HOME="$GEMHOME" bundle exec rake db:drop \
339         && HOME="$GEMHOME" bundle exec rake db:create \
340         && HOME="$GEMHOME" bundle exec rake db:setup
341 }
342 do_install apiserver
343
344 declare -a gostuff
345 gostuff=(
346     services/keepstore
347     services/keepproxy
348     sdk/go/arvadosclient
349     sdk/go/keepclient
350     sdk/go/streamer
351     )
352 for g in "${gostuff[@]}"
353 do
354     do_install "$g" go
355 done
356
357 test_doclinkchecker() {
358     cd "$WORKSPACE/doc"
359     HOME="$GEMHOME" bundle exec rake linkchecker baseurl=file://$WORKSPACE/doc/.site/
360 }
361 do_test doclinkchecker
362
363 test_ruby_sdk() {
364     cd "$WORKSPACE/sdk/ruby" \
365         && HOME="$GEMHOME" bundle install --no-deployment \
366         && HOME="$GEMHOME" bundle exec rake test
367 }
368 do_test ruby_sdk
369
370 test_cli() {
371     title "Starting SDK CLI tests"
372     cd "$WORKSPACE/sdk/cli" \
373         && HOME="$GEMHOME" bundle install --no-deployment \
374         && mkdir -p /tmp/keep \
375         && KEEP_LOCAL_STORE=/tmp/keep HOME="$GEMHOME" bundle exec rake test $cli_test
376 }
377 do_test cli
378
379 test_apiserver() {
380     cd "$WORKSPACE/services/api"
381     HOME="$GEMHOME" bundle exec rake test $apiserver_test
382 }
383 do_test apiserver
384
385 test_python_sdk() {
386     # Python SDK. We test this before testing keepproxy: keepproxy runs
387     # run_test_server.py, which depends on the yaml package, which is in
388     # tests_require but not install_requires, and therefore does not get
389     # installed by setuptools until we run "setup.py test" *and* install
390     # the .egg files that setup.py downloads.
391
392     cd "$WORKSPACE/sdk/python" \
393         && python setup.py test $python_sdk_test
394     r=$?
395     easy_install *.egg
396     return $r
397 }
398 do_test python_sdk
399
400 test_fuse() {
401     # Install test dependencies here too, in case run_test_server needs them.
402     cd "$WORKSPACE/services/fuse" \
403         && python setup.py test $fuse_test
404     r=$?
405     easy_install *.egg
406     return $r
407 }
408 do_test fuse
409
410 test_nodemanager() {
411     cd "$WORKSPACE/services/nodemanager" && python setup.py test
412 }
413 do_test nodemanager
414
415 for g in "${gostuff[@]}"
416 do
417     do_test "$g" go
418 done
419
420 test_workbench() {
421     cd "$WORKSPACE/apps/workbench" \
422         && HOME="$GEMHOME" bundle install --no-deployment \
423         && HOME="$GEMHOME" bundle exec rake test $workbench_test
424 }
425 do_test workbench
426
427 report_outcomes
428 clear_temp
429
430 exit ${#failures}