From a0c4fbd70886bcaab805e6c22636c235abdd1a85 Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Mon, 20 Oct 2025 15:30:17 -0300 Subject: [PATCH 1/3] chore: Retry booting simulator up to 5 times --- scripts/ci-boot-simulator.sh | 90 +++++++++++++++++++++++++----------- 1 file changed, 63 insertions(+), 27 deletions(-) diff --git a/scripts/ci-boot-simulator.sh b/scripts/ci-boot-simulator.sh index 13cd2931f9..65299b85e4 100755 --- a/scripts/ci-boot-simulator.sh +++ b/scripts/ci-boot-simulator.sh @@ -95,36 +95,72 @@ end_group begin_group "Simulator Boot" log_notice "Booting simulator: $SIMULATOR - iOS $IOS_VERSION (UDID: $UDID)" -if ! xcrun simctl boot "$UDID" 2>/dev/null; then - # If boot fails, it might be because the simulator is already booted - CURRENT_STATE=$(xcrun simctl list devices | grep "$UDID" | sed 's/.*(\([^)]*\)).*$/\1/') - if [ "$CURRENT_STATE" = "Booted" ]; then - log_notice "Simulator is already booted" +MAX_BOOT_ATTEMPTS=5 +BOOT_TIMEOUT=180 # 3 minutes + +for attempt in $(seq 1 $MAX_BOOT_ATTEMPTS); do + log_notice "Boot attempt $attempt of $MAX_BOOT_ATTEMPTS" + + # Ensure simulator is shutdown before attempting to boot + if [ "$attempt" -gt 1 ]; then + log_notice "Shutting down simulator before retry..." + xcrun simctl shutdown "$UDID" 2>/dev/null || true + sleep 5 + fi + + # Attempt to boot the simulator + if ! xcrun simctl boot "$UDID" 2>/dev/null; then + # If boot fails, it might be because the simulator is already booted + CURRENT_STATE=$(xcrun simctl list devices | grep "$UDID" | sed 's/.*(\([^)]*\)).*$/\1/') + if [ "$CURRENT_STATE" = "Booted" ]; then + log_notice "Simulator is already booted" + else + log_error "Failed to boot simulator. Current state: $CURRENT_STATE" + if [ "$attempt" -eq "$MAX_BOOT_ATTEMPTS" ]; then + exit 1 + fi + continue + fi else - log_error "Failed to boot simulator. Current state: $CURRENT_STATE" - exit 1 + log_notice "Simulator boot command executed successfully" fi -else - log_notice "Simulator boot command executed successfully" -fi - -log_notice "Opening Simulator app UI" -# We use `open -a Simulator` because there's no lower-level CLI like `simctl` to display the simulator UI available. -if ! open -a Simulator; then - log_error "Failed to open Simulator app" - exit 1 -fi -log_notice "Simulator app opened successfully" -end_group + + # Open Simulator app UI (only on first attempt) + if [ "$attempt" -eq 1 ]; then + log_notice "Opening Simulator app UI" + if ! open -a Simulator; then + log_error "Failed to open Simulator app" + exit 1 + fi + log_notice "Simulator app opened successfully" + fi + + # Wait for simulator to fully boot with timeout + log_notice "Waiting for simulator to fully boot (timeout: ${BOOT_TIMEOUT}s)" + if timeout $BOOT_TIMEOUT xcrun simctl bootstatus "$UDID"; then + log_notice "Simulator boot process completed successfully" + break + else + EXIT_CODE=$? + if [ $EXIT_CODE -eq 124 ]; then + log_warning "Simulator boot timed out after ${BOOT_TIMEOUT} seconds" + else + log_warning "Simulator bootstatus failed with exit code $EXIT_CODE" + fi + + # Check current state for debugging + CURRENT_STATE=$(xcrun simctl list devices | grep "$UDID" | sed 's/.*(\([^)]*\)).*$/\1/') + log_warning "Current simulator state: $CURRENT_STATE" + + if [ "$attempt" -eq "$MAX_BOOT_ATTEMPTS" ]; then + log_error "Failed to boot simulator after $MAX_BOOT_ATTEMPTS attempts" + exit 1 + fi + + log_notice "Will retry booting simulator..." + fi +done -begin_group "Boot Status Verification" -log_notice "Waiting for simulator to fully boot (this may take a moment)" -# We need to wait for the simulator to boot to avoid the test to fail due to timeout (because the simulator is not booted yet) -if ! xcrun simctl bootstatus "$UDID"; then - log_error "Failed to verify simulator boot status" - exit 1 -fi -log_notice "Simulator boot process completed successfully" end_group begin_group "Booted Device Details" From f7a9f5de84ff60140719b33c80966fec2a2dc18e Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Mon, 20 Oct 2025 15:42:58 -0300 Subject: [PATCH 2/3] Add boot simulator script to uni test file filter --- .github/file-filters.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/file-filters.yml b/.github/file-filters.yml index fbd7279c60..a9af2996dd 100644 --- a/.github/file-filters.yml +++ b/.github/file-filters.yml @@ -36,6 +36,7 @@ run_unit_tests_for_prs: &run_unit_tests_for_prs - "scripts/sentry-xcodebuild.sh" - "scripts/start-test-server.sh" - "scripts/tests-with-thread-sanitizer.sh" + - "scripts/ci-boot-simulator.sh" # Test infrastructure - "test-server/**" From 950c456b09cc4b767dbf0ad4d19e33426f0e657f Mon Sep 17 00:00:00 2001 From: Itay Brenner Date: Mon, 20 Oct 2025 15:56:40 -0300 Subject: [PATCH 3/3] Use custom timeout script --- scripts/ci-boot-simulator.sh | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/scripts/ci-boot-simulator.sh b/scripts/ci-boot-simulator.sh index 65299b85e4..014b05fbc2 100755 --- a/scripts/ci-boot-simulator.sh +++ b/scripts/ci-boot-simulator.sh @@ -11,6 +11,33 @@ set -euo pipefail +# Timeout function that works on macOS without external dependencies +run_with_timeout() { + local timeout=$1 + shift + + # Run command in background + "$@" & + local pid=$! + + # Wait for command with timeout + local count=0 + while kill -0 $pid 2>/dev/null; do + if [ $count -ge "$timeout" ]; then + kill -TERM $pid 2>/dev/null || true + sleep 1 + kill -KILL $pid 2>/dev/null || true + return 124 # Same exit code as GNU timeout + fi + sleep 1 + ((count++)) + done + + # Get the exit code of the command + wait $pid + return $? +} + # Disable SC1091 because it won't work with pre-commit # shellcheck source=./scripts/ci-utils.sh disable=SC1091 source "$(cd "$(dirname "$0")" && pwd)/ci-utils.sh" @@ -137,7 +164,7 @@ for attempt in $(seq 1 $MAX_BOOT_ATTEMPTS); do # Wait for simulator to fully boot with timeout log_notice "Waiting for simulator to fully boot (timeout: ${BOOT_TIMEOUT}s)" - if timeout $BOOT_TIMEOUT xcrun simctl bootstatus "$UDID"; then + if run_with_timeout $BOOT_TIMEOUT xcrun simctl bootstatus "$UDID"; then log_notice "Simulator boot process completed successfully" break else