| #!/usr/bin/env bash |
| |
| # Copyright 2020 The Android KVM Authors |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| source "$(dirname "${BASH_SOURCE[0]}")/../common.inc" |
| |
| default_var VHE 0 |
| default_var VERBOSE 0 |
| default_var QUIET 0 |
| default_var GDB 0 |
| default_var MODE "" |
| default_var KERNEL "" |
| default_var FIRMWARE "" |
| default_var TEST_PATH "" |
| default_var DISPLAY_NAME "" |
| default_var OUTPUT "" |
| default_var TIMEOUT "" |
| |
| DEFAULT_TIMEOUT=180s |
| |
| RESULT_ALIGN=60 |
| |
| function usage() { |
| cat <<EOF |
| |
| Usage: $0 [-h] [-v] [-q] [-G] |
| [-k KERNEL] [-F firmware] [-d DISPLAY_NAME] [-o OUTPUT] [-t TIMEOUT] |
| [-M KVM_MODE] |
| PATH [-- RUN_QEMU_ARGS] |
| |
| PATH Path to test binary. Basenames are resolved in the default output folder. |
| -h Output this help text |
| -v Print invoked command |
| -q Print only the result of the test |
| -k Kernel image |
| -F Firmware |
| -d Override test name displayed in result |
| -o Redirect stdout/stderr output to given file (implies -q) |
| -t kill test after given number of seconds |
| -M Select KVM mode |
| -G Enable debugging of emulated system with GDB |
| EOF |
| } |
| |
| while getopts ":k:F:d:o:t:M:vGqh" OPT; do |
| case "${OPT}" in |
| k) KERNEL="${OPTARG}" ;; |
| F) FIRMWARE="${OPTARG}" ;; |
| d) DISPLAY_NAME="${OPTARG}" ;; |
| t) TIMEOUT="${OPTARG}" ;; |
| M) MODE="${OPTARG}" ;; |
| v) VERBOSE=1 ;; |
| q) QUIET=1 ;; |
| G) GDB=1 ;; |
| o) |
| OUTPUT="${OPTARG}" |
| QUIET=1 |
| ;; |
| h) |
| usage |
| exit 0 |
| ;; |
| \?) |
| echo "Invalid option: -${OPTARG}" 1>&2 |
| usage 1>&2 |
| exit 1 |
| ;; |
| :) |
| echo "Invalid option: -${OPTARG} requires an argument" 1>&2 |
| usage 1>&2 |
| exit 1 |
| ;; |
| esac |
| done |
| shift $((OPTIND -1)) |
| |
| # Parse test name from a positional argument. |
| if [ $# -eq 0 ]; then |
| usage 1>&2 |
| exit 1 |
| fi |
| TEST_PATH="$1" |
| shift 1 |
| |
| # Default display name is the basename from TEST_PATH. |
| if [ -z "${DISPLAY_NAME}" ]; then |
| DISPLAY_NAME="$(basename "${TEST_PATH}")" |
| fi |
| |
| # If TEST_PATH is just a basename, search for the test in |
| # the kvm-unit-tests' default output folder. |
| if [ "$(basename "${TEST_PATH}")" = "${TEST_PATH}" ]; then |
| TEST_PATH="${KUT_TEST_DIR}/${TEST_PATH}" |
| fi |
| |
| CMD=("${SCRIPT_RUN_QEMU}" -R "${TEST_PATH}") |
| |
| if [ -n "${VERBOSE}" ]; then |
| CMD+=(-v) |
| fi |
| |
| if [ -n "${MODE}" ]; then |
| CMD+=(-M "${MODE}") |
| fi |
| |
| if [ -n "${KERNEL}" ]; then |
| CMD+=(-k "${KERNEL}") |
| fi |
| |
| if [ -n "${FIRMWARE}" ]; then |
| CMD+=(-F "${FIRMWARE}") |
| fi |
| |
| if [ "${GDB}" -eq 1 ]; then |
| CMD+=(-G) |
| # Disable timeout unless overridden by user. |
| if [ -z "${TIMEOUT}" ]; then |
| TIMEOUT=0s |
| fi |
| >&2 echo "Test will wait for GDB connection. Connect with" |
| >&2 echo "$ build/aarch64/run_gdb.sh -e gdb-multiarch" |
| fi |
| |
| # If not otherwise specified, use default timeout value. |
| if [ -z "${TIMEOUT}" ]; then |
| TIMEOUT="${DEFAULT_TIMEOUT}" |
| fi |
| CMD+=(-t "${TIMEOUT}") |
| |
| # If there are arguments after "--", pass them to the underlying run_qemu.sh. |
| if [ $# -gt 0 ]; then |
| if [ $1 = "--" ]; then |
| shift 1 |
| # Note: Due to a bug in older versions of Bash, use'${array[@]+"${array[@]}"}' |
| # to expand potentially empty arrays. '${array[@]}' is treated as undefined. |
| CMD+=(${@+"$@"}) |
| else |
| echo "Unrecognized options: $@" 1>&2 |
| usage 1>&2 |
| exit 1 |
| fi |
| fi |
| |
| # Disable exiting on failure. |
| set +eo pipefail |
| |
| if [ "${VERBOSE}" -eq 1 ]; then |
| echo "+ ${CMD[@]}" 1>&2 |
| fi |
| |
| if [ "${QUIET}" -eq 0 ]; then |
| exec "${CMD[@]}" |
| else |
| if [ -z "${OUTPUT}" ]; then |
| OUTPUT="$(mktemp)" |
| fi |
| |
| mkdir -p "$(dirname "${OUTPUT}")" |
| "${CMD[@]}" &> "${OUTPUT}" |
| EXIT_STATUS=$? |
| |
| PASS=$(grep -E -h --color=never $'(PASS|SKIP)\x1b' "${OUTPUT}") |
| FAIL=$(grep -E -h --color=never $'FAIL\x1b' "${OUTPUT}") |
| |
| # Check FAIL eagerly. |
| if [ -n "${FAIL}" ]; then |
| RESULT="${FAIL}" |
| EXIT_STATUS=1 |
| elif [ -n "${PASS}" ]; then |
| RESULT="${PASS}" |
| else |
| RESULT="\e[31;1mTIMEOUT/CRASH\e[0m" |
| EXIT_STATUS=1 |
| fi |
| |
| printf "%-${RESULT_ALIGN}s " "${DISPLAY_NAME}" |
| echo -e "${RESULT}" |
| exit ${EXIT_STATUS} |
| fi |