Skip to content

Commit

Permalink
[core][Android] Fix instrumented tests (expo#23336)
Browse files Browse the repository at this point in the history
# Why

Fixes instrumented tests can't be run from the `bare-expo` project.

# How

While dealing with another issue, I came across a problem - I couldn't run instrumented tests from the `bare-expo` project. After some investigation, I discovered that Hermes was misconfigured. I realized that Hermes should be added by prefabs, so I removed the logic responsible for downloading it. Although I'm not entirely certain if it's entirely safe, I performed a clean build and everything seemed to work correctly. cc @Kudo 

# Test Plan

- bare-expo ✅
- instrumented tests ✅
  • Loading branch information
lukmccall authored Jul 12, 2023
1 parent 2f368b8 commit 61b1559
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 89 deletions.
2 changes: 1 addition & 1 deletion packages/expo-modules-core/android/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_CXX_STANDARD 17)
set(PACKAGE_NAME "expo-modules-core")
set(BUILD_DIR ${CMAKE_SOURCE_DIR}/build)
set(ignoreMe "${PROJECT_BUILD_DIR} ${REACT_ANDROID_BUILD_DIR} ${REACT_ANDROID_DIR} ${HERMES_HEADER_DIR} ${BOOST_VERSION}")
set(ignoreMe "${PROJECT_BUILD_DIR} ${REACT_ANDROID_BUILD_DIR} ${REACT_ANDROID_DIR} ${BOOST_VERSION}")

string(APPEND CMAKE_CXX_FLAGS " -DREACT_NATIVE_TARGET_VERSION=${REACT_NATIVE_TARGET_VERSION}")

Expand Down
92 changes: 6 additions & 86 deletions packages/expo-modules-core/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -76,46 +76,14 @@ def reactNativeArchitectures() {
}

// HERMES
def prebuiltHermesDir = findProperty("expo.prebuiltHermesDir") ?: file("${rootDir}/prebuiltHermes")
def prebuiltHermesVersion = file("${prebuiltHermesDir}/.hermesversion").exists() ? file("${prebuiltHermesDir}/.hermesversion").text : null
def currentHermesVersion = file("${REACT_NATIVE_DIR}/sdks/.hermesversion").exists() ? file("${REACT_NATIVE_DIR}/sdks/.hermesversion").text : null
def hasHermesProject = findProject(":packages:react-native:ReactAndroid:hermes-engine") != null
def prebuiltHermesCacheHit = hasHermesProject && currentHermesVersion == prebuiltHermesVersion

// By default we are going to download and unzip hermes inside the /sdks/hermes folder
// but you can provide an override for where the hermes source code is located.
def hermesDir = System.getenv("REACT_NATIVE_OVERRIDE_HERMES_DIR") ?: file("${REACT_NATIVE_DIR}/sdks/hermes")

def USE_HERMES = true
def NEED_DOWNLOAD_HERMES = false
def HERMES_HEADER_DIR = null
def HERMES_AAR = null
if (findProject(":app")) {
def appProject = project(":app")
USE_HERMES = appProject?.hermesEnabled?.toBoolean() || appProject?.ext?.react?.enableHermes?.toBoolean()
}

// Currently the needs for hermes/jsc are only for androidTest, so we turn on this flag only when `isExpoModulesCoreTests` is true
USE_HERMES = USE_HERMES && isExpoModulesCoreTests

if (USE_HERMES) {
if (prebuiltHermesCacheHit) {
HERMES_HEADER_DIR = file("${thirdPartyNdkDir}/hermes/prefab/modules/libhermes/include")
HERMES_AAR = file("${prebuiltHermesDir}/hermes-engine-debug.aar")
} else if (hasHermesProject) {
HERMES_HEADER_DIR = file("${thirdPartyNdkDir}/hermes/prefab/modules/libhermes/include")
HERMES_AAR = file("${REACT_NATIVE_DIR}/ReactAndroid/hermes-engine/build/outputs/aar/hermes-engine-debug.aar")
} else {
def prebuiltAAR = fileTree(REACT_NATIVE_DIR).matching { include "**/hermes-engine/**/hermes-engine-*-debug.aar" }
if (prebuiltAAR.any()) {
HERMES_AAR = prebuiltAAR.singleFile
} else {
HERMES_AAR = file("${hermesEngineDir}/android/hermes-debug.aar")
}
HERMES_HEADER_DIR = file("${hermesDir}")
NEED_DOWNLOAD_HERMES = true
}
}
// END HERMES

def isNewArchitectureEnabled = findProperty("newArchEnabled") == "true"
Expand Down Expand Up @@ -174,7 +142,6 @@ android {
"-DREACT_NATIVE_TARGET_VERSION=${REACT_NATIVE_TARGET_VERSION}",
"-DBOOST_VERSION=${BOOST_VERSION}",
"-DUSE_HERMES=${USE_HERMES}",
"-DHERMES_HEADER_DIR=${HERMES_HEADER_DIR}",
"-DIS_NEW_ARCHITECTURE_ENABLED=${isNewArchitectureEnabled}",
"-DPROJECT_BUILD_DIR=$buildDir",
"-DREACT_ANDROID_DIR=${REACT_NATIVE_DIR}/ReactAndroid",
Expand Down Expand Up @@ -299,11 +266,12 @@ dependencies {
androidTestImplementation "com.google.truth:truth:1.1.2"
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.0"

if (USE_HERMES) {
def hermesProject = findProject(":packages:react-native:ReactAndroid:hermes-engine")
compileOnly (hermesProject ?: files(HERMES_AAR))
} else {
compileOnly "org.webkit:android-jsc:+"
if (isExpoModulesCoreTests) {
if (USE_HERMES) {
compileOnly "com.facebook.react:hermes-android"
} else {
compileOnly "org.webkit:android-jsc:+"
}
}
}

Expand All @@ -322,48 +290,6 @@ def createNativeDepsDirectories = project.tasks.findByName('createNativeDepsDire
thirdPartyNdkDir.mkdirs()
}

// TODO: Remove all these hermes code when we update our repo to react-native 0.71 by using prefab
task downloadHermes(type: Download) {
def hermesVersion = currentHermesVersion ?: "main"
src("https://github.com/facebook/hermes/tarball/${hermesVersion}")
onlyIfNewer(true)
overwrite(false)
dest(new File(downloadsDir, "hermes-${hermesVersion}.tar.gz"))
}

task unzipHermes(dependsOn: downloadHermes, type: Copy) {
from(tarTree(downloadHermes.dest)) {
eachFile { file ->
// We flatten the unzip as the tarball contains a `facebook-hermes-<SHA>`
// folder at the top level.
if (file.relativePath.segments.size() > 1) {
file.relativePath = new org.gradle.api.file.RelativePath(!file.isDirectory(), file.relativePath.segments.drop(1))
}
}
}
into(hermesDir)
}

task prepareHermes() {
if (!USE_HERMES) {
return
}
dependsOn(createNativeDepsDirectories)
if (NEED_DOWNLOAD_HERMES) {
dependsOn(unzipHermes)
}

doLast {
def files = zipTree(HERMES_AAR).matching({ it.include "**/*.so", "prefab/modules/libhermes/include/**/*" })

copy {
from files
from "$REACT_NATIVE_DIR/ReactAndroid/src/main/jni/first-party/hermes/Android.mk"
into "$thirdPartyNdkDir/hermes"
}
}
}

def downloadBoost = tasks.create('downloadBoost', Download) {
dependsOn(createNativeDepsDirectories)
def srcUrl = REACT_NATIVE_TARGET_VERSION >= 69
Expand Down Expand Up @@ -406,12 +332,6 @@ afterEvaluate {
if (REACT_NATIVE_TARGET_VERSION < 71) {
nativeBuildDependsOn(project, prepareBoost, null)
}
if (USE_HERMES) {
nativeBuildDependsOn(project, prepareHermes, null)
if (hasHermesProject && !prebuiltHermesCacheHit) {
prepareHermes.dependsOn(":packages:react-native:ReactAndroid:hermes-engine:assembleDebug")
}
}
}

if (REACT_NATIVE_TARGET_VERSION < 71) {
Expand Down
5 changes: 3 additions & 2 deletions tools/src/commands/AndroidNativeUnitTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ const excludedInTests = [
];

const packagesNeedToBeTestedUsingBareExpo = [
'expo-dev-menu',
'expo-dev-launcher',
'expo-dev-menu-interface',
'expo-dev-menu',
'expo-modules-core',
];

type TestType = 'local' | 'instrumented';
Expand Down Expand Up @@ -105,7 +106,7 @@ export async function androidNativeUnitTests({
// will have duplicated fbjni.so when building expo-eas-client.
const isExpoModulesCore = (pkg: Packages.Package) => pkg.packageName === 'expo-modules-core';
const isNotExpoModulesCore = (pkg: Packages.Package) => pkg.packageName !== 'expo-modules-core';
await runGradlew(androidPackages.filter(isExpoModulesCore), testCommand, ANDROID_DIR);
await runGradlew(androidPackages.filter(isExpoModulesCore), testCommand, BARE_EXPO_DIR);

await runGradlew(
androidPackagesTestedUsingExpoProject.filter(isNotExpoModulesCore),
Expand Down

0 comments on commit 61b1559

Please sign in to comment.