From 19bee4c09bb49f5abc342d73c4090b2449d20daa Mon Sep 17 00:00:00 2001 From: Zijie He Date: Fri, 20 Oct 2023 17:08:31 +0000 Subject: [PATCH] [Fuchsia] Really running cfv2 test Though it's still failing, the test-script integration has pretty much finished. ```=== 298 tests passed, 40 failed ===``` Errors are mainly ``` Exhausted heap space, trying to allocate 32 bytes. ../../runtime/vm/object.cc: 2854: error: Out of memory. ``` This change requires https://crrev.com/c/4913284 and `"fuchsia_sdk_version": "version:15.20231007.2.1",` in DEPS. Bug: #38752 Change-Id: I92a387f4289fce7d05d84e483560729301541c1b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/330025 Commit-Queue: Zijie He Reviewed-by: Ryan Macnak Reviewed-by: Alexander Thomas --- pkg/test_runner/lib/src/fuchsia.dart | 3 +- pkg/test_runner/lib/src/fuchsia_cfv1.dart | 3 +- pkg/test_runner/lib/src/fuchsia_cfv2.dart | 142 +++++++++++++----- .../lib/src/runtime_configuration.dart | 11 +- 4 files changed, 118 insertions(+), 41 deletions(-) diff --git a/pkg/test_runner/lib/src/fuchsia.dart b/pkg/test_runner/lib/src/fuchsia.dart index 192987ec27a..288848c4631 100644 --- a/pkg/test_runner/lib/src/fuchsia.dart +++ b/pkg/test_runner/lib/src/fuchsia.dart @@ -17,7 +17,8 @@ abstract class FuchsiaEmulator { void stop(); // Returns a command to execute a set of tests against the running Fuchsia // environment. - VMCommand getTestCommand(String mode, String arch, List arguments); + VMCommand getTestCommand( + String buildDir, String mode, String arch, List arguments); static final FuchsiaEmulator _instance = _create(); diff --git a/pkg/test_runner/lib/src/fuchsia_cfv1.dart b/pkg/test_runner/lib/src/fuchsia_cfv1.dart index c7b2de63ecf..a120e44ecaa 100644 --- a/pkg/test_runner/lib/src/fuchsia_cfv1.dart +++ b/pkg/test_runner/lib/src/fuchsia_cfv1.dart @@ -74,7 +74,8 @@ class FuchsiaEmulatorCFv1 extends FuchsiaEmulator { } @override - VMCommand getTestCommand(String mode, String arch, List arguments) { + VMCommand getTestCommand( + String buildDir, String mode, String arch, List arguments) { arguments = arguments .map((arg) => arg.replaceAll(Repository.uri.toFilePath(), '/pkg/data/')) .toList(); diff --git a/pkg/test_runner/lib/src/fuchsia_cfv2.dart b/pkg/test_runner/lib/src/fuchsia_cfv2.dart index a4e4e6cb445..5766416f09d 100644 --- a/pkg/test_runner/lib/src/fuchsia_cfv2.dart +++ b/pkg/test_runner/lib/src/fuchsia_cfv2.dart @@ -16,64 +16,136 @@ class FuchsiaEmulatorCFv2 extends FuchsiaEmulator { static const String ffx = "./third_party/fuchsia/sdk/linux/tools/x64/ffx"; static const String testScriptRoot = "./third_party/fuchsia/test_scripts/test/"; + static const String withEnv = "./build/fuchsia/with_envs.py"; + static const String tmpRoot = "/tmp/dart_ffi_test/"; + static const String cmName = "fuchsia_ffi_test_component.cm"; + final Map envs = {}; Process? daemonProc; Process? emuProc; String? emuName; + Process? repoProc; @override Future publishPackage(String buildDir, String mode, String arch) async { - housekeeping(); - + try { + Directory(tmpRoot).deleteSync(recursive: true); + } catch (_) {} + // The /tmp/ should always be present, recursive creation is not expected. + Directory(tmpRoot).createSync(); assert(daemonProc == null); - daemonProc = await runWithOutput("isolate_daemon.py", []); + daemonProc = await _run("isolate_daemon.py", []); + var isolateDir = await _captureStdout(daemonProc!); + print("+ ffx daemon running on $isolateDir should be ready now."); + envs["FFX_ISOLATE_DIR"] = isolateDir; assert(emuProc == null); - emuProc = await run( - "start_emulator.py", ["--disable-graphics", "--target-id-only"]); - emuName = await emuProc!.stdout.transform(utf8.decoder).first; + emuProc = await _run("start_emulator.py", [ + "--disable-graphics", + "--target-id-only", + "--device-spec", + "virtual_device_large" + ]); + emuName = await _captureStdout(emuProc!); print("+ Targeting emu name $emuName"); + await _assertRun("test_connection.py", [emuName!]); + await _assertRun("publish_package.py", [ + "--packages", + _testPackagePath(buildDir, mode), + "--purge-repo", + "--repo", + _tempDirectoryOf("repo") + ]); + repoProc = await _run("serve_repo.py", [ + "run", + "--serve-repo", + _tempDirectoryOf("repo"), + "--repo-name", + "dart-ffi-test-repo", + "--target-id", + emuName! + ]); + print("+ Fuchsia repo ${await _captureStdout(repoProc!)} is running " + "at ${_tempDirectoryOf('repo')}"); + await _assertRun("pkg_resolve.py", [emuName!, cmName]); } @override - void stop() { - // isolate_daemon.py should respect the sigterm and gracefully stop the - // daemon process. + Future stop() async { + assert(repoProc != null); + repoProc!.kill(); + await repoProc!.exitCode; + assert(emuProc != null); + emuProc!.kill(); + await emuProc!.exitCode; assert(daemonProc != null); daemonProc!.kill(); - emuProc!.kill(); - - // In case anything goes wrong, ensure everything is cleaned up. - housekeeping(); + await daemonProc!.exitCode; } @override - VMCommand getTestCommand(String mode, String arch, List arguments) { - return VMCommand("echo", arguments, {}); + VMCommand getTestCommand( + String buildDir, String mode, String arch, List arguments) { + return VMCommand( + withEnv, + _runArgs("run_executable_test.py", [ + "--target-id", + emuName!, + "--out-dir", + _tempDirectoryOf("out"), + "--test-name", + "fuchsia-pkg://fuchsia.com/${_testPackageName(mode)}#meta/$cmName", + "--logs-dir", + _tempDirectoryOf("logs"), + "--package-deps", + _testPackagePath(buildDir, mode), + ...arguments + ]), + envs); } - static void housekeeping() { - Process.runSync(ffx, ["emu", "stop", "--all"]); - Process.runSync(ffx, ["repository", "server", "stop"]); - Process.runSync(ffx, ["daemon", "stop", "-t", "10000"]); + static String _testPackageName(String mode) { + return "dart_ffi_test_cfv2_$mode"; } - // Same as run, but capture the stdout and stderr. - static Future runWithOutput(String script, List args) async { - return run(script, args).then((proc) { - proc.stdout.transform(utf8.decoder).forEach((x) { - print("++ [$script] stdout: $x"); - }); - proc.stderr.transform(utf8.decoder).forEach((x) { - print("++ [$script] stderr: $x"); - }); - return proc; - }); + static String _testPackagePath(String buildDir, String mode) { + var farName = _testPackageName(mode); + return "$buildDir/gen/$farName/$farName.far"; } - // Executes a test script inside of third_party/fuchsia/test_scripts/test/ - // with the required environment setup and the arguments. - static Future run(String script, List args) async { - return Process.start("./build/fuchsia/with_envs.py", - [Uri.directory(testScriptRoot).resolve(script).toString(), ...args]); + static String _tempDirectoryOf(String name) { + return tmpRoot + name; + } + + List _runArgs(String script, List args) { + return [testScriptRoot + script, ...args]; + } + + /// Executes a test script inside of third_party/fuchsia/test_scripts/test/ + /// with the required environment setup and the arguments. + Future _run(String script, List args) async { + var newArgs = _runArgs(script, args); + print("+ Start $withEnv with $newArgs with environment $envs."); + return Process.start(withEnv, newArgs, environment: envs); + } + + /// Executes a test script and asserts its return code is 0; see _run and + /// _assert. + Future _assertRun(String script, List args) async { + _assert((await (await _run(script, args)).exitCode) == 0); + } + + /// Captures the first line of output in utf8. + Future _captureStdout(Process proc) async { + // The stderr needs to be fully consumed as well. + proc.stderr.transform(utf8.decoder).forEach((x) => stderr.write(x)); + return (await proc.stdout.transform(utf8.decoder).first).trim(); + } + + /// Unlike assert keyword, always evaluates the input function and throws + /// exception when the evaluated result is false. + void _assert(bool condition) { + if (!condition) { + throw AssertionError(); + } } } diff --git a/pkg/test_runner/lib/src/runtime_configuration.dart b/pkg/test_runner/lib/src/runtime_configuration.dart index 22e2c24c4ff..e364b5a8e56 100644 --- a/pkg/test_runner/lib/src/runtime_configuration.dart +++ b/pkg/test_runner/lib/src/runtime_configuration.dart @@ -476,12 +476,15 @@ class DartkFuchsiaEmulatorRuntimeConfiguration arguments.insert(0, '--suppress-core-dump'); } var command = FuchsiaEmulator.instance().getTestCommand( - _configuration.mode.name, _configuration.architecture.name, arguments); + _configuration.buildDirectory, + _configuration.mode.name, + _configuration.architecture.name, + arguments); command.arguments .insert(command.arguments.length - 1, '--disable-dart-dev'); - return [ - VMCommand(command.executable, command.arguments, environmentOverrides) - ]; + command.environmentOverrides.addAll(environmentOverrides); + print("+ About to run command $command to test against fuchsia vm"); + return [command]; } }