Skip to content

Commit 8ba2013

Browse files
committed
Use emulator runner action for instrumentation tests
1 parent 9317f4c commit 8ba2013

File tree

2 files changed

+46
-131
lines changed

2 files changed

+46
-131
lines changed

.github/workflows/scripts-android.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,18 @@ jobs:
2626
- name: Add Android instrumentation test
2727
run: ./scripts/add-android-instrumentation-test.sh
2828
- name: Run Android instrumentation tests on emulator
29-
run: ./scripts/run-android-instrumentation-tests.sh
29+
uses: reactivecircus/android-emulator-runner@v2
30+
with:
31+
api-level: 35
32+
target: google_apis
33+
arch: arm64-v8a
34+
force-avd-creation: true
35+
disable-animations: true
36+
emulator-options: >-
37+
-no-window -no-boot-anim -gpu swiftshader_indirect
38+
-no-snapshot -camera-back none -camera-front none
39+
-accel off
40+
script: ./scripts/run-android-instrumentation-tests.sh
3041
- name: Export Android emulator screenshot path
3142
if: always()
3243
run: |

scripts/run-android-instrumentation-tests.sh

Lines changed: 34 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -61,150 +61,54 @@ if [ -z "$ANDROID_SDK_ROOT" ] || [ ! -d "$ANDROID_SDK_ROOT" ]; then
6161
fi
6262
export ANDROID_SDK_ROOT ANDROID_HOME="$ANDROID_SDK_ROOT"
6363

64-
find_tool() {
65-
local binary="$1"
66-
shift
67-
for dir in "$@"; do
68-
if [ -x "$dir/$binary" ]; then
69-
printf '%s' "$dir/$binary"
70-
return 0
71-
fi
72-
done
73-
return 1
74-
}
75-
76-
run_sdkmanager_noninteractive() {
77-
local description="$1"
78-
shift
79-
log "$description"
80-
# Temporarily disable errexit and pipefail so we can inspect the pipeline exit
81-
# codes manually without the shell aborting on the SIGPIPE emitted by `yes`.
82-
set +e
83-
set +o pipefail
84-
yes 2>/dev/null | "$SDKMANAGER" "$@" >/dev/null
85-
local statuses=("${PIPESTATUS[@]}")
86-
set -o pipefail
87-
set -e
88-
local sdk_status="${statuses[1]:-1}"
89-
if [ "$sdk_status" -ne 0 ]; then
90-
log "sdkmanager command failed (exit $sdk_status): $SDKMANAGER $*" >&2
91-
return "$sdk_status"
92-
fi
93-
return 0
94-
}
95-
96-
cmdline_tool_dirs=(
97-
"$ANDROID_SDK_ROOT/cmdline-tools/latest/bin"
98-
"$ANDROID_SDK_ROOT/cmdline-tools/bin"
99-
"$ANDROID_SDK_ROOT/tools/bin"
100-
)
101-
while IFS= read -r -d '' dir; do
102-
cmdline_tool_dirs+=("$dir")
103-
done < <(find "$ANDROID_SDK_ROOT/cmdline-tools" -maxdepth 2 -type d -name bin -print0 2>/dev/null || true)
104-
105-
SDKMANAGER=$(find_tool sdkmanager "${cmdline_tool_dirs[@]}" || true)
106-
AVDMANAGER=$(find_tool avdmanager "${cmdline_tool_dirs[@]}" || true)
107-
108-
if [ -z "$SDKMANAGER" ] || [ -z "$AVDMANAGER" ]; then
109-
log "Required Android command-line tools were not found." >&2
110-
log "SDKMANAGER=$SDKMANAGER AVDMANAGER=$AVDMANAGER" >&2
111-
exit 1
112-
fi
113-
114-
run_sdkmanager_noninteractive "Accepting Android SDK licenses" --licenses
115-
116-
run_sdkmanager_noninteractive "Installing Android 35 ARM system image" --install \
117-
"platform-tools" \
118-
"platforms;android-35" \
119-
"emulator" \
120-
"system-images;android-35;google_apis;arm64-v8a"
121-
122-
EMU_BIN="$ANDROID_SDK_ROOT/emulator/emulator"
12364
ADB_BIN="$ANDROID_SDK_ROOT/platform-tools/adb"
12465

125-
if [ ! -x "$EMU_BIN" ] || [ ! -x "$ADB_BIN" ]; then
126-
log "Android emulator or adb binary not found after installation." >&2
127-
log "EMULATOR=$EMU_BIN ADB=$ADB_BIN" >&2
66+
if [ ! -x "$ADB_BIN" ]; then
67+
log "adb binary not found. Ensure Android platform-tools are installed." >&2
68+
log "ANDROID_SDK_ROOT=$ANDROID_SDK_ROOT"
12869
exit 1
12970
fi
13071

131-
AVD_NAME="cn1-api35-arm"
132-
if ! "$AVDMANAGER" list avd | grep -q "Name: $AVD_NAME"; then
133-
log "Creating AVD $AVD_NAME"
134-
if ! printf 'no\n' | "$AVDMANAGER" create avd -n "$AVD_NAME" -k "system-images;android-35;google_apis;arm64-v8a" -d pixel >/dev/null 2>&1; then
135-
log "Failed to create AVD $AVD_NAME" >&2
136-
exit 1
137-
fi
138-
fi
139-
140-
log "Starting AVD $AVD_NAME in headless mode"
141-
EMU_LOG="$TMPDIR/$AVD_NAME.log"
142-
: >"$EMU_LOG"
143-
"$EMU_BIN" -avd "$AVD_NAME" -no-boot-anim -no-audio -no-snapshot -no-window -gpu swiftshader_indirect -netfast \
144-
>"$EMU_LOG" 2>&1 &
145-
EMU_PID=$!
146-
dump_emulator_log() {
147-
if [ -f "$EMU_LOG" ]; then
148-
log "Emulator log tail ($EMU_LOG):"
149-
tail -n 200 "$EMU_LOG" | while IFS= read -r line; do
150-
echo "[run-android-instrumentation-tests] | $line"
151-
done
152-
fi
153-
}
154-
cleanup() {
155-
log "Cleaning up emulator"
156-
if [ -n "${EMULATOR_SERIAL:-}" ]; then
157-
"$ADB_BIN" -s "$EMULATOR_SERIAL" emu kill >/dev/null 2>&1 || true
158-
else
159-
"$ADB_BIN" emu kill >/dev/null 2>&1 || true
160-
fi
161-
kill "$EMU_PID" >/dev/null 2>&1 || true
162-
}
163-
trap cleanup EXIT
72+
ensure_emulator_ready() {
73+
log "Waiting for emulator to register with adb"
74+
"$ADB_BIN" start-server >/dev/null 2>&1 || true
16475

165-
log "Waiting for emulator to register with adb"
166-
"$ADB_BIN" start-server >/dev/null 2>&1 || true
76+
local adb_device_timeout=180
77+
for _ in $(seq 1 "$adb_device_timeout"); do
78+
EMULATOR_SERIAL=$("$ADB_BIN" devices | awk 'NR>1 && /^emulator-/{print $1; exit}') || true
79+
if [ -n "${EMULATOR_SERIAL:-}" ]; then
80+
break
81+
fi
82+
sleep 1
83+
done
16784

168-
ADB_DEVICE_TIMEOUT=180
169-
for _ in $(seq 1 "$ADB_DEVICE_TIMEOUT"); do
170-
if ! kill -0 "$EMU_PID" >/dev/null 2>&1; then
171-
log "Emulator process exited before appearing in adb" >&2
172-
dump_emulator_log
85+
if [ -z "${EMULATOR_SERIAL:-}" ]; then
86+
log "No emulator appeared in adb devices within ${adb_device_timeout}s" >&2
87+
"$ADB_BIN" devices >&2 || true
88+
cat <<'EOF' >&2
89+
Ensure an Android emulator is booted before invoking this script. In CI, run it
90+
inside the reactivecircus/android-emulator-runner action (see scripts-android.yml).
91+
EOF
17392
exit 1
17493
fi
175-
EMULATOR_SERIAL=$("$ADB_BIN" devices | awk 'NR>1 && /^emulator-/{print $1; exit}') || true
176-
if [ -n "${EMULATOR_SERIAL:-}" ]; then
177-
break
178-
fi
179-
sleep 1
180-
done
18194

182-
if [ -z "${EMULATOR_SERIAL:-}" ]; then
183-
log "Emulator did not appear in adb devices within ${ADB_DEVICE_TIMEOUT}s" >&2
184-
dump_emulator_log
185-
exit 1
186-
fi
95+
log "Waiting for emulator to boot"
96+
local boot_completed="0"
97+
for _ in $(seq 1 120); do
98+
boot_completed=$("$ADB_BIN" -s "$EMULATOR_SERIAL" shell getprop sys.boot_completed 2>/dev/null | tr -d '\r') || true
99+
if [ "$boot_completed" = "1" ]; then
100+
break
101+
fi
102+
sleep 5
103+
done
187104

188-
log "Waiting for emulator to boot"
189-
BOOT_COMPLETED="0"
190-
for _ in $(seq 1 120); do
191-
BOOT_COMPLETED=$("$ADB_BIN" -s "$EMULATOR_SERIAL" shell getprop sys.boot_completed 2>/dev/null | tr -d '\r') || true
192-
if [ "$BOOT_COMPLETED" = "1" ]; then
193-
break
194-
fi
195-
if ! kill -0 "$EMU_PID" >/dev/null 2>&1; then
196-
log "Emulator process exited before boot completed" >&2
197-
dump_emulator_log
105+
if [ "$boot_completed" != "1" ]; then
106+
log "Emulator did not boot in the allotted time" >&2
198107
exit 1
199108
fi
200-
sleep 5
201-
done
109+
}
202110

203-
if [ "$BOOT_COMPLETED" != "1" ]; then
204-
log "Emulator did not boot in the allotted time" >&2
205-
dump_emulator_log
206-
exit 1
207-
fi
111+
ensure_emulator_ready
208112

209113
log "Executing connected Android tests"
210114
chmod +x "$GRADLE_PROJECT_DIR/gradlew"

0 commit comments

Comments
 (0)