mirror of
https://github.com/dart-lang/sdk
synced 2024-07-25 04:15:45 +00:00
[ package:vm_service ] Cleanup for 13.0.0 release
This change includes: - Removal of deprecated methods and constants - Removal of dependency on package:expect for testing, instead copying over the minimal amount of functionality needed for testing from package:expect into pkg/vm_service/test/common/expect.dart - Removal of classes and interfaces that are now found in package:vm_service_interface Change-Id: I21c2d228e615f97e64dd98b6512bf2e533916454 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/331760 Reviewed-by: Derek Xu <derekx@google.com> Commit-Queue: Ben Konyi <bkonyi@google.com>
This commit is contained in:
parent
bd57548de1
commit
fa6253ec11
|
@ -1,14 +1,21 @@
|
|||
## 13.0.0
|
||||
- Add Dart IO extension methods:
|
||||
- `isSocketProfilingAvailable`
|
||||
- `isHttpTimelineLoggingAvailable`
|
||||
- `isHttpProfilingAvailable`.
|
||||
- Remove deprecated Dart IO extension methods:
|
||||
- `startSocketProfiling`
|
||||
- `pauseSocketProfiling`
|
||||
- `getHttpEnableTimelineLogging`
|
||||
- `setHttpEnableTimelineLogging`
|
||||
- Remove deprecated `vmServiceConnect` from `package:vm_service/vm_service_io.dart`.
|
||||
- Remove deprecated constants from `RPCError`.
|
||||
- Add `wrapFuture` method that can be overridden to add additional logic to
|
||||
each VM service RPC call (like logging, tracking values, etc.).
|
||||
- Add `vmServiceConnectUriWithFactory` helper that can create a generic [VmService]
|
||||
instance and connect it to a web socket URI.
|
||||
- Add `VmServiceFactory` typedef.
|
||||
- Add a static method `VmService.defaultFactory` that provides a `VmServiceFactory` method for the `VmService` class.
|
||||
- Add Dart IO extension methods `isSocketProfilingAvailable`,
|
||||
`isHttpTimelineLoggingAvailable`, `isHttpProfilingAvailable`.
|
||||
- Remove deprecated Dart IO extension methods: `startSocketProfiling`
|
||||
`pauseSocketProfiling`, `getHttpEnableTimelineLogging`, `setHttpEnableTimelineLogging`.
|
||||
- Update SDK constraint to ^3.0.0
|
||||
|
||||
## 12.0.1
|
||||
|
|
|
@ -47,8 +47,8 @@ void main() {
|
|||
|
||||
await Future.delayed(Duration(milliseconds: 500));
|
||||
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
serviceClient = await vmServiceConnect(host, port, log: StdoutLog());
|
||||
final wsUri = 'ws://$host$port/ws';
|
||||
serviceClient = await vmServiceConnectUri(wsUri, log: StdoutLog());
|
||||
|
||||
print('socket connected');
|
||||
|
||||
|
@ -157,9 +157,8 @@ Future testServiceRegistration() async {
|
|||
};
|
||||
});
|
||||
await serviceClient.registerService(serviceName, serviceAlias);
|
||||
VmService otherClient =
|
||||
// ignore: deprecated_member_use_from_same_package
|
||||
await vmServiceConnect(host, port, log: StdoutLog());
|
||||
final wsUri = 'ws://$host$port/ws';
|
||||
VmService otherClient = await vmServiceConnectUri(wsUri, log: StdoutLog());
|
||||
Completer completer = Completer();
|
||||
otherClient.onEvent('Service').listen((e) async {
|
||||
if (e.service == serviceName && e.kind == EventKind.kServiceRegistered) {
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
// 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' show RPCError, Event, EventKind;
|
||||
|
||||
import 'stream_helpers.dart';
|
||||
import 'vm_service_interface.dart' show VmServerConnection;
|
||||
|
||||
/// A registry of custom service extensions to [VmServerConnection]s in which
|
||||
/// they were registered.
|
||||
class ServiceExtensionRegistry {
|
||||
/// Maps service extensions registered through the protocol to the
|
||||
/// [VmServerConnection] in which they were registered.
|
||||
///
|
||||
/// Note: this does not track services registered through `dart:developer`,
|
||||
/// only the services registered through the `_registerService` rpc method.
|
||||
final _extensionToConnection = <String, VmServerConnection>{};
|
||||
|
||||
/// Controller for tracking registration and unregistration events.
|
||||
final _eventController = StreamController<Event>.broadcast();
|
||||
|
||||
ServiceExtensionRegistry();
|
||||
|
||||
/// Registers [extension] for [client].
|
||||
///
|
||||
/// All future requests for [extension] will be routed to [client].
|
||||
void registerExtension(String extension, VmServerConnection client) {
|
||||
if (_extensionToConnection.containsKey(extension)) {
|
||||
throw RPCError('registerExtension', 111, 'Service already registered');
|
||||
}
|
||||
_eventController.sink.add(_toRegistrationEvent(extension));
|
||||
_extensionToConnection[extension] = client;
|
||||
// Remove the mapping if the client disconnects.
|
||||
client.done.whenComplete(() {
|
||||
_extensionToConnection.remove(extension);
|
||||
_eventController.sink.add(_toRegistrationEvent(extension,
|
||||
kind: EventKind.kServiceUnregistered));
|
||||
});
|
||||
}
|
||||
|
||||
/// Returns the [VmServerConnection] for a given [extension], or `null` if
|
||||
/// none is registered.
|
||||
///
|
||||
/// The result of this function should not be stored, because clients may
|
||||
/// shut down at any time.
|
||||
VmServerConnection? clientFor(String extension) =>
|
||||
_extensionToConnection[extension];
|
||||
|
||||
/// All of the currently registered extensions
|
||||
Iterable<String> get registeredExtensions => _extensionToConnection.keys;
|
||||
|
||||
/// Emits an [Event] of type `ServiceRegistered` for all current and future
|
||||
/// extensions that are registered, and `ServiceUnregistered` when those
|
||||
/// clients disconnect.
|
||||
Stream<Event> get onExtensionEvent => _eventController.stream
|
||||
.transform(startWithMany(registeredExtensions.map(_toRegistrationEvent)));
|
||||
|
||||
/// Creates a `_Service` stream event, with a default kind of
|
||||
/// [EventKind.kServiceRegistered].
|
||||
Event _toRegistrationEvent(String method,
|
||||
{String kind = EventKind.kServiceRegistered}) =>
|
||||
Event(
|
||||
kind: kind,
|
||||
service: method,
|
||||
method: method,
|
||||
timestamp: DateTime.now().millisecondsSinceEpoch,
|
||||
);
|
||||
}
|
|
@ -1977,21 +1977,6 @@ enum RPCErrorKind {
|
|||
}
|
||||
|
||||
class RPCError implements Exception {
|
||||
@Deprecated('Use RPCErrorKind.kServerError.code instead.')
|
||||
static int get kServerError => RPCErrorKind.kServerError.code;
|
||||
|
||||
@Deprecated('Use RPCErrorKind.kInvalidRequest.code instead.')
|
||||
static int get kInvalidRequest => RPCErrorKind.kInvalidRequest.code;
|
||||
|
||||
@Deprecated('Use RPCErrorKind.kMethodNotFound.code instead.')
|
||||
static int get kMethodNotFound => RPCErrorKind.kMethodNotFound.code;
|
||||
|
||||
@Deprecated('Use RPCErrorKind.kInvalidParams.code instead.')
|
||||
static int get kInvalidParams => RPCErrorKind.kInvalidParams.code;
|
||||
|
||||
@Deprecated('Use RPCErrorKind.kInternalError.code instead.')
|
||||
static int get kInternalError => RPCErrorKind.kInternalError.code;
|
||||
|
||||
static RPCError parse(String callingMethod, dynamic json) {
|
||||
return RPCError(callingMethod, json['code'], json['message'], json['data']);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -7,5 +7,3 @@ library vm_service;
|
|||
export 'src/dart_io_extensions.dart';
|
||||
export 'src/snapshot_graph.dart';
|
||||
export 'src/vm_service.dart' hide addTypeFactory, extensionCallHelper;
|
||||
// TODO(bkonyi): remove before publishing 13.0.0
|
||||
export 'src/vm_service_interface.dart' hide vmServiceVersion;
|
||||
|
|
|
@ -7,12 +7,6 @@ import 'dart:io';
|
|||
|
||||
import 'vm_service.dart';
|
||||
|
||||
@Deprecated('Prefer vmServiceConnectUri')
|
||||
Future<VmService> vmServiceConnect(String host, int port, {Log? log}) async {
|
||||
final wsUri = 'ws://$host$port/ws';
|
||||
return vmServiceConnectUri(wsUri, log: log);
|
||||
}
|
||||
|
||||
/// Connect to the given uri and return a new [VmService] instance.
|
||||
Future<VmService> vmServiceConnectUri(String wsUri, {Log? log}) async {
|
||||
return vmServiceConnectUriWithFactory<VmService>(
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
name: vm_service
|
||||
version: 13.0.0
|
||||
# TODO(bkonyi): resolve outstanding TODOs required for 13.0.0 release before
|
||||
# removing.
|
||||
publish_to: none
|
||||
description: >-
|
||||
A library to communicate with a service implementing the Dart VM
|
||||
service protocol.
|
||||
|
@ -19,7 +16,6 @@ environment:
|
|||
dev_dependencies:
|
||||
async: any
|
||||
collection: any
|
||||
expect: any
|
||||
lints: any
|
||||
markdown: any
|
||||
path: any
|
||||
|
@ -28,12 +24,6 @@ dev_dependencies:
|
|||
test: any
|
||||
vm_service_protos: any
|
||||
|
||||
# TODO(bkonyi): remove expect and smith overrides before
|
||||
# publishing 13.0.0.
|
||||
dependency_overrides:
|
||||
expect:
|
||||
path: '../expect'
|
||||
smith:
|
||||
path: '../smith'
|
||||
test_package:
|
||||
path: 'test/test_package'
|
||||
|
|
|
@ -10,8 +10,7 @@
|
|||
import 'dart:developer';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:expect/expect.dart';
|
||||
|
||||
import 'common/expect.dart';
|
||||
import 'common/service_test_common.dart';
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
|
|
155
pkg/vm_service/test/common/expect.dart
Normal file
155
pkg/vm_service/test/common/expect.dart
Normal file
|
@ -0,0 +1,155 @@
|
|||
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Originally from package:expect in the Dart SDK.
|
||||
|
||||
/// This library contains an Expect class with static methods that can be used
|
||||
/// for simple unit-tests.
|
||||
library expect;
|
||||
|
||||
/// Expect is used for tests that do not want to make use of the
|
||||
/// Dart unit test library - for example, the core language tests.
|
||||
/// Third parties are discouraged from using this, and should use
|
||||
/// the expect() function in the unit test library instead for
|
||||
/// test assertions.
|
||||
class Expect {
|
||||
/// Return a slice of a string.
|
||||
///
|
||||
/// The slice will contain at least the substring from [start] to the lower of
|
||||
/// [end] and `start + length`.
|
||||
/// If the result is no more than `length - 10` characters long,
|
||||
/// context may be added by extending the range of the slice, by decreasing
|
||||
/// [start] and increasing [end], up to at most length characters.
|
||||
/// If the start or end of the slice are not matching the start or end of
|
||||
/// the string, ellipses are added before or after the slice.
|
||||
/// Characters other than printable ASCII are escaped.
|
||||
static String _truncateString(String string, int start, int end, int length) {
|
||||
if (end - start > length) {
|
||||
end = start + length;
|
||||
} else if (end - start < length) {
|
||||
int overflow = length - (end - start);
|
||||
if (overflow > 10) overflow = 10;
|
||||
// Add context.
|
||||
start = start - ((overflow + 1) ~/ 2);
|
||||
end = end + (overflow ~/ 2);
|
||||
if (start < 0) start = 0;
|
||||
if (end > string.length) end = string.length;
|
||||
}
|
||||
StringBuffer buf = StringBuffer();
|
||||
if (start > 0) buf.write("...");
|
||||
_escapeSubstring(buf, string, 0, string.length);
|
||||
if (end < string.length) buf.write("...");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/// Return the string with characters that are not printable ASCII characters
|
||||
/// escaped as either "\xXX" codes or "\uXXXX" codes.
|
||||
static String _escapeString(String string) {
|
||||
StringBuffer buf = StringBuffer();
|
||||
_escapeSubstring(buf, string, 0, string.length);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
static _escapeSubstring(StringBuffer buf, String string, int start, int end) {
|
||||
const hexDigits = "0123456789ABCDEF";
|
||||
for (int i = start; i < end; i++) {
|
||||
int code = string.codeUnitAt(i);
|
||||
if (0x20 <= code && code < 0x7F) {
|
||||
if (code == 0x5C) {
|
||||
buf.write(r"\\");
|
||||
} else {
|
||||
buf.writeCharCode(code);
|
||||
}
|
||||
} else if (code < 0x100) {
|
||||
buf.write(r"\x");
|
||||
buf.write(hexDigits[code >> 4]);
|
||||
buf.write(hexDigits[code & 15]);
|
||||
} else {
|
||||
buf.write(r"\u{");
|
||||
buf.write(code.toRadixString(16).toUpperCase());
|
||||
buf.write(r"}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Find the difference between two strings.
|
||||
///
|
||||
/// This finds the first point where two strings differ, and returns
|
||||
/// a text describing the difference.
|
||||
///
|
||||
/// For small strings (length less than 20) nothing is done, and "" is
|
||||
/// returned. Small strings can be compared visually, but for longer strings
|
||||
/// only a slice containing the first difference will be shown.
|
||||
static String _stringDifference(String expected, String actual) {
|
||||
if (expected.length < 20 && actual.length < 20) return "";
|
||||
for (int i = 0; i < expected.length && i < actual.length; i++) {
|
||||
if (expected.codeUnitAt(i) != actual.codeUnitAt(i)) {
|
||||
int start = i;
|
||||
i++;
|
||||
while (i < expected.length && i < actual.length) {
|
||||
if (expected.codeUnitAt(i) == actual.codeUnitAt(i)) break;
|
||||
i++;
|
||||
}
|
||||
int end = i;
|
||||
var truncExpected = _truncateString(expected, start, end, 20);
|
||||
var truncActual = _truncateString(actual, start, end, 20);
|
||||
return "at index $start: Expected <$truncExpected>, "
|
||||
"Found: <$truncActual>";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/// Checks whether the expected and actual values are equal (using `==`).
|
||||
static void equals(dynamic expected, dynamic actual, [String reason = ""]) {
|
||||
if (expected == actual) return;
|
||||
String msg = _getMessage(reason);
|
||||
if (expected is String && actual is String) {
|
||||
String stringDifference = _stringDifference(expected, actual);
|
||||
if (stringDifference.isNotEmpty) {
|
||||
_fail("Expect.equals($stringDifference$msg) fails.");
|
||||
}
|
||||
_fail("Expect.equals(expected: <${_escapeString(expected)}>"
|
||||
", actual: <${_escapeString(actual)}>$msg) fails.");
|
||||
}
|
||||
_fail("Expect.equals(expected: <$expected>, actual: <$actual>$msg) fails.");
|
||||
}
|
||||
|
||||
static String _getMessage(String reason) =>
|
||||
(reason.isEmpty) ? "" : ", '$reason'";
|
||||
|
||||
static Never _fail(String message) {
|
||||
throw ExpectException(message);
|
||||
}
|
||||
}
|
||||
|
||||
/// Exception thrown on a failed expectation check.
|
||||
///
|
||||
/// Always recognized by [Expect.throws] as an unexpected error.
|
||||
class ExpectException {
|
||||
/// Call this to provide a function that associates a test name with this
|
||||
/// failure.
|
||||
///
|
||||
/// Used by async_helper/async_minitest.dart to inject logic to bind the
|
||||
/// `group()` and `test()` name strings to a test failure.
|
||||
static void setTestNameCallback(String Function() getName) {
|
||||
_getTestName = getName;
|
||||
}
|
||||
|
||||
static String Function() _getTestName = _kEmptyString;
|
||||
|
||||
final String message;
|
||||
final String name;
|
||||
|
||||
ExpectException(this.message) : name = _getTestName();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
if (name != "") return 'In test "$name" $message';
|
||||
return message;
|
||||
}
|
||||
|
||||
/// Initial value for _getTestName.
|
||||
static String _kEmptyString() => "";
|
||||
}
|
|
@ -5,10 +5,10 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
|
||||
import 'common/expect.dart';
|
||||
import 'common/service_test_common.dart';
|
||||
import 'common/test_helper.dart';
|
||||
|
||||
|
|
|
@ -308,21 +308,6 @@ enum RPCErrorKind {
|
|||
}
|
||||
|
||||
class RPCError implements Exception {
|
||||
@Deprecated('Use RPCErrorKind.kServerError.code instead.')
|
||||
static int get kServerError => RPCErrorKind.kServerError.code;
|
||||
|
||||
@Deprecated('Use RPCErrorKind.kInvalidRequest.code instead.')
|
||||
static int get kInvalidRequest => RPCErrorKind.kInvalidRequest.code;
|
||||
|
||||
@Deprecated('Use RPCErrorKind.kMethodNotFound.code instead.')
|
||||
static int get kMethodNotFound => RPCErrorKind.kMethodNotFound.code;
|
||||
|
||||
@Deprecated('Use RPCErrorKind.kInvalidParams.code instead.')
|
||||
static int get kInvalidParams => RPCErrorKind.kInvalidParams.code;
|
||||
|
||||
@Deprecated('Use RPCErrorKind.kInternalError.code instead.')
|
||||
static int get kInternalError => RPCErrorKind.kInternalError.code;
|
||||
|
||||
static RPCError parse(String callingMethod, dynamic json) {
|
||||
return RPCError(callingMethod, json['code'], json['message'], json['data']);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ Future<void> main(List<String> args) async {
|
|||
|
||||
Future<void> _generateDartClient(
|
||||
String codeGeneratorDir, List<Node> nodes) async {
|
||||
var outputFilePath = await _generateDartCommon(
|
||||
final outputFilePath = await _generateDartCommon(
|
||||
api: VmServiceApi(),
|
||||
nodes: nodes,
|
||||
codeGeneratorDir: codeGeneratorDir,
|
||||
|
@ -49,15 +49,6 @@ Future<void> _generateDartClient(
|
|||
interfaceName: 'VmService',
|
||||
);
|
||||
print('Wrote Dart client to $outputFilePath.');
|
||||
outputFilePath = await _generateDartCommon(
|
||||
api: VmServiceInterfaceApi(),
|
||||
nodes: nodes,
|
||||
codeGeneratorDir: codeGeneratorDir,
|
||||
packageName: 'vm_service',
|
||||
interfaceName: 'VmServiceInterface',
|
||||
fileNameOverride: 'vm_service_interface',
|
||||
);
|
||||
print('Wrote Dart temporary interface to $outputFilePath.');
|
||||
}
|
||||
|
||||
Future<void> _generateDartInterface(
|
||||
|
@ -78,7 +69,6 @@ Future<String> _generateDartCommon({
|
|||
required String codeGeneratorDir,
|
||||
required String packageName,
|
||||
required String interfaceName,
|
||||
String? fileNameOverride,
|
||||
}) async {
|
||||
final outDirPath = normalize(
|
||||
join(
|
||||
|
@ -96,7 +86,7 @@ Future<String> _generateDartCommon({
|
|||
final outputFile = File(
|
||||
join(
|
||||
outDirPath,
|
||||
'${fileNameOverride ?? packageName}.dart',
|
||||
'$packageName.dart',
|
||||
),
|
||||
);
|
||||
final generator = DartGenerator(interfaceName: interfaceName);
|
||||
|
|
|
@ -11,8 +11,7 @@ library;
|
|||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:vm_service/vm_service.dart'
|
||||
hide ServiceExtensionRegistry, VmServerConnection, VmServiceInterface;
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
|
||||
import 'service_extension_registry.dart';
|
||||
|
||||
|
|
|
@ -9,8 +9,7 @@ import 'dart:convert';
|
|||
import 'package:async/async.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:vm_service/vm_service.dart'
|
||||
hide ServiceExtensionRegistry, VmServiceInterface, VmServerConnection;
|
||||
import 'package:vm_service/vm_service.dart';
|
||||
import 'package:vm_service_interface/vm_service_interface.dart';
|
||||
|
||||
void main() {
|
||||
|
|
Loading…
Reference in a new issue