blob: cdfeffcc7bbb19d33cf862dbf2fb8ce0189642fd [file] [log] [blame]
#!/bin/bash
# Copyright (C) 2019 The Android Open Source Project
#
# 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.
#
# Test Android Runtime (Boot) device configuration flags (living in namespace
# `runtime_native_boot`).
me=$(basename $0)
# Namespace containing the tested flag.
namespace=runtime_native_boot
# Default set of checked zygote processes.
zygotes=
# Status of whole test script.
exit_status=0
function say {
echo "$me: $*"
}
function banner {
local separator=$(echo "$@" | sed s/./=/g )
say "$separator"
say "$@"
say "$separator"
}
function fail {
say "FAILED: $@"
exit_status=1
}
function reboot_and_wait_for_device {
say "Rebooting device..."
adb reboot
adb wait-for-device >/dev/null
# Wait until the device has finished booting. Give the device 60 iterations
# (~60 seconds) to try and finish booting before declaring defeat.
local niters=60
for i in $(seq $niters); do
[[ $(adb shell getprop sys.boot_completed) -eq 1 ]] && return 0
sleep 1
done
fail "Device did not finish booting before timeout (~$niters seconds)"
}
# check_device_config_flag CONTEXT FLAG VALUE
# -------------------------------------------
# Check that the device configuration flag FLAG is set to VALUE. Use CONTEXT in
# logging.
function check_device_config_flag {
local context=$1
local flag=$2
local value=$3
say "[$context] Check that the device configuration flag is set..."
local flag_value=$(adb shell device_config get "$namespace" "$flag")
[[ "$flag_value" = "$value" ]] \
|| fail "Device configuration flag \`$flag\` set to \`$flag_value\` (expected \`$value\`)"
}
# check_no_device_config_flag CONTEXT FLAG
# ----------------------------------------
# Check that the device configuration flag FLAG is not set. Use CONTEXT in
# logging.
function check_no_device_config_flag {
local context=$1
local flag=$2
say "[$context] Check that the device configuration flag is not set..."
local flag_value=$(adb shell device_config get "$namespace" "$flag")
[[ "$flag_value" = null ]] \
|| fail "Device configuration flag \`$flag\` set to \`$flag_value\` (expected `null`)"
}
# get_system_property PROP
# ------------------------
# Get system property PROP associated with a device configuration flag.
function get_system_property {
local prop=$1
# Note that we need to be root to read that system property.
adb root >/dev/null
local prop_value=$(adb shell getprop "$prop")
adb unroot >/dev/null
echo "$prop_value"
}
# check_system_property CONTEXT PROP VALUE
# ----------------------------------------
# Check that the system property PROP associated with a device configuration
# flag is set to VALUE. Use CONTEXT in logging.
function check_system_property {
local context=$1
local prop=$2
local value=$3
say "[$context] Check that the persistent system property is set..."
local prop_value=$(get_system_property "$prop")
[[ "$prop_value" = "$value" ]] \
|| fail "System property \`$prop\` set to \`$prop_value\` (expected \`$value\`)"
}
# check_no_system_property CONTEXT PROP
# -------------------------------------
# Check that the system property PROP associated with a device configuration
# flag is not set. Use CONTEXT in logging.
function check_no_system_property {
local context=$1
local prop=$2
say "[$context] Check that the persistent system property is not set..."
local prop_value=$(get_system_property "$prop")
[[ -z "$prop_value" ]] \
|| fail "System property \`$prop\` set to \`$prop_value\` (expected unset property)"
}
# find_zygote_runtime_option ZYGOTE RUNTIME_OPTION
# ------------------------------------------------
# Return whether ZYGOTE is passed RUNTIME_OPTION.
function find_zygote_runtime_option {
local zygote=$1
local runtime_option=$2
adb logcat -d -s "$zygote" | grep -q -e "option\[[0-9]\+\]=$runtime_option"
}
# check_zygote_runtime_option CONTEXT RUNTIME_OPTION
# --------------------------------------------------
# Check that all zygote processes are passed RUNTIME_OPTION as runtime option. Use
# CONTEXT in logging.
function check_zygote_runtime_option {
local context=$1
local runtime_option=$2
say \
"[$context] Check that all zygote processes are passed \`$runtime_option\` as runtime option..."
for zygote in $zygotes; do
find_zygote_runtime_option "$zygote" "$runtime_option" \
|| fail "Found no \`$runtime_option\` among runtime options passed to \`$zygote\`"
done
}
# check_no_zygote_runtime_option CONTEXT RUNTIME_OPTION
# -----------------------------------------------------
# Check that no zygote process is passed RUNTIME_OPTION as runtime option. Use
# CONTEXT in logging.
function check_no_zygote_runtime_option {
local context=$1
local runtime_option=$2
say "[$context] Check that no zygote process is passed \`$runtime_option\` as runtime option..."
for zygote in $zygotes; do
find_zygote_runtime_option "$zygote" "$runtime_option" \
&& fail "Found \`$runtime_option\` among runtime options passed to \`$zygote\`"
done
}
# check_android_runtime_message CONTEXT MESSAGE
# ---------------------------------------------
# Return whether AndroidRuntime generated MESSAGE in logcat. Use CONTEXT in
# logging.
function check_android_runtime_message {
local context=$1
local message=$2
say "[$context] Check that AndroidRuntime generated expected message in logcat..."
adb logcat -d -s AndroidRuntime | grep -F -q "$message" \
|| fail "Found no message \"$message\" generated by AndroidRuntime"
}
# check_no_android_runtime_message CONTEXT MESSAGE
# ------------------------------------------------
# Return whether AndroidRuntime did not generate MESSAGE in logcat. Use CONTEXT
# in logging.
function check_no_android_runtime_message {
local context=$1
local message=$2
say "[$context] Check that AndroidRuntime did not generate unexpected message in logcat..."
adb logcat -d -s AndroidRuntime | grep -F -q -v "$message" \
|| fail "Found message \"$message\" generated by AndroidRuntime"
}
# test_android_runtime_flag FLAG VALUE CHECK_EFFECT CHECK_NO_EFFECT
# -----------------------------------------------------------------
# Test device configuration FLAG with VALUE. CHECK_EFFECT and CHECK_NO_EFFECT
# are functions that are passed a context as sole argument and that respectively
# check the effect or the absence of effect of the flag.
function test_android_runtime_flag {
local flag=$1
local value=$2
local check_effect=$3
local check_no_effect=$4
# Persistent system property (set after a reboot) associated with the device
# configuration flag.
local prop="persist.device_config.$namespace.$flag"
banner "Testing \`$flag\` value \`$value\`."
say "Setting device configuration flag..."
adb shell device_config put "$namespace" "$flag" "$value"
# Give some time to the device to digest this change before rebooting.
sleep 3
# Check that both the device configuration flag and the associated system
# property are set, but that flag has not produced an effect on the system (as
# we haven't rebooted yet).
local context="Flag set, before reboot"
check_device_config_flag "$context" "$flag" "$value"
check_system_property "$context" "$prop" "$value"
$check_no_effect "$context"
# Reboot device for the flag value to take effect.
reboot_and_wait_for_device
context="Flag set, after 1st reboot"
check_device_config_flag "$context" "$flag" "$value"
check_system_property "$context" "$prop" "$value"
$check_effect "$context"
# Reboot device a second time and check that the state has persisted.
reboot_and_wait_for_device
context="Flag set, after 2nd reboot"
check_device_config_flag "$context" "$flag" "$value"
check_system_property "$context" "$prop" "$value"
$check_effect "$context"
say "Unsetting device configuration flag..."
adb shell device_config delete "$namespace" "$flag" >/dev/null
# Give some time to the device to digest this change before rebooting.
sleep 3
# Reboot and check that the device is back to its default state.
reboot_and_wait_for_device
context="Flag unset, after 3rd reboot"
check_no_device_config_flag "$context" "$flag"
check_no_system_property "$context" "$prop"
$check_no_effect "$context"
}
# Pre-test actions.
# =================
# Enumerate Zygote processes.
case $(adb shell getprop ro.zygote) in
(zygote32) zygotes="zygote";;
(zygote64) zygotes="zygote64";;
(zygote32_64|zygote64_32) zygotes="zygote zygote64";;
esac
# Test "enable_generational_cc" flag values.
# ==========================================
function check_nogenerational_cc {
check_zygote_runtime_option "$1" "-Xgc:nogenerational_cc"
}
function check_no_nogenerational_cc {
check_no_zygote_runtime_option "$1" "-Xgc:nogenerational_cc"
}
function check_generational_cc {
check_zygote_runtime_option "$1" "-Xgc:generational_cc"
}
function check_no_generational_cc {
check_no_zygote_runtime_option "$1" "-Xgc:generational_cc"
}
test_android_runtime_flag \
enable_generational_cc false check_nogenerational_cc check_no_nogenerational_cc
test_android_runtime_flag \
enable_generational_cc true check_generational_cc check_no_generational_cc
# Test "enable_apex_image" flag values.
# =====================================
default_boot_image_message="Using default boot image"
function check_default_boot_image {
check_android_runtime_message "$1" "$default_boot_image_message"
}
function check_no_default_boot_image {
check_no_android_runtime_message "$1" "$default_boot_image_message"
}
apex_boot_image_option="-Ximage:/system/framework/apex.art"
apex_boot_image_message="Using Apex boot image: '$apex_boot_image_option'"
function check_apex_boot_image {
check_zygote_runtime_option "$1" "$apex_boot_image_option"
check_android_runtime_message "$1" "$apex_boot_image_message"
}
function check_no_apex_boot_image {
check_no_zygote_runtime_option "$1" "$apex_boot_image_option"
check_no_android_runtime_message "$1" "$apex_boot_image_message"
}
test_android_runtime_flag \
enable_apex_image false check_default_boot_image check_no_default_boot_image
test_android_runtime_flag \
enable_apex_image true check_apex_boot_image check_no_apex_boot_image
# Post-test actions.
# ==================
if [[ "$exit_status" -eq 0 ]]; then
banner "All tests passed."
else
banner "Test(s) failed."
fi
exit $exit_status