Index: tests/standalone/io/raw_synchronous_socket_test.dart |
diff --git a/tests/standalone/io/raw_synchronous_socket_test.dart b/tests/standalone/io/raw_synchronous_socket_test.dart |
deleted file mode 100644 |
index af60a3b963226ee0874e3b9ad6273430982c7f71..0000000000000000000000000000000000000000 |
--- a/tests/standalone/io/raw_synchronous_socket_test.dart |
+++ /dev/null |
@@ -1,490 +0,0 @@ |
-// Copyright (c) 2017, 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:io"; |
-import "dart:isolate"; |
-import "dart:math"; |
- |
-import "package:async_helper/async_helper.dart"; |
-import "package:expect/expect.dart"; |
- |
-const String LOOPBACK_IP_V4_STRING = "127.0.0.1"; |
- |
-void testArguments() { |
- Expect.throws(() => RawSynchronousSocket.connectSync(null, 0)); |
- Expect.throws( |
- () => RawSynchronousSocket.connectSync(LOOPBACK_IP_V4_STRING, null)); |
- Expect.throws( |
- () => RawSynchronousSocket.connectSync(LOOPBACK_IP_V4_STRING, 65536)); |
- Expect.throws( |
- () => RawSynchronousSocket.connectSync(LOOPBACK_IP_V4_STRING, -1)); |
- Expect.throws(() => |
- RawSynchronousSocket.connectSync(LOOPBACK_IP_V4_STRING, 0, backlog: -1)); |
-} |
- |
-/* |
-void testInvalidConnect() { |
- // Connect to an unknown DNS name. |
- try { |
- var socket = RawSynchronousSocket.connectSync("ko.faar.__hest__", 0); |
- Expect.fail("Failure expected"); |
- } catch (e) { |
- Expect.isTrue(e is SocketException); |
- } |
- |
- // Connect to an unavaliable IP-address. |
- try { |
- var socket = RawSynchronousSocket.connectSync("1.2.3.4", 0); |
- Expect.fail("Failure expected"); |
- } catch (e) { |
- Expect.isTrue(e is SocketException); |
- } |
- ; |
-} |
-*/ |
- |
-void testSimpleConnect() { |
- asyncStart(); |
- RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) { |
- var socket = |
- RawSynchronousSocket.connectSync(LOOPBACK_IP_V4_STRING, server.port); |
- server.listen((serverSocket) { |
- Expect.equals(socket.address, serverSocket.remoteAddress); |
- Expect.equals(socket.port, serverSocket.remotePort); |
- Expect.equals(socket.remoteAddress, server.address); |
- Expect.equals(socket.remotePort, server.port); |
- socket.closeSync(); |
- server.close(); |
- asyncEnd(); |
- }); |
- }); |
-} |
- |
-void testServerListenAfterConnect() { |
- asyncStart(); |
- RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) { |
- Expect.isTrue(server.port > 0); |
- var client = |
- RawSynchronousSocket.connectSync(LOOPBACK_IP_V4_STRING, server.port); |
- server.listen((socket) { |
- client.closeSync(); |
- server.close(); |
- socket.close(); |
- asyncEnd(); |
- }); |
- }); |
-} |
- |
-const messageSize = 1000; |
-// Configuration fields for the EchoServer. |
-enum EchoServerTypes { |
- // Max accumulated connections to server before close. Defaults to 1. |
- CONNECTION_COUNT, |
- // Sets the range of the fields to check in the list generated by |
- // createTestData(). |
- OFFSET_END, |
- OFFSET_START, |
- // The port used to communicate with an isolate. |
- ISOLATE_SEND_PORT, |
- // The port of the newly created echo server. |
- SERVER_PORT |
-} |
- |
-List<int> createTestData() { |
- return new List<int>.generate(messageSize, (index) => index & 0xff); |
-} |
- |
-// Consumes data generated by a test and compares it against the original test |
-// data. The optional fields, start and end, are used to compare against |
-// segments of the original test data list. In other words, data.length == (end |
-// - start). |
-void verifyTestData(List<int> data, [int start = 0, int end]) { |
- assert(data != null); |
- List<int> expected = createTestData(); |
- if (end == null) { |
- end = data.length; |
- } |
- end = min(messageSize, end); |
- Expect.equals(end - start, data.length); |
- for (int i = 0; i < (end - start); i++) { |
- Expect.equals(expected[start + i], data[i]); |
- } |
-} |
- |
-// The echo server is spawned in a new isolate and is used to test various |
-// synchronous read/write operations by echoing any data received back to the |
-// sender. The server should shutdown automatically after a specified number of |
-// socket disconnections (default: 1). |
-Future echoServer(var sendPort) async { |
- RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) async { |
- ReceivePort receivePort = new ReceivePort(); |
- Map response = { |
- EchoServerTypes.ISOLATE_SEND_PORT: receivePort.sendPort, |
- EchoServerTypes.SERVER_PORT: server.port |
- }; |
- sendPort.send(response); |
- Map limits = await receivePort.first; |
- int start = limits[EchoServerTypes.OFFSET_START]; |
- int end = limits[EchoServerTypes.OFFSET_END]; |
- int length = end - start; |
- int connection_count = limits[EchoServerTypes.CONNECTION_COUNT] ?? 1; |
- int connections = 0; |
- sendPort = limits[EchoServerTypes.ISOLATE_SEND_PORT]; |
- server.listen((client) { |
- int bytesRead = 0; |
- int bytesWritten = 0; |
- bool closedEventReceived = false; |
- List<int> data = new List<int>(length); |
- client.writeEventsEnabled = false; |
- client.listen((event) { |
- switch (event) { |
- case RawSocketEvent.READ: |
- Expect.isTrue(bytesWritten == 0); |
- Expect.isTrue(client.available() > 0); |
- var buffer = client.read(client.available()); |
- data.setRange(bytesRead, bytesRead + buffer.length, buffer); |
- bytesRead += buffer.length; |
- // Once we've read all the data, we can echo it back. Otherwise, |
- // keep waiting for more bytes. |
- if (bytesRead >= length) { |
- verifyTestData(data, start, end); |
- client.writeEventsEnabled = true; |
- } |
- break; |
- case RawSocketEvent.WRITE: |
- Expect.isFalse(client.writeEventsEnabled); |
- bytesWritten += |
- client.write(data, bytesWritten, data.length - bytesWritten); |
- if (bytesWritten < length) { |
- client.writeEventsEnabled = true; |
- } else if (bytesWritten == length) { |
- // Close the socket for writing from the server since we're done |
- // writing to this socket. The connection is closed completely |
- // after the client closes the socket for reading from the server. |
- client.shutdown(SocketDirection.SEND); |
- } |
- break; |
- case RawSocketEvent.READ_CLOSED: |
- client.close(); |
- break; |
- case RawSocketEvent.CLOSED: |
- Expect.isFalse(closedEventReceived); |
- closedEventReceived = true; |
- break; |
- default: |
- throw "Unexpected event $event"; |
- } |
- }, onDone: () { |
- Expect.isTrue(closedEventReceived); |
- connections++; |
- if (connections >= connection_count) { |
- server.close(); |
- } |
- }); |
- }, onDone: () { |
- // Let the client know we're shutting down then kill the isolate. |
- sendPort.send(null); |
- kill(); |
- }); |
- }); |
-} |
- |
-Future testSimpleReadWrite({bool dropReads}) async { |
- asyncStart(); |
- // This test creates a server and a client connects. The client writes data |
- // to the socket and the server echos it back. The client confirms the data it |
- // reads is the same as the data sent, then closes the socket, resulting in |
- // the closing of the server, which responds on receivePort with null to |
- // specify the echo server isolate is about to be killed. If an error occurs |
- // in the echo server, the exception and stack trace are sent to receivePort, |
- // which prints the exception and stack trace before eventually throwing an |
- // error. |
- ReceivePort receivePort = new ReceivePort(); |
- Isolate echo = await Isolate.spawn(echoServer, receivePort.sendPort); |
- |
- Map response = await receivePort.first; |
- SendPort sendPort = response[EchoServerTypes.ISOLATE_SEND_PORT]; |
- int serverInternetPort = response[EchoServerTypes.SERVER_PORT]; |
- |
- receivePort = new ReceivePort(); |
- echo.addErrorListener(receivePort.sendPort); |
- |
- Map limits = { |
- EchoServerTypes.OFFSET_START: 0, |
- EchoServerTypes.OFFSET_END: messageSize, |
- EchoServerTypes.ISOLATE_SEND_PORT: receivePort.sendPort |
- }; |
- sendPort.send(limits); |
- |
- try { |
- var socket = RawSynchronousSocket.connectSync( |
- LOOPBACK_IP_V4_STRING, serverInternetPort); |
- List<int> data = createTestData(); |
- socket.writeFromSync(data); |
- List<int> result = socket.readSync(data.length); |
- verifyTestData(result); |
- socket.shutdown(SocketDirection.SEND); |
- socket.closeSync(); |
- } catch (e, stack) { |
- print("Echo test failed in the client"); |
- rethrow; |
- } |
- // Wait for the server to shutdown before finishing the test. |
- var result = await receivePort.first; |
- if (result != null) { |
- throw "Echo test failed in server!\nError: ${result[0]}\nStack trace:" + |
- " ${result[1]}"; |
- } |
- asyncEnd(); |
-} |
- |
-Future testPartialRead() async { |
- asyncStart(); |
- // This test is based on testSimpleReadWrite, but instead of reading the |
- // entire echoed message at once, it reads it in two calls to readIntoSync. |
- ReceivePort receivePort = new ReceivePort(); |
- Isolate echo = await Isolate.spawn(echoServer, receivePort.sendPort); |
- |
- Map response = await receivePort.first; |
- SendPort sendPort = response[EchoServerTypes.ISOLATE_SEND_PORT]; |
- int serverInternetPort = response[EchoServerTypes.SERVER_PORT]; |
- List<int> data = createTestData(); |
- |
- receivePort = new ReceivePort(); |
- echo.addErrorListener(receivePort.sendPort); |
- |
- Map limits = { |
- EchoServerTypes.OFFSET_START: 0, |
- EchoServerTypes.OFFSET_END: 1000, |
- EchoServerTypes.ISOLATE_SEND_PORT: receivePort.sendPort |
- }; |
- sendPort.send(limits); |
- |
- try { |
- var socket = RawSynchronousSocket.connectSync( |
- LOOPBACK_IP_V4_STRING, serverInternetPort); |
- int half_length = (data.length / 2).toInt(); |
- |
- // Send the full data list to the server. |
- socket.writeFromSync(data); |
- List<int> result = new List<int>(data.length); |
- |
- // Read half at a time and check that there's still more bytes available. |
- socket.readIntoSync(result, 0, half_length); |
- verifyTestData(result.sublist(0, half_length), 0, half_length); |
- Expect.isTrue(socket.available() == (data.length - half_length)); |
- |
- // Read the second half and verify again. |
- socket.readIntoSync(result, half_length); |
- verifyTestData(result); |
- Expect.isTrue(socket.available() == 0); |
- |
- socket.closeSync(); |
- } catch (e, stack) { |
- print("Echo test failed in the client."); |
- rethrow; |
- } |
- // Wait for the server to shutdown before finishing the test. |
- var result = await receivePort.first; |
- if (result != null) { |
- throw "Echo test failed in server!\nError: ${result[0]}\nStack trace:" + |
- " ${result[1]}"; |
- } |
- asyncEnd(); |
-} |
- |
-Future testPartialWrite() async { |
- asyncStart(); |
- // This test is based on testSimpleReadWrite, but instead of writing the |
- // entire data buffer at once, it writes different parts of the buffer over |
- // multiple calls to writeFromSync. |
- ReceivePort receivePort = new ReceivePort(); |
- Isolate echo = await Isolate.spawn(echoServer, receivePort.sendPort); |
- |
- Map response = await receivePort.first; |
- List<int> data = createTestData(); |
- SendPort sendPort = response[EchoServerTypes.ISOLATE_SEND_PORT]; |
- int startOffset = 32; |
- int endOffset = (data.length / 2).toInt(); |
- int serverInternetPort = response[EchoServerTypes.SERVER_PORT]; |
- |
- receivePort = new ReceivePort(); |
- echo.addErrorListener(receivePort.sendPort); |
- |
- Map limits = { |
- EchoServerTypes.OFFSET_START: startOffset, |
- EchoServerTypes.OFFSET_END: endOffset, |
- EchoServerTypes.ISOLATE_SEND_PORT: receivePort.sendPort |
- }; |
- sendPort.send(limits); |
- try { |
- var socket = RawSynchronousSocket.connectSync( |
- LOOPBACK_IP_V4_STRING, serverInternetPort); |
- List<int> data = createTestData(); |
- |
- // Write a subset of data to the server. |
- socket.writeFromSync(data, startOffset, endOffset); |
- |
- // Grab the response and verify it's correct. |
- List<int> result = new List<int>(endOffset - startOffset); |
- socket.readIntoSync(result); |
- |
- Expect.equals(result.length, endOffset - startOffset); |
- verifyTestData(result, startOffset, endOffset); |
- socket.closeSync(); |
- } catch (e, stack) { |
- print("Echo test failed in the client."); |
- rethrow; |
- } |
- |
- // Wait for the server to shutdown before finishing the test. |
- var result = await receivePort.first; |
- if (result != null) { |
- throw "Echo test failed in server!\nError: ${result[0]}\nStack trace:" + |
- " ${result[1]}"; |
- } |
- asyncEnd(); |
-} |
- |
-Future testShutdown() async { |
- asyncStart(); |
- // This test creates a server and a client connects. The client then tries to |
- // perform various operations after being shutdown in a specific direction, to |
- // ensure reads or writes cannot be performed if the socket has been shutdown |
- // for reading or writing. |
- ReceivePort receivePort = new ReceivePort(); |
- Isolate echo = await Isolate.spawn(echoServer, receivePort.sendPort); |
- |
- Map response = await receivePort.first; |
- SendPort sendPort = response[EchoServerTypes.ISOLATE_SEND_PORT]; |
- int serverInternetPort = response[EchoServerTypes.SERVER_PORT]; |
- List<int> data = createTestData(); |
- |
- receivePort = new ReceivePort(); |
- echo.addErrorListener(receivePort.sendPort); |
- |
- Map limits = { |
- EchoServerTypes.OFFSET_START: 0, |
- EchoServerTypes.OFFSET_END: data.length, |
- EchoServerTypes.ISOLATE_SEND_PORT: receivePort.sendPort, |
- // Tell the server to shutdown after 3 sockets disconnect. |
- EchoServerTypes.CONNECTION_COUNT: 3 |
- }; |
- sendPort.send(limits); |
- |
- try { |
- var socket = RawSynchronousSocket.connectSync( |
- LOOPBACK_IP_V4_STRING, serverInternetPort); |
- |
- // Close from both directions. Shouldn't be able to read/write to the |
- // socket. |
- socket.shutdown(SocketDirection.BOTH); |
- Expect.throws( |
- () => socket.writeFromSync(data), (e) => e is SocketException); |
- Expect.throws( |
- () => socket.readSync(data.length), (e) => e is SocketException); |
- socket.closeSync(); |
- |
- // Close the socket for reading, do a write, and see if we can get any |
- // response from the server (we shouldn't be able to). |
- socket = RawSynchronousSocket.connectSync( |
- LOOPBACK_IP_V4_STRING, serverInternetPort); |
- socket.shutdown(SocketDirection.RECEIVE); |
- socket.writeFromSync(data); |
- // Throws exception when the socket is closed for RECEIVE. |
- Expect.throws( |
- () => socket.readSync(data.length), (e) => e is SocketException); |
- Expect.isTrue(socket.available() == 0); |
- socket.closeSync(); |
- |
- // Close the socket for writing and try to do a write. This should cause an |
- // OSError to be throw as the pipe is closed for writing. |
- socket = RawSynchronousSocket.connectSync( |
- LOOPBACK_IP_V4_STRING, serverInternetPort); |
- socket.shutdown(SocketDirection.SEND); |
- Expect.throws( |
- () => socket.writeFromSync(data), (e) => e is SocketException); |
- socket.closeSync(); |
- } catch (e, stack) { |
- print("Echo test failed in client."); |
- rethrow; |
- } |
- // Wait for the server to shutdown before finishing the test. |
- var result = await receivePort.first; |
- if (result != null) { |
- throw "Echo test failed in server!\nError: ${result[0]}\nStack trace:" + |
- " ${result[1]}"; |
- } |
- asyncEnd(); |
-} |
- |
-Future testInvalidReadWriteOperations() { |
- asyncStart(); |
- RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) { |
- server.listen((socket) {}); |
- List<int> data = createTestData(); |
- var socket = |
- RawSynchronousSocket.connectSync(LOOPBACK_IP_V4_STRING, server.port); |
- |
- // Invalid writeFromSync invocations |
- Expect.throws(() => socket.writeFromSync(data, data.length + 1), |
- (e) => e is RangeError); |
- Expect.throws(() => socket.writeFromSync(data, 0, data.length + 1), |
- (e) => e is RangeError); |
- Expect.throws( |
- () => socket.writeFromSync(data, 1, 0), (e) => e is RangeError); |
- Expect.throws( |
- () => socket.writeFromSync(data, null), (e) => e is ArgumentError); |
- |
- // Invalid readIntoSync invocations |
- List<int> buffer = new List<int>(10); |
- Expect.throws(() => socket.readIntoSync(buffer, buffer.length + 1), |
- (e) => e is RangeError); |
- Expect.throws(() => socket.readIntoSync(buffer, 0, buffer.length + 1), |
- (e) => e is RangeError); |
- Expect.throws( |
- () => socket.readIntoSync(buffer, 1, 0), (e) => e is RangeError); |
- Expect.throws( |
- () => socket.readIntoSync(buffer, null), (e) => e is ArgumentError); |
- |
- // Invalid readSync invocation |
- Expect.throws(() => socket.readSync(-1), (e) => e is ArgumentError); |
- |
- server.close(); |
- socket.closeSync(); |
- asyncEnd(); |
- }); |
-} |
- |
-void testClosedError() { |
- asyncStart(); |
- RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) { |
- server.listen((socket) { |
- socket.close(); |
- }); |
- var socket = |
- RawSynchronousSocket.connectSync(LOOPBACK_IP_V4_STRING, server.port); |
- server.close(); |
- socket.closeSync(); |
- Expect.throws(() => socket.remotePort, (e) => e is SocketException); |
- Expect.throws(() => socket.remoteAddress, (e) => e is SocketException); |
- asyncEnd(); |
- }); |
-} |
- |
-main() async { |
- asyncStart(); |
- testArguments(); |
- // testInvalidConnect(); Long timeout for bad lookups, so disable for bots. |
- await testShutdown(); |
- testSimpleConnect(); |
- testServerListenAfterConnect(); |
- await testSimpleReadWrite(); |
- await testPartialRead(); |
- await testPartialWrite(); |
- testInvalidReadWriteOperations(); |
- testClosedError(); |
- asyncEnd(); |
-} |