Skip to content

Commit be328fb

Browse files
andrewdacenkofacebook-github-bot
authored andcommitted
Introduce isOSS (#52222)
Summary: Pull Request resolved: #52222 Changelog: [Internal] Introduce environment option to force usage of OSS fantom test runner. If env is not set - check for BUCK file in tester which is checked in for FB but not for OSS. Reviewed By: rubennorte Differential Revision: D77160761
1 parent bc7a9d9 commit be328fb

File tree

12 files changed

+212
-126
lines changed

12 files changed

+212
-126
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
"test-typescript": "tsc -p packages/react-native/types/tsconfig.json",
3333
"test-generated-typescript": "tsc -p packages/react-native/types_generated/tsconfig.test.json",
3434
"test": "jest",
35-
"fantom": "JS_DIR='..' yarn jest --config private/react-native-fantom/config/jest.config.js",
35+
"fantom": "./scripts/fantom.sh",
3636
"trigger-react-native-release": "node ./scripts/releases-local/trigger-react-native-release.js",
3737
"update-lock": "npx yarn-deduplicate"
3838
},

private/react-native-fantom/build.gradle.kts

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,24 @@ plugins {
1515
alias(libs.plugins.download)
1616
}
1717

18+
// This is the version of CMake we're requesting to the Android SDK to use.
19+
// If missing it will be downloaded automatically. Only CMake versions shipped with the
20+
// Android SDK are supported (you can find them listed in the SDK Manager of Android Studio).
21+
val cmakeVersion = System.getenv("CMAKE_VERSION") ?: "3.30.5"
22+
val cmakePath = "${getSDKPath()}/cmake/$cmakeVersion"
23+
val cmakeBinaryPath = "${cmakePath}/bin/cmake"
24+
val ndkBuildJobs = Runtime.getRuntime().availableProcessors().toString()
25+
26+
fun getSDKPath(): String {
27+
val androidSdkRoot = System.getenv("ANDROID_SDK_ROOT")
28+
val androidHome = System.getenv("ANDROID_HOME")
29+
return when {
30+
!androidSdkRoot.isNullOrBlank() -> androidSdkRoot
31+
!androidHome.isNullOrBlank() -> androidHome
32+
else -> throw IllegalStateException("Neither ANDROID_SDK_ROOT nor ANDROID_HOME is set.")
33+
}
34+
}
35+
1836
val FOLLY_VERSION = libs.versions.folly.get()
1937
val GFLAGS_VERSION = libs.versions.gflags.get()
2038
val NLOHMANNJSON_VERSION = libs.versions.nlohmannjson.get()
@@ -27,15 +45,24 @@ val downloadsDir =
2745
File("$buildDir/downloads")
2846
}
2947
val thirdParty = File("$buildDir/third-party")
48+
val reportsDir = File("$buildDir/reports")
3049
val reactNativeRootDir = projectDir.parentFile.parentFile
31-
val reactAndroidBuildDir = File("$reactNativeRootDir/packages/react-native/ReactAndroid/build")
32-
val reactAndroidDownloasdDir =
33-
File("$reactNativeRootDir/packages/react-native/ReactAndroid/build/downloads")
50+
val reactNativeDir = File("$reactNativeRootDir/packages/react-native")
51+
val reactAndroidDir = File("$reactNativeDir/ReactAndroid")
52+
val reactAndroidBuildDir = File("$reactAndroidDir/build")
53+
val reactAndroidDownloasdDir = File("$reactAndroidBuildDir/downloads")
54+
55+
val testerDir = File("$projectDir/tester")
56+
val testerBuildDir = File("$buildDir/tester")
57+
val testerBuildOutputFileTree =
58+
fileTree(testerBuildDir.toString())
59+
.include("**/*.cmake", "**/*.marks", "**/compiler_depends.ts", "**/Makefile", "**/link.txt")
3460

3561
val createNativeDepsDirectories by
3662
tasks.registering {
3763
downloadsDir.mkdirs()
3864
thirdParty.mkdirs()
65+
reportsDir.mkdirs()
3966
}
4067

4168
val downloadFollyDest = File(reactAndroidDownloasdDir, "folly-${FOLLY_VERSION}.tar.gz")
@@ -137,3 +164,48 @@ val prepareAllDependencies by
137164
tasks.registering {
138165
dependsOn(prepareRNCodegen, prepareHermesDependencies, prepareNative3pDependencies)
139166
}
167+
168+
val configureFantomTester by
169+
tasks.registering(CustomExecTask::class) {
170+
dependsOn(prepareAllDependencies)
171+
workingDir(testerDir)
172+
inputs.dir(testerDir)
173+
outputs.files(testerBuildOutputFileTree)
174+
val cmdArgs =
175+
mutableListOf(
176+
cmakeBinaryPath,
177+
// Suppress all warnings as this is the Hermes build and we can't fix them.
178+
"--log-level=ERROR",
179+
"-S",
180+
".",
181+
"-B",
182+
testerBuildDir.toString(),
183+
"-DCMAKE_BUILD_TYPE=Debug",
184+
"-DFANTOM_CODEGEN_DIR=$buildDir/codegen",
185+
"-DFANTOM_THIRD_PARTY_DIR=$buildDir/third-party",
186+
"-DREACT_ANDROID_DIR=$reactAndroidDir",
187+
"-DREACT_COMMON_DIR=$reactNativeDir/ReactCommon",
188+
"-DREACT_CXX_PLATFORM_DIR=$reactNativeDir/ReactCxxPlatform",
189+
"-DREACT_THIRD_PARTY_NDK_DIR=$reactAndroidBuildDir/third-party-ndk")
190+
commandLine(cmdArgs)
191+
standardOutputFile.set(project.file("$buildDir/reports/configure-fantom_tester.log"))
192+
errorOutputFile.set(project.file("$buildDir/reports/configure-fantom_tester.error.log"))
193+
}
194+
195+
val buildFantomTester by
196+
tasks.registering(CustomExecTask::class) {
197+
dependsOn(configureFantomTester)
198+
workingDir(testerDir)
199+
inputs.files(testerBuildOutputFileTree)
200+
commandLine(
201+
cmakeBinaryPath,
202+
"--build",
203+
testerBuildDir.toString(),
204+
"--target",
205+
"fantom_tester",
206+
"-j",
207+
ndkBuildJobs,
208+
)
209+
standardOutputFile.set(project.file("$buildDir/reports/build-fantom_tester.log"))
210+
errorOutputFile.set(project.file("$buildDir/reports/build-fantom_tester.error.log"))
211+
}

private/react-native-fantom/prepare.sh renamed to private/react-native-fantom/build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@
77
set -e
88

99
pushd ../..
10-
./gradlew :private:react-native-fantom:prepareAllDependencies
10+
./gradlew :private:react-native-fantom:buildFantomTester
1111
popd

private/react-native-fantom/config/metro.config.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ const config /*: InputConfigT */ = {
3434
},
3535
resolver: {
3636
blockList: /\/RendererProxy\.fb\.js$/, // Disable dependency injection for the renderer
37-
sourceExts: ['fb.js', ...rnTesterConfig.resolver.sourceExts],
37+
sourceExts:
38+
JS_DIR != null
39+
? ['fb.js', ...rnTesterConfig.resolver.sourceExts]
40+
: rnTesterConfig.resolver.sourceExts,
3841
nodeModulesPaths:
3942
JS_DIR != null ? [path.join(JS_DIR, 'public', 'node_modules')] : [],
4043
hasteImplModulePath: path.resolve(__dirname, 'hasteImpl.js'),

private/react-native-fantom/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
"version": "0.0.0",
55
"main": "src/index.js",
66
"description": "Internal integration testing and benchmarking tool for React Native",
7+
"scripts": {
8+
"build": "./build.sh"
9+
},
710
"peerDependencies": {
811
"jest": "^29.7.0",
912
"jest-snapshot": "^29.7.0"

private/react-native-fantom/runner/EnvironmentOptions.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@ export const logCommands: boolean = Boolean(process.env.FANTOM_LOG_COMMANDS);
1515
export const enableCppDebugging: boolean = Boolean(
1616
process.env.FANTOM_ENABLE_CPP_DEBUGGING,
1717
);
18+
19+
export const isOSS: boolean = Boolean(process.env.FANTOM_FORCE_OSS_BUILD);

private/react-native-fantom/runner/runner.js

Lines changed: 103 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*/
1010

1111
import type {FailureDetail, TestSuiteResult} from '../runtime/setup';
12+
import type {TestSnapshotResults} from '../runtime/snapshotContext';
1213
import type {
1314
AsyncCommandResult,
1415
ConsoleLogMessage,
@@ -25,6 +26,7 @@ import {
2526
updateSnapshotsAndGetJestSnapshotResult,
2627
} from './snapshotUtils';
2728
import {
29+
HermesVariant as HermesVariantEnum,
2830
getBuckModesForPlatform,
2931
getBuckOptionsForHermes,
3032
getDebugInfoFromCommandResult,
@@ -34,6 +36,7 @@ import {
3436
printConsoleLog,
3537
runBuck2,
3638
runBuck2Sync,
39+
runCommand,
3740
symbolicateStackTrace,
3841
} from './utils';
3942
import fs from 'fs';
@@ -151,22 +154,34 @@ function generateBytecodeBundle({
151154
isOptimizedMode: boolean,
152155
hermesVariant: HermesVariant,
153156
}): void {
154-
const hermesCompilerCommandResult = runBuck2Sync(
155-
[
156-
'run',
157-
...getBuckModesForPlatform(isOptimizedMode),
158-
...getBuckOptionsForHermes(hermesVariant),
159-
getHermesCompilerTarget(hermesVariant),
160-
'--',
161-
'-emit-binary',
162-
isOptimizedMode ? '-O' : null,
163-
'-max-diagnostic-width',
164-
'80',
165-
'-out',
166-
bytecodePath,
167-
sourcePath,
168-
].filter(Boolean),
169-
);
157+
const hermescArgs = [
158+
'-emit-binary',
159+
isOptimizedMode ? '-O' : null,
160+
'-max-diagnostic-width',
161+
'80',
162+
'-out',
163+
bytecodePath,
164+
sourcePath,
165+
].filter(Boolean);
166+
const hermesCompilerCommandResult = false
167+
? runCommand(
168+
path.join(
169+
__dirname,
170+
'..',
171+
'..',
172+
'..',
173+
'packages/react-native/ReactAndroid/hermes-engine/build/hermes/bin/hermesc',
174+
),
175+
hermescArgs,
176+
)
177+
: runBuck2Sync([
178+
'run',
179+
...getBuckModesForPlatform(isOptimizedMode),
180+
...getBuckOptionsForHermes(hermesVariant),
181+
getHermesCompilerTarget(hermesVariant),
182+
'--',
183+
...hermescArgs,
184+
]);
170185

171186
if (hermesCompilerCommandResult.status !== 0) {
172187
throw new Error(getDebugInfoFromCommandResult(hermesCompilerCommandResult));
@@ -215,6 +230,47 @@ module.exports = async function runTest(
215230
const testResultsByConfig = [];
216231

217232
for (const testConfig of testConfigs) {
233+
if (
234+
EnvironmentOptions.isOSS &&
235+
testConfig.mode === FantomTestConfigMode.Optimized
236+
) {
237+
testResultsByConfig.push([
238+
{
239+
ancestorTitles: ['"@fantom_mode opt" in docblock'],
240+
duration: 0,
241+
failureDetails: [] as Array<Error>,
242+
failureMessages: [] as Array<string>,
243+
fullName: 'Optimized mode is not yet supoprted in OSS',
244+
numPassingAsserts: 0,
245+
snapshotResults: {} as TestSnapshotResults,
246+
status: 'pending' as 'passed' | 'failed' | 'pending',
247+
testFilePath: testPath,
248+
title: 'Optimized mode is not yet supoprted in OSS',
249+
},
250+
]);
251+
continue;
252+
}
253+
254+
if (testConfig.hermesVariant !== HermesVariantEnum.Hermes) {
255+
testResultsByConfig.push([
256+
{
257+
ancestorTitles: [
258+
'"@fantom_hermes_variant static_hermes" in docblock (shermes 🧪)',
259+
],
260+
duration: 0,
261+
failureDetails: [] as Array<Error>,
262+
failureMessages: [] as Array<string>,
263+
fullName: 'Static Hermes is not yet supoprted in OSS',
264+
numPassingAsserts: 0,
265+
snapshotResults: {} as TestSnapshotResults,
266+
status: 'pending' as 'passed' | 'failed' | 'pending',
267+
testFilePath: testPath,
268+
title: 'Static Hermes is not yet supoprted in OSS',
269+
},
270+
]);
271+
continue;
272+
}
273+
218274
const entrypointContents = entrypointTemplate({
219275
testPath: `${path.relative(BUILD_OUTPUT_PATH, testPath)}`,
220276
setupModulePath: `${path.relative(BUILD_OUTPUT_PATH, setupModulePath)}`,
@@ -261,28 +317,37 @@ module.exports = async function runTest(
261317
});
262318
}
263319

264-
const rnTesterCommandResult = runBuck2(
265-
[
266-
'run',
267-
...getBuckModesForPlatform(
268-
testConfig.mode === FantomTestConfigMode.Optimized,
269-
),
270-
...getBuckOptionsForHermes(testConfig.hermesVariant),
271-
'//xplat/js/react-native-github/private/react-native-fantom/tester:tester',
272-
'--',
273-
'--bundlePath',
274-
testConfig.mode === FantomTestConfigMode.DevelopmentWithSource
275-
? testJSBundlePath
276-
: testBytecodeBundlePath,
277-
'--featureFlags',
278-
JSON.stringify(testConfig.flags.common),
279-
'--minLogLevel',
280-
EnvironmentOptions.printCLIOutput ? 'info' : 'error',
281-
],
282-
{
283-
withFDB: EnvironmentOptions.enableCppDebugging,
284-
},
285-
);
320+
const rnTesterCommandArgs = [
321+
'--bundlePath',
322+
testConfig.mode === FantomTestConfigMode.DevelopmentWithSource
323+
? testJSBundlePath
324+
: testBytecodeBundlePath,
325+
'--featureFlags',
326+
JSON.stringify(testConfig.flags.common),
327+
'--minLogLevel',
328+
EnvironmentOptions.printCLIOutput ? 'info' : 'error',
329+
];
330+
331+
const rnTesterCommandResult = EnvironmentOptions.isOSS
332+
? runCommand(
333+
path.join(__dirname, '..', 'build', 'tester', 'fantom_tester'),
334+
rnTesterCommandArgs,
335+
)
336+
: runBuck2(
337+
[
338+
'run',
339+
...getBuckModesForPlatform(
340+
testConfig.mode === FantomTestConfigMode.Optimized,
341+
),
342+
...getBuckOptionsForHermes(testConfig.hermesVariant),
343+
'//xplat/js/react-native-github/private/react-native-fantom/tester:tester',
344+
'--',
345+
...rnTesterCommandArgs,
346+
],
347+
{
348+
withFDB: EnvironmentOptions.enableCppDebugging,
349+
},
350+
);
286351

287352
const processedResult = await processRNTesterCommandResult(
288353
rnTesterCommandResult,

private/react-native-fantom/tester/CMakeLists.txt

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,21 @@ cmake_minimum_required(VERSION 3.13)
77
set(CMAKE_VERBOSE_MAKEFILE on)
88

99
project(fantom_tester)
10-
find_library(LIB_HERMES libhermes
11-
NAMES hermes
12-
HINTS ${REACT_ANDROID_DIR}/hermes-engine/build/hermes/API/hermes
13-
REQUIRED)
14-
# Ensure the library path is correct and the library exists
15-
if(NOT LIB_HERMES)
16-
message(FATAL_ERROR "libhermes not found at the specified path.")
17-
endif()
18-
# Check if the found library is a framework (macOS specific)
19-
get_filename_component(LIB_EXT ${LIB_HERMES} EXT)
20-
if(LIB_EXT STREQUAL ".framework")
21-
# For frameworks, we need to use a different approach
22-
add_library(hermes-engine::libhermes INTERFACE IMPORTED)
23-
set_target_properties(hermes-engine::libhermes PROPERTIES
24-
INTERFACE_LINK_LIBRARIES ${LIB_HERMES})
25-
else()
26-
# For regular libraries, use ALIAS as before
27-
add_library(hermes-engine::libhermes ALIAS ${LIB_HERMES})
28-
endif()
29-
30-
find_package(OpenSSL REQUIRED)
3110

3211
include_directories(${REACT_ANDROID_DIR}/hermes-engine/build/prefab-headers)
3312

34-
include(${REACT_COMMON_DIR}/cmake-utils/react-native-flags.cmake)
35-
3613
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/")
37-
3814
include(Deps)
3915

16+
find_library(LIB_HERMES libhermes
17+
NAMES hermes
18+
HINTS ${REACT_ANDROID_DIR}/hermes-engine/build/hermes/API/hermes
19+
REQUIRED)
20+
add_library(hermes-engine::libhermes INTERFACE IMPORTED)
21+
set_target_properties(hermes-engine::libhermes PROPERTIES
22+
INTERFACE_LINK_LIBRARIES ${LIB_HERMES})
23+
find_package(OpenSSL REQUIRED)
24+
4025
# Boost in NDK is not compatible with desktop build
4126
add_third_party_subdir(boost)
4227

0 commit comments

Comments
 (0)