From 8443487ad5fca1607fa975af252362572915068d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= Date: Wed, 3 Apr 2019 10:09:11 -0700 Subject: [PATCH] Avoid failing Obj-C tests when xcpretty is not installed (#24173) Summary: Fixes an issue where `scripts/objc-test-ios.sh` would fail if `xcpretty` is not installed. As this tool is not bundled with macOS, and it's not explicitly called out in our docs on testing, the script should not fail if it's not present. In a related change, JUnit reports are written to a more sensible location when the script is run outside of Circle CI. [iOS] [Fixed] - Fixed test script failure when xcpretty is not present Pull Request resolved: https://github.com/facebook/react-native/pull/24173 Differential Revision: D14726101 Pulled By: hramos fbshipit-source-id: 9f3081a75a4a262f55aef8498241fe7d1e04b931 --- scripts/objc-test-ios.sh | 3 +- scripts/objc-test-tvos.sh | 1 + scripts/objc-test.sh | 114 +++++++++++++++++++++++--------------- 3 files changed, 73 insertions(+), 45 deletions(-) diff --git a/scripts/objc-test-ios.sh b/scripts/objc-test-ios.sh index 10d0f00a8..48100cc9e 100755 --- a/scripts/objc-test-ios.sh +++ b/scripts/objc-test-ios.sh @@ -11,7 +11,7 @@ # also run the RNTester integration test (needs JS and packager): # ./objc-test-ios.sh test -set -ex +set -e SCRIPTS=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) ROOT=$(dirname "$SCRIPTS") @@ -25,6 +25,7 @@ export TEST_NAME="iOS" export SCHEME="RNTester" export SDK="iphonesimulator" export DESTINATION="platform=iOS Simulator,name=${IOS_DEVICE},OS=${IOS_TARGET_OS}" +export USE_MODERN_BUILD_SYSTEM="NO" # If there's a "test" argument, pass it to the test script. ./scripts/objc-test.sh $1 diff --git a/scripts/objc-test-tvos.sh b/scripts/objc-test-tvos.sh index e58ac222f..281dd4672 100755 --- a/scripts/objc-test-tvos.sh +++ b/scripts/objc-test-tvos.sh @@ -25,6 +25,7 @@ export TEST_NAME="tvOS" export SCHEME="RNTester-tvOS" export SDK="appletvsimulator" export DESTINATION="platform=tvOS Simulator,name=${TVOS_DEVICE},OS=${IOS_TARGET_OS}" +export USE_MODERN_BUILD_SYSTEM="NO" # If there's a "test" argument, pass it to the test script. ./scripts/objc-test.sh $1 diff --git a/scripts/objc-test.sh b/scripts/objc-test.sh index 08ef7205e..daa03b7ae 100755 --- a/scripts/objc-test.sh +++ b/scripts/objc-test.sh @@ -12,15 +12,11 @@ # also run the RNTester integration test (needs JS and packager). # ./objc-test.sh test -set -ex - SCRIPTS=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) ROOT=$(dirname "$SCRIPTS") -cd "$ROOT" - # Create cleanup handler -function cleanup { +cleanup() { EXIT=$? set +e @@ -34,14 +30,13 @@ function cleanup { # kill whatever is occupying port 5555 (web socket server) lsof -i tcp:5555 | awk 'NR!=1 {print $2}' | xargs kill } -trap cleanup EXIT # Wait for the package to start -function waitForPackager { +waitForPackager() { local -i max_attempts=60 local -i attempt_num=1 - until $(curl -s http://localhost:8081/status | grep "packager-status:running" -q); do + 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 @@ -55,47 +50,78 @@ function waitForPackager { echo "Packager is ready!" } -# If first argument is "test", actually start the packager and run tests. -# Otherwise, just build RNTester for tvOS and exit +runTests() { + xcodebuild \ + -project "RNTester/RNTester.xcodeproj" \ + -scheme "$SCHEME" \ + -sdk "$SDK" \ + -destination "$DESTINATION" \ + -UseModernBuildSystem="$USE_MODERN_BUILD_SYSTEM" \ + build test +} -if [ "$1" = "test" ]; then +buildProject() { + xcodebuild \ + -project "RNTester/RNTester.xcodeproj" \ + -scheme "$SCHEME" \ + -sdk "$SDK" \ + -UseModernBuildSystem="$USE_MODERN_BUILD_SYSTEM" \ + build +} -# Start the packager -yarn start --max-workers=1 || echo "Can't start packager automatically" & -# Start the WebSocket test server -open "./IntegrationTests/launchWebSocketServer.command" || echo "Can't start web socket server automatically" +xcprettyFormat() { + if [ "$CI" ]; then + # Circle CI expects JUnit reports to be available here + REPORTS_DIR="$HOME/react-native/reports" + else + THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd) -waitForPackager + # Write reports to the react-native root dir + REPORTS_DIR="$THIS_DIR/../build/reports" + fi -# Preload the RNTesterApp bundle for better performance in integration tests -curl 'http://localhost:8081/RNTester/js/RNTesterApp.ios.bundle?platform=ios&dev=true' -o temp.bundle -rm temp.bundle -curl 'http://localhost:8081/RNTester/js/RNTesterApp.ios.bundle?platform=ios&dev=true&minify=false' -o temp.bundle -rm temp.bundle -curl 'http://localhost:8081/IntegrationTests/IntegrationTestsApp.bundle?platform=ios&dev=true' -o temp.bundle -rm temp.bundle -curl 'http://localhost:8081/IntegrationTests/RCTRootViewIntegrationTestApp.bundle?platform=ios&dev=true' -o temp.bundle -rm temp.bundle + xcpretty --report junit --output "$REPORTS_DIR/junit/$TEST_NAME/results.xml" +} -# Run tests -xcodebuild \ - -project "RNTester/RNTester.xcodeproj" \ - -scheme "$SCHEME" \ - -sdk "$SDK" \ - -destination "$DESTINATION" \ - -UseModernBuildSystem=NO \ - build test \ - | xcpretty --report junit --output "$HOME/react-native/reports/junit/$TEST_NAME/results.xml" \ - && exit "${PIPESTATUS[0]}" +preloadBundles() { + # Preload the RNTesterApp bundle for better performance in integration tests + curl -s 'http://localhost:8081/RNTester/js/RNTesterApp.ios.bundle?platform=ios&dev=true' -o /dev/null + curl -s 'http://localhost:8081/RNTester/js/RNTesterApp.ios.bundle?platform=ios&dev=true&minify=false' -o /dev/null + curl -s 'http://localhost:8081/IntegrationTests/IntegrationTestsApp.bundle?platform=ios&dev=true' -o /dev/null + curl -s 'http://localhost:8081/IntegrationTests/RCTRootViewIntegrationTestApp.bundle?platform=ios&dev=true' -o /dev/null +} -else +main() { + cd "$ROOT" || exit -# Don't run tests. No need to pass -destination to xcodebuild. -xcodebuild \ - -project "RNTester/RNTester.xcodeproj" \ - -scheme "$SCHEME" \ - -sdk "$SDK" \ - -UseModernBuildSystem=NO \ - build + # If first argument is "test", actually start the packager and run tests. + # Otherwise, just build RNTester and exit + if [ "$1" = "test" ]; then -fi + # Start the packager + yarn start --max-workers=1 || echo "Can't start packager automatically" & + # Start the WebSocket test server + open "./IntegrationTests/launchWebSocketServer.command" || echo "Can't start web socket server automatically" + + waitForPackager + preloadBundles + + # Build and run tests. + if [ -x "$(command -v xcpretty)" ]; then + runTests | xcprettyFormat && exit "${PIPESTATUS[0]}" + else + echo 'Warning: xcpretty is not installed. Install xcpretty to generate JUnit reports.' + runTests + fi + else + # Build without running tests. + if [ -x "$(command -v xcpretty)" ]; then + buildProject | xcprettyFormat && exit "${PIPESTATUS[0]}" + else + buildProject + fi + fi +} + +trap cleanup EXIT +main "$@"