1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
|
#!/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
|