| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file | 
|  | 2 // for details. All rights reserved. Use of this source code is governed by a | 
|  | 3 // BSD-style license that can be found in the LICENSE file. | 
|  | 4 | 
|  | 5 import "dart:async"; | 
|  | 6 import "dart:io"; | 
|  | 7 import "dart:isolate"; | 
|  | 8 import "dart:math"; | 
|  | 9 | 
|  | 10 import "package:async_helper/async_helper.dart"; | 
|  | 11 import "package:expect/expect.dart"; | 
|  | 12 | 
|  | 13 const String LOOPBACK_IP_V4_STRING = "127.0.0.1"; | 
|  | 14 | 
|  | 15 void testArguments() { | 
|  | 16   Expect.throws(() => RawSynchronousSocket.connectSync(null, 0)); | 
|  | 17   Expect.throws( | 
|  | 18       () => RawSynchronousSocket.connectSync(LOOPBACK_IP_V4_STRING, null)); | 
|  | 19   Expect.throws( | 
|  | 20       () => RawSynchronousSocket.connectSync(LOOPBACK_IP_V4_STRING, 65536)); | 
|  | 21   Expect.throws( | 
|  | 22       () => RawSynchronousSocket.connectSync(LOOPBACK_IP_V4_STRING, -1)); | 
|  | 23   Expect.throws(() => | 
|  | 24       RawSynchronousSocket.connectSync(LOOPBACK_IP_V4_STRING, 0, backlog: -1)); | 
|  | 25 } | 
|  | 26 | 
|  | 27 /* | 
|  | 28 void testInvalidConnect() { | 
|  | 29   // Connect to an unknown DNS name. | 
|  | 30   try { | 
|  | 31     var socket = RawSynchronousSocket.connectSync("ko.faar.__hest__", 0); | 
|  | 32     Expect.fail("Failure expected"); | 
|  | 33   } catch (e) { | 
|  | 34     Expect.isTrue(e is SocketException); | 
|  | 35   } | 
|  | 36 | 
|  | 37   // Connect to an unavaliable IP-address. | 
|  | 38   try { | 
|  | 39     var socket = RawSynchronousSocket.connectSync("1.2.3.4", 0); | 
|  | 40     Expect.fail("Failure expected"); | 
|  | 41   } catch (e) { | 
|  | 42     Expect.isTrue(e is SocketException); | 
|  | 43   } | 
|  | 44   ; | 
|  | 45 } | 
|  | 46 */ | 
|  | 47 | 
|  | 48 void testSimpleConnect() { | 
|  | 49   asyncStart(); | 
|  | 50   RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) { | 
|  | 51     var socket = | 
|  | 52         RawSynchronousSocket.connectSync(LOOPBACK_IP_V4_STRING, server.port); | 
|  | 53     server.listen((serverSocket) { | 
|  | 54       Expect.equals(socket.address, serverSocket.remoteAddress); | 
|  | 55       Expect.equals(socket.port, serverSocket.remotePort); | 
|  | 56       Expect.equals(socket.remoteAddress, server.address); | 
|  | 57       Expect.equals(socket.remotePort, server.port); | 
|  | 58       socket.closeSync(); | 
|  | 59       server.close(); | 
|  | 60       asyncEnd(); | 
|  | 61     }); | 
|  | 62   }); | 
|  | 63 } | 
|  | 64 | 
|  | 65 void testServerListenAfterConnect() { | 
|  | 66   asyncStart(); | 
|  | 67   RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) { | 
|  | 68     Expect.isTrue(server.port > 0); | 
|  | 69     var client = | 
|  | 70         RawSynchronousSocket.connectSync(LOOPBACK_IP_V4_STRING, server.port); | 
|  | 71     server.listen((socket) { | 
|  | 72       client.closeSync(); | 
|  | 73       server.close(); | 
|  | 74       socket.close(); | 
|  | 75       asyncEnd(); | 
|  | 76     }); | 
|  | 77   }); | 
|  | 78 } | 
|  | 79 | 
|  | 80 const messageSize = 1000; | 
|  | 81 // Configuration fields for the EchoServer. | 
|  | 82 enum EchoServerTypes { | 
|  | 83   // Max accumulated connections to server before close. Defaults to 1. | 
|  | 84   CONNECTION_COUNT, | 
|  | 85   // Sets the range of the fields to check in the list generated by | 
|  | 86   // createTestData(). | 
|  | 87   OFFSET_END, | 
|  | 88   OFFSET_START, | 
|  | 89   // The port used to communicate with an isolate. | 
|  | 90   ISOLATE_SEND_PORT, | 
|  | 91   // The port of the newly created echo server. | 
|  | 92   SERVER_PORT | 
|  | 93 } | 
|  | 94 | 
|  | 95 List<int> createTestData() { | 
|  | 96   return new List<int>.generate(messageSize, (index) => index & 0xff); | 
|  | 97 } | 
|  | 98 | 
|  | 99 // Consumes data generated by a test and compares it against the original test | 
|  | 100 // data. The optional fields, start and end, are used to compare against | 
|  | 101 // segments of the original test data list. In other words, data.length == (end | 
|  | 102 // - start). | 
|  | 103 void verifyTestData(List<int> data, [int start = 0, int end]) { | 
|  | 104   assert(data != null); | 
|  | 105   List<int> expected = createTestData(); | 
|  | 106   if (end == null) { | 
|  | 107     end = data.length; | 
|  | 108   } | 
|  | 109   end = min(messageSize, end); | 
|  | 110   Expect.equals(end - start, data.length); | 
|  | 111   for (int i = 0; i < (end - start); i++) { | 
|  | 112     Expect.equals(expected[start + i], data[i]); | 
|  | 113   } | 
|  | 114 } | 
|  | 115 | 
|  | 116 // The echo server is spawned in a new isolate and is used to test various | 
|  | 117 // synchronous read/write operations by echoing any data received back to the | 
|  | 118 // sender. The server should shutdown automatically after a specified number of | 
|  | 119 // socket disconnections (default: 1). | 
|  | 120 Future echoServer(var sendPort) async { | 
|  | 121   RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) async { | 
|  | 122     ReceivePort receivePort = new ReceivePort(); | 
|  | 123     Map response = { | 
|  | 124       EchoServerTypes.ISOLATE_SEND_PORT: receivePort.sendPort, | 
|  | 125       EchoServerTypes.SERVER_PORT: server.port | 
|  | 126     }; | 
|  | 127     sendPort.send(response); | 
|  | 128     Map limits = await receivePort.first; | 
|  | 129     int start = limits[EchoServerTypes.OFFSET_START]; | 
|  | 130     int end = limits[EchoServerTypes.OFFSET_END]; | 
|  | 131     int length = end - start; | 
|  | 132     int connection_count = limits[EchoServerTypes.CONNECTION_COUNT] ?? 1; | 
|  | 133     int connections = 0; | 
|  | 134     sendPort = limits[EchoServerTypes.ISOLATE_SEND_PORT]; | 
|  | 135     server.listen((client) { | 
|  | 136       int bytesRead = 0; | 
|  | 137       int bytesWritten = 0; | 
|  | 138       bool closedEventReceived = false; | 
|  | 139       List<int> data = new List<int>(length); | 
|  | 140       client.writeEventsEnabled = false; | 
|  | 141       client.listen((event) { | 
|  | 142         switch (event) { | 
|  | 143           case RawSocketEvent.READ: | 
|  | 144             Expect.isTrue(bytesWritten == 0); | 
|  | 145             Expect.isTrue(client.available() > 0); | 
|  | 146             var buffer = client.read(client.available()); | 
|  | 147             data.setRange(bytesRead, bytesRead + buffer.length, buffer); | 
|  | 148             bytesRead += buffer.length; | 
|  | 149             // Once we've read all the data, we can echo it back. Otherwise, | 
|  | 150             // keep waiting for more bytes. | 
|  | 151             if (bytesRead >= length) { | 
|  | 152               verifyTestData(data, start, end); | 
|  | 153               client.writeEventsEnabled = true; | 
|  | 154             } | 
|  | 155             break; | 
|  | 156           case RawSocketEvent.WRITE: | 
|  | 157             Expect.isFalse(client.writeEventsEnabled); | 
|  | 158             bytesWritten += | 
|  | 159                 client.write(data, bytesWritten, data.length - bytesWritten); | 
|  | 160             if (bytesWritten < length) { | 
|  | 161               client.writeEventsEnabled = true; | 
|  | 162             } else if (bytesWritten == length) { | 
|  | 163               // Close the socket for writing from the server since we're done | 
|  | 164               // writing to this socket. The connection is closed completely | 
|  | 165               // after the client closes the socket for reading from the server. | 
|  | 166               client.shutdown(SocketDirection.SEND); | 
|  | 167             } | 
|  | 168             break; | 
|  | 169           case RawSocketEvent.READ_CLOSED: | 
|  | 170             client.close(); | 
|  | 171             break; | 
|  | 172           case RawSocketEvent.CLOSED: | 
|  | 173             Expect.isFalse(closedEventReceived); | 
|  | 174             closedEventReceived = true; | 
|  | 175             break; | 
|  | 176           default: | 
|  | 177             throw "Unexpected event $event"; | 
|  | 178         } | 
|  | 179       }, onDone: () { | 
|  | 180         Expect.isTrue(closedEventReceived); | 
|  | 181         connections++; | 
|  | 182         if (connections >= connection_count) { | 
|  | 183           server.close(); | 
|  | 184         } | 
|  | 185       }); | 
|  | 186     }, onDone: () { | 
|  | 187       // Let the client know we're shutting down then kill the isolate. | 
|  | 188       sendPort.send(null); | 
|  | 189       kill(); | 
|  | 190     }); | 
|  | 191   }); | 
|  | 192 } | 
|  | 193 | 
|  | 194 Future testSimpleReadWrite({bool dropReads}) async { | 
|  | 195   asyncStart(); | 
|  | 196   // This test creates a server and a client connects. The client writes data | 
|  | 197   // to the socket and the server echos it back. The client confirms the data it | 
|  | 198   // reads is the same as the data sent, then closes the socket, resulting in | 
|  | 199   // the closing of the server, which responds on receivePort with null to | 
|  | 200   // specify the echo server isolate is about to be killed. If an error occurs | 
|  | 201   // in the echo server, the exception and stack trace are sent to receivePort, | 
|  | 202   // which prints the exception and stack trace before eventually throwing an | 
|  | 203   // error. | 
|  | 204   ReceivePort receivePort = new ReceivePort(); | 
|  | 205   Isolate echo = await Isolate.spawn(echoServer, receivePort.sendPort); | 
|  | 206 | 
|  | 207   Map response = await receivePort.first; | 
|  | 208   SendPort sendPort = response[EchoServerTypes.ISOLATE_SEND_PORT]; | 
|  | 209   int serverInternetPort = response[EchoServerTypes.SERVER_PORT]; | 
|  | 210 | 
|  | 211   receivePort = new ReceivePort(); | 
|  | 212   echo.addErrorListener(receivePort.sendPort); | 
|  | 213 | 
|  | 214   Map limits = { | 
|  | 215     EchoServerTypes.OFFSET_START: 0, | 
|  | 216     EchoServerTypes.OFFSET_END: messageSize, | 
|  | 217     EchoServerTypes.ISOLATE_SEND_PORT: receivePort.sendPort | 
|  | 218   }; | 
|  | 219   sendPort.send(limits); | 
|  | 220 | 
|  | 221   try { | 
|  | 222     var socket = RawSynchronousSocket.connectSync( | 
|  | 223         LOOPBACK_IP_V4_STRING, serverInternetPort); | 
|  | 224     List<int> data = createTestData(); | 
|  | 225     socket.writeFromSync(data); | 
|  | 226     List<int> result = socket.readSync(data.length); | 
|  | 227     verifyTestData(result); | 
|  | 228     socket.shutdown(SocketDirection.SEND); | 
|  | 229     socket.closeSync(); | 
|  | 230   } catch (e, stack) { | 
|  | 231     print("Echo test failed in the client"); | 
|  | 232     rethrow; | 
|  | 233   } | 
|  | 234   // Wait for the server to shutdown before finishing the test. | 
|  | 235   var result = await receivePort.first; | 
|  | 236   if (result != null) { | 
|  | 237     throw "Echo test failed in server!\nError: ${result[0]}\nStack trace:" + | 
|  | 238         " ${result[1]}"; | 
|  | 239   } | 
|  | 240   asyncEnd(); | 
|  | 241 } | 
|  | 242 | 
|  | 243 Future testPartialRead() async { | 
|  | 244   asyncStart(); | 
|  | 245   // This test is based on testSimpleReadWrite, but instead of reading the | 
|  | 246   // entire echoed message at once, it reads it in two calls to readIntoSync. | 
|  | 247   ReceivePort receivePort = new ReceivePort(); | 
|  | 248   Isolate echo = await Isolate.spawn(echoServer, receivePort.sendPort); | 
|  | 249 | 
|  | 250   Map response = await receivePort.first; | 
|  | 251   SendPort sendPort = response[EchoServerTypes.ISOLATE_SEND_PORT]; | 
|  | 252   int serverInternetPort = response[EchoServerTypes.SERVER_PORT]; | 
|  | 253   List<int> data = createTestData(); | 
|  | 254 | 
|  | 255   receivePort = new ReceivePort(); | 
|  | 256   echo.addErrorListener(receivePort.sendPort); | 
|  | 257 | 
|  | 258   Map limits = { | 
|  | 259     EchoServerTypes.OFFSET_START: 0, | 
|  | 260     EchoServerTypes.OFFSET_END: 1000, | 
|  | 261     EchoServerTypes.ISOLATE_SEND_PORT: receivePort.sendPort | 
|  | 262   }; | 
|  | 263   sendPort.send(limits); | 
|  | 264 | 
|  | 265   try { | 
|  | 266     var socket = RawSynchronousSocket.connectSync( | 
|  | 267         LOOPBACK_IP_V4_STRING, serverInternetPort); | 
|  | 268     int half_length = (data.length / 2).toInt(); | 
|  | 269 | 
|  | 270     // Send the full data list to the server. | 
|  | 271     socket.writeFromSync(data); | 
|  | 272     List<int> result = new List<int>(data.length); | 
|  | 273 | 
|  | 274     // Read half at a time and check that there's still more bytes available. | 
|  | 275     socket.readIntoSync(result, 0, half_length); | 
|  | 276     verifyTestData(result.sublist(0, half_length), 0, half_length); | 
|  | 277     Expect.isTrue(socket.available() == (data.length - half_length)); | 
|  | 278 | 
|  | 279     // Read the second half and verify again. | 
|  | 280     socket.readIntoSync(result, half_length); | 
|  | 281     verifyTestData(result); | 
|  | 282     Expect.isTrue(socket.available() == 0); | 
|  | 283 | 
|  | 284     socket.closeSync(); | 
|  | 285   } catch (e, stack) { | 
|  | 286     print("Echo test failed in the client."); | 
|  | 287     rethrow; | 
|  | 288   } | 
|  | 289   // Wait for the server to shutdown before finishing the test. | 
|  | 290   var result = await receivePort.first; | 
|  | 291   if (result != null) { | 
|  | 292     throw "Echo test failed in server!\nError: ${result[0]}\nStack trace:" + | 
|  | 293         " ${result[1]}"; | 
|  | 294   } | 
|  | 295   asyncEnd(); | 
|  | 296 } | 
|  | 297 | 
|  | 298 Future testPartialWrite() async { | 
|  | 299   asyncStart(); | 
|  | 300   // This test is based on testSimpleReadWrite, but instead of writing the | 
|  | 301   // entire data buffer at once, it writes different parts of the buffer over | 
|  | 302   // multiple calls to writeFromSync. | 
|  | 303   ReceivePort receivePort = new ReceivePort(); | 
|  | 304   Isolate echo = await Isolate.spawn(echoServer, receivePort.sendPort); | 
|  | 305 | 
|  | 306   Map response = await receivePort.first; | 
|  | 307   List<int> data = createTestData(); | 
|  | 308   SendPort sendPort = response[EchoServerTypes.ISOLATE_SEND_PORT]; | 
|  | 309   int startOffset = 32; | 
|  | 310   int endOffset = (data.length / 2).toInt(); | 
|  | 311   int serverInternetPort = response[EchoServerTypes.SERVER_PORT]; | 
|  | 312 | 
|  | 313   receivePort = new ReceivePort(); | 
|  | 314   echo.addErrorListener(receivePort.sendPort); | 
|  | 315 | 
|  | 316   Map limits = { | 
|  | 317     EchoServerTypes.OFFSET_START: startOffset, | 
|  | 318     EchoServerTypes.OFFSET_END: endOffset, | 
|  | 319     EchoServerTypes.ISOLATE_SEND_PORT: receivePort.sendPort | 
|  | 320   }; | 
|  | 321   sendPort.send(limits); | 
|  | 322   try { | 
|  | 323     var socket = RawSynchronousSocket.connectSync( | 
|  | 324         LOOPBACK_IP_V4_STRING, serverInternetPort); | 
|  | 325     List<int> data = createTestData(); | 
|  | 326 | 
|  | 327     // Write a subset of data to the server. | 
|  | 328     socket.writeFromSync(data, startOffset, endOffset); | 
|  | 329 | 
|  | 330     // Grab the response and verify it's correct. | 
|  | 331     List<int> result = new List<int>(endOffset - startOffset); | 
|  | 332     socket.readIntoSync(result); | 
|  | 333 | 
|  | 334     Expect.equals(result.length, endOffset - startOffset); | 
|  | 335     verifyTestData(result, startOffset, endOffset); | 
|  | 336     socket.closeSync(); | 
|  | 337   } catch (e, stack) { | 
|  | 338     print("Echo test failed in the client."); | 
|  | 339     rethrow; | 
|  | 340   } | 
|  | 341 | 
|  | 342   // Wait for the server to shutdown before finishing the test. | 
|  | 343   var result = await receivePort.first; | 
|  | 344   if (result != null) { | 
|  | 345     throw "Echo test failed in server!\nError: ${result[0]}\nStack trace:" + | 
|  | 346         " ${result[1]}"; | 
|  | 347   } | 
|  | 348   asyncEnd(); | 
|  | 349 } | 
|  | 350 | 
|  | 351 Future testShutdown() async { | 
|  | 352   asyncStart(); | 
|  | 353   // This test creates a server and a client connects. The client then tries to | 
|  | 354   // perform various operations after being shutdown in a specific direction, to | 
|  | 355   // ensure reads or writes cannot be performed if the socket has been shutdown | 
|  | 356   // for reading or writing. | 
|  | 357   ReceivePort receivePort = new ReceivePort(); | 
|  | 358   Isolate echo = await Isolate.spawn(echoServer, receivePort.sendPort); | 
|  | 359 | 
|  | 360   Map response = await receivePort.first; | 
|  | 361   SendPort sendPort = response[EchoServerTypes.ISOLATE_SEND_PORT]; | 
|  | 362   int serverInternetPort = response[EchoServerTypes.SERVER_PORT]; | 
|  | 363   List<int> data = createTestData(); | 
|  | 364 | 
|  | 365   receivePort = new ReceivePort(); | 
|  | 366   echo.addErrorListener(receivePort.sendPort); | 
|  | 367 | 
|  | 368   Map limits = { | 
|  | 369     EchoServerTypes.OFFSET_START: 0, | 
|  | 370     EchoServerTypes.OFFSET_END: data.length, | 
|  | 371     EchoServerTypes.ISOLATE_SEND_PORT: receivePort.sendPort, | 
|  | 372     // Tell the server to shutdown after 3 sockets disconnect. | 
|  | 373     EchoServerTypes.CONNECTION_COUNT: 3 | 
|  | 374   }; | 
|  | 375   sendPort.send(limits); | 
|  | 376 | 
|  | 377   try { | 
|  | 378     var socket = RawSynchronousSocket.connectSync( | 
|  | 379         LOOPBACK_IP_V4_STRING, serverInternetPort); | 
|  | 380 | 
|  | 381     // Close from both directions. Shouldn't be able to read/write to the | 
|  | 382     // socket. | 
|  | 383     socket.shutdown(SocketDirection.BOTH); | 
|  | 384     Expect.throws( | 
|  | 385         () => socket.writeFromSync(data), (e) => e is SocketException); | 
|  | 386     Expect.throws( | 
|  | 387         () => socket.readSync(data.length), (e) => e is SocketException); | 
|  | 388     socket.closeSync(); | 
|  | 389 | 
|  | 390     // Close the socket for reading, do a write, and see if we can get any | 
|  | 391     // response from the server (we shouldn't be able to). | 
|  | 392     socket = RawSynchronousSocket.connectSync( | 
|  | 393         LOOPBACK_IP_V4_STRING, serverInternetPort); | 
|  | 394     socket.shutdown(SocketDirection.RECEIVE); | 
|  | 395     socket.writeFromSync(data); | 
|  | 396     // Throws exception when the socket is closed for RECEIVE. | 
|  | 397     Expect.throws( | 
|  | 398         () => socket.readSync(data.length), (e) => e is SocketException); | 
|  | 399     Expect.isTrue(socket.available() == 0); | 
|  | 400     socket.closeSync(); | 
|  | 401 | 
|  | 402     // Close the socket for writing and try to do a write. This should cause an | 
|  | 403     // OSError to be throw as the pipe is closed for writing. | 
|  | 404     socket = RawSynchronousSocket.connectSync( | 
|  | 405         LOOPBACK_IP_V4_STRING, serverInternetPort); | 
|  | 406     socket.shutdown(SocketDirection.SEND); | 
|  | 407     Expect.throws( | 
|  | 408         () => socket.writeFromSync(data), (e) => e is SocketException); | 
|  | 409     socket.closeSync(); | 
|  | 410   } catch (e, stack) { | 
|  | 411     print("Echo test failed in client."); | 
|  | 412     rethrow; | 
|  | 413   } | 
|  | 414   // Wait for the server to shutdown before finishing the test. | 
|  | 415   var result = await receivePort.first; | 
|  | 416   if (result != null) { | 
|  | 417     throw "Echo test failed in server!\nError: ${result[0]}\nStack trace:" + | 
|  | 418         " ${result[1]}"; | 
|  | 419   } | 
|  | 420   asyncEnd(); | 
|  | 421 } | 
|  | 422 | 
|  | 423 Future testInvalidReadWriteOperations() { | 
|  | 424   asyncStart(); | 
|  | 425   RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) { | 
|  | 426     server.listen((socket) {}); | 
|  | 427     List<int> data = createTestData(); | 
|  | 428     var socket = | 
|  | 429         RawSynchronousSocket.connectSync(LOOPBACK_IP_V4_STRING, server.port); | 
|  | 430 | 
|  | 431     // Invalid writeFromSync invocations | 
|  | 432     Expect.throws(() => socket.writeFromSync(data, data.length + 1), | 
|  | 433         (e) => e is RangeError); | 
|  | 434     Expect.throws(() => socket.writeFromSync(data, 0, data.length + 1), | 
|  | 435         (e) => e is RangeError); | 
|  | 436     Expect.throws( | 
|  | 437         () => socket.writeFromSync(data, 1, 0), (e) => e is RangeError); | 
|  | 438     Expect.throws( | 
|  | 439         () => socket.writeFromSync(data, null), (e) => e is ArgumentError); | 
|  | 440 | 
|  | 441     // Invalid readIntoSync invocations | 
|  | 442     List<int> buffer = new List<int>(10); | 
|  | 443     Expect.throws(() => socket.readIntoSync(buffer, buffer.length + 1), | 
|  | 444         (e) => e is RangeError); | 
|  | 445     Expect.throws(() => socket.readIntoSync(buffer, 0, buffer.length + 1), | 
|  | 446         (e) => e is RangeError); | 
|  | 447     Expect.throws( | 
|  | 448         () => socket.readIntoSync(buffer, 1, 0), (e) => e is RangeError); | 
|  | 449     Expect.throws( | 
|  | 450         () => socket.readIntoSync(buffer, null), (e) => e is ArgumentError); | 
|  | 451 | 
|  | 452     // Invalid readSync invocation | 
|  | 453     Expect.throws(() => socket.readSync(-1), (e) => e is ArgumentError); | 
|  | 454 | 
|  | 455     server.close(); | 
|  | 456     socket.closeSync(); | 
|  | 457     asyncEnd(); | 
|  | 458   }); | 
|  | 459 } | 
|  | 460 | 
|  | 461 void testClosedError() { | 
|  | 462   asyncStart(); | 
|  | 463   RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) { | 
|  | 464     server.listen((socket) { | 
|  | 465       socket.close(); | 
|  | 466     }); | 
|  | 467     var socket = | 
|  | 468         RawSynchronousSocket.connectSync(LOOPBACK_IP_V4_STRING, server.port); | 
|  | 469     server.close(); | 
|  | 470     socket.closeSync(); | 
|  | 471     Expect.throws(() => socket.remotePort, (e) => e is SocketException); | 
|  | 472     Expect.throws(() => socket.remoteAddress, (e) => e is SocketException); | 
|  | 473     asyncEnd(); | 
|  | 474   }); | 
|  | 475 } | 
|  | 476 | 
|  | 477 main() async { | 
|  | 478   asyncStart(); | 
|  | 479   testArguments(); | 
|  | 480   // testInvalidConnect(); Long timeout for bad lookups, so disable for bots. | 
|  | 481   await testShutdown(); | 
|  | 482   testSimpleConnect(); | 
|  | 483   testServerListenAfterConnect(); | 
|  | 484   await testSimpleReadWrite(); | 
|  | 485   await testPartialRead(); | 
|  | 486   await testPartialWrite(); | 
|  | 487   testInvalidReadWriteOperations(); | 
|  | 488   testClosedError(); | 
|  | 489   asyncEnd(); | 
|  | 490 } | 
| OLD | NEW | 
|---|