// Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @dart = 2.6 import 'dart:isolate'; import 'dart:ui'; import 'package:test/test.dart'; const String kPortName = 'foobar'; const int kErrorCode = -1; const int kStartCode = 0; const int kCloseCode = 1; const int kDeletedCode = 2; void isolateSpawnEntrypoint(SendPort port) { void sendHelper(int code, [String message = '']) { port.send([code, message]); } final SendPort shared = IsolateNameServer.lookupPortByName(kPortName); if (shared == null) { sendHelper(kErrorCode, 'Could not find port: $kPortName'); return; } // ack that the SendPort lookup was successful. sendHelper(kStartCode); shared.send(kPortName); sendHelper(kCloseCode); // We'll fail if the ReceivePort's callback is called more than once. Try to // send another message to ensure we don't crash. shared.send('garbage'); final bool result = IsolateNameServer.removePortNameMapping(kPortName); if (result) { sendHelper(kDeletedCode); } else { sendHelper(kErrorCode, 'Was unable to remove mapping for $kPortName'); } } void main() { tearDown(() { IsolateNameServer.removePortNameMapping(kPortName); }); test('simple isolate name server', () { // Mapping for 'foobar' isn't set. Check these cases to ensure correct // negative response. expect(IsolateNameServer.lookupPortByName(kPortName), isNull); expect(IsolateNameServer.removePortNameMapping(kPortName), isFalse); // Register a SendPort. final ReceivePort receivePort = ReceivePort(); final SendPort sendPort = receivePort.sendPort; expect(IsolateNameServer.registerPortWithName(sendPort, kPortName), isTrue); expect(IsolateNameServer.lookupPortByName(kPortName), sendPort); // Check we can't register the same name twice. final ReceivePort receivePort2 = ReceivePort(); final SendPort sendPort2 = receivePort2.sendPort; expect( IsolateNameServer.registerPortWithName(sendPort2, kPortName), isFalse); expect(IsolateNameServer.lookupPortByName(kPortName), sendPort); // Remove the mapping. expect(IsolateNameServer.removePortNameMapping(kPortName), isTrue); expect(IsolateNameServer.lookupPortByName(kPortName), isNull); // Ensure registering a new port with the old name returns the new port. expect( IsolateNameServer.registerPortWithName(sendPort2, kPortName), isTrue); expect(IsolateNameServer.lookupPortByName(kPortName), sendPort2); // Close so the test runner doesn't hang. receivePort.close(); receivePort2.close(); }); test('isolate name server multi-isolate', () async { // Register our send port with the name server. final ReceivePort receivePort = ReceivePort(); final SendPort sendPort = receivePort.sendPort; expect(IsolateNameServer.registerPortWithName(sendPort, kPortName), isTrue); // Test driver. final ReceivePort testReceivePort = ReceivePort(); testReceivePort.listen(expectAsync1((dynamic response) { final int code = response[0] as int; final String message = response[1] as String; switch (code) { case kStartCode: break; case kCloseCode: receivePort.close(); break; case kDeletedCode: expect(IsolateNameServer.lookupPortByName(kPortName), isNull); // Test is done, close the last ReceivePort. testReceivePort.close(); break; case kErrorCode: throw message; default: throw 'UNREACHABLE'; } }, count: 3)); receivePort.listen(expectAsync1((dynamic message) { // If we don't get this message, we timeout and fail. expect(message, kPortName); })); // Run the test. await Isolate.spawn(isolateSpawnEntrypoint, testReceivePort.sendPort); }); }