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