[ VM / Service ] Added additional tests for package:vm_service and fixed service bugs

Change-Id: I3c96521a16bf0493cd0dc7ca9249487b3d9e3e64
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/118465
Commit-Queue: Ben Konyi <bkonyi@google.com>
Reviewed-by: Devon Carew <devoncarew@google.com>
This commit is contained in:
Ben Konyi 2019-09-25 00:39:56 +00:00 committed by commit-bot@chromium.org
parent 79cc54e519
commit 35748514c7
8 changed files with 190 additions and 7 deletions

View file

@ -16,6 +16,7 @@ src/org/dartlang/vm/service/consumer/InvokeConsumer.java
src/org/dartlang/vm/service/consumer/ReloadReportConsumer.java
src/org/dartlang/vm/service/consumer/RetainingPathConsumer.java
src/org/dartlang/vm/service/consumer/ScriptListConsumer.java
src/org/dartlang/vm/service/consumer/SetFlagConsumer.java
src/org/dartlang/vm/service/consumer/SourceReportConsumer.java
src/org/dartlang/vm/service/consumer/StackConsumer.java
src/org/dartlang/vm/service/consumer/SuccessConsumer.java

View file

@ -197,7 +197,7 @@ Map<String, List<String>> _methodReturnTypes = {
'requestHeapSnapshot': const ['Success'],
'resume': const ['Success'],
'setExceptionPauseMode': const ['Success'],
'setFlag': const ['Success'],
'setFlag': const ['Success', 'Error'],
'setLibraryDebuggable': const ['Success'],
'setName': const ['Success'],
'setVMName': const ['Success'],
@ -767,7 +767,9 @@ abstract class VmServiceInterface {
/// value is of the wrong type for the flag.
///
/// The following flags may be set at runtime:
Future<Success> setFlag(String name, String value);
///
/// The return value can be one of [Success] or [Error].
Future<dynamic> setFlag(String name, String value);
/// The `setLibraryDebuggable` RPC is used to enable or disable whether
/// breakpoints and stepping work for a given library.
@ -1616,7 +1618,7 @@ class VmService implements VmServiceInterface {
}
@override
Future<Success> setFlag(String name, String value) {
Future<dynamic> setFlag(String name, String value) {
return _call('setFlag', {'name': name, 'value': value});
}

View file

@ -0,0 +1,67 @@
// 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/test_helper.dart';
Future<void> sleep(int milliseconds) =>
Future.delayed(Duration(milliseconds: milliseconds));
var tests = <IsolateTest>[
(VmService service, IsolateRef isolate) async {
AllocationProfile result = await service.getAllocationProfile(isolate.id);
expect(result.dateLastAccumulatorReset, isNull);
expect(result.dateLastServiceGC, isNull);
expect(result.members.length, isPositive);
ClassHeapStats member = result.members[0];
expect(member.instancesAccumulated, isNotNull);
expect(member.instancesCurrent, isNotNull);
expect(member.bytesCurrent, isNotNull);
expect(member.accumulatedSize, isNotNull);
// reset.
result = await service.getAllocationProfile(isolate.id, reset: true);
final firstReset = result.dateLastAccumulatorReset;
expect(firstReset, isNotNull);
expect(result.dateLastServiceGC, isNull);
expect(result.members.length, isPositive);
member = result.members[0];
expect(member.instancesAccumulated, isNotNull);
expect(member.instancesCurrent, isNotNull);
expect(member.bytesCurrent, isNotNull);
expect(member.accumulatedSize, isNotNull);
await sleep(1000);
result = await service.getAllocationProfile(isolate.id, reset: true);
final secondReset = result.dateLastAccumulatorReset;
expect(secondReset, isNot(firstReset));
// gc.
result = await service.getAllocationProfile(isolate.id, gc: true);
expect(result.dateLastAccumulatorReset, secondReset);
final firstGC = result.dateLastServiceGC;
expect(firstGC, isNotNull);
expect(result.members.length, isPositive);
member = result.members[0];
expect(member.instancesAccumulated, isNotNull);
expect(member.instancesCurrent, isNotNull);
expect(member.bytesCurrent, isNotNull);
expect(member.accumulatedSize, isNotNull);
await sleep(1000);
result = await service.getAllocationProfile(isolate.id, gc: true);
final secondGC = result.dateLastAccumulatorReset;
expect(secondGC, isNot(firstGC));
},
];
main(args) async => runIsolateTests(args, tests);

View file

@ -0,0 +1,77 @@
// 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:test/test.dart';
import 'package:vm_service/vm_service.dart';
import 'common/test_helper.dart';
Future getFlagValue(VmService service, String flagName) async {
final result = await service.getFlagList();
final flags = result.flags;
for (final flag in flags) {
if (flag.name == flagName) {
return flag.valueAsString;
}
}
}
var tests = <VMTest>[
// Modify a flag which does not exist.
(VmService service) async {
final result = await service.setFlag('does_not_exist', 'true');
expect(result, TypeMatcher<Error>());
expect(result.message, 'Cannot set flag: flag not found');
},
// Modify a flag with the wrong value type.
(VmService service) async {
final result =
await service.setFlag('pause_isolates_on_start', 'not-boolean');
expect(result, TypeMatcher<Error>());
expect(result.message, equals('Cannot set flag: invalid value'));
},
// Modify a flag with the right value type.
(VmService service) async {
final result = await service.setFlag('pause_isolates_on_start', 'false');
expect(result, TypeMatcher<Success>());
},
// Modify a flag which cannot be set at runtime.
(VmService service) async {
final result = await service.setFlag('random_seed', '42');
expect(result, TypeMatcher<Error>());
expect(result.message, 'Cannot set flag: cannot change at runtime');
},
// Modify the profile_period at runtime.
(VmService service) async {
final kProfilePeriod = 'profile_period';
final kValue = 100;
expect(await getFlagValue(service, kProfilePeriod), '1000');
final completer = Completer();
final stream = await service.onVMEvent;
var subscription;
subscription = stream.listen((Event event) {
print(event);
if (event.kind == EventKind.kVMFlagUpdate) {
expect(event.flag, kProfilePeriod);
expect(event.newValue, kValue.toString());
subscription.cancel();
completer.complete();
}
});
await service.streamListen(EventStreams.kVM);
final result = await service.setFlag(kProfilePeriod, kValue.toString());
expect(result, TypeMatcher<Success>());
await completer.future;
expect(await getFlagValue(service, kProfilePeriod), kValue.toString());
await service.streamCancel(EventStreams.kVM);
}
];
main(args) async => runVMTests(args, tests);

View file

@ -0,0 +1,32 @@
// 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 'package:test/test.dart';
import 'package:vm_service/vm_service.dart';
import 'common/test_helper.dart';
var tests = <VMTest>[
(VmService service) async {
final vm = await service.getVM();
final result = await service.getMemoryUsage(vm.isolates.first.id);
expect(result.heapUsage, isPositive);
expect(result.heapCapacity, isPositive);
expect(result.externalUsage, isPositive);
},
(VmService service) async {
bool caughtException;
try {
await service.getMemoryUsage('badid');
fail('Unreachable');
} on RPCError catch (e) {
caughtException = true;
expect(e.details,
contains("getMemoryUsage: invalid 'isolateId' parameter: badid"));
}
expect(caughtException, isTrue);
},
];
main(args) async => runVMTests(args, tests);

View file

@ -2222,8 +2222,8 @@ class ServiceEvent extends ServiceObject {
if (map['flag'] != null) {
flag = map['flag'];
}
if (map['new_value'] != null) {
newValue = map['new_value'];
if (map['newValue'] != null) {
newValue = map['newValue'];
}
}

View file

@ -1110,8 +1110,8 @@ All | Pause isolate on all thrown exceptions
### setFlag
```
Success setFlag(string name,
string value)
Success|Error setFlag(string name,
string value)
```
The _setFlag_ RPC is used to set a VM flag at runtime. Returns an error if the

View file

@ -180,7 +180,11 @@ void ServiceEvent::PrintJSON(JSONStream* js) const {
PrintJSONHeader(&jsobj);
if (kind() == kVMFlagUpdate) {
jsobj.AddProperty("flag", flag_name());
// For backwards compatibility, "new_value" is also provided.
// TODO(bkonyi): remove when service protocol major version is incremented.
ASSERT(SERVICE_PROTOCOL_MAJOR_VERSION == 3);
jsobj.AddProperty("new_value", flag_new_value());
jsobj.AddProperty("newValue", flag_new_value());
}
if (kind() == kIsolateReload) {
if (reload_error_ == NULL) {