From 92a476661cc09bb087acdfadc397d5dbc462ba2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Thu, 21 Nov 2024 03:58:36 -0800 Subject: [PATCH] Add flag to force running tests in optimized mode (#47870) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47870 Changelog: [internal] This flag allows us to run optimized mode by using the right buck modes for the Fantom CLI, using minified + dev in Metro and building bytecode using Buck as well. It's disabled by default but in the future we can enable it based on the configuration in the test file (e.g.: if it's a benchmark) or we can run tests in both modes by default to catch problems caused by the differences between environments. Reviewed By: rshest Differential Revision: D66292709 fbshipit-source-id: d25294b739ff6a67507990241784b838d5b30dcd --- jest/integration/runner/runner.js | 81 ++++++++++++++++++++++++++++--- 1 file changed, 73 insertions(+), 8 deletions(-) diff --git a/jest/integration/runner/runner.js b/jest/integration/runner/runner.js index f494cc57162..ab1be82180d 100644 --- a/jest/integration/runner/runner.js +++ b/jest/integration/runner/runner.js @@ -23,6 +23,8 @@ import os from 'os'; import path from 'path'; const BUILD_OUTPUT_PATH = path.resolve(__dirname, '..', 'build'); + +const ENABLE_OPTIMIZED_MODE: false = false; const PRINT_FANTOM_OUTPUT: false = false; function parseRNTesterCommandResult( @@ -59,15 +61,17 @@ function parseRNTesterCommandResult( } function getBuckModeForPlatform() { + const mode = ENABLE_OPTIMIZED_MODE ? 'opt' : 'dev'; + switch (os.platform()) { case 'linux': - return '@//arvr/mode/linux/dev'; + return `@//arvr/mode/linux/${mode}`; case 'darwin': return os.arch() === 'arm64' - ? '@//arvr/mode/mac-arm/dev' - : '@//arvr/mode/mac/dev'; + ? `@//arvr/mode/mac-arm/${mode}` + : `@//arvr/mode/mac/${mode}`; case 'win32': - return '@//arvr/mode/win/dev'; + return `@//arvr/mode/win/${mode}`; default: throw new Error(`Unsupported platform: ${os.platform()}`); } @@ -77,6 +81,55 @@ function getShortHash(contents: string): string { return crypto.createHash('md5').update(contents).digest('hex').slice(0, 8); } +function generateBytecodeBundle({ + sourcePath, + bytecodePath, +}: { + sourcePath: string, + bytecodePath: string, +}): void { + const hermesCompilerCommandArgs = [ + 'run', + getBuckModeForPlatform(), + '//xplat/hermes/tools/hermesc:hermesc', + '--', + '-emit-binary', + '-O', + '-max-diagnostic-width', + '80', + '-out', + bytecodePath, + sourcePath, + ]; + + const hermesCompilerCommandResult = spawnSync( + 'buck2', + hermesCompilerCommandArgs, + { + encoding: 'utf8', + env: { + ...process.env, + PATH: `/usr/local/bin:${process.env.PATH ?? ''}`, + }, + }, + ); + + if (hermesCompilerCommandResult.status !== 0) { + throw new Error( + [ + 'Failed to run Hermes compiler. Full output:', + 'buck2 ' + hermesCompilerCommandArgs.join(' '), + 'stdout:', + hermesCompilerCommandResult.stdout, + 'stderr:', + hermesCompilerCommandResult.stderr, + 'error:', + hermesCompilerCommandResult.error, + ].join('\n'), + ); + } +} + module.exports = async function runTest( globalConfig: {...}, config: {...}, @@ -86,6 +139,8 @@ module.exports = async function runTest( ): mixed { const startTime = Date.now(); + const isOptimizedMode = ENABLE_OPTIMIZED_MODE; + const metroConfig = await Metro.loadConfig({ config: path.resolve(__dirname, '..', 'config', 'metro.config.js'), }); @@ -102,24 +157,34 @@ module.exports = async function runTest( `${getShortHash(entrypointContents)}-${path.basename(testPath)}`, ); const testBundlePath = entrypointPath + '.bundle'; + const testJSBundlePath = testBundlePath + '.js'; + const testBytecodeBundlePath = testJSBundlePath + '.hbc'; fs.mkdirSync(path.dirname(entrypointPath), {recursive: true}); fs.writeFileSync(entrypointPath, entrypointContents, 'utf8'); await Metro.runBuild(metroConfig, { entry: entrypointPath, - out: testBundlePath, + out: testJSBundlePath, platform: 'android', - minify: false, - dev: true, + minify: isOptimizedMode, + dev: !isOptimizedMode, }); + if (isOptimizedMode) { + generateBytecodeBundle({ + sourcePath: testJSBundlePath, + bytecodePath: testBytecodeBundlePath, + }); + } + const rnTesterCommandArgs = [ 'run', getBuckModeForPlatform(), '//xplat/ReactNative/react-native-cxx/samples/tester:tester', '--', - `--bundlePath=${testBundlePath}`, + '--bundlePath', + testBundlePath, ]; const rnTesterCommandResult = spawnSync('buck2', rnTesterCommandArgs, { encoding: 'utf8',