aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtem Serov <artem.serov@linaro.org>2021-07-30 16:32:36 +0000
committerLinaro Android Code Review <android-review@review.linaro.org>2021-07-30 16:32:36 +0000
commitd00da4f4b235c07f9cf384cb5d9a013d801e4aae (patch)
treebbf6d6ebbed4139b7b15e653e3a257cea9ac3c1d
parentd43985f793bb42d00028e3cdce823d7df0f1776f (diff)
parentc9edeb90472cb9cb5392c2b00011d4e1885786fe (diff)
downloadart-build-scripts-d00da4f4b235c07f9cf384cb5d9a013d801e4aae.tar.gz
Merge "Extends options for host test and sharing common functions."
-rwxr-xr-xtests/test_art_host.sh203
-rwxr-xr-xtests/test_art_target.sh197
-rw-r--r--utils/utils.sh40
-rw-r--r--utils/utils_run.sh130
-rw-r--r--utils/utils_test.sh16
5 files changed, 375 insertions, 211 deletions
diff --git a/tests/test_art_host.sh b/tests/test_art_host.sh
index dc0baac1..f9226583 100755
--- a/tests/test_art_host.sh
+++ b/tests/test_art_host.sh
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright (c) 2016-2017, Linaro Ltd.
+# Copyright (c) 2016-2021, Linaro Ltd.
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,20 +25,74 @@ source "${local_path}/../utils/utils.sh"
source "${local_path}/../utils/utils_test.sh"
source "${local_path}/../utils/utils_android.sh"
source "${local_path}/../utils/utils_android_root.sh"
+source "${local_path}/../utils/utils_run.sh"
readonly timer_name="Host Test"
readonly default_lunch_target="aosp_arm64-eng"
+job_count=${JCPU_COUNT}
+
# shellcheck disable=SC2034
declare -A options_format=(
+ ["32bit"]="false"
+ ["64bit"]="false"
+ ["default"]="p:set_defaults_wrapper()"
+ ["gcstress"]="false"
+ ["gtest"]="false"
["help"]="p:usage()"
["h"]="r:&help"
+ ["interpreter"]="false"
+ ["isa-features"]=""
+ ["jit"]="false"
+ ["jobs"]=""
+ ["keep-failures"]="false"
+ ["keep-going"]="false"
+ ["optimizing"]="false"
+ ["single-test"]=""
["verbose"]="p:enable_verbose()"
["v"]="r:&verbose"
)
# shellcheck disable=SC2034
declare -A options=()
+set_defaults_wrapper() {
+ new_opts_string=$(set_default_options "$(declare -p options)" "host" "")
+ declare -A -g options=${new_opts_string#*=}
+}
+
+validate_options() {
+ # Check that at least one test has been selected.
+ if ! ${options["gtest"]} && ! ${options["optimizing"]} \
+ && ! ${options["interpreter"]} && ! ${options["jit"]} \
+ && [[ -z ${options["single-test"]} ]]; then
+ log E "Please select at least one of the \"Tests\" to be run or use --default."
+ log E "See the options ( -h | --help ) for more info."
+ exit 1
+ fi
+ # Check for conflict between bitness in test name and bitness option
+ if [[ "${options["single-test"]}" = *"32" ]] && ${options["64bit"]}; then
+ log E "The test name specifies to run the test in the 32-bit mode but"
+ log E "'--64bit' is used. The test mode option can be omitted in this case."
+ exit 1
+ fi
+ if [[ "${options["single-test"]}" = *"64" ]] && ${options["32bit"]}; then
+ log E "The test name specifies to run the test in the 64-bit mode but"
+ log E "'--32bit' is used. The test mode option can be omitted in this case."
+ exit 1
+ fi
+
+ if [[ -n "${options["jobs"]}" ]] && [[ ! ${options["jobs"]} =~ ^[0-9]+$ ]]; then
+ log E "The --jobs option must be followed by an integer."
+ exit 1
+ fi
+}
+
+set_job_count() {
+ if [[ -n "${options["jobs"]}" ]]; then
+ job_count="${options["jobs"]}"
+ fi
+}
+
usage() {
log I "$0"
log I "This script is used to run the host Jenkins test."
@@ -48,6 +102,33 @@ usage() {
log I "instead. (current environment's default: $(lunch_target_from_env))"
log I " -h - help"
log I " -v - verbose"
+ log I "-------------------------------------------"
+ log I "Test Modes:"
+ log I " --32bit - run 32bit tests."
+ log I " --64bit - run 64bit tests."
+ log I " Not providing a test mode means to run both 32bit and 64bit tests."
+ log I "-------------------------------------------"
+ log I "Test Options:"
+ log I " --jobs - a number of jobs on a target. Defaults to CPU count."
+ log I " --keep-failures - keep failing tests around (useful for debugging)."
+ log I " --keep-going - don't stop at the first failing test."
+ log I " --gcstress - use gc stress testing for run-tests."
+ log I " --isa-features - specify isa features to be used.
+ Possible values: default, runtime, a list of comma-separated
+ feature names. When the list is used, '-' before a feature name
+ means the ART compiler must not use the feature for code
+ generation."
+ log I "-------------------------------------------"
+ log I "Tests:"
+ log I " --gtest - run gtests."
+ log I " --optimizing - run optimizing tests."
+ log I " --interpreter - run interpreter tests."
+ log I " --jit - run jit tests."
+ log I " --single-test <test> - run specified test only"
+ log I "-------------------------------------------"
+ log I "Default Configuration:"
+ log I " --default - default test configuration, running all sections for 32 and 64 bits"
+ log I "-------------------------------------------"
exit 0
}
@@ -69,58 +150,116 @@ argument_parser() {
done
}
-run_test_unwrapped() {
- disable_error_on_unset_expansion
- local -r test_command="art/test.py -v -j${JCPU_COUNT} --host --$1 --$2"
- log I "Running ${test_command}"
- ${test_command}
- local -r return_code=$?
- enable_error_on_unset_expansion
-
- return ${return_code}
-}
-
+# Arguments:
+# ${1}: test type {run-test, single-test}
+# ${2}: test section
+# ${3}: bitness (32/64)
run_test() {
- start_section "$2"
+ local section_name=$2_$3
+ if [[ -z "$3" ]]; then
+ section_name+="32_64"
+ fi
- run_test_unwrapped "$1" "$2"
- end_section "$2" "$?"
+ # Check if we should skip section
+ if ! ${options["$2"]}; then
+ section_starter "${section_name}" "host"
+ skip_section "${section_name}"
+ return
+ fi
+
+ section_starter "${section_name}" "host"
+ run_test_unwrapped "$1" "$2" "" "$3" "host" "${job_count}" "$(declare -p options)"
+ local return_code=$?
+ section_ender "${section_name}" "host" "${return_code}" "${options["keep-going"]}"
}
-# Until the art/test.py wrapper is fixed, we need to run the test manually
-# using the --make-mode syntax.
+# Arguments
+# ${1}: bitness (32/64)
test_gtest() {
- start_section "gtest"
- build/soong/soong_ui.bash --make-mode -j"${JCPU_COUNT}" "test-art-host-gtest"
- end_section "gtest" "$?"
+ section_starter "gtest_$1" "host"
+
+ if ! ${options["gtest"]}; then
+ skip_section "gtest_$1"
+ return
+ fi
+
+ # Until the art/test.py wrapper is fixed, we need to run the test manually
+ # using the --make-mode syntax.
+ build/soong/soong_ui.bash --make-mode -j"${JCPU_COUNT}" "test-art-host-gtest${1}"
+ local return_code=$?
+ section_ender "gtest_$1" "host" "${return_code}" "${options["keep-going"]}"
}
+# Arguments
+# ${1}: bitness (32/64)
test_optimizing() {
- run_test "run-test" "optimizing"
+ run_test "run-test" "optimizing" "${1}"
}
+# Arguments
+# ${1}: bitness
test_interpreter() {
- run_test "run-test" "interpreter"
+ run_test "run-test" "interpreter" "${1}"
}
+# Arguments
+# ${1}: bitness (32/64)
test_jit() {
- run_test "run-test" "jit"
+ run_test "run-test" "jit" "${1}"
+}
+
+set_environment() {
+ source_android_environment_default
+ set_environment_host
+ setup_android_target_to_environment_or_default "${default_lunch_target}"
+ if ${options["keep-failures"]}; then
+ set_environment_keep_test_failures
+ fi
}
main() {
exit_on_failure arguments_parser options_format options -- "$@"
- start_test "${timer_name}"
+ if [[ ! -d "${PWD}/.repo" ]]; then
+ log E "Script needs to be run at the root of the android tree."
+ exit 1
+ fi
- source_android_environment_default
- setup_android_target_to_environment_or_default "${default_lunch_target}"
- set_environment_host
- build_host
+ # Set bitness options when they are not provided via the command line.
+ # A single test name can contain the bitness at the end of its name.
+ if ! ${options["32bit"]} && ! ${options["64bit"]}; then
+ if [[ "${options["single-test"]}" = *"32" ]]; then
+ options["32bit"]="true"
+ elif [[ "${options["single-test"]}" = *"64" ]]; then
+ options["64bit"]="true"
+ else
+ options["32bit"]="true"
+ options["64bit"]="true"
+ fi
+ fi
- test_gtest
- test_optimizing
- test_interpreter
- test_jit
+ readonly options
+ validate_options
+ dump_options
+ set_environment
+ set_job_count
+ start_test "${timer_name}"
+ build_host
+ for bits in 32 64; do
+ if ! ${options["${bits}bit"]}; then
+ log I "Skipping ${bits}bit tests."
+ continue
+ fi
+ log I "Starting ${bits}bit tests."
+ if [[ -n ${options["single-test"]} ]]; then
+ test_single "${bits}" "host" "${job_count}" "$(declare -p options)"
+ continue
+ fi
+ test_gtest "${bits}"
+ test_optimizing "${bits}"
+ test_interpreter "${bits}"
+ test_jit "${bits}"
+ done
end_test "${timer_name}"
}
diff --git a/tests/test_art_target.sh b/tests/test_art_target.sh
index b7f1a617..04b7074a 100755
--- a/tests/test_art_target.sh
+++ b/tests/test_art_target.sh
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright (c) 2016-2018, Linaro Ltd.
+# Copyright (c) 2016-2021, Linaro Ltd.
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,11 +25,10 @@ source "${local_path}/../utils/utils.sh"
source "${local_path}/../utils/utils_test.sh"
source "${local_path}/../utils/utils_android.sh"
source "${local_path}/../utils/utils_android_root.sh"
+source "${local_path}/../utils/utils_run.sh"
readonly target_timer_name="Target Test"
readonly LOG_DIRECTORY="$(get_workspace)"
-readonly art="$(get_art_dir)"
-readonly art_tools="$(get_art_tools_dir)"
job_count=6
@@ -69,42 +68,6 @@ set_defaults_wrapper() {
declare -A -g options=${new_opts_string#*=}
}
-# Sets default options depending on host or target
-#
-# Arguments:
-# ${1}: options
-# ${2}: host/target
-# ${3}: job count
-set_default_options() {
- declare -A options=${1#*=}
- if [[ "$2" != "host" && "$2" != "target" ]]; then
- log E "set_default_options() requires host or target as second argument"
- log E "got $2 instead"
- exit 1
- fi
- # Options common to both host and target
- options["32bit"]="true"
- options["64bit"]="true"
- options["gtest"]="true"
- options["interpreter"]="false"
- options["jit"]="false"
- options["keep-going"]="true"
- options["optimizing"]="true"
- options["gcstress"]="false"
- if [[ "$2" == "target" ]]; then
- # Target specific options
- options["concurrent-gc"]="false"
- options["debug"]="false"
- options["jdwp"]="false"
- options["libcore"]="false"
- options["jobs"]="${3}"
- options["rerun-failed-tests"]="true"
- options["restart-adb-server"]="false"
- options["fvp"]="false"
- fi
- echo " $(declare -p options)"
-}
-
# Return true if adb server is run on a different machine than
# test_art_target.sh.
is_remote_adb_server() {
@@ -113,11 +76,6 @@ is_remote_adb_server() {
[[ -v SERVER_IPADDRESS ]]
}
-# Return true if a single test is gtest.
-is_single_test_gtest() {
- [[ "${options["single-test"]}" == *_tests ]]
-}
-
validate_options() {
# Check that at least one test has been selected.
if ! ${options["gtest"]} && ! ${options["optimizing"]} \
@@ -131,14 +89,14 @@ validate_options() {
# Check for conflict between bitness in test name and bitness option
if [[ "${options["single-test"]}" = *"32" ]] && ${options["64bit"]}; then
- log E "The test name specifies to run the test in the 32-bit mode but \
-'--64bit' is used. The test mode option can be omitted in this case."
+ log E "The test name specifies to run the test in the 32-bit mode but"
+ log E "'--64bit' is used. The test mode option can be omitted in this case."
exit 1
fi
if [[ "${options["single-test"]}" = *"64" ]] && ${options["32bit"]}; then
- log E "The test name specifies to run the test in the 64-bit mode but \
-'--32bit' is used. The test mode option can be omitted in this case."
+ log E "The test name specifies to run the test in the 64-bit mode but"
+ log E "'--32bit' is used. The test mode option can be omitted in this case."
exit 1
fi
@@ -153,8 +111,8 @@ validate_options() {
fi
if ${options["gcstress"]} && ! ${options["optimizing"]} && ! ${options["interpreter"]} \
- && ! ${options["jit"]} \
- && { [[ -z ${options["single-test"]} ]] || is_single_test_gtest; }; then
+ && ! ${options["jit"]} && { [[ -z ${options["single-test"]} ]] \
+ || is_single_test_gtest "${options["single-test"]}"; }; then
log E "The --gcstress option must be used only for run-tests: optimizing, jit or interpreter."
exit 1
fi
@@ -268,61 +226,6 @@ start_prebuilt_abd_server() {
safe "$(get_prebuilt_adb)" start-server
}
-# Passes the correct arguments to test.py to run tests.
-# Caller passes options using (declare -p options) which represents the options array as a string.
-# The first line of the function converts the string back into an associative array.
-#
-# Arguments:
-# ${1}: test type {run-test, single-test}
-# ${2}: test section
-# ${3}: test name
-# ${4}: bitness (32/64)
-# ${5}: host/target
-# ${6}: job count (CPU Count when on host)
-# ${7}: options
-run_test_with_python_runner() {
- declare -A local_options=${7#*=}
- local test_command="art/test.py -v -j${6} --${5} --ndebuggable"
- if ${local_options["gcstress"]}; then
- test_command+=" --gcstress"
- fi
- if [[ -n "${options["dump-cfg"]}" ]]; then
- test_command+=" --dump-cfg ${options["dump-cfg"]} "
- fi
- if [[ $1 == "single-test" ]]; then
- test_command+=" -t $3 --run-test --${4}"
- else
- test_command+=" --run-test --$2 --${4}"
- fi
- if [[ -n "${local_options["isa-features"]}" ]]; then
- test_command+=" --run-test-option='--instruction-set-features ${local_options["isa-features"]}'"
- fi
- log I "Running ${test_command}"
- eval "${test_command}"
-}
-
-# Build (run) a test target using the Android build system.
-# If a test failed, add it to the list of failed tests.
-#
-# Arguments:
-# ${1}: test type {run-test, single-test}
-# ${2}: test section
-# ${3}: test name
-# ${4}: bitness (32/64)
-# ${5}: host/target
-# ${6}: job count (CPU Count when on host)
-# ${7}: options
-run_test_unwrapped() {
- # Android scripts don't play nice with nounset (error out on expansion of unset variables).
- disable_error_on_unset_expansion
-
- run_test_with_python_runner "$@"
-
- local -r return_code=$?
- enable_error_on_unset_expansion
- return ${return_code}
-}
-
# Arguments:
# ${1}: test type {run-test}
# ${2}: a log file of 'run_test'
@@ -359,20 +262,6 @@ rerun_failed_tests() {
return ${return_code}
}
-# Stop the run and print the test summary if some command has failed and
-# 'keep-going' is not specified.
-#
-# Arguments:
-# ${1}: some command exit code to check
-# ${2}: keep-going option
-print_summary_and_exit_if_failed_and_not_continue() {
- if ! ${2} && [[ ${1} -ne 0 ]]; then
- log E "--keep-going is not set. Stop on the first failed test."
- log E "Test Summary:\n${TESTS_SUMMARY}"
- exit 1
- fi
-}
-
# Build (run) a test target using the Android build system.
# If a test failed, add it to the list of failed tests.
#
@@ -416,20 +305,6 @@ run_test() {
section_ender "${section_name}" "target" "${return_code}" "${options["keep-going"]}"
}
-# Find all gtests in the provided directory.
-#
-# Arguments:
-# ${1}: all tests or a particular test
-find_gtests() {
- local search_pattern="$1"
- if [[ "$1" == "all" ]]; then
- search_pattern="*_tests"
- fi
- ${ADB} shell \
- "test -d $ART_TEST_CHROOT/$ART_TEST_APEX_ART_ROOT/bin/art && \
- chroot $ART_TEST_CHROOT find $ART_TEST_APEX_ART_ROOT/bin/art -name ${search_pattern}"
-}
-
# Arguments:
# ${1}: a path to gtest
run_gtest() {
@@ -445,12 +320,12 @@ run_gtest() {
# Note: This is a temporary solution.
#
# Arguments:
-# ${1}: bitness
+# ${1}: bitness (32/64)
test_gtest_parallel() {
export -f run_gtest
local joblog="$(get_workspace)/log_jobs_gtest_$1.txt"
- safe find_gtests "all" | \
+ safe find_gtests "all" "target" | \
parallel --jobs "${job_count}" --joblog "${joblog}" run_gtest {}
local return_code=$?
if [[ ${return_code} -ne 0 ]]; then
@@ -468,7 +343,11 @@ test_gtest_parallel() {
# gtest.
#
# Arguments:
-# ${1}: bitness
+# ${1}: bitness (32/64)
+# Disabling check for whether variable is declared before use.
+# Check only disabled within the scope of test_gtest function.
+# This is done as art_tools is defined in utils_run.sh, but used here.
+# shellcheck disable=2154
test_gtest() {
section_starter "gtest_$1" "target"
@@ -487,66 +366,30 @@ test_gtest() {
section_ender "gtest_$1" "target" "${return_code}" "${options["keep-going"]}"
}
-# Run a single gtest or ART Test.
-#
-# Arguments
-# ${1}: bitness (32/64)
-# ${2}: host/target
-# ${3}: job count (CPU Count when on host)
-# ${4}: options
-test_single() {
- declare -A local_options=${4#*=}
- local test_name="${local_options["single-test"]}"
- local return_code=0
- local section_name="TEST_SINGLE_"
- if is_single_test_gtest "${test_name}"; then
- if [ "$2" != "target" ]; then
- log E "Running single gtests currently only supported on target."
- exit 1
- fi
- section_name+="gtest_$1"
- section_starter "${section_name}" "${2}"
- local path_to_test=$(find_gtests "${test_name}")
- if [[ -z "${path_to_test}" ]]; then
- log E "Failed to find the test: ${test_name}"
- return_code=1
- else
- "${art_tools}"/run-gtests.sh "${path_to_test}"
- return_code=$?
- fi
- else
- section_name+="ART_$1"
- section_starter "${section_name}" "${2}"
- run_test_unwrapped "single-test" "" "${test_name}" "$1" "$2" "$3" "$4"
- return_code=$?
- fi
- section_ender "${section_name}" "$2" "${return_code}" "${local_options["keep-going"]}"
-}
-
# Run ART tests with optimizing compiler.
# Arguments:
-# ${1}: bitness
+# ${1}: bitness (32/64)
test_optimizing() {
run_test "run-test" "optimizing" "$1"
}
# Run ART tests with interpreter.
# Arguments:
-# ${1}: bitness
+# ${1}: bitness (32/64)
test_interpreter() {
run_test "run-test" "interpreter" "$1"
}
# Run ART tests with JIT compiler.
# Arguments:
-# ${1}: bitness
+# ${1}: bitness (32/64)
test_jit() {
run_test "run-test" "jit" "$1"
}
# Run licore tests.
# Arguments:
-# ${1}: bitness
+# ${1}: bitness (32/64)
test_libcore() {
section_starter "libcore_$1" "target"
@@ -567,7 +410,7 @@ test_libcore() {
}
# Run jdwp tests.
# Arguments:
-# ${1}: bitness
+# ${1}: bitness (32/64)
test_jdwp() {
section_starter "jdwp_$1" "target"
diff --git a/utils/utils.sh b/utils/utils.sh
index f768dcaf..2e2d0d79 100644
--- a/utils/utils.sh
+++ b/utils/utils.sh
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright (c) 2016-2017, Linaro Ltd.
+# Copyright (c) 2016-2021, Linaro Ltd.
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -350,6 +350,44 @@ dump_options() {
done
}
+# Sets default options depending on host or target
+# The existence of the `options` associative array with
+# all options already added is assumed.
+#
+# Arguments:
+# ${1}: options
+# ${2}: host/target
+# ${3}: job count
+set_default_options() {
+ declare -A options=${1#*=}
+ if [[ "$2" != "host" && "$2" != "target" ]]; then
+ log E "set_default_options() requires host or target as second argument"
+ log E "got $2 instead"
+ exit 1
+ fi
+ # Options common to both host and target
+ options["32bit"]="true"
+ options["64bit"]="true"
+ options["gtest"]="true"
+ options["interpreter"]="false"
+ options["jit"]="false"
+ options["keep-going"]="true"
+ options["optimizing"]="true"
+ options["gcstress"]="false"
+ if [[ "$2" == "target" ]]; then
+ # Target specific options
+ options["concurrent-gc"]="false"
+ options["debug"]="false"
+ options["jdwp"]="false"
+ options["libcore"]="false"
+ options["jobs"]="${3}"
+ options["rerun-failed-tests"]="true"
+ options["restart-adb-server"]="false"
+ options["fvp"]="false"
+ fi
+ echo " $(declare -p options)"
+}
+
# Whether it's defined by Jenkins or simply undefined, specify the concept of
# a workspace that can be used elsewhere. Defaults to $PWD.
get_workspace() {
diff --git a/utils/utils_run.sh b/utils/utils_run.sh
new file mode 100644
index 00000000..581ec0f8
--- /dev/null
+++ b/utils/utils_run.sh
@@ -0,0 +1,130 @@
+#!/bin/bash
+#
+# Copyright (c) 2016-2021, Linaro Ltd.
+# All rights reserved.
+#
+# 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.
+
+# Utility functions related to running of tests (shared code between host and target tests)
+
+# These assume that source utils.sh has been called by the parent script
+readonly art_tools="$(get_art_tools_dir)"
+readonly art="$(get_art_dir)"
+
+# Passes the correct arguments to test.py to run tests.
+# Caller passes options using (declare -p options) which represents the options array as a string.
+# The first line of the function converts the string back into an associative array.
+#
+# Arguments:
+# ${1}: test type {run-test, single-test}
+# ${2}: test section
+# ${3}: test name
+# ${4}: bitness (32/64)
+# ${5}: host/target
+# ${6}: job count (CPU Count when on host)
+# ${7}: options
+run_test_with_python_runner() {
+ declare -A local_options=${7#*=}
+ local test_command="art/test.py -v -j${6} --${5} --ndebuggable"
+ if ${local_options["gcstress"]}; then
+ test_command+=" --gcstress"
+ fi
+ if [[ $1 == "single-test" ]]; then
+ test_command+=" -t $3 --run-test --${4}"
+ else
+ test_command+=" --run-test --$2 --${4}"
+ fi
+ if [[ -n "${local_options["isa-features"]}" ]]; then
+ test_command+=" --run-test-option='--instruction-set-features ${local_options["isa-features"]}'"
+ fi
+ log I "Running ${test_command}"
+ eval "${test_command}"
+}
+
+# Arguments:
+# ${1}: test type {run-test, single-test}
+# ${2}: test section
+# ${3}: test name
+# ${4}: bitness (32/64)
+# ${5}: host/target
+# ${6}: job count (CPU Count when on host)
+# ${7}: options
+run_test_unwrapped() {
+ # Android scripts don't play nice with nounset (error out on expansion of unset variables).
+ disable_error_on_unset_expansion
+
+ run_test_with_python_runner "$@"
+
+ local -r return_code=$?
+ enable_error_on_unset_expansion
+ return ${return_code}
+}
+
+# Return true if given single test is gtest.
+#
+# Arguments:
+# ${1}: test name
+is_single_test_gtest() {
+ [[ "${1}" == *_tests ]]
+}
+
+# Find all gtests in the provided directory.
+#
+# Arguments:
+# ${1}: all tests or a particular test
+# ${2}: host/target
+find_gtests() {
+ local search_pattern="$1"
+ if [[ "$1" == "all" ]]; then
+ search_pattern="*_test"
+ fi
+ ${ADB} shell \
+ "test -d $ART_TEST_CHROOT/$ART_TEST_APEX_ART_ROOT/bin/art && \
+ chroot $ART_TEST_CHROOT find $ART_TEST_APEX_ART_ROOT/bin/art -name ${search_pattern}"
+}
+
+# Run a single gtest or ART Test.
+#
+# Arguments
+# ${1}: bitness (32/64)
+# ${2}: host/target
+# ${3}: job count (CPU Count when on host)
+# ${4}: options
+test_single() {
+ declare -A local_options=${4#*=}
+ local test_name="${local_options["single-test"]}"
+ local return_code=0
+ local section_name="TEST_SINGLE_"
+ if is_single_test_gtest "${test_name}"; then
+ if [ "$2" != "target" ]; then
+ log E "Running single gtests currently only supported on target"
+ exit 1
+ fi
+ section_name+="gtest_$1"
+ section_starter "${section_name}" "${2}"
+ local path_to_test=$(find_gtests "${test_name}" "${2}")
+ if [[ -z "${path_to_test}" ]]; then
+ log E "Failed to find the test: ${test_name}"
+ return_code=1
+ else
+ "${art_tools}"/run-gtests.sh "${path_to_test}"
+ return_code=$?
+ fi
+ else
+ section_name+="ART_$1"
+ section_starter "${section_name}" "${2}"
+ run_test_unwrapped "single-test" "" "${test_name}" "$1" "$2" "$3" "$4"
+ return_code=$?
+ fi
+ section_ender "${section_name}" "$2" "${return_code}" "${local_options["keep-going"]}"
+}
diff --git a/utils/utils_test.sh b/utils/utils_test.sh
index 9e7c8470..3a41de8f 100644
--- a/utils/utils_test.sh
+++ b/utils/utils_test.sh
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright (c) 2016-2017, Linaro Ltd.
+# Copyright (c) 2016-2021, Linaro Ltd.
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -73,6 +73,20 @@ skip_section() {
TESTS_SUMMARY+="SKIPPED\n"
}
+# Stop the run and print the test summary if some command has failed and
+# 'keep-going' is not specified.
+#
+# Arguments:
+# ${1}: some command exit code to check
+# ${2}: keep-going option
+print_summary_and_exit_if_failed_and_not_continue() {
+ if ! ${2} && [[ ${1} -ne 0 ]]; then
+ log E "--keep-going is not set. Stop on the first failed test."
+ log E "Test Summary:\n${TESTS_SUMMARY}"
+ exit 1
+ fi
+}
+
# Calls the correct section start function depending on host/target test
#
# Arguments: