blob: 754d03a39fd0c4812bbf526e6ffa77d9310b65fc [file] [log] [blame]
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// 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:developer' show debugger;
import 'dart:io' show Directory, File;
import 'dart:isolate' as i;
import 'package:path/path.dart' show join;
import 'package:test/test.dart';
import 'package:vm_service/vm_service.dart';
import 'common/service_test_common.dart';
import 'common/test_helper.dart';
// AUTOGENERATED START
//
// Update these constants by running:
//
// dart pkg/vm_service/test/update_line_numbers.dart <test.dart>
//
const LINE_A = 44;
// AUTOGENERATED END
const v0Contents = '''
import 'dart:developer';
void f() {}
void main() {
debugger();
f();
}
''';
Future<void> testeeMain() async {
// Spawn the child isolate.
final tempDir = Directory.systemTemp.createTempSync();
try {
final rootLib = File(join(tempDir.path, 'main.dart'));
rootLib.writeAsStringSync(v0Contents);
await i.Isolate.spawnUri(rootLib.uri, [], null);
debugger(); // LINE_A
tempDir.deleteSync(recursive: true);
} catch (_) {
tempDir.deleteSync(recursive: true);
rethrow;
}
}
final tests = <IsolateTest>[
// Ensure that the main isolate has stopped at the [debugger] statement at the
// end of [testeeMain].
hasStoppedAtBreakpoint,
stoppedAtLine(LINE_A),
(VmService service, IsolateRef isolateRef) async {
final tempDir = Directory.systemTemp.createTempSync();
try {
const numberOfBreakpoints = 20;
final v1Contents = StringBuffer();
v1Contents.write('''
import 'dart:developer';
void f() {
''');
for (int i = 0; i < numberOfBreakpoints; i++) {
// Add closure definitions to [v1Contents]. The test will set
// breakpoints at the [print] calls in these closures to make the
// debugger eagerly compile the closures.
v1Contents.write('''
(() {
print($i);
})();
''');
}
v1Contents.write('''
}
void main() {
debugger();
f();
}
''');
final spawnedIsolateRootLib = File(join(tempDir.path, 'main.dart'));
// Find the spawned isolate.
final vm = await service.getVM();
final isolates = vm.isolates!;
expect(isolates.length, 2);
final spawnedIsolateRef = isolates.firstWhere(
(i) => i != isolateRef,
);
final spawnedIsolateId = spawnedIsolateRef.id!;
// Load [v1Contents] into the spawned isolate.
spawnedIsolateRootLib.writeAsStringSync(v1Contents.toString());
await service.reloadSources(
spawnedIsolateId,
rootLibUri: spawnedIsolateRootLib.uri.toString(),
force: true,
);
Isolate spawnedIsolate = await service.getIsolate(spawnedIsolateId);
Library rootLib = await service.getObject(
spawnedIsolateId,
spawnedIsolate.rootLib!.id!,
) as Library;
String scriptId = rootLib.scripts![0].id!;
final testStartTime = DateTime.now();
// Add a breakpoints at all of the `print` calls.
for (int i = 0; i < numberOfBreakpoints; i++) {
expect(
(await service.addBreakpoint(spawnedIsolateId, scriptId, 5 + 3 * i))
.resolved,
true,
);
}
// Force a reload of the sources.
await service.reloadSources(
spawnedIsolateId,
rootLibUri: spawnedIsolateRootLib.uri.toString(),
force: true,
);
spawnedIsolate = await service.getIsolate(spawnedIsolateId);
rootLib = await service.getObject(
spawnedIsolateId,
spawnedIsolate.rootLib!.id!,
) as Library;
scriptId = rootLib.scripts![0].id!;
// Remove the [numberOfBreakpoints] existing breakpoints.
for (int i = 1; i <= numberOfBreakpoints; i++) {
await service.removeBreakpoint(spawnedIsolateId, 'breakpoints/$i');
}
// Add [numberOfBreakpoints] new breakpoints.
for (int i = 0; i < numberOfBreakpoints; i++) {
expect(
(await service.addBreakpoint(spawnedIsolateId, scriptId, 5 + 3 * i))
.resolved,
true,
);
}
// Remove the [numberOfBreakpoints] new breakpoints.
for (int i = numberOfBreakpoints + 1; i <= numberOfBreakpoints * 2; i++) {
await service.removeBreakpoint(spawnedIsolateId, 'breakpoints/$i');
}
print(
'Took ${DateTime.now().difference(testStartTime).inMilliseconds}ms',
);
await resumeIsolate(service, spawnedIsolateRef);
tempDir.deleteSync(recursive: true);
} catch (_) {
tempDir.deleteSync(recursive: true);
rethrow;
}
},
];
void main([args = const <String>[]]) => runIsolateTests(
args,
tests,
'set_reload_and_reset_breakpoints_test.dart',
testeeConcurrent: testeeMain,
);