mirror of
https://github.com/flatcar/scripts.git
synced 2025-08-08 05:26:58 +02:00
* Also changes the way how "new workflow" is detected in run_remote_tests.sh modified: autotest_run.sh modified: run_remote_tests.sh Review URL: http://codereview.chromium.org/3048051
306 lines
8.9 KiB
Bash
Executable File
306 lines
8.9 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Copyright (c) 2009 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.
|
|
|
|
# Script to run client or server tests on a live remote image.
|
|
|
|
# Load common constants. This should be the first executable line.
|
|
# The path to common.sh should be relative to your script's location.
|
|
|
|
. "$(dirname $0)/common.sh"
|
|
. "$(dirname $0)/remote_access.sh"
|
|
|
|
get_default_board
|
|
|
|
DEFINE_string args "" "Command line arguments for test, separated with comma" a
|
|
DEFINE_string board "$DEFAULT_BOARD" \
|
|
"The board for which you are building autotest"
|
|
DEFINE_string chroot "${DEFAULT_CHROOT_DIR}" "alternate chroot location" c
|
|
DEFINE_boolean cleanup ${FLAGS_FALSE} "Clean up temp directory"
|
|
DEFINE_integer iterations 1 "Iterations to run every top level test" i
|
|
DEFINE_string prepackaged_autotest "" "Use this prepackaged autotest dir"
|
|
DEFINE_string results_dir_root "" "alternate root results directory"
|
|
DEFINE_boolean verbose ${FLAGS_FALSE} "Show verbose autoserv output" v
|
|
|
|
RAN_ANY_TESTS=${FLAGS_FALSE}
|
|
|
|
# Check if our stdout is a tty
|
|
function is_a_tty() {
|
|
local stdout=$(readlink /proc/$$/fd/1)
|
|
[[ "${stdout#/dev/tty}" != "${stdout}" ]] && return 0
|
|
[[ "${stdout#/dev/pts}" != "${stdout}" ]] && return 0
|
|
return 1
|
|
}
|
|
|
|
# Writes out text in specified color if stdout is a tty
|
|
# Arguments:
|
|
# $1 - color
|
|
# $2 - text to color
|
|
# $3 - text following colored text (default colored)
|
|
# Returns:
|
|
# None
|
|
function echo_color() {
|
|
local color=0
|
|
[[ "$1" == "red" ]] && color=31
|
|
[[ "$1" == "green" ]] && color=32
|
|
[[ "$1" == "yellow" ]] && color=33
|
|
if is_a_tty; then
|
|
echo -e "\033[1;${color}m$2\033[0m$3"
|
|
else
|
|
echo "$2$3"
|
|
fi
|
|
}
|
|
|
|
function cleanup() {
|
|
if [[ $FLAGS_cleanup -eq ${FLAGS_TRUE} ]] || \
|
|
[[ ${RAN_ANY_TESTS} -eq ${FLAGS_FALSE} ]]; then
|
|
rm -rf "${TMP}"
|
|
else
|
|
echo ">>> Details stored under ${TMP}"
|
|
fi
|
|
cleanup_remote_access
|
|
}
|
|
|
|
# Returns an error if the test_result_file has text which indicates
|
|
# the test was not run successfully.
|
|
# Arguments:
|
|
# $1 - file name of autotest status for to check for success
|
|
# Returns:
|
|
# None
|
|
function is_successful_test() {
|
|
local file="$1"
|
|
# To be successful, must not have BAD, ERROR or FAIL in the file.
|
|
if egrep -q "(BAD|ERROR|FAIL)" "${file}"; then
|
|
return 1
|
|
fi
|
|
# To be successful, must have GOOD in the file.
|
|
if ! grep -q GOOD "${file}"; then
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
# Adds attributes to all tests run
|
|
# Arguments:
|
|
# $1 - results directory
|
|
# $2 - attribute name (key)
|
|
# $3 - attribute value (value)
|
|
function add_test_attribute() {
|
|
local results_dir="$1"
|
|
local attribute_name="$2"
|
|
local attribute_value="$3"
|
|
if [[ -z "$attribute_value" ]]; then
|
|
return;
|
|
fi
|
|
|
|
for status_file in $(echo "${results_dir}"/*/status); do
|
|
local keyval_file=$(dirname $status_file)/keyval
|
|
echo "Updating ${keyval_file}"
|
|
echo "${attribute_name}=${attribute_value}" >> "${keyval_file}"
|
|
done
|
|
}
|
|
|
|
|
|
# Ask the target what board it is
|
|
function learn_board() {
|
|
if [[ -n "${FLAGS_board}" ]]; then
|
|
return
|
|
fi
|
|
remote_sh grep CHROMEOS_RELEASE_BOARD /etc/lsb-release
|
|
FLAGS_board=$(echo "${REMOTE_OUT}" | cut -d= -f2)
|
|
if [[ -z "${FLAGS_board}" ]]; then
|
|
check_board
|
|
fi
|
|
echo "Target reports board is ${FLAGS_board}"
|
|
}
|
|
|
|
|
|
# Determine if a control is for a client or server test. Echos
|
|
# either "server" or "client".
|
|
# Arguments:
|
|
# $1 - control file path
|
|
function read_test_type() {
|
|
local control_file=$1
|
|
# Assume a line starts with TEST_TYPE =
|
|
local type=$(egrep -m1 \
|
|
'^[[:space:]]*TEST_TYPE[[:space:]]*=' "${control_file}")
|
|
if [[ -z "${type}" ]]; then
|
|
echo_color "red" ">>> Unable to find TEST_TYPE line in ${control_file}"
|
|
exit 1
|
|
fi
|
|
type=$(python -c "${type}; print TEST_TYPE.lower()")
|
|
if [[ "${type}" != "client" ]] && [[ "${type}" != "server" ]]; then
|
|
echo_color "red" ">>> Unknown type of test (${type}) in ${control_file}"
|
|
exit 1
|
|
fi
|
|
echo ${type}
|
|
}
|
|
|
|
function main() {
|
|
cd $(dirname "$0")
|
|
|
|
FLAGS "$@" || exit 1
|
|
|
|
if [[ -z "${FLAGS_ARGV}" ]]; then
|
|
echo "Please specify tests to run. For example:"
|
|
echo " $0 --remote=MyMachine BootPerfServer"
|
|
exit 1
|
|
fi
|
|
|
|
# Check the validity of the user-specified result directory
|
|
# It must be within the /tmp directory
|
|
if [[ -n "${FLAGS_results_dir_root}" ]]; then
|
|
SUBSTRING=${FLAGS_results_dir_root:0:5}
|
|
if [[ ${SUBSTRING} != "/tmp/" ]]; then
|
|
echo "User-specified result directory must be within the /tmp directory"
|
|
echo "ex: --results_dir_root=/tmp/<result_directory>"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
set -e
|
|
|
|
# Set global TMP for remote_access.sh's sake
|
|
# and if --results_dir_root is specified,
|
|
# set TMP and create dir appropriately
|
|
if [[ ${INSIDE_CHROOT} -eq 0 ]]; then
|
|
if [[ -n "${FLAGS_results_dir_root}" ]]; then
|
|
TMP=${FLAGS_chroot}${FLAGS_results_dir_root}
|
|
mkdir -m 777 ${TMP}
|
|
else
|
|
TMP=$(mktemp -d ${FLAGS_chroot}/tmp/run_remote_tests.XXXX)
|
|
fi
|
|
TMP_INSIDE_CHROOT=$(echo ${TMP#${FLAGS_chroot}})
|
|
else
|
|
if [[ -n "${FLAGS_results_dir_root}" ]]; then
|
|
TMP=${FLAGS_results_dir_root}
|
|
mkdir -m 777 ${TMP}
|
|
else
|
|
TMP=$(mktemp -d /tmp/run_remote_tests.XXXX)
|
|
fi
|
|
TMP_INSIDE_CHROOT=${TMP}
|
|
fi
|
|
|
|
trap cleanup EXIT
|
|
|
|
remote_access_init
|
|
|
|
local autotest_dir=""
|
|
if [[ -z "${FLAGS_prepackaged_autotest}" ]]; then
|
|
learn_board
|
|
autotest_dir="${GCLIENT_ROOT}/src/third_party/autotest/files"
|
|
else
|
|
autotest_dir="${FLAGS_prepackaged_autotest}"
|
|
fi
|
|
|
|
local control_files_to_run=""
|
|
|
|
# Now search for tests which unambiguously include the given identifier
|
|
local search_path=$(echo {client,server}/{tests,site_tests})
|
|
pushd ${autotest_dir} > /dev/null
|
|
for test_request in $FLAGS_ARGV; do
|
|
test_request=$(remove_quotes "${test_request}")
|
|
! finds=$(find ${search_path} -maxdepth 2 -type f \( -name control.\* -or \
|
|
-name control \) | egrep -v "~$" | egrep "${test_request}")
|
|
if [[ -z "${finds}" ]]; then
|
|
echo_color "red" ">>> Cannot find match for \"${test_request}\""
|
|
exit 1
|
|
fi
|
|
local matches=$(echo "${finds}" | wc -l)
|
|
if [[ ${matches} -gt 1 ]]; then
|
|
echo ""
|
|
echo_color "red" \
|
|
">>> \"${test_request}\" is ambiguous. These control file paths match:"
|
|
for FIND in ${finds}; do
|
|
echo_color "red" " * " "${FIND}"
|
|
done
|
|
echo ""
|
|
echo ">>> Disambiguate by copy-and-pasting the whole path above" \
|
|
"instead of passing \"${test_request}\"."
|
|
exit 1
|
|
fi
|
|
for i in $(seq 1 $FLAGS_iterations); do
|
|
control_files_to_run="${control_files_to_run} '${finds}'"
|
|
done
|
|
done
|
|
popd > /dev/null
|
|
|
|
echo ""
|
|
|
|
if [[ -z "${control_files_to_run}" ]]; then
|
|
echo_color "red" ">>> Found no control files"
|
|
exit 1
|
|
fi
|
|
|
|
echo_color "yellow" ">>> Running the following control files:"
|
|
for CONTROL_FILE in ${control_files_to_run}; do
|
|
echo_color "yellow" " * " "${CONTROL_FILE}"
|
|
done
|
|
|
|
for control_file in ${control_files_to_run}; do
|
|
# Assume a line starts with TEST_TYPE =
|
|
control_file=$(remove_quotes "${control_file}")
|
|
local type=$(read_test_type "${autotest_dir}/${control_file}")
|
|
local option
|
|
if [[ "${type}" == "client" ]]; then
|
|
option="-c"
|
|
else
|
|
option="-s"
|
|
fi
|
|
echo ""
|
|
echo_color "yellow" ">>> Running ${type} test " ${control_file}
|
|
local short_name=$(basename $(dirname "${control_file}"))
|
|
local results_dir_name="${short_name}"
|
|
local results_dir="${TMP_INSIDE_CHROOT}/${results_dir_name}"
|
|
rm -rf "${results_dir}"
|
|
local verbose=""
|
|
if [[ ${FLAGS_verbose} -eq $FLAGS_TRUE ]]; then
|
|
verbose="--verbose"
|
|
fi
|
|
local args=()
|
|
if [[ -n "${FLAGS_args}" ]]; then
|
|
local with_spaces=""
|
|
with_spaces=${FLAGS_args//,/ }
|
|
args=("-a" "${with_spaces}")
|
|
fi
|
|
|
|
RAN_ANY_TESTS=${FLAGS_TRUE}
|
|
|
|
# HACK: Temporary hack for cros-workon conversion
|
|
[[ -n "${CROS_WORKON_SRCROOT}" ]] && WORKON_SUFFIX=_workon
|
|
|
|
local enter_chroot=""
|
|
local autotest="${GCLIENT_ROOT}/src/scripts/autotest${WORKON_SUFFIX}"
|
|
if [[ ${INSIDE_CHROOT} -eq 0 ]]; then
|
|
enter_chroot="./enter_chroot.sh --chroot ${FLAGS_chroot} --"
|
|
autotest="./autotest${WORKON_SUFFIX}"
|
|
fi
|
|
|
|
${enter_chroot} ${autotest} --board "${FLAGS_board}" -m "${FLAGS_remote}" \
|
|
--ssh-port ${FLAGS_ssh_port} \
|
|
"${option}" "${control_file}" -r "${results_dir}" ${verbose} \
|
|
"${args[@]}"
|
|
|
|
results_dir="${TMP}/${results_dir_name}"
|
|
local test_status="${results_dir}/status.log"
|
|
local test_result_dir="${results_dir}/${short_name}"
|
|
local keyval_file="${test_result_dir}/results/keyval"
|
|
echo ""
|
|
if is_successful_test "${test_status}"; then
|
|
echo_color "green" ">>> SUCCESS: ${control_file}"
|
|
if [[ -f "${keyval_file}" ]]; then
|
|
echo ">>> Keyval was:"
|
|
cat "${keyval_file}"
|
|
fi
|
|
else
|
|
echo_color "red" ">>> FAILED: ${control_file}"
|
|
cat "${test_status}"
|
|
fi
|
|
local end_time=$(date '+%s')
|
|
done
|
|
}
|
|
|
|
main $@
|