blob: 3b0f42292b4a7f67fad7d1c24d4c293ebdba5b6f [file] [log] [blame]
#!/bin/bash
# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
CHROMITE_PATH=$(realpath "$(dirname "$0")/..")
IN_CHROOT="cros_sdk"
CHROOT_CHROMITE=../../chromite
set -eu
LOGFILE="$(mktemp -t buildbot.run_tests.XXXXXX)"
# Helper function to add failed logs/tests to be printed out later.
# $1 test that failed.
# $2 log file where we stored the output of the failed test.
append_failed_test() {
echo "ERROR: Unittest $1 failed. Log will be output at end of run!!!"
cat - "$2" <<EOF >>"${LOGFILE}.err.${BASHPID}"
FAIL: Unittest $1 failed output:
EOF
}
# Wrapper to run unittest. Hides output unless test fails.
# $1 test to run. Must be in chromite/buildbot.
# $2 If set, run inside the chroot.
run_test() {
local log_file="${LOGFILE}.tmp.${BASHPID}"
local special="${special_tests[$1]:-}"
local starttime="$(date +%s%N)"
if [[ "${special}" == "skip" ]]; then
echo "Skipping unittest $1"
return
elif [[ "${special}" == "outside" && -f /etc/debian_chroot ]]; then
echo "Skipping unittest $1 because it must run outside the chroot."
return
elif [[ "${special}" == "inside" && ! -f /etc/debian_chroot ]]; then
if ${SKIP_CHROOT_TESTS}; then
echo "Skipping unittest $1 because it must run inside the chroot"
return
else
echo "Starting unittest $1 inside the chroot"
${IN_CHROOT} python "${CHROOT_CHROMITE}/$1" &> "${log_file}" ||
append_failed_test "$1" "${log_file}"
fi
else
echo "Starting unittest $1"
python "${CHROMITE_PATH}/$1" &> "${log_file}" ||
append_failed_test "$1" "${log_file}"
fi
local endtime="$(date +%s%N)"
local duration=$(( (endtime - starttime) / 1000000 ))
echo "Finished unittest $1 (${duration} ms)"
rm -f "${log_file}"
}
# For some versions of 'sudo' (notably, the 'sudo' in the chroot at
# the time of this writing), sudo -v will ask for a password whether
# or not it's needed. 'sudo true' will do what we want.
sudo true
# List all exceptions, with a token describing what's odd here.
# inside - inside the chroot
# skip - don't run this test (please comment on why)
declare -A special_tests
special_tests=(
# Tests that need to run inside the chroot.
['cros/commands/cros_build_unittest.py']=inside
['lib/upgrade_table_unittest.py']=inside
['scripts/cros_mark_as_stable_unittest.py']=inside
['scripts/cros_mark_chrome_as_stable_unittest.py']=inside
['scripts/sync_package_status_unittest.py']=inside
['scripts/cros_portage_upgrade_unittest.py']=inside
['scripts/upload_package_status_unittest.py']=inside
# Tests that need to run outside the chroot.
['lib/cgroups_unittest.py']=outside
# Tests that are presently broken.
['lib/gdata_lib_unittest.py']=skip
['scripts/chrome_set_ver_unittest.py']=skip
['scripts/check_gdata_token_unittest.py']=skip
['scripts/merge_package_status_unittest.py']=skip
['scripts/upload_package_status_unittest.py']=skip
# Tests that take >2 minutes to run. All the slow tests are
# disabled atm though ...
#['scripts/cros_portage_upgrade_unittest.py']=skip
)
if [[ $# -ne 0 && $1 == "--quick" ]]; then
shift
# Tests that require network can be really slow.
special_tests['buildbot/manifest_version_unittest.py']=skip
special_tests['buildbot/repository_unittest.py']=skip
special_tests['buildbot/remote_try_unittest.py']=skip
special_tests['lib/cros_build_lib_unittest.py']=skip
special_tests['lib/gerrit_unittest.py']=skip
special_tests['lib/patch_unittest.py']=skip
# cgroups_unittest runs cros_sdk a lot, so is slow.
special_tests['lib/cgroups_unittest.py']=skip
fi
SKIP_CHROOT_TESTS=false
if ! repo list | grep -q chromiumos-overlay; then
echo "chromiumos-overlay is not present. Skipping chroot tests..."
SKIP_CHROOT_TESTS=true
# cgroups_unittest requires cros_sdk, so it doesn't work.
special_tests['lib/cgroups_unittest.py']=skip
fi
if [[ $# -eq 0 ]]; then
# List all unit test scripts that match the given pattern.
all_tests=(
$(find "${CHROMITE_PATH}" -name '*_unittest.py' -printf '%P ')
)
set -- "${all_tests[@]}"
fi
declare -a children
cleanup() {
delayed_kill() {
sleep 5
kill -9 ${children[*]} &> /dev/null
}
echo "Cleaning up backgrounded jobs."
# Graceful exit.
kill -INT ${children[*]} &> /dev/null
# Set of a hard kill timer after a while.
delayed_kill &
wait ${children[*]}
show_logs
}
show_logs() {
cat "${LOGFILE}".err.* > "${LOGFILE}" 2>/dev/null || :
rm -f "${LOGFILE}".*
if [[ -s ${LOGFILE} ]]; then
cat "${LOGFILE}"
echo
echo
echo "FAIL: The following tests failed:"
sed -nre '/^FAIL:/s/^FAIL: Unittest (.*) failed output:/\1/p' "${LOGFILE}"
rm -f "${LOGFILE}"
exit 1
fi
rm -f "${LOGFILE}"
}
trap cleanup INT TERM
for test in "$@"; do
run_test ${test} &
children+=( $! )
done
wait ${children[*]}
trap - INT TERM
show_logs
echo "All tests succeeded!"