From 15575e1acacc31d5aa5b993360d0d2b5416f68e8 Mon Sep 17 00:00:00 2001 From: Ovi Trif Date: Tue, 3 Nov 2026 00:11:49 +0100 Subject: [PATCH 1/3] ci: stop emulator teardown from hanging ui tests --- .github/scripts/run-ui-tests.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/scripts/run-ui-tests.sh b/.github/scripts/run-ui-tests.sh index 9a49ac52de..5361f0a288 100644 --- a/.github/scripts/run-ui-tests.sh +++ b/.github/scripts/run-ui-tests.sh @@ -2,6 +2,22 @@ set -euo pipefail +# The emulator runner waits for the emulator process to exit after `emu kill`, and an emulator that +# hangs while shutting down then holds the job until its timeout, after the tests already finished. +# Stop it here with a bounded wait so the test result decides the step. +EMULATOR_EXIT_TIMEOUT_SECONDS=30 + +stop_emulator() { + adb emu kill > /dev/null 2>&1 || true + for _ in $(seq "$EMULATOR_EXIT_TIMEOUT_SECONDS"); do + pgrep -f qemu-system > /dev/null || return 0 + sleep 1 + done + echo "::warning::Emulator did not exit ${EMULATOR_EXIT_TIMEOUT_SECONDS}s after emu kill; killing it." + pkill -9 -f qemu-system || true +} +trap stop_emulator EXIT + adb wait-for-device echo "Waiting for boot to complete..." adb shell 'while [ -z "$(getprop sys.boot_completed)" ]; do sleep 1; done' From 9aa22aa0a6f024791bd5f4a33275575f79a406ad Mon Sep 17 00:00:00 2001 From: Ovi Trif Date: Tue, 3 Nov 2026 01:04:15 +0100 Subject: [PATCH 2/3] ci: stop emulator helpers that keep the ui tests step open --- .github/scripts/run-ui-tests.sh | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/.github/scripts/run-ui-tests.sh b/.github/scripts/run-ui-tests.sh index 5361f0a288..f842422409 100644 --- a/.github/scripts/run-ui-tests.sh +++ b/.github/scripts/run-ui-tests.sh @@ -2,19 +2,29 @@ set -euo pipefail -# The emulator runner waits for the emulator process to exit after `emu kill`, and an emulator that -# hangs while shutting down then holds the job until its timeout, after the tests already finished. -# Stop it here with a bounded wait so the test result decides the step. +# The emulator runner waits until the emulator's output closes. Processes that outlive the emulator +# (its crashpad_handler, the Gradle daemon, the adb server) can keep it open and hold the job until +# its timeout after the tests already finished. Stop them here, with bounded waits, so the test +# result decides the step. EMULATOR_EXIT_TIMEOUT_SECONDS=30 stop_emulator() { + ./gradlew --stop > /dev/null 2>&1 || true adb emu kill > /dev/null 2>&1 || true + local exited=false for _ in $(seq "$EMULATOR_EXIT_TIMEOUT_SECONDS"); do - pgrep -f qemu-system > /dev/null || return 0 + if ! pgrep -f qemu-system > /dev/null; then + exited=true + break + fi sleep 1 done - echo "::warning::Emulator did not exit ${EMULATOR_EXIT_TIMEOUT_SECONDS}s after emu kill; killing it." - pkill -9 -f qemu-system || true + if [[ "$exited" != true ]]; then + echo "::warning::Emulator did not exit ${EMULATOR_EXIT_TIMEOUT_SECONDS}s after emu kill; killing it." + pkill -9 -f qemu-system || true + fi + pkill -9 -f crashpad_handler || true + adb kill-server > /dev/null 2>&1 || true } trap stop_emulator EXIT From e6cfbe8c2130f069c313370a7dcb3fa7d50f8579 Mon Sep 17 00:00:00 2001 From: Ovi Trif Date: Tue, 3 Nov 2026 08:37:36 +0100 Subject: [PATCH 3/3] ci: limit emulator teardown to github actions --- .github/scripts/run-ui-tests.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/scripts/run-ui-tests.sh b/.github/scripts/run-ui-tests.sh index f842422409..310e8154e5 100644 --- a/.github/scripts/run-ui-tests.sh +++ b/.github/scripts/run-ui-tests.sh @@ -5,7 +5,8 @@ set -euo pipefail # The emulator runner waits until the emulator's output closes. Processes that outlive the emulator # (its crashpad_handler, the Gradle daemon, the adb server) can keep it open and hold the job until # its timeout after the tests already finished. Stop them here, with bounded waits, so the test -# result decides the step. +# result decides the step. Only on GitHub Actions: the kills are host-wide, and a local run may share +# the host with other emulators. EMULATOR_EXIT_TIMEOUT_SECONDS=30 stop_emulator() { @@ -26,7 +27,9 @@ stop_emulator() { pkill -9 -f crashpad_handler || true adb kill-server > /dev/null 2>&1 || true } -trap stop_emulator EXIT +if [[ "${GITHUB_ACTIONS:-}" == "true" ]]; then + trap stop_emulator EXIT +fi adb wait-for-device echo "Waiting for boot to complete..."