blob: 242cee3ceb70e660d686af30bc392c798434d2e9 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#!/bin/sh
# Run scrcpy-android tests inside the project-local Docker image.
#
# ./test unit tests (JVM only, no KVM)
# ./test unit same
# ./test e2e single-emulator self-mirror E2E (needs /dev/kvm)
# ./test all unit + e2e
# ./test record boot emulator, run a Mirror session, inject events,
# capture screen recording to ./output.mp4 (needs /dev/kvm)
# ./test apk build a signed release APK with a throwaway keystore
# (exercises scripts/build-apk end-to-end, no KVM)
#
# The image is built on first run and cached as $IMG.
# /dev/kvm must be readable by the invoking user for `./test e2e` and `record`.
set -eu
ROOT="$(cd "$(dirname "$0")" && pwd)"
# The image tag is a hash of the rig inputs, so editing the Dockerfile
# or the SDK package list automatically invalidates the cached image.
IMG="scrcpy-android-test:$(cat "$ROOT/test-rig/Dockerfile" "$ROOT/test-rig/sdk-packages.txt" | sha256sum | cut -c1-12)"
cmd="${1:-unit}"
case "$cmd" in
unit|e2e|all|record|apk) ;;
-h|--help)
# Usage is the header comment block: print from line 2 down to
# the first non-comment line.
awk 'NR > 1 && /^#/ { sub(/^# ?/, ""); print; next } NR > 1 { exit }' "$0" >&2
exit 0 ;;
*)
echo "usage: $0 [unit|e2e|all|record|apk]" >&2
exit 2 ;;
esac
# Cheap supply-chain check: the gradle wrapper jar is a small binary
# we check into the tree; verify its sha before letting it run.
"$ROOT/scripts/check-wrapper"
# Build the image if needed. --network=host so RUN apt/curl can reach
# the outside on hosts where the default docker bridge has no DNS.
if ! docker image inspect "$IMG" >/dev/null 2>&1; then
echo "test: building $IMG (first run, ~10 min)" >&2
# Cheap pre-flight: warn the user up-front if the host can't resolve
# the docker registry, so they don't watch an apt step time out.
if ! getent hosts registry-1.docker.io >/dev/null 2>&1; then
echo "test: WARNING - registry-1.docker.io did not resolve via /etc/resolv.conf." >&2
echo " Build will likely fail. Fix the host DNS (e.g." >&2
echo " append 'nameserver 1.1.1.1' to /etc/resolv.conf) and retry." >&2
fi
docker build --network=host -t "$IMG" "$ROOT/test-rig"
fi
# KVM check for tiers that boot the emulator.
needs_kvm=
case "$cmd" in
e2e|all|record) needs_kvm=1 ;;
esac
kvm_args=
if [ -n "$needs_kvm" ]; then
if [ ! -e /dev/kvm ]; then
echo "test: /dev/kvm not present on this host - e2e cannot run." >&2
exit 3
fi
if [ ! -r /dev/kvm ] || [ ! -w /dev/kvm ]; then
echo "test: /dev/kvm exists but is not rw for uid $(id -u)." >&2
echo " one-time fix:" >&2
echo " sudo chmod 666 /dev/kvm" >&2
echo " or add yourself to the kvm group and re-login:" >&2
echo " sudo usermod -aG kvm $(id -un)" >&2
exit 3
fi
# Pass through /dev/kvm's owning gid (numeric - group names from the
# host don't exist inside the container) so the container user
# (mapped to host uid:gid) can actually open it.
kvm_args="--device /dev/kvm --group-add $(stat -c %g /dev/kvm)"
fi
# Forward Ctrl-C cleanly, run as the host user so files in .tools/ stay
# owned by the invoker (avoids root-owned gradle cache on the host).
# --network=host so the gradle wrapper can fetch the distribution and
# maven deps in environments where the docker bridge DNS misbehaves.
exec docker run --rm -i \
--network=host \
$kvm_args \
-u "$(id -u):$(id -g)" \
-v "$ROOT":/work \
-w /work \
-e HOME=/work/.tools/home \
"$IMG" \
/work/test-rig/run.sh "$cmd"
|