Skip to content

Commit 205da17

Browse files
committed
Harden emulator provisioning and retry instrumentation runs
1 parent 6b3bb3a commit 205da17

File tree

1 file changed

+75
-28
lines changed

1 file changed

+75
-28
lines changed

scripts/build-android-app.sh

Lines changed: 75 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ create_avd() {
363363
if [ -f "$ini_file" ] && [ -d "$image_dir" ]; then
364364
if grep -F -q "$image" "$ini_file" 2>/dev/null; then
365365
ba_log "Reusing existing Android Virtual Device $name"
366+
configure_avd "$avd_dir" "$name"
366367
return
367368
fi
368369
ba_log "Existing Android Virtual Device $name uses a different system image; recreating"
@@ -380,6 +381,34 @@ create_avd() {
380381
find "$avd_dir" -maxdepth 1 -mindepth 1 -print | sed 's/^/[build-android-app] AVD: /' >&2 || true
381382
exit 1
382383
fi
384+
configure_avd "$avd_dir" "$name"
385+
}
386+
387+
configure_avd() {
388+
local avd_dir="$1"
389+
local name="$2"
390+
local cfg="$avd_dir/$name.avd/config.ini"
391+
if [ ! -f "$cfg" ]; then
392+
return
393+
fi
394+
declare -A settings=(
395+
["hw.ramSize"]=3072
396+
["disk.dataPartition.size"]=4096M
397+
["hw.bluetooth"]=no
398+
["hw.camera.back"]=none
399+
["hw.camera.front"]=none
400+
["hw.audioInput"]=no
401+
["hw.audioOutput"]=no
402+
)
403+
local key value
404+
for key in "${!settings[@]}"; do
405+
value="${settings[$key]}"
406+
if grep -q "^${key}=" "$cfg" 2>/dev/null; then
407+
sed -i "s/^${key}=.*/${key}=${value}/" "$cfg"
408+
else
409+
echo "${key}=${value}" >>"$cfg"
410+
fi
411+
done
383412
}
384413

385414
wait_for_emulator() {
@@ -538,8 +567,7 @@ dump_emulator_diagnostics() {
538567
}
539568

540569
log_instrumentation_state() {
541-
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm path android \
542-
| sed 's/^/[build-android-app] pm path android: /' || true
570+
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm path android | sed 's/^/[build-android-app] pm path android: /' || true
543571

544572
local instrumentation_list
545573
instrumentation_list="$("$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm list instrumentation 2>/dev/null || true)"
@@ -629,8 +657,9 @@ EMULATOR_SERIAL="emulator-$EMULATOR_PORT"
629657
EMULATOR_LOG="$GRADLE_PROJECT_DIR/emulator.log"
630658
ba_log "Starting headless Android emulator $AVD_NAME on port $EMULATOR_PORT"
631659
ANDROID_AVD_HOME="$AVD_HOME" "$EMULATOR_BIN" -avd "$AVD_NAME" -port "$EMULATOR_PORT" \
632-
-no-window -gpu swiftshader_indirect -no-audio -no-boot-anim -accel off \
633-
-camera-back none -camera-front none -skip-adb-auth -no-accel -netfast -memory 2048 >"$EMULATOR_LOG" 2>&1 &
660+
-no-window -no-snapshot -gpu swiftshader_indirect -no-audio -no-boot-anim \
661+
-accel off -no-accel -camera-back none -camera-front none -skip-adb-auth \
662+
-feature -Vulkan -netfast -memory 3072 >"$EMULATOR_LOG" 2>&1 &
634663
EMULATOR_PID=$!
635664
trap stop_emulator EXIT
636665

@@ -700,12 +729,19 @@ if ! wait_for_package_service "$EMULATOR_SERIAL"; then
700729
exit 1
701730
fi
702731

732+
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell settings put global device_provisioned 1 >/dev/null 2>&1 || true
733+
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell settings put secure user_setup_complete 1 >/dev/null 2>&1 || true
734+
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell input keyevent 82 >/dev/null 2>&1 || true
735+
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell wm dismiss-keyguard >/dev/null 2>&1 || true
736+
703737
if ! wait_for_api_level "$EMULATOR_SERIAL"; then
704738
dump_emulator_diagnostics
705739
stop_emulator
706740
exit 1
707741
fi
708742

743+
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm path android | sed 's/^/[build-android-app] pm path android: /' || true
744+
709745
"$ADB_BIN" kill-server >/dev/null 2>&1 || true
710746
"$ADB_BIN" start-server >/dev/null 2>&1 || true
711747
"$ADB_BIN" -s "$EMULATOR_SERIAL" wait-for-device
@@ -832,37 +868,48 @@ if [ -z "$RUNNER" ]; then
832868
fi
833869
ba_log "Using instrumentation runner: $RUNNER"
834870

835-
UI_TEST_TIMEOUT_SECONDS="${UI_TEST_TIMEOUT_SECONDS:-900}"
871+
UI_TEST_TIMEOUT_SECONDS="${UI_TEST_TIMEOUT_SECONDS:-900}"
836872
if ! [[ "$UI_TEST_TIMEOUT_SECONDS" =~ ^[0-9]+$ ]] || [ "$UI_TEST_TIMEOUT_SECONDS" -le 0 ]; then
837873
ba_log "Invalid UI_TEST_TIMEOUT_SECONDS=$UI_TEST_TIMEOUT_SECONDS provided; falling back to 900"
838874
UI_TEST_TIMEOUT_SECONDS=900
839875
fi
840876

841-
INSTRUMENT_ARGS=(
842-
"-w"
843-
"-r"
844-
"-e"
845-
"clearPackageData"
846-
"true"
847-
"-e"
848-
"log"
849-
"true"
850-
)
851-
INSTRUMENT_CMD=("$ADB_BIN" "-s" "$EMULATOR_SERIAL" "shell" "am" "instrument" "${INSTRUMENT_ARGS[@]}" "$RUNNER")
852-
if command -v timeout >/dev/null 2>&1; then
853-
ba_log "Running instrumentation via am instrument with external timeout of ${UI_TEST_TIMEOUT_SECONDS}s"
854-
INSTRUMENT_CMD=("timeout" "$UI_TEST_TIMEOUT_SECONDS" "${INSTRUMENT_CMD[@]}")
855-
else
856-
ba_log "timeout command not found; running instrumentation without external watchdog"
857-
fi
877+
INSTRUMENT_EXIT_CODE=1
858878

859-
INSTRUMENT_LOG="$FINAL_ARTIFACT_DIR/ui-test-instrumentation.log"
860-
set +e
861-
"${INSTRUMENT_CMD[@]}" | tee "$INSTRUMENT_LOG"
862-
INSTRUMENT_EXIT_CODE=${PIPESTATUS[0]}
863-
set -e
879+
run_instrumentation() {
880+
local tries=3 delay=15 attempt exit_code=1
881+
local args=(-w -r -e clearPackageData true -e log true -e class "${PACKAGE_NAME}.${MAIN_NAME}UiTest")
882+
for attempt in $(seq 1 "$tries"); do
883+
local cmd=("$ADB_BIN" "-s" "$EMULATOR_SERIAL" "shell" "am" "instrument" "${args[@]}" "$RUNNER")
884+
if command -v timeout >/dev/null 2>&1; then
885+
cmd=("timeout" "$UI_TEST_TIMEOUT_SECONDS" "${cmd[@]}")
886+
ba_log "Instrumentation attempt $attempt/$tries with external timeout of ${UI_TEST_TIMEOUT_SECONDS}s"
887+
else
888+
ba_log "Instrumentation attempt $attempt/$tries without external watchdog"
889+
fi
890+
local attempt_log="$FINAL_ARTIFACT_DIR/ui-test-instrumentation-attempt-$attempt.log"
891+
set +e
892+
"${cmd[@]}" | tee "$attempt_log"
893+
exit_code=${PIPESTATUS[0]}
894+
set -e
895+
cp "$attempt_log" "$FINAL_ARTIFACT_DIR/ui-test-instrumentation.log" 2>/dev/null || true
896+
if [ "$exit_code" -eq 0 ]; then
897+
INSTRUMENT_EXIT_CODE=0
898+
return 0
899+
fi
900+
if grep -q "INSTRUMENTATION_ABORTED: System has crashed." "$attempt_log" 2>/dev/null && [ "$attempt" -lt "$tries" ]; then
901+
ba_log "System crashed during instrumentation attempt $attempt; retrying after ${delay}s"
902+
sleep "$delay"
903+
continue
904+
fi
905+
INSTRUMENT_EXIT_CODE=$exit_code
906+
return $exit_code
907+
done
908+
INSTRUMENT_EXIT_CODE=$exit_code
909+
return $exit_code
910+
}
864911

865-
if [ "$INSTRUMENT_EXIT_CODE" -ne 0 ]; then
912+
if ! run_instrumentation; then
866913
ba_log "Instrumentation command exited with status $INSTRUMENT_EXIT_CODE"
867914
dump_emulator_diagnostics
868915
fi

0 commit comments

Comments
 (0)