react-native/scripts/objc-test.sh
Riccardo Cipolleschi cf8d3f8007 Port CI improvements from Release branch to main (#45175)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45175

This change ports the CI improvements we made on stable branch to main.

## Changelog:
[Internal] - Port back to main improvements we made in GHA

Reviewed By: cortinico

Differential Revision: D59053873

fbshipit-source-id: 73eb7e33b9bbdc5d8c3a9294f487ad969b144bf3
2024-06-27 04:11:44 -07:00

196 lines
5.5 KiB
Bash
Executable File

#!/bin/bash
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
# Script used to run iOS tests.
# If no arguments are passed to the script, it will only compile
# the RNTester.
# If the script is called with a single argument "test", we'll
# run the RNTester unit and integration tests
# ./objc-test.sh test
SCRIPTS=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
ROOT=$(dirname "$SCRIPTS")
SKIPPED_TESTS=()
# TODO: T60408036 This test crashes iOS 13 for bad access, please investigate
# and re-enable. See https://gist.github.com/0xced/56035d2f57254cf518b5.
SKIPPED_TESTS+=("-skip-testing:RNTesterUnitTests/RCTJSONTests/testNotUTF8Convertible")
# Create cleanup handler
cleanup() {
EXIT=$?
set +e
if [ $EXIT -ne 0 ];
then
WATCHMAN_LOGS=/usr/local/Cellar/watchman/3.1/var/run/watchman/$USER.log
[ -f "$WATCHMAN_LOGS" ] && cat "$WATCHMAN_LOGS"
fi
# kill whatever is occupying port 8081 (packager)
lsof -i tcp:8081 | awk 'NR!=1 {print $2}' | xargs kill
# kill whatever is occupying port 5555 (web socket server)
lsof -i tcp:5555 | awk 'NR!=1 {print $2}' | xargs kill
}
# Wait for the package to start
waitForPackager() {
local -i max_attempts=60
local -i attempt_num=1
until curl -s http://localhost:8081/status | grep "packager-status:running" -q; do
if (( attempt_num == max_attempts )); then
echo "Packager did not respond in time. No more attempts left."
exit 1
else
(( attempt_num++ ))
echo "Packager did not respond. Retrying for attempt number $attempt_num..."
sleep 1
fi
done
echo "Packager is ready!"
}
waitForWebSocketServer() {
local -i max_attempts=60
local -i attempt_num=1
until curl -s http://localhost:5555 | grep "Upgrade Required" -q; do
if (( attempt_num == max_attempts )); then
echo "WebSocket Server did not respond in time. No more attempts left."
exit 1
else
(( attempt_num++ ))
echo "WebSocket Server did not respond. Retrying for attempt number $attempt_num..."
sleep 1
fi
done
echo "WebSocket Server is ready!"
}
runTests() {
# shellcheck disable=SC1091
source "$ROOT/scripts/.tests.env"
xcodebuild build test \
-workspace RNTesterPods.xcworkspace \
-scheme RNTester \
-sdk iphonesimulator \
-destination "platform=iOS Simulator,name=$IOS_DEVICE,OS=$IOS_TARGET_OS" \
"${SKIPPED_TESTS[@]}"
}
buildForTesting() {
# shellcheck disable=SC1091
source "$ROOT/scripts/.tests.env"
xcodebuild build-for-testing \
-workspace RNTesterPods.xcworkspace \
-scheme RNTester \
-sdk iphonesimulator
}
runTestsOnly() {
# shellcheck disable=SC1091
source "$ROOT/scripts/.tests.env"
echo "[Testing] Running tests on $IOS_DEVICE for OS $IOS_TARGET_OS"
xcodebuild test \
-workspace RNTesterPods.xcworkspace \
-scheme RNTester \
-sdk iphonesimulator \
-destination "platform=iOS Simulator,name=$IOS_DEVICE,OS=$IOS_TARGET_OS" \
"${SKIPPED_TESTS[@]}"
}
buildProject() {
xcodebuild build \
-workspace RNTesterPods.xcworkspace \
-scheme RNTester \
-sdk iphonesimulator
}
xcbeautifyFormat() {
if [ "$CI" ]; then
# Circle CI expects JUnit reports to be available here
REPORTS_DIR="$HOME/react-native/reports/junit"
else
THIS_DIR=$(cd -P "$(dirname "$(realpath "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd)
# Write reports to the react-native root dir
REPORTS_DIR="$THIS_DIR/../build/reports"
fi
xcbeautify --report junit --report-path "$REPORTS_DIR/ios/results.xml"
}
preloadBundlesRNIntegrationTests() {
# Preload IntegrationTests bundles (packages/rn-tester/)
curl -s 'http://localhost:8081/IntegrationTests/IntegrationTestsApp.bundle?platform=ios&dev=true' -o /dev/null
}
preloadBundlesRNTester() {
# Preload RNTesterApp bundles (packages/rn-tester/)
curl -s 'http://localhost:8081/js/RNTesterApp.ios.bundle?platform=ios&dev=true' -o /dev/null
curl -s 'http://localhost:8081/js/RNTesterApp.ios.bundle?platform=ios&dev=true&minify=false' -o /dev/null
}
main() {
cd "$ROOT/packages/rn-tester" || exit
# If first argument is "test", actually start the packager and run tests.
# Otherwise, just build RNTester and exit
if [ "$1" = "test" ]; then
# Start the WebSocket test server
echo "Launch WebSocket Server"
sh "./IntegrationTests/launchWebSocketServer.sh" &
waitForWebSocketServer
# Start the packager
yarn start --max-workers=1 || echo "Can't start packager automatically" &
waitForPackager
preloadBundlesRNTester
preloadBundlesRNIntegrationTests
buildForTesting
# Build and run tests.
RESULT=-1
MAX_RETRY=3
for ((i=1; i<=MAX_RETRY; i++))
do
echo "Attempt #$i of running tests..."
if [ -x "$(command -v xcbeautify)" ]; then
runTests | xcbeautifyFormat && exit "${PIPESTATUS[0]}"
RESULT="$?"
else
echo 'Warning: xcbeautify is not installed. Install xcbeautify to generate JUnit reports.'
runTests
RESULT="$?"
fi
if [[ "$RESULT" == 0 ]]; then
# Successful tests!
echo "Test completed successfully!"
exit 0
fi
done
echo "Test Failed with code $RESULT!"
exit $RESULT
else
# Build without running tests.
if [ -x "$(command -v xcbeautify)" ]; then
buildProject | xcbeautifyFormat && exit "${PIPESTATUS[0]}"
else
buildProject
fi
fi
}
trap cleanup EXIT
main "$@"