Upstream version 8.36.161.0
[platform/framework/web/crosswalk.git] / src / third_party / chromite / buildbot / run_tests
1 #!/bin/bash
2
3 # Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 CHROMITE_PATH=$(realpath "$(dirname "$0")/..")
8 IN_CHROOT="cros_sdk"
9 TIMEOUT="timeout -k 5m 20m"
10 CHROOT_CHROMITE=../../chromite
11
12 set -eu
13
14 # List all exceptions, with a token describing what's odd here.
15 # inside - inside the chroot
16 # skip - don't run this test (please comment on why)
17 declare -A special_tests
18 special_tests=(
19   # Tests that need to run inside the chroot.
20   ['cros/commands/cros_build_unittest.py']=inside
21   ['lib/upgrade_table_unittest.py']=inside
22   ['scripts/cros_mark_as_stable_unittest.py']=inside
23   ['scripts/cros_mark_chrome_as_stable_unittest.py']=inside
24   ['scripts/sync_package_status_unittest.py']=inside
25   ['scripts/cros_portage_upgrade_unittest.py']=inside
26   ['scripts/upload_package_status_unittest.py']=inside
27
28   # Tests that need to run outside the chroot.
29   ['lib/cgroups_unittest.py']=outside
30
31   # Tests that are presently broken.
32   ['lib/gdata_lib_unittest.py']=skip
33   ['scripts/chrome_set_ver_unittest.py']=skip
34   ['scripts/check_gdata_token_unittest.py']=skip
35   ['scripts/merge_package_status_unittest.py']=skip
36   ['scripts/upload_package_status_unittest.py']=skip
37   # TODO(akeshet): skip only test004GetLatestSHA1ForBranch
38   # crbug.com/352297
39   ['lib/gerrit_unittest.py']=skip
40
41   # Tests that take >2 minutes to run.  All the slow tests are
42   # disabled atm though ...
43   #['scripts/cros_portage_upgrade_unittest.py']=skip
44 )
45
46 skip_quick_tests() {
47   # Tests that require network can be really slow.
48   special_tests['buildbot/manifest_version_unittest.py']=skip
49   special_tests['buildbot/repository_unittest.py']=skip
50   special_tests['buildbot/remote_try_unittest.py']=skip
51   special_tests['lib/cros_build_lib_unittest.py']=skip
52   special_tests['lib/gerrit_unittest.py']=skip
53   special_tests['lib/patch_unittest.py']=skip
54
55   # cgroups_unittest runs cros_sdk a lot, so is slow.
56   special_tests['lib/cgroups_unittest.py']=skip
57 }
58
59 # Helper function to add failed logs/tests to be printed out later.
60 # $1 test that failed.
61 # $2 log file where we stored the output of the failed test.
62 append_failed_test() {
63   echo "ERROR: Unittest $1 failed.  Log will be output at end of run!!!"
64
65   cat - "$2" <<EOF >>"${LOGFILE}.err.${BASHPID}"
66
67 FAIL: Unittest $1 failed output:
68
69 EOF
70 }
71
72 # Wrapper to run unittest.  Hides output unless test fails.
73 # $1 test to run.  Must be in chromite/buildbot.
74 # $2 Is this a dry run?
75 run_test() {
76   local test=$1 dryrun=$2
77   local log_file="${LOGFILE}.tmp.${BASHPID}"
78   local special="${special_tests[${test}]:-}"
79   local starttime="$(date +%s%N)"
80
81   if [[ "${special}" == "skip" ]]; then
82     echo "Skipping unittest ${test}"
83     return
84   elif [[ "${special}" == "outside" && -f /etc/cros_chroot_version ]]; then
85     echo "Skipping unittest ${test} because it must run outside the chroot"
86     return
87   elif [[ "${special}" == "inside" && ! -f /etc/cros_chroot_version ]]; then
88     if ${SKIP_CHROOT_TESTS}; then
89       echo "Skipping unittest ${test} because it must run inside the chroot"
90       return
91     else
92       echo "Starting unittest ${test} inside the chroot"
93       if ! ${dryrun}; then
94         ${TIMEOUT} ${IN_CHROOT} python "${CHROOT_CHROMITE}/${test}" \
95           &> "${log_file}" || append_failed_test "${test}" "${log_file}"
96       fi
97     fi
98   else
99     echo "Starting unittest ${test}"
100     if ! ${dryrun}; then
101       ${TIMEOUT} python "${CHROMITE_PATH}/${test}" &> "${log_file}" ||
102         append_failed_test "${test}" "${log_file}"
103     fi
104   fi
105
106   if ! ${dryrun}; then
107     local endtime="$(date +%s%N)"
108     local duration=$(( (endtime - starttime) / 1000000 ))
109
110     echo "Finished unittest ${test} (${duration} ms)"
111   fi
112   rm -f "${log_file}"
113 }
114
115 cleanup() {
116   delayed_kill() {
117     sleep 5
118     kill -9 ${children[*]} &> /dev/null
119   }
120
121   echo "Cleaning up backgrounded jobs."
122   # Graceful exit.
123   kill -INT ${children[*]} &> /dev/null
124   # Set of a hard kill timer after a while.
125   delayed_kill &
126   wait ${children[*]}
127   show_logs
128 }
129
130 show_logs() {
131   cat "${LOGFILE}".err.* > "${LOGFILE}" 2>/dev/null || :
132
133   rm -f "${LOGFILE}".*
134   if [[ -s ${LOGFILE} ]]; then
135     cat "${LOGFILE}"
136     echo
137     echo
138     echo "FAIL: The following tests failed:"
139     sed -nre '/^FAIL:/s/^FAIL: Unittest (.*) failed output:/\1/p' "${LOGFILE}"
140     rm -f "${LOGFILE}"
141     exit 1
142   fi
143
144   rm -f "${LOGFILE}"
145 }
146
147 usage() {
148   cat <<EOF
149 Usage: run_tests [options] [tests]
150
151 Run the specified tests.  If none are specified, we'll scan the
152 tree looking for tests to run and then only run the semi-fast ones.
153
154 You can add a .testignore file to a dir to disable scanning it.
155
156 Options:
157   -q, --quick     Only run the really quick tests
158   -n, --dry-run   Do everything but actually run the test
159   -l, --list      List all the available tests
160   -h, --help      This screen
161 EOF
162
163   if [[ $# -gt 0 ]]; then
164     printf '\nerror: %s\n' "$*" >&2
165     exit 1
166   else
167     exit 0
168   fi
169 }
170
171 main() {
172   # Parse args from the user first.
173   local list=false
174   local dryrun=false
175   local user_tests=()
176   while [[ $# -gt 0 ]]; do
177     case $1 in
178     -h|--help)     usage;;
179     -q|--quick)    skip_quick_tests;;
180     -n|--dry-run)  dryrun=true;;
181     -l|--list)     list=true;;
182     -*)            usage "unknown option $1";;
183     *)             user_tests+=( "$1" );;
184     esac
185     shift
186   done
187   if [[ ${#user_tests[@]} -gt 0 ]]; then
188     set -- "${user_tests[@]}"
189   fi
190
191   # For some versions of 'sudo' (notably, the 'sudo' in the chroot at
192   # the time of this writing), sudo -v will ask for a password whether
193   # or not it's needed.  'sudo true' will do what we want.
194   sudo true
195
196   SKIP_CHROOT_TESTS=false
197   if ! repo list 2>/dev/null | grep -q chromiumos-overlay; then
198     echo "chromiumos-overlay is not present. Skipping chroot tests..."
199     SKIP_CHROOT_TESTS=true
200
201     # cgroups_unittest requires cros_sdk, so it doesn't work.
202     special_tests['lib/cgroups_unittest.py']=skip
203   fi
204
205   # Default to running all tests.
206   if [[ $# -eq 0 ]]; then
207     # List all unit test scripts that match the given pattern.
208     local prune_tests=(
209       $(find "${CHROMITE_PATH}" -name .testignore \
210           -printf '-path %h -prune -o ')
211     )
212     local all_tests=(
213       $(find "${CHROMITE_PATH}" \
214           ${prune_tests[*]} \
215           -name '*_unittest.py' -printf '%P ')
216     )
217     set -- "${all_tests[@]}"
218   fi
219
220   if ${list}; then
221     printf '%s\n' "$@" | sort
222     exit 0
223   fi
224
225   # Now do the real code.
226   LOGFILE="$(mktemp -t buildbot.run_tests.XXXXXX)"
227   trap cleanup INT TERM
228
229   local children=()
230   for test in "$@"; do
231     run_test ${test} ${dryrun} &
232     children+=( $! )
233   done
234
235   wait ${children[*]}
236   trap - INT TERM
237
238   show_logs
239   if ! ${dryrun}; then
240     echo "All tests succeeded!"
241   fi
242 }
243
244 main "$@"