Skip to content

Commit

Permalink
Isolate the buck OSS commands inside test_buck (#34378)
Browse files Browse the repository at this point in the history
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: #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
  • Loading branch information
cortinico authored and facebook-github-bot committed Aug 11, 2022
1 parent e0be14a commit 4699a39
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 88 deletions.
147 changes: 59 additions & 88 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }}
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1337,6 +1307,7 @@ workflows:
parameters:
newarchitecture: [true, false]
flavor: ["Debug", "Release"]
- test_buck
- test_ios_template:
requires:
- build_npm_package
Expand Down
25 changes: 25 additions & 0 deletions scripts/circleci/buckToJunit/buckToJunit.sh
Original file line number Diff line number Diff line change
@@ -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"
58 changes: 58 additions & 0 deletions scripts/circleci/buckToJunit/buckToJunit.xsl
Original file line number Diff line number Diff line change
@@ -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>

0 comments on commit 4699a39

Please sign in to comment.