diff --git a/DEPS b/DEPS index 884a16e8f4b..b93d0dcf9e3 100644 --- a/DEPS +++ b/DEPS @@ -646,7 +646,7 @@ Var("dart_root") + "/third_party/pkg/tar": "packages": [ { "package": "chromium/fuchsia/test-scripts/fuchsia", - "version": "version:2@0d97902a72c9bc224f64630177cf95cd632604a2", + "version": "version:2@30ecdcc6666ac09845a2e2d4fe7d8d5714230fba", } ], "condition": @@ -807,7 +807,7 @@ hooks = [ 'python3', 'sdk/build/fuchsia/with_envs.py', 'sdk/third_party/fuchsia/test_scripts/update_product_bundles.py', - 'terminal.qemu-x64', + 'terminal.x64', ], 'condition': 'download_fuchsia_deps' }, diff --git a/build/fuchsia/with_envs.py b/build/fuchsia/with_envs.py index b98caa6718e..8bbfcd3fceb 100755 --- a/build/fuchsia/with_envs.py +++ b/build/fuchsia/with_envs.py @@ -5,8 +5,18 @@ import os import platform +import signal import subprocess import sys +import time + +sys.path.insert( + 0, + os.path.abspath( + os.path.join(os.path.dirname(__file__), + '../../third_party/fuchsia/test_scripts/test/'))) + +from common import catch_sigterm, wait_for_sigterm def Main(): @@ -15,6 +25,9 @@ def Main(): /usr/bin/env, but provides some extra functionality to dynamically set up the environment variables. """ + # Ensures the signals can be correctly forwarded to the subprocesses. + catch_sigterm() + os.environ['SRC_ROOT'] = os.path.abspath( os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)) os.environ['FUCHSIA_IMAGES_ROOT'] = os.path.join(os.environ['SRC_ROOT'], @@ -36,7 +49,13 @@ def Main(): os.path.join(os.environ['FUCHSIA_SDK_ROOT'], 'tools', 'x64', 'ffx'), 'config', 'set', 'product.experimental', 'true' ]) - subprocess.call(sys.argv[1:]) + + with subprocess.Popen(sys.argv[1:]) as proc: + try: + proc.wait() + except: + # Use terminate / SIGTERM to allow the subprocess exiting cleanly. + proc.terminate() if __name__ == '__main__': diff --git a/pkg/test_runner/lib/src/fuchsia_cfv2.dart b/pkg/test_runner/lib/src/fuchsia_cfv2.dart index 8dd71cad164..a4e4e6cb445 100644 --- a/pkg/test_runner/lib/src/fuchsia_cfv2.dart +++ b/pkg/test_runner/lib/src/fuchsia_cfv2.dart @@ -3,6 +3,8 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; import 'command.dart'; import 'fuchsia.dart'; @@ -11,15 +13,67 @@ import 'fuchsia.dart'; // CFv2 targets. // TODO(#38752): Need implementation. class FuchsiaEmulatorCFv2 extends FuchsiaEmulator { - @override - Future publishPackage( - String buildDir, String mode, String arch) async {} + static const String ffx = "./third_party/fuchsia/sdk/linux/tools/x64/ffx"; + static const String testScriptRoot = + "./third_party/fuchsia/test_scripts/test/"; + + Process? daemonProc; + Process? emuProc; + String? emuName; @override - void stop() {} + Future publishPackage(String buildDir, String mode, String arch) async { + housekeeping(); + + assert(daemonProc == null); + daemonProc = await runWithOutput("isolate_daemon.py", []); + assert(emuProc == null); + emuProc = await run( + "start_emulator.py", ["--disable-graphics", "--target-id-only"]); + emuName = await emuProc!.stdout.transform(utf8.decoder).first; + print("+ Targeting emu name $emuName"); + } + + @override + void stop() { + // isolate_daemon.py should respect the sigterm and gracefully stop the + // daemon process. + assert(daemonProc != null); + daemonProc!.kill(); + emuProc!.kill(); + + // In case anything goes wrong, ensure everything is cleaned up. + housekeeping(); + } @override VMCommand getTestCommand(String mode, String arch, List arguments) { - return VMCommand("dummy", arguments, {}); + return VMCommand("echo", arguments, {}); + } + + static void housekeeping() { + Process.runSync(ffx, ["emu", "stop", "--all"]); + Process.runSync(ffx, ["repository", "server", "stop"]); + Process.runSync(ffx, ["daemon", "stop", "-t", "10000"]); + } + + // 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; + }); + } + + // 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]); } }