blob: bbd5b3246b963828fbf239ef8f14e69cc9315a38 [file] [log] [blame]
#!/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"
# Directory containing kvm-unit-tests' binaries
TEST_DIR="$1"
# Regex for excluding known-to-fail or irrelevant tests.
EXCLUDE="$2"
# Variable/target names from the root Makefile.
VAR_KERNEL_IMAGE="$3"
VAR_LOG_DIR="$4"
GLOBAL_TEST_TARGET="$5"
GLOBAL_TEST_LIST_TARGET="$6"
# Generates a Make target name for a test case.
# Args:
# 1) name of test case
# 2) target name of the test's group.
function target_name {
local target="$1"
local parent="$2"
echo "${parent}-${target}"
}
# Generates target name for a group of given parameters.
# Args:
# 1) Root target name
# 2) is VHE (0/1)
function group_target_name {
local group="$1"
local vhe="$2"
group="$(target_name kut "${group}")"
if [ "${vhe}" -eq 1 ]; then
group="$(target_name vhe "${group}")"
else
group="$(target_name nvhe "${group}")"
fi
echo "${group}"
}
# Generates target name for a target printing list of all test targets.
# Args:
# 1) Root target name
function list_target_name {
local name="$1"
name="$(target_name kut "${name}")"
echo "${name}"
}
# Emits a Make target and a dependency of its parent on the target.
# Args:
# 1) Target name
# 2) Parent target name
function dependency_target {
local target="$1"
local parent="$2"
cat <<EOF
.PHONY: ${target}
${target}:
${parent}: ${target}
EOF
}
# Emits a Make target for a test case.
# Args:
# 1) Target name
# 2) Test binary path
# 3) is VHE (0/1)
# 4) is GDB (0/1)
function test_target {
local target="$1"
local binary="$2"
local vhe="$3"
local gdb="$4"
local extra_args=()
if [ "${vhe}" -eq 1 ]; then
extra_args+=(-V)
fi
if [ "${gdb}" -eq 1 ]; then
extra_args+=(-G)
fi
# Note: Due to a bug in older versions of Bash, use '${array[@]+"${array[@]}"}'
# to expand potentially empty arrays. '${array[@]}' is treated as undefined.
cat <<EOF
.PHONY: ${target}
${target}: \$(${VAR_KERNEL_IMAGE}) ${binary}
@ mkdir -p "\$(${VAR_LOG_DIR})"
@ "${SCRIPT_RUN_KUT}" \
-k \$(${VAR_KERNEL_IMAGE}) \
-d "${target}" \
-o \$(${VAR_LOG_DIR})/${target}.log \
${extra_args[@]+"${extra_args[@]}"} \
"${binary}"
EOF
}
# Emits a Make target which prints all provided target names,
# one per line.
# Args:
# 1) target name
# ...) list of target names to print
function test_list_target {
local target="$1"
shift 1
cat <<EOF
.PHONY: ${target}
${target}:
@ for T in $@; do echo "\$\$T"; done
EOF
}
if [ ! -d "${TEST_DIR}" ]; then
echo "ERROR: Test directory does not exist" 1>&2
exit 1
fi
TARGET_LIST=()
for VHE in 0 1; do
# Emit a target for this test group.
ROOT="${GLOBAL_TEST_TARGET}"
GROUP="$(group_target_name "${ROOT}" "${VHE}")"
dependency_target "${GROUP}" "${ROOT}"
for TEST_PATH in "${TEST_DIR}"/*; do
NAME=$(basename "${TEST_PATH}")
if [[ ${NAME} =~ ${EXCLUDE} ]]; then
continue
fi
# Emit a target for this test case.
TARGET="$(target_name ${NAME} ${GROUP})"
GDB_TARGET="$(target_name gdb ${TARGET})"
TARGET_LIST+=("${TARGET}" "${GDB_TARGET}")
test_target "${TARGET}" "${TEST_PATH}" "${VHE}" 0
test_target "${GDB_TARGET}" "${TEST_PATH}" "${VHE}" 1
dependency_target "${TARGET}" "${GROUP}"
done
done
# Emit a target which prints all test targets from the generated Makefile.
ROOT="${GLOBAL_TEST_LIST_TARGET}"
TARGET="$(list_target_name "${ROOT}")"
# Note: Due to a bug in older versions of Bash, use '${array[@]+"${array[@]}"}'
# to expand potentially empty arrays. '${array[@]}' is treated as undefined.
test_list_target "${TARGET}" ${TARGET_LIST[@]+"${TARGET_LIST[@]}"}
dependency_target "${TARGET}" "${ROOT}"