[ CLI ] Implicitly set `--mark-main-isolate-as-system-isolate` for `dart test`
Fixes https://github.com/flutter/flutter/issues/143170
TEST=test_test.dart
Change-Id: I98044ab2362adcdd55c4f6def0752a755b1385b8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/366040
Reviewed-by: Derek Xu <derekx@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
Reviewed-by: Kenzie Davisson <kenzieschmoll@google.com>
diff --git a/pkg/dartdev/lib/src/commands/test.dart b/pkg/dartdev/lib/src/commands/test.dart
index 19f072ab..637c764 100644
--- a/pkg/dartdev/lib/src/commands/test.dart
+++ b/pkg/dartdev/lib/src/commands/test.dart
@@ -67,8 +67,17 @@
.where((e) => !e.startsWith('--$experimentFlagName='))
.toList();
log.trace('dart $testExecutable ${argsRestNoExperiment.join(' ')}');
- VmInteropHandler.run(testExecutable.executable, argsRestNoExperiment,
- packageConfigOverride: testExecutable.packageConfig!);
+ VmInteropHandler.run(
+ testExecutable.executable,
+ argsRestNoExperiment,
+ packageConfigOverride: testExecutable.packageConfig!,
+ // TODO(bkonyi): remove once DartDev moves to AOT and this flag can be
+ // provided directly to the process spawned by `dart run` and
+ // `dart test`.
+ //
+ // See https://github.com/dart-lang/sdk/issues/53576
+ markMainIsolateAsSystemIsolate: true,
+ );
return 0;
} on CommandResolutionFailedException catch (e) {
if (project.hasPubspecFile) {
diff --git a/pkg/dartdev/lib/src/vm_interop_handler.dart b/pkg/dartdev/lib/src/vm_interop_handler.dart
index ab6f189..37eed1d 100644
--- a/pkg/dartdev/lib/src/vm_interop_handler.dart
+++ b/pkg/dartdev/lib/src/vm_interop_handler.dart
@@ -16,13 +16,17 @@
///
/// If [packageConfigOverride] is given, that is where the packageConfig is found.
///
- /// If [forceNoSoundNullSafety] is given and set to true, the spawned isolate will run
- /// with `--no-sound-null-safety` enabled.
+ /// If [markMainIsolateAsSystemIsolate] is given and set to true, the spawned
+ /// isolate will run with `--mark-main-isolate-as-system-isolate` enabled.
static void run(
String script,
List<String> args, {
String? packageConfigOverride,
- bool forceNoSoundNullSafety = false,
+ // TODO(bkonyi): remove once DartDev moves to AOT and this flag can be
+ // provided directly to the process spawned by `dart run` and `dart test`.
+ //
+ // See https://github.com/dart-lang/sdk/issues/53576
+ bool markMainIsolateAsSystemIsolate = false,
}) {
final port = _port;
if (port == null) return;
@@ -30,7 +34,7 @@
_kResultRun,
script,
packageConfigOverride,
- forceNoSoundNullSafety,
+ markMainIsolateAsSystemIsolate,
// Copy the list so it doesn't get GC'd underneath us.
args.toList()
];
diff --git a/pkg/dartdev/test/commands/test_test.dart b/pkg/dartdev/test/commands/test_test.dart
index 8abeecc..e7bcd7b 100644
--- a/pkg/dartdev/test/commands/test_test.dart
+++ b/pkg/dartdev/test/commands/test_test.dart
@@ -2,11 +2,14 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:async';
+import 'dart:convert';
import 'dart:io';
import 'package:path/path.dart' as path;
import 'package:pub_semver/pub_semver.dart';
import 'package:test/test.dart';
+import 'package:vm_service/vm_service_io.dart';
import '../experiment_util.dart';
import '../utils.dart';
@@ -157,6 +160,53 @@
expect(result.stderr, isEmpty);
});
+ test('implicitly passes --mark-main-isolate-as-system-isolate', () async {
+ // --mark-main-isolate-as-system-isolate is necessary for DevTools to be
+ // able to identify the correct root library.
+ //
+ // See https://github.com/flutter/flutter/issues/143170 for details.
+ final p = project(
+ mainSrc: 'int get foo => 1;\n',
+ pubspecExtras: {
+ 'dev_dependencies': {'test': 'any'}
+ },
+ );
+ p.file('test/foo_test.dart', '''
+import 'package:test/test.dart';
+
+void main() {
+ test('', () {
+ print('hello world');
+ });
+}
+''');
+
+ final vmServiceUriRegExp =
+ RegExp(r'(http:\/\/127.0.0.1:\d*\/[\da-zA-Z-_]*=\/)');
+ final process = await p.start(['test', '--pause-after-load']);
+ final completer = Completer<Uri>();
+ late StreamSubscription sub;
+ sub = process.stdout
+ .transform(utf8.decoder)
+ .transform(const LineSplitter())
+ .listen((line) async {
+ if (line.contains(vmServiceUriRegExp)) {
+ await sub.cancel();
+ final httpUri = Uri.parse(
+ vmServiceUriRegExp.firstMatch(line)!.group(0)!,
+ );
+ completer.complete(
+ httpUri.replace(scheme: 'ws', path: '${httpUri.path}ws'),
+ );
+ }
+ });
+
+ final vmServiceUri = await completer.future;
+ final vmService = await vmServiceConnectUri(vmServiceUri.toString());
+ final vm = await vmService.getVM();
+ expect(vm.systemIsolates!.where((e) => e.name == 'main'), isNotEmpty);
+ });
+
group('--enable-experiment', () {
late TestProject p;
Future<ProcessResult> runTestWithExperimentFlag(String? flag) async {
diff --git a/runtime/bin/dartdev_isolate.cc b/runtime/bin/dartdev_isolate.cc
index d58608b..6851965 100644
--- a/runtime/bin/dartdev_isolate.cc
+++ b/runtime/bin/dartdev_isolate.cc
@@ -14,6 +14,7 @@
#include "bin/exe_utils.h"
#include "bin/file.h"
#include "bin/lockers.h"
+#include "bin/main_options.h"
#include "bin/platform.h"
#include "bin/process.h"
#include "include/dart_embedder_api.h"
@@ -160,6 +161,10 @@
auto item3 = GetArrayItem(message, 3);
ASSERT(item3->type == Dart_CObject_kBool);
+ const bool mark_main_isolate_as_system_isolate = item3->value.as_bool;
+ if (mark_main_isolate_as_system_isolate) {
+ Options::set_mark_main_isolate_as_system_isolate(true);
+ }
if (*script_ != nullptr) {
free(*script_);
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h
index a80314e..8b5e6eb 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -150,6 +150,14 @@
static const char* vm_service_server_ip() { return vm_service_server_ip_; }
static int vm_service_server_port() { return vm_service_server_port_; }
+ // TODO(bkonyi): remove once DartDev moves to AOT and this flag can be
+ // provided directly to the process spawned by `dart run` and `dart test`.
+ //
+ // See https://github.com/dart-lang/sdk/issues/53576
+ static void set_mark_main_isolate_as_system_isolate(bool state) {
+ mark_main_isolate_as_system_isolate_ = state;
+ }
+
static Dart_KernelCompilationVerbosityLevel verbosity_level() {
return VerbosityLevelToDartAPI(verbosity_);
}