File: runtime_native_boot-flags-test.sh

package info (click to toggle)
android-platform-frameworks-base 1%3A10.0.0%2Br36-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 321,788 kB
  • sloc: java: 962,234; cpp: 274,314; xml: 242,770; python: 5,060; sh: 1,432; ansic: 494; makefile: 47; sed: 19
file content (324 lines) | stat: -rwxr-xr-x 10,901 bytes parent folder | download | duplicates (4)
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