diff --git a/packages/flutter_tools/lib/src/test/flutter_tester_device.dart b/packages/flutter_tools/lib/src/test/flutter_tester_device.dart index 82fcccb4b16..5f6448610ad 100644 --- a/packages/flutter_tools/lib/src/test/flutter_tester_device.dart +++ b/packages/flutter_tools/lib/src/test/flutter_tester_device.dart @@ -16,6 +16,7 @@ import '../base/common.dart'; import '../base/file_system.dart'; import '../base/io.dart'; import '../base/logger.dart'; +import '../base/os.dart'; import '../base/platform.dart'; import '../convert.dart'; import '../device.dart'; @@ -46,7 +47,13 @@ class FlutterTesterTestDevice extends TestDevice { }) : assert(shellPath != null), // Please provide the path to the shell in the SKY_SHELL environment variable. assert(!debuggingOptions.startPaused || enableObservatory), _gotProcessObservatoryUri = enableObservatory - ? Completer() : (Completer()..complete(null)); + ? Completer() : (Completer()..complete(null)), + _operatingSystemUtils = OperatingSystemUtils( + fileSystem: fileSystem, + logger: logger, + platform: platform, + processManager: processManager, + ); /// Used for logging to identify the test that is currently being executed. final int id; @@ -70,6 +77,7 @@ class FlutterTesterTestDevice extends TestDevice { Process _process; HttpServer _server; + final OperatingSystemUtils _operatingSystemUtils; /// Starts the device. /// @@ -87,6 +95,13 @@ class FlutterTesterTestDevice extends TestDevice { logger.printTrace('test $id: test harness socket server is running at port:${_server.port}'); final List command = [ + // Until an arm64 flutter tester binary is available, force to run in Rosetta + // to avoid "unexpectedly got a signal in sigtramp" crash. + // https://github.com/flutter/flutter/issues/88106 + if (_operatingSystemUtils.hostPlatform == HostPlatform.darwin_arm) ...[ + '/usr/bin/arch', + '-x86_64', + ], shellPath, if (enableObservatory) ...[ // Some systems drive the _FlutterPlatform class in an unusual way, where diff --git a/packages/flutter_tools/test/general.shard/flutter_tester_device_test.dart b/packages/flutter_tools/test/general.shard/flutter_tester_device_test.dart index df75015aa4f..81e50452916 100644 --- a/packages/flutter_tools/test/general.shard/flutter_tester_device_test.dart +++ b/packages/flutter_tools/test/general.shard/flutter_tester_device_test.dart @@ -51,9 +51,66 @@ void main() { dartEntrypointArgs: dartEntrypointArgs, ); + testUsingContext('runs in Rosetta on arm64 Mac', () async { + final FakeProcessManager processManager = FakeProcessManager.empty(); + final FlutterTesterTestDevice device = TestFlutterTesterDevice( + platform: FakePlatform(operatingSystem: 'macos'), + fileSystem: fileSystem, + processManager: processManager, + enableObservatory: false, + dartEntrypointArgs: const [], + ); + processManager.addCommands([ + const FakeCommand( + command: [ + 'which', + 'sysctl', + ], + ), + const FakeCommand( + command: [ + 'sysctl', + 'hw.optional.arm64', + ], + stdout: 'hw.optional.arm64: 1', + ), + FakeCommand(command: const [ + '/usr/bin/arch', + '-x86_64', + '/', + '--disable-observatory', + '--ipv6', + '--enable-checked-mode', + '--verify-entry-points', + '--enable-software-rendering', + '--skia-deterministic-rendering', + '--enable-dart-profiling', + '--non-interactive', + '--use-test-fonts', + '--packages=.dart_tool/package_config.json', + 'example.dill', + ], environment: { + 'FLUTTER_TEST': 'true', + 'FONTCONFIG_FILE': device.fontConfigManager.fontConfigFile.path, + 'SERVER_PORT': '0', + 'APP_NAME': '', + }), + ]); + await device.start('example.dill'); + expect(processManager.hasRemainingExpectations, isFalse); + }); + group('The FLUTTER_TEST environment variable is passed to the test process', () { setUp(() { - processManager = FakeProcessManager.empty(); + processManager = FakeProcessManager.list([ + const FakeCommand( + command: [ + 'uname', + '-m', + ], + stdout: 'x86_64', + ), + ]); device = createDevice(); fileSystem @@ -127,6 +184,13 @@ void main() { group('Dart Entrypoint Args', () { setUp(() { processManager = FakeProcessManager.list([ + const FakeCommand( + command: [ + 'uname', + '-m', + ], + stdout: 'x86_64', + ), const FakeCommand( command: [ '/', @@ -161,6 +225,13 @@ void main() { group('DDS', () { setUp(() { processManager = FakeProcessManager.list([ + const FakeCommand( + command: [ + 'uname', + '-m', + ], + stdout: 'x86_64', + ), const FakeCommand( command: [ '/',