Isolate the buck OSS commands inside test_buck (#34378)

Summary:
This isolates and parallelize all the BUCK related work inside a `test_buck` job, so it's immediately clear where a failure happend.

I've also added a couple of minor improvements:
- Don't clone okbuck just to consume a script. I've copied the script over instead.
- Removed unnecessary `buck_cache_key`

This should reduce ~5 minute of build time from Test Android which was already beyond 10 minutes.

## Changelog

[Internal] - Isolate the buck OSS commands inside test_buck

Pull Request resolved: https://github.com/facebook/react-native/pull/34378

Test Plan: Let's wait for a `test_buck` and `test_android` output.

Reviewed By: cipolleschi

Differential Revision: D38580359

Pulled By: cortinico

fbshipit-source-id: 8b3915bbc28b4a7a169011fe9047f402c2d1f6ee
This commit is contained in:
Nicola Corti 2022-08-11 02:46:00 -07:00 committed by Facebook GitHub Bot
parent e0be14a310
commit 4699a39489
3 changed files with 142 additions and 88 deletions

View File

@ -47,7 +47,6 @@ references:
# Anchors for the cache keys
cache_keys:
buck_cache_key: &buck_cache_key v3-buck-v2019.01.10.01-{{ checksum "scripts/circleci/buck_fetch.sh" }}}
checkout_cache_key: &checkout_cache_key v1-checkout
gems_cache_key: &gems_cache_key v1-gems-{{ checksum "Gemfile.lock" }}
gradle_cache_key: &gradle_cache_key v1-gradle-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{ checksum "ReactAndroid/gradle.properties" }}
@ -177,25 +176,6 @@ commands:
- ~/.cache/yarn
key: << parameters.yarn_base_cache_key >>-{{ arch }}-{{ checksum "yarn.lock" }}
install_buck_tooling:
steps:
- restore_cache:
keys:
- *buck_cache_key
- run:
name: Install BUCK
command: |
buck --version
# Install related tooling
if [[ ! -e ~/okbuck ]]; then
git clone https://github.com/uber/okbuck.git ~/okbuck --depth=1
fi
- save_cache:
paths:
- ~/buck
- ~/okbuck
key: *buck_cache_key
install_github_bot_deps:
steps:
- run:
@ -247,12 +227,6 @@ commands:
- ReactAndroid/build/third-party-ndk
key: *gradle_cache_key
download_buck_dependencies:
steps:
- run:
name: Download Dependencies Using Buck
command: ./scripts/circleci/buck_fetch.sh
run_e2e:
parameters:
platform:
@ -560,6 +534,62 @@ jobs:
- store_test_results:
path: ./reports/junit
# -------------------------
# JOBS: Test Buck
# -------------------------
test_buck:
executor: reactnativeandroid
environment:
KOTLIN_HOME=third-party/kotlin
steps:
- checkout
- setup_artifacts
- run_yarn
- run:
name: Download Dependencies Using Buck
command: ./scripts/circleci/buck_fetch.sh
- run:
name: Build & Test React Native using Buck
command: |
buck build ReactAndroid/src/main/java/com/facebook/react
buck build ReactAndroid/src/main/java/com/facebook/react/shell
- run:
name: Validate Android Test Environment
command: ./scripts/validate-android-test-env.sh
- run:
name: Run Tests - Android Unit Tests with Buck
command: buck test ReactAndroid/src/test/... --config build.threads=$BUILD_THREADS --xml ./reports/buck/all-results-raw.xml
- run:
name: Build JavaScript Bundle for instrumentation tests
command: node cli.js bundle --max-workers 2 --platform android --dev true --entry-file ReactAndroid/src/androidTest/js/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
- run:
name: Build Tests - Android Instrumentation Tests with Buck
# Here, just build the instrumentation tests. There is a known issue with installing the APK to android-21+ emulator.
command: |
if [[ ! -e ReactAndroid/src/androidTest/assets/AndroidTestBundle.js ]]; then
echo "JavaScript bundle missing, cannot run instrumentation tests. Verify Build JavaScript Bundle step completed successfully."; exit 1;
fi
source scripts/android-setup.sh && NO_BUCKD=1 retry3 timeout 300 buck build ReactAndroid/src/androidTest/buck-runner:instrumentation-tests --config build.threads=$BUILD_THREADS
- run:
name: Collect Test Results
command: |
find . -type f -regex ".*/build/test-results/debug/.*xml" -exec cp {} ./reports/build/ \;
find . -type f -regex ".*/outputs/androidTest-results/connected/.*xml" -exec cp {} ./reports/outputs/ \;
find . -type f -regex ".*/buck-out/gen/ReactAndroid/src/test/.*/.*xml" -exec cp {} ./reports/buck/ \;
if [ -f ~/react-native/reports/buck/all-results-raw.xml ]; then
~/react-native/scripts/circleci/buckToJunit/buckToJunit.sh ~/react-native/reports/buck/all-results-raw.xml ~/react-native/reports/junit/results.xml
fi
when: always
- store_test_results:
path: ./reports/junit
# -------------------------
# JOBS: Test Android
@ -570,14 +600,11 @@ jobs:
run_disabled_tests:
type: boolean
default: false
environment:
KOTLIN_HOME=third-party/kotlin
steps:
- checkout
- setup_artifacts
- run_yarn
# Validate Android SDK installation and packages
- run:
name: Validate Android SDK Install
command: ./scripts/validate-android-sdk.sh
@ -591,60 +618,23 @@ jobs:
command: source scripts/android-setup.sh && launchAVD
background: true
# Install Buck
- install_buck_tooling
# Validate Android test environment (including Buck)
- run:
name: Validate Android Test Environment
command: ./scripts/validate-android-test-env.sh
- download_buck_dependencies
- download_gradle_dependencies
# Build and compile
- run:
name: Build & Test React Native using Buck
command: |
buck build ReactAndroid/src/main/java/com/facebook/react
buck build ReactAndroid/src/main/java/com/facebook/react/shell
- run:
name: Build & Test React Native using Gradle
command: ./gradlew buildAll
- run:
name: Compile Native Libs for Unit and Integration Tests
command: ./gradlew :ReactAndroid:packageReactNdkLibsForBuck -Pjobs=$BUILD_THREADS
no_output_timeout: 30m
- run:
name: Build RN Tester for Release using Gradle
command: ./gradlew packages:rn-tester:android:app:assembleRelease
# Build JavaScript Bundle for instrumentation tests
- run:
name: Build JavaScript Bundle
command: node cli.js bundle --max-workers 2 --platform android --dev true --entry-file ReactAndroid/src/androidTest/js/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
# Wait for AVD to finish booting before running tests
- run:
name: Wait for Android Virtual Device
command: source scripts/android-setup.sh && waitForAVD
# -------------------------
# Run Android tests
- run:
name: Run Tests - Android Unit Tests with Buck
command: buck test ReactAndroid/src/test/... --config build.threads=$BUILD_THREADS --xml ./reports/buck/all-results-raw.xml
- run:
name: Build Tests - Android Instrumentation Tests with Buck
# Here, just build the instrumentation tests. There is a known issue with installing the APK to android-21+ emulator.
command: |
if [[ ! -e ReactAndroid/src/androidTest/assets/AndroidTestBundle.js ]]; then
echo "JavaScript bundle missing, cannot run instrumentation tests. Verify Build JavaScript Bundle step completed successfully."; exit 1;
fi
source scripts/android-setup.sh && NO_BUCKD=1 retry3 timeout 300 buck build ReactAndroid/src/androidTest/buck-runner:instrumentation-tests --config build.threads=$BUILD_THREADS
- report_bundle_size:
platform: android
# Optionally, run disabled tests
- when:
@ -653,24 +643,6 @@ jobs:
- run: echo "Failing tests may be moved here temporarily."
- run_e2e:
platform: android
# -------------------------
# Collect Results
- report_bundle_size:
platform: android
- run:
name: Collect Test Results
command: |
find . -type f -regex ".*/build/test-results/debug/.*xml" -exec cp {} ./reports/build/ \;
find . -type f -regex ".*/outputs/androidTest-results/connected/.*xml" -exec cp {} ./reports/outputs/ \;
find . -type f -regex ".*/buck-out/gen/ReactAndroid/src/test/.*/.*xml" -exec cp {} ./reports/buck/ \;
if [ -f ~/react-native/reports/buck/all-results-raw.xml ]; then
cd ~/okbuck
./tooling/junit/buck_to_junit.sh ~/react-native/reports/buck/all-results-raw.xml ~/react-native/reports/junit/results.xml
fi
when: always
- store_test_results:
path: ./reports/junit
# -------------------------
# JOBS: Test Android Template
@ -1183,8 +1155,6 @@ jobs:
cp -r $HERMES_WS_DIR/linux64-bin/* ./sdks/hermesc/linux64-bin/.
- run_yarn
- install_buck_tooling
- download_buck_dependencies
- download_gradle_dependencies
# START: Stables and nightlies
@ -1337,6 +1307,7 @@ workflows:
parameters:
newarchitecture: [true, false]
flavor: ["Debug", "Release"]
- test_buck
- test_ios_template:
requires:
- build_npm_package

View File

@ -0,0 +1,25 @@
#!/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.
# Get script directory
prog="$0"
while [ -h "${prog}" ]; do
newProg=$(/bin/ls -ld "${prog}")
newProg=$(expr "${newProg}" : ".* -> \(.*\)$")
if expr "x${newProg}" : 'x/' >/dev/null; then
prog="${newProg}"
else
progdir=$(dirname "${prog}")
prog="${progdir}/${newProg}"
fi
done
DIR=$(dirname "${prog}")
# We download saxon from Maven Central rather than copying it over.
curl https://repo1.maven.org/maven2/net/sf/saxon/Saxon-HE/9.7.0-11/Saxon-HE-9.7.0-11.jar --output "$DIR/saxon.jar"
# Perform conversion
java -jar "$DIR/saxon.jar" -xsl:"$DIR/buckToJunit.xsl" -s:"$1" -o:"$2"

View File

@ -0,0 +1,58 @@
<?xml version="1.0"?>
<!--
Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:func="com.google.gerrit" xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="func" version="2.0">
<xsl:output method="xml" omit-xml-declaration="no" indent="yes" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/tests">
<xsl:result-document method="xml">
<testsuites>
<xsl:apply-templates/>
</testsuites>
</xsl:result-document>
</xsl:template>
<xsl:template match="test">
<xsl:variable name="testCount" select="count(testresult)"/>
<xsl:variable name="nonEmptyStacks" select="count(testresult[stacktrace != ''])"/>
<xsl:variable name="failures"
select="count(testresult[contains(stacktrace, 'java.lang.AssertionError')])"/>
<xsl:variable name="errors" select="$nonEmptyStacks - $failures"/>
<testsuite failures="{$failures}" time="{func:toMS(@time)}" errors="{$errors}" skipped="0"
tests="{$testCount}" name="{@name}">
<xsl:apply-templates/>
</testsuite>
</xsl:template>
<xsl:template match="testresult">
<testcase time="{func:toMS(@time)}" classname="{../@name}" name="{@name}">
<xsl:apply-templates/>
</testcase>
</xsl:template>
<xsl:template match="message"/>
<xsl:template match="stacktrace[. != '']">
<failure message="{../message}" type="{substring-before(., ':')}">
<xsl:value-of select="."/>
</failure>
</xsl:template>
<xsl:function name="func:toMS">
<xsl:param name="sec" as="xs:decimal"/>
<xsl:value-of select="$sec div 1000"/>
</xsl:function>
</xsl:stylesheet>