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