mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 21:50:11 +00:00
[ package:vm_service ] Migrate Observatory service tests to package:vm_service (Pt 2)
See https://github.com/dart-lang/sdk/issues/45037 TEST=pkg/vm_service/test/* Change-Id: I0632744fdea0da63a47d64299cbd1f96f45dcb3a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/186742 Reviewed-by: Siva Annamalai <asiva@google.com> Commit-Queue: Ben Konyi <bkonyi@google.com>
This commit is contained in:
parent
1b204a9c85
commit
ad4d10a42c
|
@ -3420,7 +3420,7 @@ class CodeRef extends ObjRef {
|
|||
}
|
||||
|
||||
/// A `Code` object represents compiled code in the Dart VM.
|
||||
class Code extends ObjRef implements CodeRef {
|
||||
class Code extends Obj implements CodeRef {
|
||||
static Code? parse(Map<String, dynamic>? json) =>
|
||||
json == null ? null : Code._fromJson(json);
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ dependencies:
|
|||
|
||||
dev_dependencies:
|
||||
async: ^2.5.0
|
||||
expect: any
|
||||
markdown: ^4.0.0-nullsafety.0
|
||||
mockito: ^5.0.0-nullsafety.1
|
||||
path: ^1.8.0
|
||||
|
|
76
pkg/vm_service/test/causal_async_stack_contents_test.dart
Normal file
76
pkg/vm_service/test/causal_async_stack_contents_test.dart
Normal file
|
@ -0,0 +1,76 @@
|
|||
// Copyright (c) 2017, 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.
|
||||
//
|
||||
// VMOptions=--lazy-async-stacks --verbose_debug
|
||||
|
||||
import 'dart:developer';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
|
||||
import 'common/service_test_common.dart';
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
const LINE_C = 20;
|
||||
const LINE_A = 26;
|
||||
const LINE_B = 32;
|
||||
|
||||
foobar() {
|
||||
debugger();
|
||||
print('foobar'); // LINE_C.
|
||||
}
|
||||
|
||||
helper() async {
|
||||
await 0; // force async gap
|
||||
debugger();
|
||||
print('helper'); // LINE_A.
|
||||
foobar();
|
||||
}
|
||||
|
||||
testMain() {
|
||||
debugger();
|
||||
helper(); // LINE_B.
|
||||
}
|
||||
|
||||
var tests = <IsolateTest>[
|
||||
hasStoppedAtBreakpoint,
|
||||
stoppedAtLine(LINE_B),
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
Stack stack = await service.getStack(isolateRef.id!);
|
||||
// No causal frames because we are in a completely synchronous stack.
|
||||
expect(stack.asyncCausalFrames, isNull);
|
||||
},
|
||||
resumeIsolate,
|
||||
hasStoppedAtBreakpoint,
|
||||
stoppedAtLine(LINE_A),
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
Stack stack = await service.getStack(isolateRef.id!);
|
||||
// Has causal frames (we are inside an async function)
|
||||
expect(stack.asyncCausalFrames, isNotNull);
|
||||
expect(
|
||||
stack.asyncCausalFrames![0].function!.owner.name,
|
||||
contains('helper'),
|
||||
);
|
||||
// "helper" is not await'ed.
|
||||
},
|
||||
resumeIsolate,
|
||||
hasStoppedAtBreakpoint,
|
||||
stoppedAtLine(LINE_C),
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
Stack stack = await service.getStack(isolateRef.id!);
|
||||
// Has causal frames (we are inside a function called by an async function)
|
||||
expect(stack.asyncCausalFrames, isNotNull);
|
||||
final asyncStack = stack.asyncCausalFrames!;
|
||||
expect(asyncStack[0].function!.name, contains('foobar'));
|
||||
expect(asyncStack[1].function!.owner.name, contains('helper'));
|
||||
// "helper" is not await'ed.
|
||||
},
|
||||
];
|
||||
|
||||
main(args) => runIsolateTestsSynchronous(
|
||||
args,
|
||||
tests,
|
||||
'causal_async_stack_contents_test.dart',
|
||||
testeeConcurrent: testMain,
|
||||
extraArgs: extraDebuggingArgs,
|
||||
);
|
67
pkg/vm_service/test/causal_async_stack_presence_test.dart
Normal file
67
pkg/vm_service/test/causal_async_stack_presence_test.dart
Normal file
|
@ -0,0 +1,67 @@
|
|||
// Copyright (c) 2017, 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.
|
||||
//
|
||||
// VMOptions=--lazy-async-stacks --verbose_debug
|
||||
|
||||
import 'dart:developer';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
import 'common/service_test_common.dart';
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
const LINE_C = 19;
|
||||
const LINE_A = 25;
|
||||
const LINE_B = 31;
|
||||
|
||||
foobar() {
|
||||
debugger();
|
||||
print('foobar'); // LINE_C.
|
||||
}
|
||||
|
||||
helper() async {
|
||||
await 0; // Yield. The rest will run async.
|
||||
debugger();
|
||||
print('helper'); // LINE_A.
|
||||
foobar();
|
||||
}
|
||||
|
||||
testMain() {
|
||||
debugger();
|
||||
helper(); // LINE_B.
|
||||
}
|
||||
|
||||
var tests = <IsolateTest>[
|
||||
hasStoppedAtBreakpoint,
|
||||
stoppedAtLine(LINE_B),
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
Stack stack = await service.getStack(isolateRef.id!);
|
||||
// No causal frames because we are in a completely synchronous stack.
|
||||
// Async function hasn't yielded yet.
|
||||
expect(stack.asyncCausalFrames, isNull);
|
||||
},
|
||||
resumeIsolate,
|
||||
hasStoppedAtBreakpoint,
|
||||
stoppedAtLine(LINE_A),
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
Stack stack = await service.getStack(isolateRef.id!);
|
||||
// Async function has yielded once, so it's now running async.
|
||||
expect(stack.asyncCausalFrames, isNotNull);
|
||||
},
|
||||
resumeIsolate,
|
||||
hasStoppedAtBreakpoint,
|
||||
stoppedAtLine(LINE_C),
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
Stack stack = await service.getStack(isolateRef.id!);
|
||||
// Has causal frames (we are inside a function called by an async function)
|
||||
expect(stack.asyncCausalFrames, isNotNull);
|
||||
},
|
||||
];
|
||||
|
||||
main(args) => runIsolateTestsSynchronous(
|
||||
args,
|
||||
tests,
|
||||
'causal_async_stack_presence_test.dart',
|
||||
testeeConcurrent: testMain,
|
||||
extraArgs: extraDebuggingArgs,
|
||||
);
|
|
@ -0,0 +1,97 @@
|
|||
// Copyright (c) 2017, 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.
|
||||
//
|
||||
// VMOptions=--lazy-async-stacks --verbose_debug
|
||||
|
||||
import 'dart:developer';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
|
||||
import 'common/service_test_common.dart';
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
const LINE_A = 29;
|
||||
const LINE_B = 21;
|
||||
const LINE_C = 23;
|
||||
|
||||
foobar() async* {
|
||||
await 0; // force async gap
|
||||
debugger();
|
||||
yield 1; // LINE_B.
|
||||
debugger();
|
||||
yield 2; // LINE_C.
|
||||
}
|
||||
|
||||
helper() async {
|
||||
await 0; // force async gap
|
||||
debugger();
|
||||
print('helper'); // LINE_A.
|
||||
await for (var i in foobar()) {
|
||||
print('helper $i');
|
||||
}
|
||||
}
|
||||
|
||||
testMain() {
|
||||
helper();
|
||||
}
|
||||
|
||||
final tests = <IsolateTest>[
|
||||
hasStoppedAtBreakpoint,
|
||||
stoppedAtLine(LINE_A),
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
Stack stack = await service.getStack(isolateRef.id!);
|
||||
// No causal frames because we are in a completely synchronous stack.
|
||||
expect(stack.asyncCausalFrames, isNotNull);
|
||||
final asyncStack = stack.asyncCausalFrames!;
|
||||
expect(asyncStack.length, greaterThanOrEqualTo(1));
|
||||
expect(asyncStack[0].function!.owner.name, contains('helper'));
|
||||
// helper isn't awaited.
|
||||
},
|
||||
resumeIsolate,
|
||||
hasStoppedAtBreakpoint,
|
||||
stoppedAtLine(LINE_B),
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
Stack stack = await service.getStack(isolateRef.id!);
|
||||
// Has causal frames (we are inside an async function)
|
||||
expect(stack.asyncCausalFrames, isNotNull);
|
||||
final asyncStack = stack.asyncCausalFrames!;
|
||||
expect(asyncStack.length, greaterThanOrEqualTo(3));
|
||||
expect(asyncStack[0].function!.owner.name, contains('foobar'));
|
||||
expect(asyncStack[1].kind, equals(FrameKind.kAsyncSuspensionMarker));
|
||||
expect(asyncStack[2].function!.owner.name, contains('helper'));
|
||||
expect(asyncStack[3].kind, equals(FrameKind.kAsyncSuspensionMarker));
|
||||
},
|
||||
resumeIsolate,
|
||||
hasStoppedAtBreakpoint,
|
||||
stoppedAtLine(LINE_C),
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
Stack stack = await service.getStack(isolateRef.id!);
|
||||
// Has causal frames (we are inside a function called by an async function)
|
||||
expect(stack.asyncCausalFrames, isNotNull);
|
||||
final asyncStack = stack.asyncCausalFrames!;
|
||||
expect(asyncStack.length, greaterThanOrEqualTo(4));
|
||||
final script = await service.getObject(
|
||||
isolateRef.id!, asyncStack[0].location!.script!.id!) as Script;
|
||||
expect(asyncStack[0].function!.owner.name, contains('foobar'));
|
||||
expect(
|
||||
script.getLineNumberFromTokenPos(asyncStack[0].location!.tokenPos!),
|
||||
LINE_C,
|
||||
);
|
||||
expect(asyncStack[1].kind, equals(FrameKind.kAsyncSuspensionMarker));
|
||||
expect(asyncStack[2].function!.owner.name, contains('helper'));
|
||||
expect(
|
||||
script.getLineNumberFromTokenPos(asyncStack[2].location!.tokenPos!),
|
||||
30,
|
||||
);
|
||||
expect(asyncStack[3].kind, equals(FrameKind.kAsyncSuspensionMarker));
|
||||
},
|
||||
];
|
||||
|
||||
main(args) => runIsolateTestsSynchronous(
|
||||
args,
|
||||
tests,
|
||||
'causal_async_star_stack_contents_test.dart',
|
||||
testeeConcurrent: testMain,
|
||||
extraArgs: extraDebuggingArgs,
|
||||
);
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright (c) 2017, 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.
|
||||
//
|
||||
// VMOptions=--lazy-async-stacks --verbose_debug
|
||||
|
||||
import 'dart:developer';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
import 'common/service_test_common.dart';
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
const LINE_A = 26;
|
||||
const LINE_B = 19;
|
||||
const LINE_C = 21;
|
||||
|
||||
foobar() async* {
|
||||
debugger();
|
||||
yield 1; // LINE_B.
|
||||
debugger();
|
||||
yield 2; // LINE_C.
|
||||
}
|
||||
|
||||
helper() async {
|
||||
debugger();
|
||||
print('helper'); // LINE_A.
|
||||
await for (var i in foobar()) {
|
||||
print('helper $i');
|
||||
}
|
||||
}
|
||||
|
||||
testMain() {
|
||||
helper();
|
||||
}
|
||||
|
||||
var tests = <IsolateTest>[
|
||||
hasStoppedAtBreakpoint,
|
||||
stoppedAtLine(LINE_A),
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
Stack stack = await service.getStack(isolateRef.id!);
|
||||
// No causal frames because we are in a completely synchronous stack.
|
||||
expect(stack.asyncCausalFrames, isNull);
|
||||
},
|
||||
resumeIsolate,
|
||||
hasStoppedAtBreakpoint,
|
||||
stoppedAtLine(LINE_B),
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
Stack stack = await service.getStack(isolateRef.id!);
|
||||
// Has causal frames (we are inside an async function)
|
||||
expect(stack.asyncCausalFrames, isNotNull);
|
||||
},
|
||||
resumeIsolate,
|
||||
hasStoppedAtBreakpoint,
|
||||
stoppedAtLine(LINE_C),
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
Stack stack = await service.getStack(isolateRef.id!);
|
||||
// Has causal frames (we are inside a function called by an async function)
|
||||
expect(stack.asyncCausalFrames, isNotNull);
|
||||
},
|
||||
];
|
||||
|
||||
main(args) => runIsolateTestsSynchronous(
|
||||
args,
|
||||
tests,
|
||||
'causal_async_star_stack_presence_test.dart',
|
||||
testeeConcurrent: testMain,
|
||||
extraArgs: extraDebuggingArgs,
|
||||
);
|
90
pkg/vm_service/test/code_test.dart
Normal file
90
pkg/vm_service/test/code_test.dart
Normal file
|
@ -0,0 +1,90 @@
|
|||
// Copyright (c) 2015, 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/test_helper.dart';
|
||||
|
||||
int counter = 0;
|
||||
|
||||
void funcB() {
|
||||
counter++; // line 13
|
||||
if (counter % 100000000 == 0) {
|
||||
print(counter);
|
||||
}
|
||||
}
|
||||
|
||||
void funcA() {
|
||||
funcB();
|
||||
}
|
||||
|
||||
void testFunction() {
|
||||
while (true) {
|
||||
funcA();
|
||||
}
|
||||
}
|
||||
|
||||
var tests = <IsolateTest>[
|
||||
// Go to breakpoint at line 13.
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final isolateId = isolateRef.id!;
|
||||
final isolate = await service.getIsolate(isolateId);
|
||||
final rootLib =
|
||||
await service.getObject(isolateId, isolate.rootLib!.id!) as Library;
|
||||
// Set up a listener to wait for breakpoint events.
|
||||
final completer = Completer<void>();
|
||||
|
||||
late final StreamSubscription subscription;
|
||||
subscription = service.onDebugEvent.listen((event) async {
|
||||
if (event.kind == EventKind.kPauseBreakpoint) {
|
||||
print('Breakpoint reached');
|
||||
await service.streamCancel(EventStreams.kDebug);
|
||||
await subscription.cancel();
|
||||
completer.complete();
|
||||
}
|
||||
});
|
||||
await service.streamListen(EventStreams.kDebug);
|
||||
|
||||
// Add the breakpoint.
|
||||
final script = rootLib.scripts![0];
|
||||
final line = 13;
|
||||
await service.addBreakpoint(isolateId, script.id!, line);
|
||||
await completer.future; // Wait for breakpoint reached.
|
||||
},
|
||||
|
||||
// Inspect code objects for top two frames.
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final isolateId = isolateRef.id!;
|
||||
Stack stack = await service.getStack(isolateId);
|
||||
// Make sure we are in the right place.
|
||||
expect(stack.frames!.length, greaterThanOrEqualTo(3));
|
||||
final frame0 = stack.frames![0];
|
||||
final frame1 = stack.frames![1];
|
||||
expect(frame0.function!.name, equals('funcB'));
|
||||
expect(frame1.function!.name, equals('funcA'));
|
||||
final codeId0 = frame0.code!.id!;
|
||||
final codeId1 = frame1.code!.id!;
|
||||
|
||||
// Load code from frame 0.
|
||||
Code code = await service.getObject(isolateId, codeId0) as Code;
|
||||
expect(code.name, contains('funcB'));
|
||||
expect(code.json!['_disassembly'], isNotNull);
|
||||
expect(code.json!['_disassembly'].length, greaterThan(0));
|
||||
|
||||
// Load code from frame 0.
|
||||
code = await service.getObject(isolateId, codeId1) as Code;
|
||||
expect(code.type, equals('Code'));
|
||||
expect(code.name, contains('funcA'));
|
||||
expect(code.json!['_disassembly'], isNotNull);
|
||||
expect(code.json!['_disassembly'].length, greaterThan(0));
|
||||
},
|
||||
];
|
||||
|
||||
main([args = const <String>[]]) => runIsolateTests(
|
||||
args,
|
||||
tests,
|
||||
'code_test.dart',
|
||||
testeeConcurrent: testFunction,
|
||||
);
|
44
pkg/vm_service/test/column_breakpoint_test.dart
Normal file
44
pkg/vm_service/test/column_breakpoint_test.dart
Normal file
|
@ -0,0 +1,44 @@
|
|||
// Copyright (c) 2019, 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 'common/service_test_common.dart';
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
code() {
|
||||
var b = [1, 2].map((i) => i == 0).toList();
|
||||
print(b.length);
|
||||
}
|
||||
|
||||
const int LINE = 9;
|
||||
const int COLUMN = 29;
|
||||
const String shortFile = "column_breakpoint_test.dart";
|
||||
const String breakpointFile =
|
||||
"package:observatory_test_package/column_breakpoint_test.dart";
|
||||
|
||||
List<String> stops = [];
|
||||
|
||||
List<String> expected = [
|
||||
"$shortFile:${LINE + 0}:23", // on 'i == 0'
|
||||
"$shortFile:${LINE + 0}:23", // iterate twice
|
||||
"$shortFile:${LINE + 1}:3" //on 'b.length'
|
||||
];
|
||||
|
||||
var tests = <IsolateTest>[
|
||||
hasPausedAtStart,
|
||||
setBreakpointAtLineColumn(LINE, COLUMN), // on 'i == 0'
|
||||
setBreakpointAtLineColumn(LINE + 1, 9), // on 'b.length'
|
||||
resumeProgramRecordingStops(stops, false),
|
||||
checkRecordedStops(stops, expected)
|
||||
];
|
||||
|
||||
main(args) {
|
||||
runIsolateTestsSynchronous(
|
||||
args,
|
||||
tests,
|
||||
'column_breakpoint_test.dart',
|
||||
testeeConcurrent: code,
|
||||
pause_on_start: true,
|
||||
pause_on_exit: true,
|
||||
);
|
||||
}
|
|
@ -142,6 +142,25 @@ IsolateTest setBreakpointAtUriAndLine(String uri, int line) {
|
|||
};
|
||||
}
|
||||
|
||||
IsolateTest setBreakpointAtLineColumn(int line, int column) {
|
||||
return (VmService service, IsolateRef isolateRef) async {
|
||||
print("Setting breakpoint for line $line column $column");
|
||||
final isolateId = isolateRef.id!;
|
||||
final isolate = await service.getIsolate(isolateId);
|
||||
final lib =
|
||||
await service.getObject(isolateId, isolate.rootLib!.id!) as Library;
|
||||
ScriptRef script = lib.scripts!.firstWhere((s) => s.uri == lib.uri);
|
||||
Breakpoint bpt = await service.addBreakpoint(
|
||||
isolateId,
|
||||
script.id!,
|
||||
line,
|
||||
column: column,
|
||||
);
|
||||
print("Breakpoint is $bpt");
|
||||
expect(bpt, isNotNull);
|
||||
};
|
||||
}
|
||||
|
||||
IsolateTest stoppedAtLine(int line) {
|
||||
return (VmService service, IsolateRef isolateRef) async {
|
||||
print("Checking we are at line $line");
|
||||
|
@ -211,6 +230,34 @@ Future<void> _unsubscribeDebugStream(VmService service) async {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> resumeAndAwaitEvent(
|
||||
VmService service,
|
||||
IsolateRef isolateRef,
|
||||
String streamId,
|
||||
Function(Event) onEvent,
|
||||
) async {
|
||||
final completer = Completer<void>();
|
||||
late final StreamSubscription sub;
|
||||
sub = service.onEvent(streamId).listen((event) async {
|
||||
await onEvent(event);
|
||||
await sub.cancel();
|
||||
await service.streamCancel(streamId);
|
||||
completer.complete();
|
||||
});
|
||||
|
||||
await service.streamListen(streamId);
|
||||
await service.resume(isolateRef.id!);
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
IsolateTest resumeIsolateAndAwaitEvent(
|
||||
String streamId,
|
||||
Function(Event) onEvent,
|
||||
) {
|
||||
return (VmService service, IsolateRef isolate) async =>
|
||||
resumeAndAwaitEvent(service, isolate, streamId, onEvent);
|
||||
}
|
||||
|
||||
Future<void> stepOver(VmService service, IsolateRef isolateRef) async {
|
||||
await service.streamListen(EventStreams.kDebug);
|
||||
await _subscribeDebugStream(service);
|
||||
|
@ -242,14 +289,13 @@ IsolateTest resumeProgramRecordingStops(
|
|||
subscription = service.onDebugEvent.listen((event) async {
|
||||
if (event.kind == EventKind.kPauseBreakpoint) {
|
||||
final stack = await service.getStack(isolateRef.id!);
|
||||
final frames = stack.frames!;
|
||||
expect(frames.length, greaterThanOrEqualTo(2));
|
||||
expect(stack.frames!.length, greaterThanOrEqualTo(2));
|
||||
|
||||
String brokeAt =
|
||||
await _locationToString(service, isolateRef, frames[0]);
|
||||
await _locationToString(service, isolateRef, stack.frames![0]);
|
||||
if (includeCaller) {
|
||||
brokeAt =
|
||||
'$brokeAt (${await _locationToString(service, isolateRef, frames[1])})';
|
||||
'$brokeAt (${await _locationToString(service, isolateRef, stack.frames![1])})';
|
||||
}
|
||||
recordStops.add(brokeAt);
|
||||
await service.resume(isolateRef.id!);
|
||||
|
|
|
@ -351,6 +351,8 @@ class _ServiceTesterRunner {
|
|||
|
||||
await service.streamListen(EventStreams.kIsolate);
|
||||
|
||||
await service.streamListen(EventStreams.kIsolate);
|
||||
|
||||
// The isolate may have started before we subscribed.
|
||||
vm = await service.getVM();
|
||||
if (vmIsolates.isNotEmpty) {
|
||||
|
|
151
pkg/vm_service/test/contexts_test.dart
Normal file
151
pkg/vm_service/test/contexts_test.dart
Normal file
|
@ -0,0 +1,151 @@
|
|||
// Copyright (c) 2014, 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 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
// Make sure these variables are not removed by the tree shaker.
|
||||
@pragma("vm:entry-point")
|
||||
var cleanBlock;
|
||||
@pragma("vm:entry-point")
|
||||
var copyingBlock;
|
||||
@pragma("vm:entry-point")
|
||||
var fullBlock;
|
||||
@pragma("vm:entry-point")
|
||||
var fullBlockWithChain;
|
||||
|
||||
Function genCleanBlock() {
|
||||
block(x) => x;
|
||||
return block;
|
||||
}
|
||||
|
||||
Function genCopyingBlock() {
|
||||
final x = 'I could be copied into the block';
|
||||
block() => x;
|
||||
return block;
|
||||
}
|
||||
|
||||
Function genFullBlock() {
|
||||
var x = 42; // I must captured in a context.
|
||||
block() => x;
|
||||
x++;
|
||||
return block;
|
||||
}
|
||||
|
||||
Function genFullBlockWithChain() {
|
||||
var x = 420; // I must captured in a context.
|
||||
outerBlock() {
|
||||
var y = 4200;
|
||||
innerBlock() => x + y;
|
||||
y++;
|
||||
return innerBlock;
|
||||
}
|
||||
|
||||
x++;
|
||||
return outerBlock();
|
||||
}
|
||||
|
||||
void script() {
|
||||
cleanBlock = genCleanBlock();
|
||||
copyingBlock = genCopyingBlock();
|
||||
fullBlock = genFullBlock();
|
||||
fullBlockWithChain = genFullBlockWithChain();
|
||||
}
|
||||
|
||||
var tests = <IsolateTest>[
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final isolateId = isolateRef.id!;
|
||||
final isolate = await service.getIsolate(isolateId);
|
||||
final lib =
|
||||
await service.getObject(isolateId, isolate.rootLib!.id!) as Library;
|
||||
final field = await service.getObject(
|
||||
isolateId,
|
||||
lib.variables!.singleWhere((v) => v.name == 'cleanBlock').id!,
|
||||
) as Field;
|
||||
|
||||
Instance block =
|
||||
await service.getObject(isolateId, field.staticValue!.id!) as Instance;
|
||||
expect(block.closureFunction, isNotNull);
|
||||
expect(block.closureContext, isNull);
|
||||
},
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final isolateId = isolateRef.id!;
|
||||
final isolate = await service.getIsolate(isolateId);
|
||||
final lib =
|
||||
await service.getObject(isolateId, isolate.rootLib!.id!) as Library;
|
||||
final field = await service.getObject(
|
||||
isolateId,
|
||||
lib.variables!.singleWhere((v) => v.name == 'copyingBlock').id!,
|
||||
) as Field;
|
||||
Instance block =
|
||||
await service.getObject(isolateId, field.staticValue!.id!) as Instance;
|
||||
|
||||
expect(block.closureContext, isNotNull);
|
||||
expect(block.closureContext!.length, equals(1));
|
||||
final ctxt = await service.getObject(isolateId, block.closureContext!.id!)
|
||||
as Context;
|
||||
expect(ctxt.variables!.single.value.kind, InstanceKind.kString);
|
||||
expect(
|
||||
ctxt.variables!.single.value.valueAsString,
|
||||
'I could be copied into the block',
|
||||
);
|
||||
expect(ctxt.parent, isNull);
|
||||
},
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final isolateId = isolateRef.id!;
|
||||
final isolate = await service.getIsolate(isolateId);
|
||||
final lib =
|
||||
await service.getObject(isolateId, isolate.rootLib!.id!) as Library;
|
||||
final field = await service.getObject(
|
||||
isolateId,
|
||||
lib.variables!.singleWhere((v) => v.name == 'fullBlock').id!,
|
||||
) as Field;
|
||||
Instance block =
|
||||
await service.getObject(isolateId, field.staticValue!.id!) as Instance;
|
||||
|
||||
expect(block.closureContext, isNotNull);
|
||||
expect(block.closureContext!.length, equals(1));
|
||||
final ctxt = await service.getObject(isolateId, block.closureContext!.id!)
|
||||
as Context;
|
||||
|
||||
expect(ctxt.variables!.single.value.kind, InstanceKind.kInt);
|
||||
expect(ctxt.variables!.single.value.valueAsString, '43');
|
||||
expect(ctxt.parent, isNull);
|
||||
},
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final isolateId = isolateRef.id!;
|
||||
final isolate = await service.getIsolate(isolateId);
|
||||
final lib =
|
||||
await service.getObject(isolateId, isolate.rootLib!.id!) as Library;
|
||||
final field = await service.getObject(
|
||||
isolateId,
|
||||
lib.variables!.singleWhere((v) => v.name == 'fullBlockWithChain').id!,
|
||||
) as Field;
|
||||
final block =
|
||||
await service.getObject(isolateId, field.staticValue!.id!) as Instance;
|
||||
|
||||
expect(block.closureContext, isNotNull);
|
||||
expect(block.closureContext!.length, equals(1));
|
||||
final ctxt = await service.getObject(isolateId, block.closureContext!.id!)
|
||||
as Context;
|
||||
expect(ctxt.variables!.single.value.kind, InstanceKind.kInt);
|
||||
expect(ctxt.variables!.single.value.valueAsString, '4201');
|
||||
expect(ctxt.parent!.length, 1);
|
||||
|
||||
final outerCtxt =
|
||||
await service.getObject(isolateId, ctxt.parent!.id!) as Context;
|
||||
expect(outerCtxt.variables!.single.value.kind, InstanceKind.kInt);
|
||||
expect(outerCtxt.variables!.single.value.valueAsString, '421');
|
||||
expect(outerCtxt.parent, isNull);
|
||||
},
|
||||
];
|
||||
|
||||
main(args) => runIsolateTests(
|
||||
args,
|
||||
tests,
|
||||
'contexts_test.dart',
|
||||
testeeBefore: script,
|
||||
);
|
|
@ -0,0 +1,83 @@
|
|||
// Copyright (c) 2019, 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';
|
||||
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
|
||||
import 'common/service_test_common.dart';
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
const int LINE_A = 17; // LINE_A - 4
|
||||
const int LINE_B = 25; // LINE_A - 3
|
||||
|
||||
class Bar {
|
||||
static const String field = "field"; // LINE_A
|
||||
}
|
||||
|
||||
Future<String> fooAsync(int x) async {
|
||||
if (x == 42) {
|
||||
return '*' * x;
|
||||
}
|
||||
return List.generate(x, (_) => 'xyzzy').join(' ');
|
||||
} // LINE_B
|
||||
|
||||
Future<void> testFunction() async {
|
||||
await Future.delayed(Duration(milliseconds: 500));
|
||||
// ignore: unawaited_futures
|
||||
fooAsync(42).then((_) {});
|
||||
debugger();
|
||||
}
|
||||
|
||||
var tests = <IsolateTest>[
|
||||
hasStoppedAtBreakpoint,
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final isolateId = isolateRef.id!;
|
||||
final isolate = await service.getIsolate(isolateId);
|
||||
final stack = await service.getStack(isolateId);
|
||||
|
||||
// Make sure we are in the right place.
|
||||
expect(stack.frames!.length, greaterThanOrEqualTo(1));
|
||||
// Async closure of testFunction
|
||||
expect(stack.frames![0].function!.name, 'async_op');
|
||||
|
||||
final rootLib =
|
||||
await service.getObject(isolateId, isolate.rootLib!.id!) as Library;
|
||||
final script = await service.getObject(
|
||||
isolateId, rootLib.scripts!.first.id!) as Script;
|
||||
|
||||
final report = await service.getSourceReport(
|
||||
isolateId,
|
||||
['Coverage'],
|
||||
scriptId: script.id!,
|
||||
forceCompile: true,
|
||||
);
|
||||
int match = 0;
|
||||
for (var range in report.ranges!) {
|
||||
for (int i in range.coverage!.hits!) {
|
||||
int? line = script.getLineNumberFromTokenPos(i);
|
||||
if (line == null) {
|
||||
throw FormatException('token ${i} was missing source location');
|
||||
}
|
||||
// Check LINE.
|
||||
if (line == LINE_A || line == LINE_A - 3 || line == LINE_A - 4) {
|
||||
match = match + 1;
|
||||
}
|
||||
// _clearAsyncThreadStackTrace should have an invalid token position.
|
||||
expect(line, isNot(LINE_B));
|
||||
}
|
||||
}
|
||||
// Neither LINE nor Bar.field should be added into coverage.
|
||||
expect(match, 0);
|
||||
},
|
||||
resumeIsolate
|
||||
];
|
||||
|
||||
main([args = const <String>[]]) => runIsolateTests(
|
||||
args,
|
||||
tests,
|
||||
'coverage_const_field_async_closure_test.dart',
|
||||
testeeConcurrent: testFunction,
|
||||
);
|
|
@ -3,8 +3,10 @@
|
|||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
|
||||
import 'common/service_test_common.dart';
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
|
@ -38,7 +40,7 @@ IsolateTest coverageTest(Map<String, dynamic> expectedRange,
|
|||
expect(stack.frames!.length, greaterThanOrEqualTo(1));
|
||||
expect(stack.frames![0].function!.name, 'testFunction');
|
||||
|
||||
final Library root =
|
||||
final root =
|
||||
await service.getObject(isolateId, isolate.rootLib!.id!) as Library;
|
||||
FuncRef funcRef =
|
||||
root.functions!.singleWhere((f) => f.name == 'leafFunction');
|
||||
|
@ -69,12 +71,12 @@ var tests = <IsolateTest>[
|
|||
coverageTest(
|
||||
{
|
||||
'scriptIndex': 0,
|
||||
'startPos': 397,
|
||||
'endPos': 447,
|
||||
'startPos': 399,
|
||||
'endPos': 449,
|
||||
'compiled': true,
|
||||
'coverage': {
|
||||
'hits': [],
|
||||
'misses': [397]
|
||||
'misses': [399]
|
||||
}
|
||||
},
|
||||
reportLines: false,
|
||||
|
@ -82,12 +84,12 @@ var tests = <IsolateTest>[
|
|||
coverageTest(
|
||||
{
|
||||
'scriptIndex': 0,
|
||||
'startPos': 397,
|
||||
'endPos': 447,
|
||||
'startPos': 399,
|
||||
'endPos': 449,
|
||||
'compiled': true,
|
||||
'coverage': {
|
||||
'hits': [],
|
||||
'misses': [11]
|
||||
'misses': [13]
|
||||
}
|
||||
},
|
||||
reportLines: true,
|
||||
|
@ -97,11 +99,11 @@ var tests = <IsolateTest>[
|
|||
coverageTest(
|
||||
{
|
||||
'scriptIndex': 0,
|
||||
'startPos': 397,
|
||||
'endPos': 447,
|
||||
'startPos': 399,
|
||||
'endPos': 449,
|
||||
'compiled': true,
|
||||
'coverage': {
|
||||
'hits': [397],
|
||||
'hits': [399],
|
||||
'misses': []
|
||||
}
|
||||
},
|
||||
|
@ -110,11 +112,11 @@ var tests = <IsolateTest>[
|
|||
coverageTest(
|
||||
{
|
||||
'scriptIndex': 0,
|
||||
'startPos': 397,
|
||||
'endPos': 447,
|
||||
'startPos': 399,
|
||||
'endPos': 449,
|
||||
'compiled': true,
|
||||
'coverage': {
|
||||
'hits': [11],
|
||||
'hits': [13],
|
||||
'misses': []
|
||||
}
|
||||
},
|
||||
|
|
73
pkg/vm_service/test/coverage_optimized_function_test.dart
Normal file
73
pkg/vm_service/test/coverage_optimized_function_test.dart
Normal file
|
@ -0,0 +1,73 @@
|
|||
// Copyright (c) 2017, 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.
|
||||
// VMOptions=--no_background_compilation --optimization_counter_threshold=10
|
||||
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
|
||||
import 'common/service_test_common.dart';
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
String optimizedFunction() {
|
||||
return 5.toString() + 3.toString();
|
||||
}
|
||||
|
||||
void testFunction() {
|
||||
for (var i = 0; i < 20; i++) {
|
||||
optimizedFunction();
|
||||
}
|
||||
debugger();
|
||||
}
|
||||
|
||||
var tests = <IsolateTest>[
|
||||
hasStoppedAtBreakpoint,
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final isolateId = isolateRef.id!;
|
||||
final isolate = await service.getIsolate(isolateId);
|
||||
final stack = await service.getStack(isolateId);
|
||||
|
||||
// Make sure we are in the right place.
|
||||
expect(stack.frames!.length, greaterThanOrEqualTo(1));
|
||||
expect(stack.frames![0].function!.name, 'testFunction');
|
||||
|
||||
final root =
|
||||
await service.getObject(isolateId, isolate.rootLib!.id!) as Library;
|
||||
final func = await service.getObject(
|
||||
isolateId,
|
||||
root.functions!.singleWhere((f) => f.name == 'optimizedFunction').id!,
|
||||
) as Func;
|
||||
|
||||
final report = await service.getSourceReport(
|
||||
isolateId,
|
||||
['Coverage'],
|
||||
scriptId: func.location!.script!.id!,
|
||||
tokenPos: func.location!.tokenPos,
|
||||
endTokenPos: func.location!.endTokenPos,
|
||||
forceCompile: true,
|
||||
);
|
||||
expect(report.ranges!.length, 1);
|
||||
final range = report.ranges![0];
|
||||
expect(range.scriptIndex, 0);
|
||||
expect(range.startPos, 476);
|
||||
expect(range.endPos, 543);
|
||||
expect(range.compiled, true);
|
||||
final coverage = range.coverage!;
|
||||
expect(coverage.hits, const [476, 516, 527, 531]);
|
||||
expect(coverage.misses, isEmpty);
|
||||
expect(report.scripts!.length, 1);
|
||||
expect(
|
||||
report.scripts![0].uri,
|
||||
endsWith('coverage_optimized_function_test.dart'),
|
||||
);
|
||||
},
|
||||
];
|
||||
|
||||
main([args = const <String>[]]) => runIsolateTests(
|
||||
args,
|
||||
tests,
|
||||
'coverage_optimized_function_test.dart',
|
||||
testeeConcurrent: testFunction,
|
||||
);
|
54
pkg/vm_service/test/debugger_inspect_test.dart
Normal file
54
pkg/vm_service/test/debugger_inspect_test.dart
Normal file
|
@ -0,0 +1,54 @@
|
|||
// Copyright (c) 2015, 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 'dart:developer';
|
||||
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
class Point {
|
||||
int x, y;
|
||||
Point(this.x, this.y);
|
||||
}
|
||||
|
||||
void testeeDo() {
|
||||
inspect(Point(3, 4));
|
||||
}
|
||||
|
||||
final tests = <IsolateTest>[
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final isolateId = isolateRef.id!;
|
||||
final isolate = await service.getIsolate(isolateId);
|
||||
|
||||
final completer = Completer();
|
||||
late StreamSubscription sub;
|
||||
sub = service.onDebugEvent.listen((event) async {
|
||||
if (event.kind == EventKind.kInspect) {
|
||||
expect(event.inspectee!.classRef!.name, 'Point');
|
||||
await sub.cancel();
|
||||
await service.streamCancel(EventStreams.kDebug);
|
||||
completer.complete();
|
||||
}
|
||||
});
|
||||
|
||||
await service.streamListen(EventStreams.kDebug);
|
||||
|
||||
// Start listening for events first.
|
||||
await service.evaluate(
|
||||
isolateRef.id!,
|
||||
isolate.rootLib!.id!,
|
||||
'testeeDo()',
|
||||
);
|
||||
await completer.future;
|
||||
},
|
||||
];
|
||||
|
||||
main([args = const <String>[]]) => runIsolateTests(
|
||||
args,
|
||||
tests,
|
||||
'debugger_inspect_test.dart',
|
||||
);
|
143
pkg/vm_service/test/debugging_inlined_finally_test.dart
Normal file
143
pkg/vm_service/test/debugging_inlined_finally_test.dart
Normal file
|
@ -0,0 +1,143 @@
|
|||
// Copyright (c) 2015, 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';
|
||||
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
|
||||
import 'common/service_test_common.dart';
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
const int LINE_A = 25;
|
||||
const int LINE_B = 28;
|
||||
const int LINE_C = 31;
|
||||
|
||||
testFunction() {
|
||||
debugger();
|
||||
var a;
|
||||
try {
|
||||
var b;
|
||||
try {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
var x = () => i + a + b;
|
||||
return x; // LINE_A
|
||||
}
|
||||
} finally {
|
||||
b = 10; // LINE_B
|
||||
}
|
||||
} finally {
|
||||
a = 1; // LINE_C
|
||||
}
|
||||
}
|
||||
|
||||
testMain() {
|
||||
var f = testFunction();
|
||||
expect(f(), equals(11));
|
||||
}
|
||||
|
||||
var tests = <IsolateTest>[
|
||||
hasStoppedAtBreakpoint,
|
||||
// Add breakpoint
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final isolateId = isolateRef.id!;
|
||||
Isolate isolate = await service.getIsolate(isolateId);
|
||||
final rootLib =
|
||||
await service.getObject(isolateId, isolate.rootLib!.id!) as Library;
|
||||
|
||||
final script =
|
||||
await service.getObject(isolateId, rootLib.scripts![0].id!) as Script;
|
||||
|
||||
// Add 3 breakpoints.
|
||||
{
|
||||
final bpt = await service.addBreakpoint(isolateId, script.id!, LINE_A);
|
||||
expect(bpt.location!.script.id!, script.id);
|
||||
final tmpScript =
|
||||
await service.getObject(isolateId, script.id!) as Script;
|
||||
expect(
|
||||
tmpScript.getLineNumberFromTokenPos(bpt.location!.tokenPos),
|
||||
LINE_A,
|
||||
);
|
||||
isolate = await service.getIsolate(isolateId);
|
||||
expect(isolate.breakpoints!.length, 1);
|
||||
}
|
||||
|
||||
{
|
||||
final bpt = await service.addBreakpoint(isolateId, script.id!, LINE_B);
|
||||
expect(bpt.location!.script.id, script.id);
|
||||
final tmpScript =
|
||||
await service.getObject(isolateId, script.id!) as Script;
|
||||
expect(
|
||||
tmpScript.getLineNumberFromTokenPos(bpt.location!.tokenPos),
|
||||
LINE_B,
|
||||
);
|
||||
isolate = await service.getIsolate(isolateId);
|
||||
expect(isolate.breakpoints!.length, 2);
|
||||
}
|
||||
|
||||
{
|
||||
final bpt = await service.addBreakpoint(isolateId, script.id!, LINE_C);
|
||||
expect(bpt.location!.script.id, script.id!);
|
||||
final tmpScript =
|
||||
await service.getObject(isolateId, script.id!) as Script;
|
||||
expect(
|
||||
tmpScript.getLineNumberFromTokenPos(bpt.location!.tokenPos),
|
||||
LINE_C,
|
||||
);
|
||||
isolate = await service.getIsolate(isolateId);
|
||||
expect(isolate.breakpoints!.length, 3);
|
||||
}
|
||||
// Wait for breakpoint events.
|
||||
},
|
||||
resumeIsolate,
|
||||
hasStoppedAtBreakpoint,
|
||||
// We are at the breakpoint on line LINE_A.
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final stack = await service.getStack(isolateRef.id!);
|
||||
expect(stack.frames!.length, greaterThanOrEqualTo(1));
|
||||
|
||||
final script = await service.getObject(
|
||||
isolateRef.id!, stack.frames![0].location!.script!.id!) as Script;
|
||||
expect(
|
||||
script.getLineNumberFromTokenPos(stack.frames![0].location!.tokenPos!),
|
||||
LINE_A,
|
||||
);
|
||||
},
|
||||
resumeIsolate,
|
||||
hasStoppedAtBreakpoint,
|
||||
// We are at the breakpoint on line LINE_B.
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final stack = await service.getStack(isolateRef.id!);
|
||||
expect(stack.frames!.length, greaterThanOrEqualTo(1));
|
||||
|
||||
final script = await service.getObject(
|
||||
isolateRef.id!, stack.frames![0].location!.script!.id!) as Script;
|
||||
expect(
|
||||
script.getLineNumberFromTokenPos(stack.frames![0].location!.tokenPos!),
|
||||
LINE_B,
|
||||
);
|
||||
},
|
||||
resumeIsolate,
|
||||
hasStoppedAtBreakpoint,
|
||||
// We are at the breakpoint on line LINE_C.
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final stack = await service.getStack(isolateRef.id!);
|
||||
expect(stack.frames!.length, greaterThanOrEqualTo(1));
|
||||
|
||||
final script = await service.getObject(
|
||||
isolateRef.id!, stack.frames![0].location!.script!.id!) as Script;
|
||||
expect(
|
||||
script.getLineNumberFromTokenPos(stack.frames![0].location!.tokenPos!),
|
||||
LINE_C,
|
||||
);
|
||||
},
|
||||
resumeIsolate,
|
||||
];
|
||||
|
||||
main(args) => runIsolateTests(
|
||||
args,
|
||||
tests,
|
||||
'debugging_inlined_finally_test.dart',
|
||||
testeeConcurrent: testMain,
|
||||
);
|
137
pkg/vm_service/test/developer_extension_test.dart
Normal file
137
pkg/vm_service/test/developer_extension_test.dart
Normal file
|
@ -0,0 +1,137 @@
|
|||
// Copyright (c) 2015, 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 'dart:convert';
|
||||
import 'dart:developer';
|
||||
// ignore: import_of_legacy_library_into_null_safe
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
|
||||
import 'common/service_test_common.dart';
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
Future<ServiceExtensionResponse> Handler(String method, Map paremeters) {
|
||||
print('Invoked extension: $method');
|
||||
switch (method) {
|
||||
case 'ext..delay':
|
||||
var c = Completer<ServiceExtensionResponse>();
|
||||
Timer(Duration(seconds: 1), () {
|
||||
c.complete(ServiceExtensionResponse.result(jsonEncode({
|
||||
'type': '_delayedType',
|
||||
'method': method,
|
||||
'parameters': paremeters,
|
||||
})));
|
||||
});
|
||||
return c.future;
|
||||
case 'ext..error':
|
||||
return Future<ServiceExtensionResponse>.value(
|
||||
ServiceExtensionResponse.error(
|
||||
ServiceExtensionResponse.extensionErrorMin, 'My error detail.'));
|
||||
case 'ext..exception':
|
||||
throw "I always throw!";
|
||||
case 'ext..success':
|
||||
return Future<ServiceExtensionResponse>.value(
|
||||
ServiceExtensionResponse.result(jsonEncode({
|
||||
'type': '_extensionType',
|
||||
'method': method,
|
||||
'parameters': paremeters,
|
||||
})));
|
||||
}
|
||||
throw "Unknown extension: $method";
|
||||
}
|
||||
|
||||
void test() {
|
||||
registerExtension('ext..delay', Handler);
|
||||
debugger();
|
||||
postEvent('ALPHA', {'cat': 'dog'});
|
||||
debugger();
|
||||
registerExtension('ext..error', Handler);
|
||||
registerExtension('ext..exception', Handler);
|
||||
registerExtension('ext..success', Handler);
|
||||
bool exceptionThrown = false;
|
||||
try {
|
||||
registerExtension('ext..delay', Handler);
|
||||
} catch (e) {
|
||||
exceptionThrown = true;
|
||||
}
|
||||
// This check is running in the target process so we can't used package:test.
|
||||
Expect.equals(exceptionThrown, true);
|
||||
}
|
||||
|
||||
var tests = <IsolateTest>[
|
||||
hasStoppedAtBreakpoint,
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final isolate = await service.getIsolate(isolateRef.id!);
|
||||
// Note: extensions other than those is this test might already be
|
||||
// registered by core libraries.
|
||||
expect(isolate.extensionRPCs, contains('ext..delay'));
|
||||
expect(isolate.extensionRPCs, isNot(contains('ext..error')));
|
||||
expect(isolate.extensionRPCs, isNot(contains('ext..exception')));
|
||||
expect(isolate.extensionRPCs, isNot(contains('ext..success')));
|
||||
},
|
||||
resumeIsolateAndAwaitEvent(EventStreams.kExtension, (event) {
|
||||
expect(event.kind, EventKind.kExtension);
|
||||
expect(event.extensionKind, 'ALPHA');
|
||||
expect(event.extensionData!.data['cat'], equals('dog'));
|
||||
}),
|
||||
hasStoppedAtBreakpoint,
|
||||
resumeIsolateAndAwaitEvent(EventStreams.kIsolate, (event) {
|
||||
// Check that we received an event when '__error' was registered.
|
||||
expect(event.kind, equals(EventKind.kServiceExtensionAdded));
|
||||
expect(event.extensionRPC, 'ext..error');
|
||||
}),
|
||||
// Initial.
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final isolateId = isolateRef.id!;
|
||||
var result = await service.callServiceExtension(
|
||||
'ext..delay',
|
||||
isolateId: isolateId,
|
||||
);
|
||||
|
||||
expect(result.json!['type'], '_delayedType');
|
||||
expect(result.json!['method'], equals('ext..delay'));
|
||||
expect(result.json!['parameters']['isolateId'], isNotNull);
|
||||
|
||||
try {
|
||||
await service.callServiceExtension(
|
||||
'ext..error',
|
||||
isolateId: isolateId,
|
||||
);
|
||||
} on RPCError catch (e) {
|
||||
expect(e.code, ServiceExtensionResponse.extensionErrorMin);
|
||||
expect(e.details, 'My error detail.');
|
||||
}
|
||||
|
||||
try {
|
||||
await service.callServiceExtension(
|
||||
'ext..exception',
|
||||
isolateId: isolateId,
|
||||
);
|
||||
} on RPCError catch (e) {
|
||||
expect(e.code, ServiceExtensionResponse.extensionError);
|
||||
expect(e.details!.startsWith('I always throw!\n'), isTrue);
|
||||
}
|
||||
|
||||
result = await service.callServiceExtension(
|
||||
'ext..success',
|
||||
isolateId: isolateId,
|
||||
args: {
|
||||
'apple': 'banana',
|
||||
},
|
||||
);
|
||||
expect(result.json!['type'], '_extensionType');
|
||||
expect(result.json!['method'], 'ext..success');
|
||||
expect(result.json!['parameters']['isolateId'], isNotNull);
|
||||
expect(result.json!['parameters']['apple'], 'banana');
|
||||
},
|
||||
];
|
||||
|
||||
main([args = const <String>[]]) async => runIsolateTests(
|
||||
args,
|
||||
tests,
|
||||
'developer_extension_test.dart',
|
||||
testeeConcurrent: test,
|
||||
);
|
105
pkg/vm_service/test/developer_service_get_isolate_id_test.dart
Normal file
105
pkg/vm_service/test/developer_service_get_isolate_id_test.dart
Normal file
|
@ -0,0 +1,105 @@
|
|||
// Copyright (c) 2016, 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 'dart:developer';
|
||||
import 'dart:isolate' as iso;
|
||||
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
import 'common/service_test_common.dart';
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
// testee state.
|
||||
late String selfId;
|
||||
late iso.Isolate childIsolate;
|
||||
late String childId;
|
||||
|
||||
void spawnEntry(int i) {
|
||||
debugger();
|
||||
}
|
||||
|
||||
Future testeeMain() async {
|
||||
debugger();
|
||||
// Spawn an isolate.
|
||||
childIsolate = await iso.Isolate.spawn(spawnEntry, 0);
|
||||
// Assign the id for this isolate and it's child to strings so they can
|
||||
// be read by the tester.
|
||||
selfId = Service.getIsolateID(iso.Isolate.current)!;
|
||||
childId = Service.getIsolateID(childIsolate)!;
|
||||
debugger();
|
||||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
getSelfId() => selfId;
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
getChildId() => childId;
|
||||
|
||||
// tester state:
|
||||
late IsolateRef initialIsolate;
|
||||
late IsolateRef localChildIsolate;
|
||||
|
||||
var tests = <VMTest>[
|
||||
(VmService service) async {
|
||||
final vm = await service.getVM();
|
||||
// Sanity check.
|
||||
expect(vm.isolates!.length, 1);
|
||||
initialIsolate = vm.isolates![0];
|
||||
await hasStoppedAtBreakpoint(service, initialIsolate);
|
||||
// Resume.
|
||||
await service.resume(initialIsolate.id!);
|
||||
},
|
||||
(VmService service) async {
|
||||
// Initial isolate has paused at second debugger call.
|
||||
await hasStoppedAtBreakpoint(service, initialIsolate);
|
||||
},
|
||||
(VmService service) async {
|
||||
final vm = await service.getVM();
|
||||
|
||||
// Grab the child isolate.
|
||||
localChildIsolate =
|
||||
vm.isolates!.firstWhere((IsolateRef i) => i != initialIsolate);
|
||||
expect(localChildIsolate, isNotNull);
|
||||
|
||||
// Reload the initial isolate.
|
||||
initialIsolate = await service.getIsolate(initialIsolate.id!);
|
||||
|
||||
// Grab the root library.
|
||||
Library rootLib = await service.getObject(
|
||||
initialIsolate.id!,
|
||||
(initialIsolate as Isolate).rootLib!.id!,
|
||||
) as Library;
|
||||
|
||||
// Grab self id.
|
||||
final localSelfId = await service.invoke(
|
||||
initialIsolate.id!,
|
||||
rootLib.id!,
|
||||
'getSelfId',
|
||||
[],
|
||||
) as InstanceRef;
|
||||
|
||||
// Check that the id reported from dart:loper matches the id reported
|
||||
// from the service protocol.
|
||||
expect(localSelfId.kind, InstanceKind.kString);
|
||||
expect(initialIsolate.id, localSelfId.valueAsString);
|
||||
|
||||
// Grab the child isolate's id.
|
||||
final localChildId =
|
||||
await service.invoke(initialIsolate.id!, rootLib.id!, 'getChildId', [])
|
||||
as InstanceRef;
|
||||
|
||||
// Check that the id reported from dart:loper matches the id reported
|
||||
// from the service protocol.
|
||||
expect(localChildId.kind, InstanceKind.kString);
|
||||
expect(localChildIsolate.id, localChildId.valueAsString);
|
||||
}
|
||||
];
|
||||
|
||||
main(args) async => runVMTests(
|
||||
args,
|
||||
tests,
|
||||
'developer_service_get_isolate_id_test.dart',
|
||||
testeeConcurrent: testeeMain,
|
||||
);
|
72
pkg/vm_service/test/echo_test.dart
Normal file
72
pkg/vm_service/test/echo_test.dart
Normal file
|
@ -0,0 +1,72 @@
|
|||
// Copyright (c) 2014, 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/src/vm_service.dart';
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
class EchoResponse extends Response {
|
||||
static EchoResponse? parse(Map<String, dynamic>? json) =>
|
||||
json == null ? null : EchoResponse._fromJson(json);
|
||||
|
||||
EchoResponse._fromJson(Map<String, dynamic> json) : text = json['text'];
|
||||
|
||||
@override
|
||||
String get type => '_EchoResponse';
|
||||
final String text;
|
||||
}
|
||||
|
||||
var tests = <IsolateTest>[
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
addTypeFactory('_EchoResponse', EchoResponse.parse);
|
||||
},
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
// Echo from VM target.
|
||||
final result = await service.callMethod('_echo', args: {
|
||||
'text': 'hello',
|
||||
});
|
||||
expect(result, isA<EchoResponse>());
|
||||
expect((result as EchoResponse).text, 'hello');
|
||||
},
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
// Echo from Isolate target.
|
||||
final result =
|
||||
await service.callMethod('_echo', isolateId: isolateRef.id!, args: {
|
||||
'text': 'hello',
|
||||
});
|
||||
expect(result, isA<EchoResponse>());
|
||||
expect((result as EchoResponse).text, 'hello');
|
||||
},
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final completer = Completer<void>();
|
||||
late final StreamSubscription sub;
|
||||
sub = service.onEvent('_Echo').listen((event) async {
|
||||
expect(event.kind, '_Echo');
|
||||
expect(event.data!.lengthInBytes, 3);
|
||||
expect(event.data!.getUint8(0), 0);
|
||||
expect(event.data!.getUint8(1), 128);
|
||||
expect(event.data!.getUint8(2), 255);
|
||||
await sub.cancel();
|
||||
await service.streamCancel('_Echo');
|
||||
completer.complete();
|
||||
});
|
||||
|
||||
await service.streamListen('_Echo');
|
||||
await service.callMethod(
|
||||
'_triggerEchoEvent',
|
||||
isolateId: isolateRef.id!,
|
||||
args: {
|
||||
'text': 'hello',
|
||||
},
|
||||
);
|
||||
await completer.future;
|
||||
},
|
||||
];
|
||||
|
||||
main(args) => runIsolateTests(
|
||||
args,
|
||||
tests,
|
||||
'echo_test.dart',
|
||||
);
|
82
pkg/vm_service/test/eval_internal_class_test.dart
Normal file
82
pkg/vm_service/test/eval_internal_class_test.dart
Normal file
|
@ -0,0 +1,82 @@
|
|||
// Copyright (c) 2016, 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 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
var tests = <IsolateTest>[
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final isolateId = isolateRef.id!;
|
||||
final isolate = await service.getIsolate(isolateId);
|
||||
final rootLib = await service.getObject(
|
||||
isolateId,
|
||||
isolate.rootLib!.id!,
|
||||
) as Library;
|
||||
Class classLibrary = await service.getObject(
|
||||
isolateId,
|
||||
rootLib.classRef!.id!,
|
||||
) as Class;
|
||||
|
||||
{
|
||||
bool caughtExceptions = false;
|
||||
try {
|
||||
dynamic result = await service.evaluate(
|
||||
isolateId,
|
||||
classLibrary.id!,
|
||||
'3 + 4',
|
||||
);
|
||||
print(result);
|
||||
} on RPCError catch (e) {
|
||||
expect(e.toString(), contains('can be evaluated only'));
|
||||
caughtExceptions = true;
|
||||
}
|
||||
expect(caughtExceptions, isTrue);
|
||||
}
|
||||
|
||||
final classClass = await service.getObject(
|
||||
isolateId,
|
||||
classLibrary.classRef!.id!,
|
||||
) as Class;
|
||||
{
|
||||
bool caughtExceptions = false;
|
||||
try {
|
||||
dynamic result = await service.evaluate(
|
||||
isolateId,
|
||||
classClass.id!,
|
||||
'3 + 4',
|
||||
);
|
||||
print(result);
|
||||
} on RPCError catch (e) {
|
||||
expect(e.toString(), contains('can be evaluated only'));
|
||||
caughtExceptions = true;
|
||||
}
|
||||
expect(caughtExceptions, isTrue);
|
||||
}
|
||||
final classArray = await service.getObject(
|
||||
isolateId,
|
||||
(await service.evaluate(
|
||||
isolateId,
|
||||
rootLib.id!,
|
||||
"List<dynamic>.filled(2, null)",
|
||||
) as InstanceRef)
|
||||
.classRef!
|
||||
.id!,
|
||||
) as Class;
|
||||
dynamic result = await service.evaluate(
|
||||
isolateId,
|
||||
classArray.id!,
|
||||
'3 + 4',
|
||||
);
|
||||
expect(result is InstanceRef, isTrue);
|
||||
expect(result.valueAsString, '7');
|
||||
},
|
||||
];
|
||||
|
||||
main([args = const <String>[]]) => runIsolateTests(
|
||||
args,
|
||||
tests,
|
||||
'eval_internal_class_test.dart',
|
||||
);
|
108
pkg/vm_service/test/eval_regression_flutter20255_test.dart
Normal file
108
pkg/vm_service/test/eval_regression_flutter20255_test.dart
Normal file
|
@ -0,0 +1,108 @@
|
|||
// Copyright (c) 2018, 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 'dart:developer';
|
||||
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
|
||||
import 'common/service_test_common.dart';
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
class Base<T> {
|
||||
String field;
|
||||
|
||||
Base(this.field);
|
||||
String foo() => 'Base-$field';
|
||||
}
|
||||
|
||||
class Sub<T> extends Base<T> {
|
||||
String field;
|
||||
|
||||
Sub(this.field) : super(field);
|
||||
String foo() {
|
||||
debugger();
|
||||
return 'Sub-$field';
|
||||
}
|
||||
}
|
||||
|
||||
class ISub<T> implements Base<T> {
|
||||
String field;
|
||||
|
||||
ISub(this.field);
|
||||
String foo() => 'ISub-$field';
|
||||
}
|
||||
|
||||
class Box<T> {
|
||||
late T value;
|
||||
|
||||
@pragma('vm:never-inline')
|
||||
void setValue(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
final objects = <Base>[Base<int>('b'), Sub<double>('a'), ISub<bool>('c')];
|
||||
|
||||
String triggerTypeTestingStubGeneration() {
|
||||
final Box<Object> box = Box<Base>();
|
||||
for (int i = 0; i < 1000000; ++i) {
|
||||
box.setValue(objects.last);
|
||||
}
|
||||
return 'tts-generated';
|
||||
}
|
||||
|
||||
void testFunction() {
|
||||
// Triggers the debugger, which will evaluate an expression in the context of
|
||||
// [Sub<double>], which will make a subclass of [Base<T>].
|
||||
print(objects[1].foo());
|
||||
|
||||
triggerTypeTestingStubGeneration();
|
||||
|
||||
// Triggers the debugger, which will evaluate an expression in the context of
|
||||
// [Sub<double>], which will make a subclass of [Base<T>].
|
||||
print(objects[1].foo());
|
||||
}
|
||||
|
||||
Future triggerEvaluation(VmService service, IsolateRef isolateRef) async {
|
||||
Stack stack = await service.getStack(isolateRef.id!);
|
||||
|
||||
// Make sure we are in the right place.
|
||||
expect(stack.frames!.length, greaterThanOrEqualTo(2));
|
||||
expect(stack.frames![0].function!.name, 'foo');
|
||||
expect(stack.frames![0].function!.owner.name, 'Sub');
|
||||
|
||||
// Trigger an evaluation, which will create a subclass of Base<T>.
|
||||
final dynamic result = await service.evaluateInFrame(
|
||||
isolateRef.id!,
|
||||
0,
|
||||
'this.field + " world \$T"',
|
||||
);
|
||||
expect(result.valueAsString, 'a world double');
|
||||
|
||||
// Trigger an optimization of a type testing stub (and usage of it).
|
||||
final dynamic result2 = await service.evaluateInFrame(
|
||||
isolateRef.id!,
|
||||
0,
|
||||
'triggerTypeTestingStubGeneration()',
|
||||
);
|
||||
expect(result2.valueAsString, 'tts-generated');
|
||||
}
|
||||
|
||||
final testSteps = <IsolateTest>[
|
||||
hasStoppedAtBreakpoint,
|
||||
triggerEvaluation,
|
||||
resumeIsolate,
|
||||
hasStoppedAtBreakpoint,
|
||||
triggerEvaluation,
|
||||
resumeIsolate,
|
||||
];
|
||||
|
||||
main([args = const <String>[]]) => runIsolateTests(
|
||||
args,
|
||||
testSteps,
|
||||
'eval_regression_flutter20255_test.dart',
|
||||
testeeConcurrent: testFunction,
|
||||
);
|
55
pkg/vm_service/test/eval_skip_breakpoint.dart
Normal file
55
pkg/vm_service/test/eval_skip_breakpoint.dart
Normal file
|
@ -0,0 +1,55 @@
|
|||
// Copyright (c) 2019, 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.
|
||||
// VMOptions=--verbose_debug
|
||||
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
|
||||
import 'common/service_test_common.dart';
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
const int LINE_A = 22;
|
||||
const int LINE_B = 17;
|
||||
|
||||
bar() {
|
||||
print('bar');
|
||||
}
|
||||
|
||||
testMain() {
|
||||
debugger();
|
||||
bar();
|
||||
print("Done");
|
||||
}
|
||||
|
||||
var tests = <IsolateTest>[
|
||||
hasStoppedAtBreakpoint,
|
||||
stoppedAtLine(LINE_A),
|
||||
// Add breakpoint
|
||||
setBreakpointAtLine(LINE_B),
|
||||
// Evaluate 'bar()'
|
||||
(VmService service, IsolateRef isolateRef) async {
|
||||
final isolate = await service.getIsolate(isolateRef.id!);
|
||||
await service.evaluate(
|
||||
isolateRef.id!,
|
||||
isolate.rootLib!.id!,
|
||||
'bar()',
|
||||
disableBreakpoints: true,
|
||||
);
|
||||
},
|
||||
hasStoppedAtBreakpoint,
|
||||
stoppedAtLine(LINE_A),
|
||||
resumeIsolate,
|
||||
|
||||
hasStoppedAtBreakpoint,
|
||||
stoppedAtLine(LINE_B),
|
||||
resumeIsolate,
|
||||
];
|
||||
|
||||
main([args = const <String>[]]) => runIsolateTests(
|
||||
args,
|
||||
tests,
|
||||
'eval_skip_breakpoint.dart',
|
||||
testeeConcurrent: testMain,
|
||||
);
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) 2016, 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';
|
||||
|
||||
var topLevel = "OtherLibrary";
|
||||
|
||||
class Superclass2 {
|
||||
var _instVar = 'Superclass2';
|
||||
var instVar = 'Superclass2';
|
||||
method() => 'Superclass2';
|
||||
static staticMethod() => 'Superclass2';
|
||||
suppress_warning() => _instVar;
|
||||
}
|
||||
|
||||
class Superclass1 extends Superclass2 {
|
||||
var _instVar = 'Superclass1';
|
||||
var instVar = 'Superclass1';
|
||||
method() => 'Superclass1';
|
||||
static staticMethod() => 'Superclass1';
|
||||
|
||||
test() {
|
||||
var _local = 'Superclass1';
|
||||
debugger();
|
||||
// Suppress unused variable warning.
|
||||
print(_local);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
// Copyright (c) 2016, 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.
|
||||
|
||||
// Tests that expressions evaluated in a frame see the same scope as the
|
||||
// frame's method.
|
||||
|
||||
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';
|
||||
import 'evaluate_activation_in_method_class_other.dart';
|
||||
|
||||
var topLevel = "TestLibrary";
|
||||
|
||||
class Subclass extends Superclass1 {
|
||||
var _instVar = 'Subclass';
|
||||
var instVar = 'Subclass';
|
||||
method() => 'Subclass';
|
||||
static staticMethod() => 'Subclass';
|
||||
suppress_warning() => _instVar;
|
||||
}
|
||||
|
||||
testeeDo() {
|
||||
var obj = Subclass();
|
||||
obj.test();
|
||||
}
|
||||
|
||||
Future testerDo(VmService service, IsolateRef isolateRef) async {
|
||||
await hasStoppedAtBreakpoint(service, isolateRef);
|
||||
final isolateId = isolateRef.id!;
|
||||
|
||||
// Make sure we are in the right place.
|
||||
var stack = await service.getStack(isolateId);
|
||||
var topFrame = 0;
|
||||
expect(
|
||||
stack.frames![topFrame].function!.name,
|
||||
equals('test'),
|
||||
);
|
||||
expect(
|
||||
stack.frames![topFrame].function!.owner.name,
|
||||
equals('Superclass1'),
|
||||
);
|
||||
|
||||
InstanceRef result;
|
||||
|
||||
result = await service.evaluateInFrame(isolateId, topFrame, '_local')
|
||||
as InstanceRef;
|
||||
print(result);
|
||||
expect(result.valueAsString, equals('Superclass1'));
|
||||
|
||||
result = await service.evaluateInFrame(isolateId, topFrame, '_instVar')
|
||||
as InstanceRef;
|
||||
print(result);
|
||||
expect(result.valueAsString, equals('Superclass1'));
|
||||
|
||||
result = await service.evaluateInFrame(isolateId, topFrame, 'instVar')
|
||||
as InstanceRef;
|
||||
print(result);
|
||||
expect(result.valueAsString, equals('Subclass'));
|
||||
|
||||
result = await service.evaluateInFrame(isolateId, topFrame, 'method()')
|
||||
as InstanceRef;
|
||||
print(result);
|
||||
expect(result.valueAsString, equals('Subclass'));
|
||||
|
||||
result = await service.evaluateInFrame(isolateId, topFrame, 'super._instVar')
|
||||
as InstanceRef;
|
||||
print(result);
|
||||
expect(result.valueAsString, equals('Superclass2'));
|
||||
|
||||
result = await service.evaluateInFrame(isolateId, topFrame, 'super.instVar')
|
||||
as InstanceRef;
|
||||
print(result);
|
||||
expect(result.valueAsString, equals('Superclass2'));
|
||||
|
||||
result = await service.evaluateInFrame(isolateId, topFrame, 'super.method()')
|
||||
as InstanceRef;
|
||||
print(result);
|
||||
expect(result.valueAsString, equals('Superclass2'));
|
||||
|
||||
result = await service.evaluateInFrame(isolateId, topFrame, 'staticMethod()')
|
||||
as InstanceRef;
|
||||
print(result);
|
||||
expect(result.valueAsString, equals('Superclass1'));
|
||||
|
||||
// function.Owner verus function.Origin
|
||||
// The mixin of Superclass is in _other.dart and the mixin
|
||||
// application is in _test.dart.
|
||||
result = await service.evaluateInFrame(isolateId, topFrame, 'topLevel')
|
||||
as InstanceRef;
|
||||
print(result);
|
||||
expect(result.valueAsString, equals('OtherLibrary'));
|
||||
}
|
||||
|
||||
main([args = const <String>[]]) => runIsolateTests(
|
||||
args,
|
||||
[testerDo],
|
||||
'evaluate_activation_in_method_class_test.dart',
|
||||
testeeConcurrent: testeeDo,
|
||||
);
|
|
@ -1903,7 +1903,7 @@ class @Code extends @Object {
|
|||
_@Code_ is a reference to a _Code_ object.
|
||||
|
||||
```
|
||||
class Code extends @Object {
|
||||
class Code extends Object {
|
||||
// A name for this code object.
|
||||
string name;
|
||||
|
||||
|
|
Loading…
Reference in a new issue