summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitrios Apostolou <jimis@qt.io>2022-01-06 11:05:21 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-01-07 23:15:25 +0000
commit905c24826fdc408c95d8fe939c85cb5513edb284 (patch)
treefbbccdbbeb8b761ea464a06d129c763ff2d5faf8
parentcb6fbeefd51b36f54e1081a4b341670e9693669a (diff)
Properly wait for the Android emulator to fully boot
It had been noticed that sometimes the Android emulator in our CI took several minutes to fully boot. It turns out that this behavior can be reproduced locally by removing the image files under $HOME/.android especially the "userdata-qemu.img.qcow2" file. Then the emulator goes through several reboots until fully booted with a full set of packages installed. We discovered that the property that signifies it is finished is dev.bootcomplete=1. So we now check for this flag and remove the other heuristics we had. We also disable the debug output to avoid hundreds lines of logs. Instead we selectively print the values that the emulator returns, every second until full boot is detected. We increase the Coin timeout for the shell script, from 5min to 10min, since it has been measured that it takes about 2.5min on a good day, and the script itself retries several times to restart the emulator in case of failure. Finally we adjust the coding style a bit to be more consistent. Fixes: QTQAINFRA-4681 Change-Id: I77062dceb91477e957696c89bfacb4ebabc34c1f Reviewed-by: Toni Saario <toni.saario@qt.io> Reviewed-by: Daniel Smith <Daniel.Smith@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> (cherry picked from commit 98f1034f96edbd7e7e88a513f8549259fd07c35b) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--coin/instructions/coin_module_test_android_start_emulator.yaml4
-rwxr-xr-xutil/android/android_emulator_launcher.sh63
2 files changed, 31 insertions, 36 deletions
diff --git a/coin/instructions/coin_module_test_android_start_emulator.yaml b/coin/instructions/coin_module_test_android_start_emulator.yaml
index 448a9ca9af..a212f5742e 100644
--- a/coin/instructions/coin_module_test_android_start_emulator.yaml
+++ b/coin/instructions/coin_module_test_android_start_emulator.yaml
@@ -4,9 +4,9 @@ instructions:
instructions:
- type: ExecuteCommand
command: "{{.InstallDir}}/libexec/android_emulator_launcher.sh"
- maxTimeInSeconds: 300
+ maxTimeInSeconds: 600
maxTimeBetweenOutput: 300
- userMessageOnFailure: "Failed to start emulator, check logs."
+ userMessageOnFailure: "Failed to start emulator, check coin log and ~/emulator.log"
enable_if:
condition: property
property: features
diff --git a/util/android/android_emulator_launcher.sh b/util/android/android_emulator_launcher.sh
index df334c3255..df40997fdb 100755
--- a/util/android/android_emulator_launcher.sh
+++ b/util/android/android_emulator_launcher.sh
@@ -29,12 +29,14 @@
# This util launches the Android emulator and ensures it doesn't stuck/freeze
# by detecting that and restarting it
-set -ex
+set -e
+
EMULATOR_MAX_RETRIES=5
EMULATOR_EXEC="$ANDROID_SDK_ROOT/emulator/emulator"
ADB_EXEC="$ANDROID_SDK_ROOT/platform-tools/adb"
-if [[ -z "${ANDROID_EMULATOR}" ]]; then
+if [ -z "${ANDROID_EMULATOR}" ]
+then
EMULATOR_NAME="@x86emulator"
else
EMULATOR_NAME="$ANDROID_EMULATOR"
@@ -47,37 +49,32 @@ function check_for_android_device
| awk 'NR==2{print $2}' | grep -qE '^(online|device)$'
}
+# WARNING: On the very first boot of the emulator it happens that the device
+# "finishes" booting and getprop shows bootanim=stopped and
+# boot_completed=1. But sometimes not all packages have been installed (`pm
+# list packages` shows only 16 packages installed), and after around half a
+# minute the boot animation starts spinning (bootanim=running) again despite
+# boot_completed=1 all the time. After some minutes the boot animation stops
+# again and the list of packages contains 80 packages. Only then the device is
+# fully booted, and only then is dev.bootcomplete=1.
+#
+# To reproduce the emulator booting as the first time, you have to delete the
+# cached images found inside $HOME/.android especially the
+# "userdata-qemu.img.qcow2" file.
function check_if_fully_booted
{
# The "getprop" command separates lines with \r\n so we trim them
bootanim=` $ADB_EXEC shell getprop init.svc.bootanim | tr -d '\r\n'`
boot_completed=`$ADB_EXEC shell getprop sys.boot_completed | tr -d '\r\n'`
- [ "$bootanim" = stopped ] && [ "$boot_completed" = 1 ]
+ bootcomplete=` $ADB_EXEC shell getprop dev.bootcomplete | tr -d '\r\n'`
+ echo "bootanim=$bootanim boot_completed=$boot_completed bootcomplete=$bootcomplete"
+ [ "$bootanim" = stopped ] && [ "$boot_completed" = 1 ] && [ "$bootcomplete" = 1 ]
}
-function check_for_package_manager
-{
-( set +e
- pm_output=`$ADB_EXEC shell pm get-install-location`
- pm_retval=$?
- [ $pm_retval = 0 ] && [[ ! "$pm_output" =~ ^Error: ]]
-)}
-
-# NOTE: It happens that the device "finishes" booting and getprop shows
-# bootanim=stopped and boot_completed=1. But sometimes not all packages have
-# been installed (`pm list packages` shows only 16 packages installed), and
-# after around half a minute the boot animation starts spinning
-# (bootanim=running) again despite boot_completed=1 all the time. After some
-# minutes the boot animation stops again and the list of packages contains 80
-# packages, among which is also the "development" package.
-function check_for_development_installed
-{
- package_list=`$ADB_EXEC shell pm list packages`
- echo "$package_list" | grep -q package:com.android.development
-}
-for counter in `seq 1 ${EMULATOR_MAX_RETRIES}`; do
+for counter in `seq ${EMULATOR_MAX_RETRIES}`
+do
$ADB_EXEC start-server
if check_for_android_device
@@ -94,20 +91,16 @@ for counter in `seq 1 ${EMULATOR_MAX_RETRIES}`; do
emulator_pid=$!
disown $emulator_pid
+ echo "Waiting for emulated device to appear..."
$ADB_EXEC wait-for-device
- # Wait about one minute for the emulator to come up
+ echo "Waiting a few minutes for the emulator to fully boot..."
emulator_status=down
for i in `seq 300`
do
sleep 1
- echo $i
- # Yes, you need to check continuously for all these heuristics,
- # see comment above
- if check_for_android_device \
- && check_if_fully_booted \
- && check_for_package_manager \
- && check_for_development_installed
+
+ if check_for_android_device && check_if_fully_booted
then
emulator_status=up
break
@@ -121,11 +114,13 @@ for counter in `seq 1 ${EMULATOR_MAX_RETRIES}`; do
echo "Emulator started successfully"
break
else
- if [ $counter -lt $EMULATOR_MAX_RETRIES ]; then
+ if [ $counter -lt $EMULATOR_MAX_RETRIES ]
+ then
echo "Emulator failed to start, forcefully killing current instance and re-starting emulator"
kill $emulator_pid || true
sleep 5
- elif [ $counter -eq $EMULATOR_MAX_RETRIES ]; then
+ elif [ $counter -eq $EMULATOR_MAX_RETRIES ]
+ then
echo "Emulator failed to start, reached maximum number of retries. Aborting\!"
exit 2
fi