blob: d020ffe4b22929a869a8fd3886d809041ac962d5 [file] [log] [blame]
// Copyright (c) 2023, 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:async';
import 'package:test/test.dart';
import 'package:vm_service/vm_service.dart';
import 'common/service_test_common.dart';
import 'common/test_helper.dart';
int counter = 0;
const LINE_A = 20;
const LINE_B = LINE_A + 1;
const LINE_C = LINE_A - 2;
void periodicTask(_) {
counter++;
counter++; // Line 19. We set our breakpoint here.
counter++;
if (counter % 300 == 0) {
print('counter = $counter');
}
}
void startTimer() {
Timer.periodic(const Duration(milliseconds: 10), periodicTask);
}
Future<void> waitForEvent(VmService service, String eventKind) {
final completer = Completer<void>();
late final StreamSubscription<Event> subscription;
subscription = service.onDebugEvent.listen((Event event) {
if (event.kind == eventKind) {
subscription.cancel();
completer.complete();
}
});
return completer.future;
}
final tests = <IsolateTest>[
// Initialize stream.
(VmService service, IsolateRef isolateRef) async {
await service.streamListen(EventStreams.kDebug);
},
// Pause
(VmService service, IsolateRef isolateRef) async {
final isolateId = isolateRef.id!;
final event = waitForEvent(service, EventKind.kPauseInterrupted);
await service.pause(isolateId);
await event;
},
// Resume
resumeIsolate,
// Add breakpoint
(VmService service, IsolateRef isolateRef) async {
final isolateId = isolateRef.id!;
var isolate = await service.getIsolate(isolateId);
final rootLib =
await service.getObject(isolateId, isolate.rootLib!.id!) as Library;
final scriptId = rootLib.scripts![0].id!;
final script = await service.getObject(isolateId, scriptId) as Script;
final event = waitForEvent(service, EventKind.kPauseBreakpoint);
// Add the breakpoint.
final bpt = await service.addBreakpoint(isolateId, scriptId, LINE_A);
expect(bpt.location!.script!.id, scriptId);
expect(script.getLineNumberFromTokenPos(bpt.location!.tokenPos), LINE_A);
isolate = await service.getIsolate(isolateId);
expect(isolate.breakpoints!.length, 1);
await event; // Wait for breakpoint events.
},
// We are at the breakpoint on LINE_A.
stoppedAtLine(LINE_A),
// Stepping
(VmService service, IsolateRef isolateRef) async {
final event = waitForEvent(service, EventKind.kPauseBreakpoint);
await service.resume(isolateRef.id!, step: StepOption.kOver);
await event; // Wait for breakpoint events.
},
// We are now at line LINE_B.
stoppedAtLine(LINE_B),
// Remove breakpoint
(VmService service, IsolateRef isolateRef) async {
final isolateId = isolateRef.id!;
var isolate = await service.getIsolate(isolateId);
// Set up a listener to wait for breakpoint events.
final event = waitForEvent(service, EventKind.kBreakpointRemoved);
expect(isolate.breakpoints!.length, 1);
final bpt = isolate.breakpoints!.first;
await service.removeBreakpoint(isolateId, bpt.id!);
await event;
isolate = await service.getIsolate(isolateId);
expect(isolate.breakpoints!.length, 0);
},
// Resume
resumeIsolate,
// Add breakpoint at function entry
(VmService service, IsolateRef isolateRef) async {
// Set up a listener to wait for breakpoint events.
final event = waitForEvent(service, EventKind.kPauseBreakpoint);
final isolateId = isolateRef.id!;
var isolate = await service.getIsolate(isolateId);
final rootLib =
await service.getObject(isolateId, isolate.rootLib!.id!) as Library;
// Find a specific function.
final function = rootLib.functions!.firstWhere(
(f) => f.name == 'periodicTask',
);
// Add the breakpoint at function entry
final bpt = await service.addBreakpointAtEntry(isolateId, function.id!);
final script =
await service.getObject(isolateId, bpt.location!.script!.id!) as Script;
expect(script.uri, endsWith('debugging_test.dart'));
expect(script.getLineNumberFromTokenPos(bpt.location!.tokenPos), LINE_C);
isolate = await service.getIsolate(isolateId);
expect(isolate.breakpoints!.length, 1);
await event; // Wait for breakpoint events.
},
// We are now at line LINE_C, the entrypoint for periodicTask.
stoppedAtLine(LINE_C),
];
void main(List<String> args) => runIsolateTests(
args,
tests,
'debugging_test.dart',
testeeBefore: startTimer,
);