| OLD | NEW | 
 | (Empty) | 
|    1 // Copyright (c) 2012, 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 // VMOptions= |  | 
|    6 // VMOptions=--short_socket_read |  | 
|    7 // VMOptions=--short_socket_write |  | 
|    8 // VMOptions=--short_socket_read --short_socket_write |  | 
|    9 // |  | 
|   10 // Test socket close events. |  | 
|   11  |  | 
|   12 #import("dart:io"); |  | 
|   13 #import("dart:isolate"); |  | 
|   14  |  | 
|   15 final SERVERSHUTDOWN = -1; |  | 
|   16 final ITERATIONS = 10; |  | 
|   17  |  | 
|   18  |  | 
|   19 class SocketClose { |  | 
|   20  |  | 
|   21   SocketClose.start(this._mode, this._donePort) |  | 
|   22       : _receivePort = new ReceivePort(), |  | 
|   23         _sendPort = null, |  | 
|   24         _readBytes = 0, |  | 
|   25         _dataEvents = 0, |  | 
|   26         _closeEvents = 0, |  | 
|   27         _errorEvents = 0, |  | 
|   28         _iterations = 0 { |  | 
|   29     new SocketCloseServer().spawn().then((SendPort port) { |  | 
|   30       _sendPort = port; |  | 
|   31       start(); |  | 
|   32     }); |  | 
|   33   } |  | 
|   34  |  | 
|   35   void proceed() { |  | 
|   36     if (_iterations < ITERATIONS) { |  | 
|   37       new Timer(0, sendData); |  | 
|   38     } else { |  | 
|   39       shutdown(); |  | 
|   40     } |  | 
|   41   } |  | 
|   42  |  | 
|   43   void sendData(Timer timer) { |  | 
|   44  |  | 
|   45     void dataHandler() { |  | 
|   46       switch (_mode) { |  | 
|   47         case 0: |  | 
|   48         case 1: |  | 
|   49         case 2: |  | 
|   50           Expect.fail("No data expected"); |  | 
|   51           break; |  | 
|   52         case 3: |  | 
|   53         case 4: |  | 
|   54         case 5: |  | 
|   55         case 6: |  | 
|   56           List<int> b = new List<int>(5); |  | 
|   57           _readBytes += _socket.readList(b, 0, 5); |  | 
|   58           if ((_readBytes % 5) == 0) { |  | 
|   59             _dataEvents++; |  | 
|   60           } |  | 
|   61           break; |  | 
|   62         default: |  | 
|   63           Expect.fail("Unknown test mode"); |  | 
|   64       } |  | 
|   65     } |  | 
|   66  |  | 
|   67     void closeHandler() { |  | 
|   68       _closeEvents++; |  | 
|   69       switch (_mode) { |  | 
|   70         case 0: |  | 
|   71         case 1: |  | 
|   72           Expect.fail("No close expected"); |  | 
|   73           break; |  | 
|   74         case 2: |  | 
|   75         case 3: |  | 
|   76           _socket.close(); |  | 
|   77           proceed(); |  | 
|   78           break; |  | 
|   79         case 4: |  | 
|   80           proceed(); |  | 
|   81           break; |  | 
|   82         case 5: |  | 
|   83           _socket.close(); |  | 
|   84           proceed(); |  | 
|   85           break; |  | 
|   86         case 6: |  | 
|   87           proceed(); |  | 
|   88           break; |  | 
|   89         default: |  | 
|   90           Expect.fail("Unknown test mode"); |  | 
|   91       } |  | 
|   92     } |  | 
|   93  |  | 
|   94     void errorHandler(Exception e) { |  | 
|   95       _errorEvents++; |  | 
|   96       _socket.close(); |  | 
|   97     } |  | 
|   98  |  | 
|   99     void connectHandler() { |  | 
|  100       _socket.onData = dataHandler; |  | 
|  101       _socket.onClosed = closeHandler; |  | 
|  102       _socket.onError = errorHandler; |  | 
|  103  |  | 
|  104       void writeHello() { |  | 
|  105         int bytesWritten = 0; |  | 
|  106         while (bytesWritten != 5) { |  | 
|  107           bytesWritten += _socket.writeList("Hello".charCodes(), |  | 
|  108                                             bytesWritten, |  | 
|  109                                             5 - bytesWritten); |  | 
|  110         } |  | 
|  111       } |  | 
|  112  |  | 
|  113       _iterations++; |  | 
|  114       switch (_mode) { |  | 
|  115         case 0: |  | 
|  116           _socket.close(); |  | 
|  117           proceed(); |  | 
|  118           break; |  | 
|  119         case 1: |  | 
|  120           writeHello(); |  | 
|  121           _socket.close(); |  | 
|  122           proceed(); |  | 
|  123           break; |  | 
|  124         case 2: |  | 
|  125         case 3: |  | 
|  126           writeHello(); |  | 
|  127           break; |  | 
|  128         case 4: |  | 
|  129           writeHello(); |  | 
|  130           _socket.close(true); |  | 
|  131           break; |  | 
|  132         case 5: |  | 
|  133           writeHello(); |  | 
|  134           break; |  | 
|  135         case 6: |  | 
|  136           writeHello(); |  | 
|  137           _socket.close(true); |  | 
|  138           break; |  | 
|  139         default: |  | 
|  140           Expect.fail("Unknown test mode"); |  | 
|  141       } |  | 
|  142     } |  | 
|  143  |  | 
|  144     _socket = new Socket(SocketCloseServer.HOST, _port); |  | 
|  145     Expect.equals(true, _socket !== null); |  | 
|  146     _socket.onConnect = connectHandler; |  | 
|  147   } |  | 
|  148  |  | 
|  149   void start() { |  | 
|  150     _receivePort.receive((var message, SendPort replyTo) { |  | 
|  151       _port = message; |  | 
|  152       proceed(); |  | 
|  153     }); |  | 
|  154     _sendPort.send(_mode, _receivePort.toSendPort()); |  | 
|  155   } |  | 
|  156  |  | 
|  157   void shutdown() { |  | 
|  158     _sendPort.send(SERVERSHUTDOWN, _receivePort.toSendPort()); |  | 
|  159     _receivePort.receive((message, ignore) { |  | 
|  160       _donePort.send(null); |  | 
|  161       _receivePort.close(); |  | 
|  162     }); |  | 
|  163  |  | 
|  164     switch (_mode) { |  | 
|  165       case 0: |  | 
|  166       case 1: |  | 
|  167         Expect.equals(0, _dataEvents); |  | 
|  168         Expect.equals(0, _closeEvents); |  | 
|  169         break; |  | 
|  170       case 2: |  | 
|  171         Expect.equals(0, _dataEvents); |  | 
|  172         Expect.equals(ITERATIONS, _closeEvents); |  | 
|  173         break; |  | 
|  174       case 3: |  | 
|  175       case 4: |  | 
|  176       case 5: |  | 
|  177       case 6: |  | 
|  178         Expect.equals(ITERATIONS, _dataEvents); |  | 
|  179         Expect.equals(ITERATIONS, _closeEvents); |  | 
|  180         break; |  | 
|  181       default: |  | 
|  182         Expect.fail("Unknown test mode"); |  | 
|  183     } |  | 
|  184     Expect.equals(0, _errorEvents); |  | 
|  185   } |  | 
|  186  |  | 
|  187   int _port; |  | 
|  188   ReceivePort _receivePort; |  | 
|  189   SendPort _sendPort; |  | 
|  190   Socket _socket; |  | 
|  191   List<int> _buffer; |  | 
|  192   int _readBytes; |  | 
|  193   int _dataEvents; |  | 
|  194   int _closeEvents; |  | 
|  195   int _errorEvents; |  | 
|  196   int _iterations; |  | 
|  197   int _mode; |  | 
|  198   SendPort _donePort; |  | 
|  199 } |  | 
|  200  |  | 
|  201  |  | 
|  202 class ConnectionData { |  | 
|  203   ConnectionData(Socket this.connection) : readBytes = 0; |  | 
|  204   Socket connection; |  | 
|  205   int readBytes; |  | 
|  206 } |  | 
|  207  |  | 
|  208  |  | 
|  209 class SocketCloseServer extends Isolate { |  | 
|  210  |  | 
|  211   static final HOST = "127.0.0.1"; |  | 
|  212  |  | 
|  213   SocketCloseServer() : super() {} |  | 
|  214  |  | 
|  215   void main() { |  | 
|  216  |  | 
|  217     void connectionHandler(ConnectionData data) { |  | 
|  218       var connection = data.connection; |  | 
|  219  |  | 
|  220       void readBytes(whenFiveBytes) { |  | 
|  221         List<int> b = new List<int>(5); |  | 
|  222         data.readBytes += connection.readList(b, 0, 5); |  | 
|  223         if (data.readBytes == 5) { |  | 
|  224           whenFiveBytes(); |  | 
|  225         } |  | 
|  226       } |  | 
|  227  |  | 
|  228       void writeHello() { |  | 
|  229         int bytesWritten = 0; |  | 
|  230         while (bytesWritten != 5) { |  | 
|  231           bytesWritten += connection.writeList("Hello".charCodes(), |  | 
|  232                                                bytesWritten, |  | 
|  233                                                5 - bytesWritten); |  | 
|  234         } |  | 
|  235       } |  | 
|  236  |  | 
|  237       void dataHandler() { |  | 
|  238         switch (_mode) { |  | 
|  239           case 0: |  | 
|  240             Expect.fail("No data expected"); |  | 
|  241             break; |  | 
|  242           case 1: |  | 
|  243             readBytes(() { _dataEvents++; }); |  | 
|  244             break; |  | 
|  245           case 2: |  | 
|  246             readBytes(() { |  | 
|  247               _dataEvents++; |  | 
|  248               connection.close(); |  | 
|  249             }); |  | 
|  250             break; |  | 
|  251           case 3: |  | 
|  252             readBytes(() { |  | 
|  253               _dataEvents++; |  | 
|  254               writeHello(); |  | 
|  255               connection.close(); |  | 
|  256             }); |  | 
|  257             break; |  | 
|  258           case 4: |  | 
|  259             readBytes(() { |  | 
|  260               _dataEvents++; |  | 
|  261               writeHello(); |  | 
|  262             }); |  | 
|  263             break; |  | 
|  264           case 5: |  | 
|  265           case 6: |  | 
|  266             readBytes(() { |  | 
|  267               _dataEvents++; |  | 
|  268               writeHello(); |  | 
|  269               connection.close(true); |  | 
|  270             }); |  | 
|  271             break; |  | 
|  272           default: |  | 
|  273             Expect.fail("Unknown test mode"); |  | 
|  274         } |  | 
|  275       } |  | 
|  276  |  | 
|  277       void closeHandler() { |  | 
|  278         _closeEvents++; |  | 
|  279         connection.close(); |  | 
|  280       } |  | 
|  281  |  | 
|  282       void errorHandler(Exception e) { |  | 
|  283         Expect.fail("Socket error $e"); |  | 
|  284       } |  | 
|  285  |  | 
|  286       _iterations++; |  | 
|  287  |  | 
|  288       connection.onData = dataHandler; |  | 
|  289       connection.onClosed = closeHandler; |  | 
|  290       connection.onError = errorHandler; |  | 
|  291     } |  | 
|  292  |  | 
|  293     void errorHandlerServer(Exception e) { |  | 
|  294       Expect.fail("Server socket error"); |  | 
|  295     } |  | 
|  296  |  | 
|  297     waitForResult(Timer timer) { |  | 
|  298       // Make sure all iterations have been run. In multiple of these |  | 
|  299       // scenarios it is possible to get the SERVERSHUTDOWN message |  | 
|  300       // before we have received the last close event on the |  | 
|  301       // server. In these cases we wait for the correct number of |  | 
|  302       // close events. |  | 
|  303       if (_iterations == ITERATIONS && |  | 
|  304           (_closeEvents == ITERATIONS || (_mode == 2 || _mode == 3))) { |  | 
|  305         switch (_mode) { |  | 
|  306           case 0: |  | 
|  307             Expect.equals(0, _dataEvents); |  | 
|  308             Expect.equals(ITERATIONS, _closeEvents); |  | 
|  309             break; |  | 
|  310           case 1: |  | 
|  311             Expect.equals(ITERATIONS, _dataEvents); |  | 
|  312             Expect.equals(ITERATIONS, _closeEvents); |  | 
|  313             break; |  | 
|  314           case 2: |  | 
|  315           case 3: |  | 
|  316             Expect.equals(ITERATIONS, _dataEvents); |  | 
|  317             Expect.equals(0, _closeEvents); |  | 
|  318             break; |  | 
|  319           case 4: |  | 
|  320           case 5: |  | 
|  321           case 6: |  | 
|  322             Expect.equals(ITERATIONS, _dataEvents); |  | 
|  323             Expect.equals(ITERATIONS, _closeEvents); |  | 
|  324             break; |  | 
|  325           default: |  | 
|  326             Expect.fail("Unknown test mode"); |  | 
|  327         } |  | 
|  328         Expect.equals(0, _errorEvents); |  | 
|  329         _server.close(); |  | 
|  330         this.port.close(); |  | 
|  331         _donePort.send(null); |  | 
|  332       } else { |  | 
|  333         new Timer(100, waitForResult); |  | 
|  334       } |  | 
|  335     } |  | 
|  336  |  | 
|  337     this.port.receive((message, SendPort replyTo) { |  | 
|  338       _donePort = replyTo; |  | 
|  339       if (message != SERVERSHUTDOWN) { |  | 
|  340         _readBytes = 0; |  | 
|  341         _errorEvents = 0; |  | 
|  342         _dataEvents = 0; |  | 
|  343         _closeEvents = 0; |  | 
|  344         _iterations = 0; |  | 
|  345         _mode = message; |  | 
|  346         _server = new ServerSocket(HOST, 0, 10); |  | 
|  347         Expect.equals(true, _server !== null); |  | 
|  348         _server.onConnection = (connection) { |  | 
|  349           var data = new ConnectionData(connection); |  | 
|  350           connectionHandler(data); |  | 
|  351         }; |  | 
|  352         _server.onError = errorHandlerServer; |  | 
|  353         replyTo.send(_server.port, null); |  | 
|  354       } else { |  | 
|  355         new Timer(0, waitForResult); |  | 
|  356       } |  | 
|  357     }); |  | 
|  358   } |  | 
|  359  |  | 
|  360   ServerSocket _server; |  | 
|  361   SendPort _donePort; |  | 
|  362   int _readBytes; |  | 
|  363   int _errorEvents; |  | 
|  364   int _dataEvents; |  | 
|  365   int _closeEvents; |  | 
|  366   int _iterations; |  | 
|  367   int _mode; |  | 
|  368 } |  | 
|  369  |  | 
|  370  |  | 
|  371 main() { |  | 
|  372   // Run the close test in these different "modes". |  | 
|  373   // 0: Client closes without sending at all. |  | 
|  374   // 1: Client sends and closes. |  | 
|  375   // 2: Client sends. Server closes. |  | 
|  376   // 3: Client sends. Server responds and closes. |  | 
|  377   // 4: Client sends and half-closes. Server responds and closes. |  | 
|  378   // 5: Client sends. Server responds and half closes. |  | 
|  379   // 6: Client sends and half-closes. Server responds and half closes. |  | 
|  380   var tests = 7; |  | 
|  381   var port = new ReceivePort(); |  | 
|  382   var completed = 0; |  | 
|  383   port.receive((message, ignore) { |  | 
|  384     if (++completed == tests) port.close(); |  | 
|  385   }); |  | 
|  386   for (var i = 0; i < tests; i++) { |  | 
|  387     new SocketClose.start(i, port.toSendPort()); |  | 
|  388   } |  | 
|  389 } |  | 
| OLD | NEW |