-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Expand file tree
/
Copy pathensure-simulator-ready.sh
More file actions
executable file
·182 lines (157 loc) · 5.35 KB
/
Copy pathensure-simulator-ready.sh
File metadata and controls
executable file
·182 lines (157 loc) · 5.35 KB
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#!/bin/bash
# Wait until an iOS Simulator is fully ready for integration tests (including first-boot
# data migration). Intended to run after futureware-tech/simulator-action (or any step
# that has issued simctl boot) and before flutter test / flutter drive.
#
# Usage:
# SIMULATOR=<udid-or-device-name> ./ensure-simulator-ready.sh
# ./ensure-simulator-ready.sh <udid-or-device-name>
#
# Environment:
# SIMULATOR UDID or device name (required if not passed as arg)
# BOOT_POLL_INTERVAL_SECONDS Poll interval (default: 20)
# BOOT_PROBE_TIMEOUT_SECONDS Per-probe timeout (default: 12)
# BOOT_MAX_WAIT_SECONDS Max wait for full boot (default: 660)
# ENSURE_OPEN_SIMULATOR_APP Open Simulator.app when booting (default: 1)
# ENSURE_BOOT_IF_NEEDED simctl boot when not Booted yet (default: 1)
set -euo pipefail
BOOT_POLL_INTERVAL_SECONDS="${BOOT_POLL_INTERVAL_SECONDS:-20}"
BOOT_PROBE_TIMEOUT_SECONDS="${BOOT_PROBE_TIMEOUT_SECONDS:-12}"
BOOT_MAX_WAIT_SECONDS="${BOOT_MAX_WAIT_SECONDS:-660}"
ENSURE_OPEN_SIMULATOR_APP="${ENSURE_OPEN_SIMULATOR_APP:-1}"
ENSURE_BOOT_IF_NEEDED="${ENSURE_BOOT_IF_NEEDED:-1}"
DEVICE="${SIMULATOR:-${1:-}}"
if [[ -z "$DEVICE" ]]; then
echo "[boot-status] ERROR: set SIMULATOR or pass device UDID/name as first argument" >&2
exit 1
fi
run_with_timeout() {
local max="$1"
shift
"$@" &
local cmd_pid=$!
local waited=0
while kill -0 "$cmd_pid" 2>/dev/null && (( waited < max )); do
sleep 1
waited=$((waited + 1))
done
if kill -0 "$cmd_pid" 2>/dev/null; then
kill "$cmd_pid" 2>/dev/null
wait "$cmd_pid" 2>/dev/null || true
return 124
fi
wait "$cmd_pid"
}
log_boot_status() {
echo "[boot-status] $*"
}
is_udid() {
[[ "$1" =~ ^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$ ]]
}
describe_booted_device() {
local device="$1"
if is_udid "$device"; then
xcrun simctl list devices booted 2>/dev/null \
| grep -F "$device" \
| grep -v 'unavailable' \
| head -1 \
|| true
else
xcrun simctl list devices booted 2>/dev/null \
| grep -i "${device} (" \
| grep -v 'Phone:' \
| grep -v 'unavailable' \
| grep -v CoreSimulator \
| head -1 \
|| true
fi
}
is_device_booted() {
[[ -n "$(describe_booted_device "$1")" ]]
}
log_migration_status() {
local device="$1"
local migration_output probe_rc
log_boot_status "probing data migration (bootstatus -d, up to ${BOOT_PROBE_TIMEOUT_SECONDS}s)..."
set +e
migration_output="$(run_with_timeout "$BOOT_PROBE_TIMEOUT_SECONDS" xcrun simctl bootstatus "$device" -d 2>&1)"
probe_rc=$?
set -e
if [[ "$probe_rc" -eq 124 ]]; then
log_boot_status " data migration / system bring-up still in progress"
return 1
fi
if [[ -n "$migration_output" ]]; then
while IFS= read -r line; do
[[ -z "$line" ]] && continue
log_boot_status " ${line}"
done <<<"$migration_output"
else
log_boot_status " no migration details reported"
fi
return 0
}
wait_for_simulator_ready() {
local device="$1"
local start=$SECONDS
while (( SECONDS - start < BOOT_MAX_WAIT_SECONDS )); do
local elapsed=$(( SECONDS - start ))
local booted_line ready_rc
log_boot_status "elapsed=${elapsed}s phase=wait_for_full_boot device=\"${device}\""
booted_line="$(describe_booted_device "$device")"
if [[ -z "$booted_line" ]]; then
log_boot_status " simctl list: not in Booted state yet"
else
log_boot_status " simctl list: ${booted_line}"
log_migration_status "$device" || true
fi
set +e
run_with_timeout "$BOOT_PROBE_TIMEOUT_SECONDS" xcrun simctl bootstatus "$device" >/dev/null 2>&1
ready_rc=$?
set -e
if [[ "$ready_rc" -eq 0 ]]; then
log_boot_status "bootstatus: simulator ready after ${elapsed}s"
log_migration_status "$device" || true
return 0
fi
if [[ "$ready_rc" -eq 124 ]]; then
log_boot_status "bootstatus: still booting (probe timed out after ${BOOT_PROBE_TIMEOUT_SECONDS}s)"
else
log_boot_status "bootstatus: probe exited with status ${ready_rc}"
fi
sleep "$BOOT_POLL_INTERVAL_SECONDS"
done
log_boot_status "ERROR: timed out after ${BOOT_MAX_WAIT_SECONDS}s waiting for simulator to become ready"
return 1
}
if is_udid "$DEVICE"; then
log_boot_status "phase=resolve_device udid=\"${DEVICE}\""
else
log_boot_status "phase=resolve_device name=\"${DEVICE}\""
fi
if ! is_device_booted "$DEVICE"; then
if [[ "$ENSURE_BOOT_IF_NEEDED" == "1" ]]; then
log_boot_status "phase=boot_command device not Booted; starting simctl boot..."
set +e
boot_output="$(xcrun simctl boot "$DEVICE" 2>&1)"
boot_rc=$?
set -e
if [[ "$boot_rc" -ne 0 ]]; then
log_boot_status "simctl boot exited ${boot_rc}: ${boot_output}"
else
log_boot_status "simctl boot command returned (device may still be migrating data)"
fi
if [[ "$ENSURE_OPEN_SIMULATOR_APP" == "1" ]]; then
log_boot_status "phase=foreground_simulator opening Simulator.app..."
open -a Simulator.app || true
fi
else
log_boot_status "phase=boot_command skipped (ENSURE_BOOT_IF_NEEDED=0); waiting for existing boot..."
fi
else
log_boot_status "phase=boot_command device already Booted; waiting for full readiness..."
fi
if ! wait_for_simulator_ready "$DEVICE"; then
exit 1
fi
log_boot_status "phase=complete device=\"${DEVICE}\" ready for flutter test"