[ package:vm_service ] Migrate Observatory HTTP service invocation tests

Also adds READMEs to some test sub-directories.

Change-Id: Ibf48654bcb43d7d52bd3bc0d2ab6afabc1ea3df6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/333100
Commit-Queue: Ben Konyi <bkonyi@google.com>
Reviewed-by: Derek Xu <derekx@google.com>
This commit is contained in:
Ben Konyi 2023-10-31 19:54:28 +00:00 committed by Commit Queue
parent 94f8809607
commit 8b3d93234d
12 changed files with 282 additions and 8 deletions

View file

@ -108,46 +108,46 @@ class Expect {
if (expected is String && actual is String) { if (expected is String && actual is String) {
String stringDifference = _stringDifference(expected, actual); String stringDifference = _stringDifference(expected, actual);
if (stringDifference.isNotEmpty) { if (stringDifference.isNotEmpty) {
_fail("Expect.equals($stringDifference$msg) fails."); fail("Expect.equals($stringDifference$msg) fails.");
} }
_fail("Expect.equals(expected: <${_escapeString(expected)}>" fail("Expect.equals(expected: <${_escapeString(expected)}>"
", actual: <${_escapeString(actual)}>$msg) fails."); ", actual: <${_escapeString(actual)}>$msg) fails.");
} }
_fail("Expect.equals(expected: <$expected>, actual: <$actual>$msg) fails."); fail("Expect.equals(expected: <$expected>, actual: <$actual>$msg) fails.");
} }
/// Checks whether the actual value is a bool and its value is true. /// Checks whether the actual value is a bool and its value is true.
static void isTrue(dynamic actual, [String reason = ""]) { static void isTrue(dynamic actual, [String reason = ""]) {
if (_identical(actual, true)) return; if (_identical(actual, true)) return;
String msg = _getMessage(reason); String msg = _getMessage(reason);
_fail("Expect.isTrue($actual$msg) fails."); fail("Expect.isTrue($actual$msg) fails.");
} }
/// Checks whether the actual value is a bool and its value is false. /// Checks whether the actual value is a bool and its value is false.
static void isFalse(dynamic actual, [String reason = ""]) { static void isFalse(dynamic actual, [String reason = ""]) {
if (_identical(actual, false)) return; if (_identical(actual, false)) return;
String msg = _getMessage(reason); String msg = _getMessage(reason);
_fail("Expect.isFalse($actual$msg) fails."); fail("Expect.isFalse($actual$msg) fails.");
} }
/// Checks whether [actual] is null. /// Checks whether [actual] is null.
static void isNull(dynamic actual, [String reason = ""]) { static void isNull(dynamic actual, [String reason = ""]) {
if (null == actual) return; if (null == actual) return;
String msg = _getMessage(reason); String msg = _getMessage(reason);
_fail("Expect.isNull(actual: <$actual>$msg) fails."); fail("Expect.isNull(actual: <$actual>$msg) fails.");
} }
/// Checks whether [actual] is not null. /// Checks whether [actual] is not null.
static void isNotNull(dynamic actual, [String reason = ""]) { static void isNotNull(dynamic actual, [String reason = ""]) {
if (null != actual) return; if (null != actual) return;
String msg = _getMessage(reason); String msg = _getMessage(reason);
_fail("Expect.isNotNull(actual: <$actual>$msg) fails."); fail("Expect.isNotNull(actual: <$actual>$msg) fails.");
} }
static String _getMessage(String reason) => static String _getMessage(String reason) =>
(reason.isEmpty) ? "" : ", '$reason'"; (reason.isEmpty) ? "" : ", '$reason'";
static Never _fail(String message) { static Never fail(String message) {
throw ExpectException(message); throw ExpectException(message);
} }
} }

View file

@ -0,0 +1 @@
This directory contains tests that make VM service requests via HTTP rather than a web socket, only making use of `package:vm_service` to parse the response JSON.

View file

@ -0,0 +1,13 @@
// 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.
import 'http_get_isolate_rpc_common.dart';
import '../common/test_helper.dart';
void main([args = const <String>[]]) => runIsolateTests(
args,
tests,
'http_auth_get_isolate_rpc_test.dart',
testeeBefore: testeeBefore,
);

View file

@ -0,0 +1,13 @@
// 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.
import 'http_get_vm_rpc_common.dart';
import '../common/test_helper.dart';
void main([args = const <String>[]]) => runIsolateTests(
args,
tests,
'http_auth_get_vm_rpc_test.dart',
testeeBefore: testeeBefore,
);

View file

@ -0,0 +1,50 @@
// 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.
import 'dart:async';
import 'dart:developer';
import 'package:test/test.dart';
import 'package:vm_service/vm_service.dart';
import '../common/expect.dart';
import '../common/test_helper.dart';
import 'http_request_helpers.dart';
Future<String> getIsolateGroupId(
Uri serverUri,
) async {
final result = await makeHttpServiceRequest(
serverUri: serverUri,
method: 'getVM',
);
return result['isolateGroups'][0]['id'] as String;
}
Future<void> testeeBefore() async {
final info = await Service.getInfo();
final serverUri = info.serverUri!;
try {
final result = createServiceObject(
await makeHttpServiceRequest(
serverUri: serverUri,
method: 'getIsolateGroup',
params: {'isolateGroupId': await getIsolateGroupId(serverUri)}),
['IsolateGroup'],
)! as IsolateGroup;
Expect.isTrue(result.id!.startsWith('isolateGroups/'));
Expect.isNotNull(result.number);
Expect.isFalse(result.isSystemIsolateGroup);
Expect.isTrue(result.isolates!.length > 0);
} catch (e) {
fail('invalid request: $e');
}
}
final tests = <IsolateTest>[
(VmService service, IsolateRef isolate) async {
// Just getting here means that the testee enabled the service protocol
// web server.
}
];

View file

@ -0,0 +1,13 @@
// 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.
import 'http_get_isolate_group_rpc_common.dart';
import '../common/test_helper.dart';
void main([args = const <String>[]]) => runIsolateTests(
args,
tests,
'http_get_isolate_group_rpc_test.dart',
testeeBefore: testeeBefore,
);

View file

@ -0,0 +1,64 @@
// 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.
import 'dart:async';
import 'dart:developer';
import 'package:vm_service/vm_service.dart';
import '../common/expect.dart';
import '../common/test_helper.dart';
import 'http_request_helpers.dart';
Future<String> getIsolateId(Uri serverUri) async {
final result = await makeHttpServiceRequest(
serverUri: serverUri,
method: 'getVM',
);
return result['isolates'][0]['id'] as String;
}
Future<void> testeeBefore() async {
final info = await Service.getInfo();
final serverUri = info.serverUri!;
try {
// Build the request.
final params = <String, String>{
'isolateId': await getIsolateId(serverUri),
};
final result = createServiceObject(
await makeHttpServiceRequest(
serverUri: serverUri,
method: 'getIsolate',
params: params,
),
['Isolate'],
)! as Isolate;
Expect.isTrue(result.id!.startsWith('isolates/'));
Expect.isNotNull(result.number);
Expect.equals(result.json!['_originNumber'], result.number);
Expect.isTrue(result.startTime! > 0);
Expect.isTrue(result.livePorts! > 0);
Expect.isFalse(result.pauseOnExit);
Expect.isNotNull(result.pauseEvent);
Expect.isNull(result.error);
Expect.isNotNull(result.rootLib);
Expect.isTrue(result.libraries!.isNotEmpty);
Expect.isTrue(result.breakpoints!.isEmpty);
Expect.equals(result.json!['_heaps']['new']['type'], 'HeapSpace');
Expect.equals(result.json!['_heaps']['old']['type'], 'HeapSpace');
Expect.equals(result.json!['isolate_group']['type'], '@IsolateGroup');
} catch (e) {
Expect.fail('invalid request: $e');
}
}
final tests = <IsolateTest>[
(VmService service, IsolateRef isolateRef) async {
// Just getting here means that the testee enabled the service protocol
// web server.
}
];

View file

@ -0,0 +1,14 @@
// 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.
import 'http_get_isolate_rpc_common.dart';
import '../common/test_helper.dart';
void main([args = const <String>[]]) => runIsolateTests(
args,
tests,
'http_get_isolate_rpc_test.dart',
testeeBefore: testeeBefore,
useAuthToken: false,
);

View file

@ -0,0 +1,45 @@
// 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.
import 'dart:async';
import 'dart:developer';
import 'package:vm_service/vm_service.dart';
import '../common/expect.dart';
import '../common/test_helper.dart';
import 'http_request_helpers.dart';
Future<void> testeeBefore() async {
final info = await Service.getInfo();
final serverUri = info.serverUri!;
try {
final result = createServiceObject(
await makeHttpServiceRequest(
serverUri: serverUri,
method: 'getVM',
),
['VM'],
)! as VM;
Expect.equals(result.name, 'vm');
Expect.isTrue(result.architectureBits! > 0);
Expect.isNotNull(result.targetCPU);
Expect.isNotNull(result.hostCPU);
Expect.isNotNull(result.version);
Expect.isNotNull(result.pid);
Expect.isTrue(result.startTime! > 0);
Expect.isTrue(result.isolates!.isNotEmpty);
Expect.isTrue(result.isolateGroups!.isNotEmpty);
} catch (e) {
Expect.fail('invalid request: $e');
}
}
final tests = <IsolateTest>[
(VmService service, IsolateRef isolateRef) async {
// Just getting here means that the testee enabled the service protocol
// web server.
}
];

View file

@ -0,0 +1,14 @@
// 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.
import 'http_get_vm_rpc_common.dart';
import '../common/test_helper.dart';
void main([args = const <String>[]]) => runIsolateTests(
args,
tests,
'http_get_vm_rpc_test.dart',
testeeBefore: testeeBefore,
useAuthToken: false,
);

View file

@ -0,0 +1,44 @@
// 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.
import 'dart:convert';
import 'dart:io';
Uri buildRequestUri({
required Uri serverUri,
required String method,
Map<String, dynamic> params = const {},
}) {
final pathSegments = <String>[]..addAll(serverUri.pathSegments);
if (pathSegments.isNotEmpty) {
pathSegments[pathSegments.length - 1] = method;
} else {
pathSegments.add(method);
}
return serverUri.replace(
pathSegments: pathSegments,
queryParameters: params,
);
}
Future<Map<String, dynamic>> makeHttpServiceRequest({
required Uri serverUri,
required String method,
Map<String, dynamic> params = const {},
}) async {
final requestUri = buildRequestUri(
serverUri: serverUri,
method: method,
params: params,
);
final httpClient = HttpClient();
final request = await httpClient.getUrl(requestUri);
final response = await request.close();
final jsonResponse = await response
.cast<List<int>>()
.transform(utf8.decoder)
.transform(json.decoder)
.first as Map<String, dynamic>;
return jsonResponse['result'];
}

View file

@ -0,0 +1,3 @@
This directory contains tests for private VM service RPCs.
**WARNING:** Functionality covered by these tests should not be relied on by clients not owned by the Dart and Flutter teams as private RPCs can and will be changed or removed without notice.