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