[ 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:
Ben Konyi 2022-02-05 00:12:29 +00:00 committed by Commit Bot
parent 1b204a9c85
commit ad4d10a42c
25 changed files with 1708 additions and 19 deletions

View file

@ -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);

View file

@ -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

View 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,
);

View 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,
);

View file

@ -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,
);

View file

@ -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,
);

View 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,
);

View 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,
);
}

View file

@ -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!);

View file

@ -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) {

View 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,
);

View file

@ -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,
);

View file

@ -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': []
}
},

View 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,
);

View 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',
);

View 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,
);

View 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,
);

View 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,
);

View 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',
);

View 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',
);

View 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,
);

View 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,
);

View file

@ -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);
}
}

View file

@ -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,
);

View file

@ -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;