blob: 1c161bf0f68cae1e90026b46e1febab7c9f50b20 [file] [log] [blame]
// 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 'package:test/test.dart';
import 'package:vm_service/vm_service.dart';
import 'package:vm_service/vm_service_io.dart';
import 'common/service_test_common.dart';
import 'common/test_helper.dart';
const serviceName = 'disappearService';
const serviceAlias = 'serviceAlias';
const paramKey = 'pkey';
const paramValue = 'pvalue';
const repetition = 5;
final tests = <IsolateTest>[
(VmService primaryClient, IsolateRef isolateRef) async {
final secondaryClient = await vmServiceConnectUri(primaryClient.wsUri!);
final allRequestsReceivedCompleter = Completer<void>();
final requests = <Map<String, dynamic>>[];
// Register the service.
final serviceMethodName = await registerServiceHelper(
primaryClient,
secondaryClient,
serviceName,
(params) async {
final completer = Completer<Map<String, dynamic>>();
requests.add(params);
if (requests.length == repetition) {
allRequestsReceivedCompleter.complete();
}
// We never complete this future as we want to see how the client
// handles the service disappearing while there are outstanding
// requests.
return await completer.future;
},
);
// Invoke the service multiple times.
{
final results = <Future<Response>>[
for (int i = 0; i < repetition; ++i)
primaryClient.callServiceExtension(
serviceMethodName,
args: {
paramKey + i.toString(): paramValue + i.toString(),
},
)
// We ignore these futures so that when they complete with an error
// without being awaited or do not have an error handler registered
// they won't cause an unhandled exception.
..ignore(),
];
// Wait for all of the requests to be received before processing.
await allRequestsReceivedCompleter.future;
// Verify the request parameters as a sanity check.
for (final params in requests) {
final iteration = requests.indexOf(params);
final end = iteration.toString();
// check requests while they arrive
expect(params[paramKey + end], paramValue + end);
}
// Disconnect the service client that registered the service extension.
await secondaryClient.dispose();
// Check that all of the outstanding requests complete with an RPC error.
for (final future in results) {
try {
await future;
fail('Service should have disappeared');
} on RPCError catch (e) {
expect(e.code, RPCErrorKind.kServiceDisappeared.code);
expect(e.message, 'Service has disappeared');
}
}
}
},
];
void main([args = const <String>[]]) => runIsolateTests(
args,
tests,
'external_service_disappear_test.dart',
);