mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 15:17:07 +00:00
[ package:vm_service ] Added support for service protocol version 3.27.
Change-Id: I1cb3ca42821f817eaa9aed98d1aabb93e53fb0ce Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/115079 Commit-Queue: Ben Konyi <bkonyi@google.com> Reviewed-by: Devon Carew <devoncarew@google.com>
This commit is contained in:
parent
13a69b5631
commit
9391e15cfd
8 changed files with 402 additions and 3 deletions
|
@ -1,5 +1,10 @@
|
|||
# Changelog
|
||||
|
||||
## 1.2.0
|
||||
- Support service protocol version 3.27:
|
||||
- Added `getCpuSamples` and `clearCpuSamples` methods
|
||||
- Added `CpuSamples`, `CpuSample`, and `ProfileFunction` classes.
|
||||
|
||||
## 1.1.2
|
||||
- Fixed issue where `closureFunction` and `closureContext` were only expected in
|
||||
`Instance` objects rather than `InstanceRef`.
|
||||
|
|
|
@ -28,6 +28,11 @@ double assertDouble(double obj) {
|
|||
return obj;
|
||||
}
|
||||
|
||||
dynamic assertDynamic(dynamic obj) {
|
||||
assertNotNull(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
List<int> assertListOfInt(List<int> list) {
|
||||
for (int elem in list) {
|
||||
assertInt(elem);
|
||||
|
@ -429,6 +434,36 @@ List<vms.ContextElement> assertListOfContextElement(
|
|||
return list;
|
||||
}
|
||||
|
||||
vms.CpuSamples assertCpuSamples(vms.CpuSamples obj) {
|
||||
assertNotNull(obj);
|
||||
assertString(obj.type);
|
||||
assertInt(obj.samplePeriod);
|
||||
assertInt(obj.maxStackDepth);
|
||||
assertInt(obj.sampleCount);
|
||||
assertInt(obj.timeSpan);
|
||||
assertInt(obj.timeOriginMicros);
|
||||
assertInt(obj.timeExtentMicros);
|
||||
assertInt(obj.pid);
|
||||
assertListOfProfileFunction(obj.functions);
|
||||
assertListOfCpuSample(obj.samples);
|
||||
return obj;
|
||||
}
|
||||
|
||||
vms.CpuSample assertCpuSample(vms.CpuSample obj) {
|
||||
assertNotNull(obj);
|
||||
assertInt(obj.tid);
|
||||
assertInt(obj.timestamp);
|
||||
assertListOfInt(obj.stack);
|
||||
return obj;
|
||||
}
|
||||
|
||||
List<vms.CpuSample> assertListOfCpuSample(List<vms.CpuSample> list) {
|
||||
for (vms.CpuSample elem in list) {
|
||||
assertCpuSample(elem);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
vms.ErrorRef assertErrorRef(vms.ErrorRef obj) {
|
||||
assertNotNull(obj);
|
||||
assertString(obj.type);
|
||||
|
@ -773,6 +808,12 @@ List<vms.Message> assertListOfMessage(List<vms.Message> list) {
|
|||
return list;
|
||||
}
|
||||
|
||||
vms.NativeFunction assertNativeFunction(vms.NativeFunction obj) {
|
||||
assertNotNull(obj);
|
||||
assertString(obj.name);
|
||||
return obj;
|
||||
}
|
||||
|
||||
vms.NullValRef assertNullValRef(vms.NullValRef obj) {
|
||||
assertNotNull(obj);
|
||||
assertString(obj.type);
|
||||
|
@ -821,6 +862,24 @@ vms.Obj assertObj(vms.Obj obj) {
|
|||
return obj;
|
||||
}
|
||||
|
||||
vms.ProfileFunction assertProfileFunction(vms.ProfileFunction obj) {
|
||||
assertNotNull(obj);
|
||||
assertString(obj.kind);
|
||||
assertInt(obj.inclusiveTicks);
|
||||
assertInt(obj.exclusiveTicks);
|
||||
assertString(obj.resolvedUrl);
|
||||
assertDynamic(obj.function);
|
||||
return obj;
|
||||
}
|
||||
|
||||
List<vms.ProfileFunction> assertListOfProfileFunction(
|
||||
List<vms.ProfileFunction> list) {
|
||||
for (vms.ProfileFunction elem in list) {
|
||||
assertProfileFunction(elem);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
vms.ReloadReport assertReloadReport(vms.ReloadReport obj) {
|
||||
assertNotNull(obj);
|
||||
assertString(obj.type);
|
||||
|
|
5
pkg/vm_service/java/.gitignore
vendored
5
pkg/vm_service/java/.gitignore
vendored
|
@ -3,6 +3,7 @@
|
|||
src/org/dartlang/vm/service/VmService.java
|
||||
src/org/dartlang/vm/service/consumer/AllocationProfileConsumer.java
|
||||
src/org/dartlang/vm/service/consumer/BreakpointConsumer.java
|
||||
src/org/dartlang/vm/service/consumer/CpuSamplesConsumer.java
|
||||
src/org/dartlang/vm/service/consumer/EvaluateConsumer.java
|
||||
src/org/dartlang/vm/service/consumer/EvaluateInFrameConsumer.java
|
||||
src/org/dartlang/vm/service/consumer/FlagListConsumer.java
|
||||
|
@ -37,6 +38,8 @@ src/org/dartlang/vm/service/element/CodeRef.java
|
|||
src/org/dartlang/vm/service/element/Context.java
|
||||
src/org/dartlang/vm/service/element/ContextElement.java
|
||||
src/org/dartlang/vm/service/element/ContextRef.java
|
||||
src/org/dartlang/vm/service/element/CpuSample.java
|
||||
src/org/dartlang/vm/service/element/CpuSamples.java
|
||||
src/org/dartlang/vm/service/element/ErrorKind.java
|
||||
src/org/dartlang/vm/service/element/ErrorObj.java
|
||||
src/org/dartlang/vm/service/element/ErrorRef.java
|
||||
|
@ -67,10 +70,12 @@ src/org/dartlang/vm/service/element/LogRecord.java
|
|||
src/org/dartlang/vm/service/element/MapAssociation.java
|
||||
src/org/dartlang/vm/service/element/MemoryUsage.java
|
||||
src/org/dartlang/vm/service/element/Message.java
|
||||
src/org/dartlang/vm/service/element/NativeFunction.java
|
||||
src/org/dartlang/vm/service/element/Null.java
|
||||
src/org/dartlang/vm/service/element/NullRef.java
|
||||
src/org/dartlang/vm/service/element/Obj.java
|
||||
src/org/dartlang/vm/service/element/ObjRef.java
|
||||
src/org/dartlang/vm/service/element/ProfileFunction.java
|
||||
src/org/dartlang/vm/service/element/ReloadReport.java
|
||||
src/org/dartlang/vm/service/element/Response.java
|
||||
src/org/dartlang/vm/service/element/RetainingObject.java
|
||||
|
|
|
@ -1 +1 @@
|
|||
version=3.26
|
||||
version=3.27
|
||||
|
|
|
@ -17,7 +17,7 @@ import 'src/service_extension_registry.dart';
|
|||
|
||||
export 'src/service_extension_registry.dart' show ServiceExtensionRegistry;
|
||||
|
||||
const String vmServiceVersion = '3.26.0';
|
||||
const String vmServiceVersion = '3.27.0';
|
||||
|
||||
/// @optional
|
||||
const String optional = 'optional';
|
||||
|
@ -102,6 +102,8 @@ Map<String, Function> _typeFactories = {
|
|||
'@Context': ContextRef.parse,
|
||||
'Context': Context.parse,
|
||||
'ContextElement': ContextElement.parse,
|
||||
'CpuSamples': CpuSamples.parse,
|
||||
'CpuSample': CpuSample.parse,
|
||||
'@Error': ErrorRef.parse,
|
||||
'Error': Error.parse,
|
||||
'Event': Event.parse,
|
||||
|
@ -127,10 +129,12 @@ Map<String, Function> _typeFactories = {
|
|||
'MapAssociation': MapAssociation.parse,
|
||||
'MemoryUsage': MemoryUsage.parse,
|
||||
'Message': Message.parse,
|
||||
'NativeFunction': NativeFunction.parse,
|
||||
'@Null': NullValRef.parse,
|
||||
'Null': NullVal.parse,
|
||||
'@Object': ObjRef.parse,
|
||||
'Object': Obj.parse,
|
||||
'ProfileFunction': ProfileFunction.parse,
|
||||
'ReloadReport': ReloadReport.parse,
|
||||
'RetainingObject': RetainingObject.parse,
|
||||
'RetainingPath': RetainingPath.parse,
|
||||
|
@ -161,11 +165,13 @@ Map<String, List<String>> _methodReturnTypes = {
|
|||
'addBreakpoint': const ['Breakpoint'],
|
||||
'addBreakpointWithScriptUri': const ['Breakpoint'],
|
||||
'addBreakpointAtEntry': const ['Breakpoint'],
|
||||
'clearCpuSamples': const ['Success'],
|
||||
'clearVMTimeline': const ['Success'],
|
||||
'invoke': const ['InstanceRef', 'ErrorRef', 'Sentinel'],
|
||||
'evaluate': const ['InstanceRef', 'ErrorRef', 'Sentinel'],
|
||||
'evaluateInFrame': const ['InstanceRef', 'ErrorRef', 'Sentinel'],
|
||||
'getAllocationProfile': const ['AllocationProfile'],
|
||||
'getCpuSamples': const ['CpuSamples'],
|
||||
'getFlagList': const ['FlagList'],
|
||||
'getInboundReferences': const ['InboundReferences', 'Sentinel'],
|
||||
'getInstances': const ['InstanceSet'],
|
||||
|
@ -283,6 +289,11 @@ abstract class VmServiceInterface {
|
|||
/// Note that breakpoints are added and removed on a per-isolate basis.
|
||||
Future<Breakpoint> addBreakpointAtEntry(String isolateId, String functionId);
|
||||
|
||||
/// Clears all CPU profiling samples.
|
||||
///
|
||||
/// See [Success].
|
||||
Future<Success> clearCpuSamples(String isolateId);
|
||||
|
||||
/// Clears all VM timeline events.
|
||||
///
|
||||
/// See [Success].
|
||||
|
@ -410,6 +421,16 @@ abstract class VmServiceInterface {
|
|||
Future<AllocationProfile> getAllocationProfile(String isolateId,
|
||||
{bool reset, bool gc});
|
||||
|
||||
/// The `getCpuSamples` RPC is used to retrieve samples collected by the CPU
|
||||
/// profiler. Only samples collected in the time range `[timeOriginMicros,
|
||||
/// timeOriginMicros + timeExtentMicros]` will be reported.
|
||||
///
|
||||
/// If the profiler is disabled, an error response will be returned.
|
||||
///
|
||||
/// See [CpuSamples].
|
||||
Future<CpuSamples> getCpuSamples(
|
||||
String isolateId, int timeOriginMicros, int timeExtentMicros);
|
||||
|
||||
/// The `getFlagList` RPC returns a list of all command line flags in the VM
|
||||
/// along with their current values.
|
||||
///
|
||||
|
@ -921,6 +942,11 @@ class VmServerConnection {
|
|||
params['functionId'],
|
||||
);
|
||||
break;
|
||||
case 'clearCpuSamples':
|
||||
response = await _serviceImplementation.clearCpuSamples(
|
||||
params['isolateId'],
|
||||
);
|
||||
break;
|
||||
case 'clearVMTimeline':
|
||||
response = await _serviceImplementation.clearVMTimeline();
|
||||
break;
|
||||
|
@ -958,6 +984,13 @@ class VmServerConnection {
|
|||
gc: params['gc'],
|
||||
);
|
||||
break;
|
||||
case 'getCpuSamples':
|
||||
response = await _serviceImplementation.getCpuSamples(
|
||||
params['isolateId'],
|
||||
params['timeOriginMicros'],
|
||||
params['timeExtentMicros'],
|
||||
);
|
||||
break;
|
||||
case 'getFlagList':
|
||||
response = await _serviceImplementation.getFlagList();
|
||||
break;
|
||||
|
@ -1305,6 +1338,11 @@ class VmService implements VmServiceInterface {
|
|||
{'isolateId': isolateId, 'functionId': functionId});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Success> clearCpuSamples(String isolateId) {
|
||||
return _call('clearCpuSamples', {'isolateId': isolateId});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Success> clearVMTimeline() => _call('clearVMTimeline');
|
||||
|
||||
|
@ -1385,6 +1423,16 @@ class VmService implements VmServiceInterface {
|
|||
return _call('getAllocationProfile', m);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<CpuSamples> getCpuSamples(
|
||||
String isolateId, int timeOriginMicros, int timeExtentMicros) {
|
||||
return _call('getCpuSamples', {
|
||||
'isolateId': isolateId,
|
||||
'timeOriginMicros': timeOriginMicros,
|
||||
'timeExtentMicros': timeExtentMicros
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<FlagList> getFlagList() => _call('getFlagList');
|
||||
|
||||
|
@ -2732,6 +2780,144 @@ class ContextElement {
|
|||
String toString() => '[ContextElement value: ${value}]';
|
||||
}
|
||||
|
||||
/// See [getCpuSamples] and [CpuSample].
|
||||
class CpuSamples extends Response {
|
||||
static CpuSamples parse(Map<String, dynamic> json) =>
|
||||
json == null ? null : new CpuSamples._fromJson(json);
|
||||
|
||||
/// The sampling rate for the profiler in microseconds.
|
||||
int samplePeriod;
|
||||
|
||||
/// The maximum possible stack depth for samples.
|
||||
int maxStackDepth;
|
||||
|
||||
/// The number of samples returned.
|
||||
int sampleCount;
|
||||
|
||||
/// The timespan the set of returned samples covers, in microseconds.
|
||||
int timeSpan;
|
||||
|
||||
/// The start of the period of time in which the returned samples were
|
||||
/// collected.
|
||||
int timeOriginMicros;
|
||||
|
||||
/// The duration of time covered by the returned samples.
|
||||
int timeExtentMicros;
|
||||
|
||||
/// The process ID for the VM.
|
||||
int pid;
|
||||
|
||||
/// A list of functions seen in the relevant samples. These references can be
|
||||
/// looked up using the indicies provided in a `CpuSample` `stack` to
|
||||
/// determine which function was on the stack.
|
||||
List<ProfileFunction> functions;
|
||||
|
||||
/// A list of samples collected in the range `[timeOriginMicros,
|
||||
/// timeOriginMicros + timeExtentMicros]`
|
||||
List<CpuSample> samples;
|
||||
|
||||
CpuSamples();
|
||||
|
||||
CpuSamples._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
|
||||
samplePeriod = json['samplePeriod'];
|
||||
maxStackDepth = json['maxStackDepth'];
|
||||
sampleCount = json['sampleCount'];
|
||||
timeSpan = json['timeSpan'];
|
||||
timeOriginMicros = json['timeOriginMicros'];
|
||||
timeExtentMicros = json['timeExtentMicros'];
|
||||
pid = json['pid'];
|
||||
functions = new List<ProfileFunction>.from(
|
||||
createServiceObject(json['functions'], const ['ProfileFunction']));
|
||||
samples = new List<CpuSample>.from(
|
||||
createServiceObject(json['samples'], const ['CpuSample']));
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
var json = <String, dynamic>{};
|
||||
json['type'] = 'CpuSamples';
|
||||
json.addAll({
|
||||
'samplePeriod': samplePeriod,
|
||||
'maxStackDepth': maxStackDepth,
|
||||
'sampleCount': sampleCount,
|
||||
'timeSpan': timeSpan,
|
||||
'timeOriginMicros': timeOriginMicros,
|
||||
'timeExtentMicros': timeExtentMicros,
|
||||
'pid': pid,
|
||||
'functions': functions.map((f) => f.toJson()).toList(),
|
||||
'samples': samples.map((f) => f.toJson()).toList(),
|
||||
});
|
||||
return json;
|
||||
}
|
||||
|
||||
String toString() => '[CpuSamples]';
|
||||
}
|
||||
|
||||
/// See [getCpuSamples] and [CpuSamples].
|
||||
class CpuSample {
|
||||
static CpuSample parse(Map<String, dynamic> json) =>
|
||||
json == null ? null : new CpuSample._fromJson(json);
|
||||
|
||||
/// The thread ID representing the thread on which this sample was collected.
|
||||
int tid;
|
||||
|
||||
/// The time this sample was collected in microseconds.
|
||||
int timestamp;
|
||||
|
||||
/// The name of VM tag set when this sample was collected. Omitted if the VM
|
||||
/// tag for the sample is not considered valid.
|
||||
@optional
|
||||
String vmTag;
|
||||
|
||||
/// The name of the User tag set when this sample was collected. Omitted if no
|
||||
/// User tag was set when this sample was collected.
|
||||
@optional
|
||||
String userTag;
|
||||
|
||||
/// Provided and set to true if the sample's stack was truncated. This can
|
||||
/// happen if the stack is deeper than the `stackDepth` in the `CpuSamples`
|
||||
/// response.
|
||||
@optional
|
||||
bool truncated;
|
||||
|
||||
/// The call stack at the time this sample was collected. The stack is to be
|
||||
/// interpreted as top to bottom. Each element in this array is a key into the
|
||||
/// `functions` array in `CpuSamples`.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// `functions[stack[0]] = @Function(bar())` `functions[stack[1]] =
|
||||
/// @Function(foo())` `functions[stack[2]] = @Function(main())`
|
||||
List<int> stack;
|
||||
|
||||
CpuSample();
|
||||
|
||||
CpuSample._fromJson(Map<String, dynamic> json) {
|
||||
tid = json['tid'];
|
||||
timestamp = json['timestamp'];
|
||||
vmTag = json['vmTag'];
|
||||
userTag = json['userTag'];
|
||||
truncated = json['truncated'];
|
||||
stack = new List<int>.from(json['stack']);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
var json = <String, dynamic>{};
|
||||
json.addAll({
|
||||
'tid': tid,
|
||||
'timestamp': timestamp,
|
||||
'stack': stack.map((f) => f).toList(),
|
||||
});
|
||||
_setIfNotNull(json, 'vmTag', vmTag);
|
||||
_setIfNotNull(json, 'userTag', userTag);
|
||||
_setIfNotNull(json, 'truncated', truncated);
|
||||
return json;
|
||||
}
|
||||
|
||||
String toString() =>
|
||||
'[CpuSample tid: ${tid}, timestamp: ${timestamp}, stack: ${stack}]';
|
||||
}
|
||||
|
||||
/// `ErrorRef` is a reference to an `Error`.
|
||||
class ErrorRef extends ObjRef {
|
||||
static ErrorRef parse(Map<String, dynamic> json) =>
|
||||
|
@ -4510,6 +4696,32 @@ class Message extends Response {
|
|||
'size: ${size}]';
|
||||
}
|
||||
|
||||
/// A `NativeFunction` object is used to represent native functions in profiler
|
||||
/// samples. See [CpuSamples];
|
||||
class NativeFunction {
|
||||
static NativeFunction parse(Map<String, dynamic> json) =>
|
||||
json == null ? null : new NativeFunction._fromJson(json);
|
||||
|
||||
/// The name of the native function this object represents.
|
||||
String name;
|
||||
|
||||
NativeFunction();
|
||||
|
||||
NativeFunction._fromJson(Map<String, dynamic> json) {
|
||||
name = json['name'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
var json = <String, dynamic>{};
|
||||
json.addAll({
|
||||
'name': name,
|
||||
});
|
||||
return json;
|
||||
}
|
||||
|
||||
String toString() => '[NativeFunction name: ${name}]';
|
||||
}
|
||||
|
||||
/// `NullValRef` is a reference to an a `NullVal`.
|
||||
class NullValRef extends InstanceRef {
|
||||
static NullValRef parse(Map<String, dynamic> json) =>
|
||||
|
@ -4685,6 +4897,57 @@ class Obj extends Response {
|
|||
String toString() => '[Obj type: ${type}, id: ${id}]';
|
||||
}
|
||||
|
||||
/// A `ProfileFunction` contains profiling information about a Dart or native
|
||||
/// function.
|
||||
///
|
||||
/// See [CpuSamples].
|
||||
class ProfileFunction {
|
||||
static ProfileFunction parse(Map<String, dynamic> json) =>
|
||||
json == null ? null : new ProfileFunction._fromJson(json);
|
||||
|
||||
/// The kind of function this object represents.
|
||||
String kind;
|
||||
|
||||
/// The number of times function appeared on the stack during sampling events.
|
||||
int inclusiveTicks;
|
||||
|
||||
/// The number of times function appeared on the top of the stack during
|
||||
/// sampling events.
|
||||
int exclusiveTicks;
|
||||
|
||||
/// The resolved URL for the script containing function.
|
||||
String resolvedUrl;
|
||||
|
||||
/// The function captured during profiling.
|
||||
dynamic function;
|
||||
|
||||
ProfileFunction();
|
||||
|
||||
ProfileFunction._fromJson(Map<String, dynamic> json) {
|
||||
kind = json['kind'];
|
||||
inclusiveTicks = json['inclusiveTicks'];
|
||||
exclusiveTicks = json['exclusiveTicks'];
|
||||
resolvedUrl = json['resolvedUrl'];
|
||||
function = createServiceObject(json['function'], const ['dynamic']);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
var json = <String, dynamic>{};
|
||||
json.addAll({
|
||||
'kind': kind,
|
||||
'inclusiveTicks': inclusiveTicks,
|
||||
'exclusiveTicks': exclusiveTicks,
|
||||
'resolvedUrl': resolvedUrl,
|
||||
'function': function.toJson(),
|
||||
});
|
||||
return json;
|
||||
}
|
||||
|
||||
String toString() => '[ProfileFunction ' //
|
||||
'kind: ${kind}, inclusiveTicks: ${inclusiveTicks}, exclusiveTicks: ${exclusiveTicks}, ' //
|
||||
'resolvedUrl: ${resolvedUrl}, function: ${function}]';
|
||||
}
|
||||
|
||||
class ReloadReport extends Response {
|
||||
static ReloadReport parse(Map<String, dynamic> json) =>
|
||||
json == null ? null : new ReloadReport._fromJson(json);
|
||||
|
|
|
@ -2,7 +2,7 @@ name: vm_service
|
|||
description: >-
|
||||
A library to communicate with a service implementing the Dart VM
|
||||
service protocol.
|
||||
version: 1.1.2
|
||||
version: 1.2.0
|
||||
|
||||
author: Dart Team <misc@dartlang.org>
|
||||
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_service
|
||||
|
|
61
pkg/vm_service/test/get_cpu_samples_rpc_test.dart
Normal file
61
pkg/vm_service/test/get_cpu_samples_rpc_test.dart
Normal file
|
@ -0,0 +1,61 @@
|
|||
// 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:async';
|
||||
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import 'common/service_test_common.dart';
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
fib(n) {
|
||||
if (n < 0) return 0;
|
||||
if (n == 0) return 1;
|
||||
return fib(n - 1) + fib(n - 2);
|
||||
}
|
||||
|
||||
testeeDo() {
|
||||
print("Testee doing something.");
|
||||
fib(30);
|
||||
print("Testee did something.");
|
||||
}
|
||||
|
||||
Future checkSamples(VmService service, IsolateRef isolate) async {
|
||||
// Grab all the samples.
|
||||
final result = await service.getCpuSamples(isolate.id, 0, ~0);
|
||||
|
||||
final isString = TypeMatcher<String>();
|
||||
final isInt = TypeMatcher<int>();
|
||||
final isList = TypeMatcher<List>();
|
||||
expect(result.functions.length, greaterThan(10),
|
||||
reason: "Should have many functions");
|
||||
|
||||
final samples = result.samples;
|
||||
expect(samples.length, greaterThan(10), reason: "Should have many samples");
|
||||
expect(samples.length, result.sampleCount);
|
||||
|
||||
final sample = samples.first;
|
||||
expect(sample.tid, isInt);
|
||||
expect(sample.timestamp, isInt);
|
||||
if (sample.vmTag != null) {
|
||||
expect(sample.vmTag, isString);
|
||||
}
|
||||
if (sample.userTag != null) {
|
||||
expect(sample.userTag, isString);
|
||||
}
|
||||
expect(sample.stack, isList);
|
||||
}
|
||||
|
||||
var tests = <IsolateTest>[
|
||||
(VmService service, IsolateRef i) => checkSamples(service, i),
|
||||
];
|
||||
|
||||
var vmArgs = [
|
||||
'--profiler=true',
|
||||
'--profile-vm=false', // So this also works with DBC and KBC.
|
||||
];
|
||||
|
||||
main(args) async =>
|
||||
runIsolateTests(args, tests, testeeBefore: testeeDo, extraArgs: vmArgs);
|
|
@ -831,6 +831,11 @@ double assertDouble(double obj) {
|
|||
return obj;
|
||||
}
|
||||
|
||||
dynamic assertDynamic(dynamic obj) {
|
||||
assertNotNull(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
List<int> assertListOfInt(List<int> list) {
|
||||
for (int elem in list) {
|
||||
assertInt(elem);
|
||||
|
@ -925,6 +930,7 @@ vms.Event assertIsolateEvent(vms.Event event) {
|
|||
'ClassHeapStats',
|
||||
'CodeRegion',
|
||||
'ContextElement',
|
||||
'CpuSample',
|
||||
'Flag',
|
||||
'Frame',
|
||||
'InboundReference',
|
||||
|
|
Loading…
Reference in a new issue