who_need_help/scripts/android-instrumentation-test.sh

151 lines
4.3 KiB
Bash
Executable File

#!/bin/sh
set -eu
ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
ANDROID_ENV="$ROOT/.env"
TEST_ENV="$ROOT/.env.android-test"
run_id=$(date -u +%Y%m%d%H%M%S)-$$
image="who-need-help-android:instrumentation-$run_id"
container="who-need-help-android-instrumentation-$run_id"
output="$ROOT/output/android-instrumentation/$run_id"
geo_pid=""
if [ ! -e /dev/kvm ]; then
echo "/dev/kvm is required for the containerized Android emulator." >&2
exit 1
fi
if [ ! -f "$ANDROID_ENV" ]; then
echo "Missing $ANDROID_ENV. Copy .env.example to .env and configure Android timings." >&2
exit 1
fi
"$ROOT/scripts/ensure-local-android-test-env.sh"
set -a
. "$ANDROID_ENV"
. "$TEST_ENV"
set +a
: "${WNH_ANDROID_TEST_BASE_URL:?Set WNH_ANDROID_TEST_BASE_URL in .env.android-test}"
: "${WNH_TRACKING_MIN_TIME_MS:?Set WNH_TRACKING_MIN_TIME_MS in .env}"
: "${WNH_TRACKING_HTTP_TIMEOUT_MS:?Set WNH_TRACKING_HTTP_TIMEOUT_MS in .env}"
android_test_port=${WNH_ANDROID_TEST_BASE_URL#http://127.0.0.1:}
if [ "$android_test_port" = "$WNH_ANDROID_TEST_BASE_URL" ]; then
echo "WNH_ANDROID_TEST_BASE_URL must be an http://127.0.0.1:PORT origin." >&2
exit 1
fi
case "$android_test_port" in
""|*[!0-9]*)
echo "WNH_ANDROID_TEST_BASE_URL must contain only a numeric port." >&2
exit 1
;;
esac
if [ "$android_test_port" -lt 1 ] || [ "$android_test_port" -gt 65535 ]; then
echo "WNH_ANDROID_TEST_BASE_URL port must be between 1 and 65535." >&2
exit 1
fi
mkdir -p "$output"
cleanup() {
status=$?
if [ -n "$geo_pid" ]; then
kill "$geo_pid" >/dev/null 2>&1 || true
wait "$geo_pid" >/dev/null 2>&1 || true
fi
if [ "$status" -ne 0 ] && docker inspect "$container" >/dev/null 2>&1; then
docker exec "$container" adb logcat -d > "$output/logcat.txt" 2>&1 || true
docker exec "$container" adb shell dumpsys activity services \
org.whoneedhelp.mobile.debug > "$output/services.txt" 2>&1 || true
docker logs "$container" > "$output/emulator.log" 2>&1 || true
fi
docker rm -f "$container" >/dev/null 2>&1 || true
docker image rm "$image" >/dev/null 2>&1 || true
exit "$status"
}
trap cleanup EXIT HUP INT TERM
docker build \
--build-arg "WNH_DEBUG_BASE_URL=$WNH_ANDROID_TEST_BASE_URL" \
--build-arg "WNH_TRACKING_MIN_TIME_MS=$WNH_TRACKING_MIN_TIME_MS" \
--build-arg "WNH_TRACKING_HTTP_TIMEOUT_MS=$WNH_TRACKING_HTTP_TIMEOUT_MS" \
--target emulator \
-t "$image" \
"$ROOT/android"
docker run -d \
--name "$container" \
--device /dev/kvm \
--network none \
"$image" > "$output/container-id.txt"
docker exec "$container" adb wait-for-device
booted=""
attempt=0
while [ "$attempt" -lt 90 ]; do
booted=$(docker exec "$container" adb shell getprop sys.boot_completed 2>/dev/null \
| tr -d '\r')
if [ "$booted" = "1" ]; then
break
fi
attempt=$((attempt + 1))
sleep 2
done
if [ "$booted" != "1" ]; then
echo "Android emulator did not finish booting." >&2
exit 1
fi
docker exec "$container" adb shell input keyevent 82
docker exec "$container" adb shell settings put global window_animation_scale 0
docker exec "$container" adb shell settings put global transition_animation_scale 0
docker exec "$container" adb shell settings put global animator_duration_scale 0
docker exec "$container" adb shell cmd location set-location-enabled true
docker exec "$container" adb emu geo fix -122.084000 37.422000
docker exec "$container" adb install -r \
/opt/who-need-help/who-need-help-debug.apk
docker exec "$container" adb install -r \
/opt/who-need-help/who-need-help-debug-androidTest.apk
docker exec "$container" adb shell pm list instrumentation \
> "$output/instrumentation.txt"
(
while docker inspect "$container" >/dev/null 2>&1; do
docker exec "$container" adb emu geo fix -122.084000 37.422000 \
>/dev/null 2>&1 || true
sleep 2
done
) &
geo_pid=$!
set +e
docker exec "$container" adb shell am instrument -w -r \
org.whoneedhelp.mobile.debug.test/androidx.test.runner.AndroidJUnitRunner \
> "$output/results.txt" 2>&1
instrumentation_status=$?
set -e
cat "$output/results.txt"
if [ "$instrumentation_status" -ne 0 ] \
|| ! grep -Eq '^OK \([0-9]+ tests?\)$' "$output/results.txt" \
|| grep -Eq 'FAILURES!!!|INSTRUMENTATION_FAILED|Process crashed' "$output/results.txt"; then
echo "Android instrumentation failed; diagnostics are retained in $output." >&2
exit 1
fi
echo "Android instrumentation passed. Evidence: $output"