| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 // | 4 // |
| 5 // VMOptions= | 5 // VMOptions= |
| 6 // VMOptions=--short_socket_read | 6 // VMOptions=--short_socket_read |
| 7 // VMOptions=--short_socket_write | 7 // VMOptions=--short_socket_write |
| 8 // VMOptions=--short_socket_read --short_socket_write | 8 // VMOptions=--short_socket_read --short_socket_write |
| 9 // | 9 // |
| 10 // Test socket close events. | 10 // Test socket close events. |
| 11 | 11 |
| 12 #import("dart:io"); | 12 #import("dart:io"); |
| 13 #import("dart:isolate"); | 13 #import("dart:isolate"); |
| 14 | 14 |
| 15 final SERVERSHUTDOWN = -1; | 15 final SERVERSHUTDOWN = -1; |
| 16 final ITERATIONS = 10; | 16 final ITERATIONS = 10; |
| 17 | 17 |
| 18 | 18 |
| 19 class SocketClose { | 19 class SocketClose { |
| 20 | 20 |
| 21 SocketClose.start(this._mode, this._donePort) | 21 SocketClose.start(this._mode, this._donePort) |
| 22 : _receivePort = new ReceivePort(), | 22 : _receivePort = new ReceivePort(), |
| 23 _sendPort = null, | 23 _sendPort = null, |
| 24 _readBytes = 0, | 24 _readBytes = 0, |
| 25 _dataEvents = 0, | 25 _dataEvents = 0, |
| 26 _closeEvents = 0, | 26 _closeEvents = 0, |
| 27 _errorEvents = 0, | 27 _errorEvents = 0, |
| 28 _iterations = 0 { | 28 _iterations = 0 { |
| 29 new SocketCloseServer().spawn().then((SendPort port) { | 29 _sendPort = spawnFunction(startSocketCloseServer); |
| 30 _sendPort = port; | 30 start(); |
| 31 start(); | |
| 32 }); | |
| 33 } | 31 } |
| 34 | 32 |
| 35 void proceed() { | 33 void proceed() { |
| 36 if (_iterations < ITERATIONS) { | 34 if (_iterations < ITERATIONS) { |
| 37 new Timer(0, sendData); | 35 new Timer(0, sendData); |
| 38 } else { | 36 } else { |
| 39 shutdown(); | 37 shutdown(); |
| 40 } | 38 } |
| 41 } | 39 } |
| 42 | 40 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 } | 206 } |
| 209 | 207 |
| 210 | 208 |
| 211 class ConnectionData { | 209 class ConnectionData { |
| 212 ConnectionData(Socket this.connection) : readBytes = 0; | 210 ConnectionData(Socket this.connection) : readBytes = 0; |
| 213 Socket connection; | 211 Socket connection; |
| 214 int readBytes; | 212 int readBytes; |
| 215 } | 213 } |
| 216 | 214 |
| 217 | 215 |
| 218 class SocketCloseServer extends Isolate { | 216 void startSocketCloseServer() { |
| 217 var server = new SocketCloseServer(); |
| 218 port.receive(server.dispatch); |
| 219 } |
| 220 |
| 221 |
| 222 class SocketCloseServer { |
| 219 | 223 |
| 220 static final HOST = "127.0.0.1"; | 224 static final HOST = "127.0.0.1"; |
| 221 | 225 |
| 222 SocketCloseServer() : super() {} | 226 SocketCloseServer() : super() {} |
| 223 | 227 |
| 224 void main() { | 228 void connectionHandler(ConnectionData data) { |
| 229 var connection = data.connection; |
| 225 | 230 |
| 226 void connectionHandler(ConnectionData data) { | 231 void readBytes(whenFiveBytes) { |
| 227 var connection = data.connection; | 232 var read = connection.inputStream.read(); |
| 228 | 233 data.readBytes += read.length; |
| 229 void readBytes(whenFiveBytes) { | 234 if (data.readBytes == 5) { |
| 230 var read = connection.inputStream.read(); | 235 whenFiveBytes(); |
| 231 data.readBytes += read.length; | |
| 232 if (data.readBytes == 5) { | |
| 233 whenFiveBytes(); | |
| 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(() { | |
| 244 _dataEvents++; | |
| 245 }); | |
| 246 break; | |
| 247 case 2: | |
| 248 readBytes(() { | |
| 249 _dataEvents++; | |
| 250 connection.inputStream.close(); | |
| 251 }); | |
| 252 break; | |
| 253 case 3: | |
| 254 readBytes(() { | |
| 255 _dataEvents++; | |
| 256 connection.outputStream.write("Hello".charCodes()); | |
| 257 connection.outputStream.onNoPendingWrites = () { | |
| 258 connection.inputStream.close(); | |
| 259 }; | |
| 260 }); | |
| 261 break; | |
| 262 case 4: | |
| 263 readBytes(() { | |
| 264 _dataEvents++; | |
| 265 connection.outputStream.write("Hello".charCodes()); | |
| 266 connection.inputStream.close(); | |
| 267 }); | |
| 268 break; | |
| 269 case 5: | |
| 270 readBytes(() { | |
| 271 _dataEvents++; | |
| 272 connection.outputStream.write("Hello".charCodes()); | |
| 273 }); | |
| 274 break; | |
| 275 case 6: | |
| 276 case 7: | |
| 277 readBytes(() { | |
| 278 _dataEvents++; | |
| 279 connection.outputStream.write("Hello".charCodes()); | |
| 280 connection.outputStream.onNoPendingWrites = () { | |
| 281 connection.outputStream.close(); | |
| 282 }; | |
| 283 }); | |
| 284 break; | |
| 285 case 8: | |
| 286 readBytes(() { | |
| 287 _dataEvents++; | |
| 288 connection.outputStream.write("Hello".charCodes()); | |
| 289 connection.outputStream.close(); | |
| 290 }); | |
| 291 break; | |
| 292 default: | |
| 293 Expect.fail("Unknown test mode"); | |
| 294 } | |
| 295 } | |
| 296 | |
| 297 void closeHandler() { | |
| 298 _closeEvents++; | |
| 299 connection.outputStream.close(); | |
| 300 } | |
| 301 | |
| 302 void errorHandler(Exception e) { | |
| 303 Expect.fail("Socket error $e"); | |
| 304 } | |
| 305 | |
| 306 _iterations++; | |
| 307 | |
| 308 connection.inputStream.onData = dataHandler; | |
| 309 connection.inputStream.onClosed = closeHandler; | |
| 310 connection.onError = errorHandler; | |
| 311 } | |
| 312 | |
| 313 void errorHandlerServer(Exception e) { | |
| 314 Expect.fail("Server socket error"); | |
| 315 } | |
| 316 | |
| 317 waitForResult(Timer timer) { | |
| 318 // Make sure all iterations have been run. In multiple of these | |
| 319 // scenarios it is possible to get the SERVERSHUTDOWN message | |
| 320 // before we have received the last close event on the | |
| 321 // server. In these cases we wait for the correct number of | |
| 322 // close events. | |
| 323 if (_iterations == ITERATIONS && | |
| 324 (_closeEvents == ITERATIONS || | |
| 325 (_mode == 2 || _mode == 3 || _mode == 4))) { | |
| 326 switch (_mode) { | |
| 327 case 0: | |
| 328 Expect.equals(0, _dataEvents); | |
| 329 Expect.equals(ITERATIONS, _closeEvents); | |
| 330 break; | |
| 331 case 1: | |
| 332 Expect.equals(ITERATIONS, _dataEvents); | |
| 333 Expect.equals(ITERATIONS, _closeEvents); | |
| 334 break; | |
| 335 case 2: | |
| 336 case 3: | |
| 337 case 4: | |
| 338 Expect.equals(ITERATIONS, _dataEvents); | |
| 339 Expect.equals(0, _closeEvents); | |
| 340 break; | |
| 341 case 5: | |
| 342 case 6: | |
| 343 case 7: | |
| 344 case 8: | |
| 345 Expect.equals(ITERATIONS, _dataEvents); | |
| 346 Expect.equals(ITERATIONS, _closeEvents); | |
| 347 break; | |
| 348 default: | |
| 349 Expect.fail("Unknown test mode"); | |
| 350 } | |
| 351 Expect.equals(0, _errorEvents); | |
| 352 _server.close(); | |
| 353 this.port.close(); | |
| 354 _donePort.send(null); | |
| 355 } else { | |
| 356 new Timer(100, waitForResult); | |
| 357 } | 236 } |
| 358 } | 237 } |
| 359 | 238 |
| 360 this.port.receive((message, SendPort replyTo) { | 239 void dataHandler() { |
| 361 _donePort = replyTo; | 240 switch (_mode) { |
| 362 if (message != SERVERSHUTDOWN) { | 241 case 0: |
| 363 _readBytes = 0; | 242 Expect.fail("No data expected"); |
| 364 _errorEvents = 0; | 243 break; |
| 365 _dataEvents = 0; | 244 case 1: |
| 366 _closeEvents = 0; | 245 readBytes(() { |
| 367 _iterations = 0; | 246 _dataEvents++; |
| 368 _mode = message; | 247 }); |
| 369 _server = new ServerSocket(HOST, 0, 10); | 248 break; |
| 370 Expect.equals(true, _server !== null); | 249 case 2: |
| 371 _server.onConnection = (connection) { | 250 readBytes(() { |
| 372 var data = new ConnectionData(connection); | 251 _dataEvents++; |
| 373 connectionHandler(data); | 252 connection.inputStream.close(); |
| 374 }; | 253 }); |
| 375 _server.onError = errorHandlerServer; | 254 break; |
| 376 replyTo.send(_server.port, null); | 255 case 3: |
| 377 } else { | 256 readBytes(() { |
| 378 new Timer(0, waitForResult); | 257 _dataEvents++; |
| 258 connection.outputStream.write("Hello".charCodes()); |
| 259 connection.outputStream.onNoPendingWrites = () { |
| 260 connection.inputStream.close(); |
| 261 }; |
| 262 }); |
| 263 break; |
| 264 case 4: |
| 265 readBytes(() { |
| 266 _dataEvents++; |
| 267 connection.outputStream.write("Hello".charCodes()); |
| 268 connection.inputStream.close(); |
| 269 }); |
| 270 break; |
| 271 case 5: |
| 272 readBytes(() { |
| 273 _dataEvents++; |
| 274 connection.outputStream.write("Hello".charCodes()); |
| 275 }); |
| 276 break; |
| 277 case 6: |
| 278 case 7: |
| 279 readBytes(() { |
| 280 _dataEvents++; |
| 281 connection.outputStream.write("Hello".charCodes()); |
| 282 connection.outputStream.onNoPendingWrites = () { |
| 283 connection.outputStream.close(); |
| 284 }; |
| 285 }); |
| 286 break; |
| 287 case 8: |
| 288 readBytes(() { |
| 289 _dataEvents++; |
| 290 connection.outputStream.write("Hello".charCodes()); |
| 291 connection.outputStream.close(); |
| 292 }); |
| 293 break; |
| 294 default: |
| 295 Expect.fail("Unknown test mode"); |
| 379 } | 296 } |
| 380 }); | 297 } |
| 298 |
| 299 void closeHandler() { |
| 300 _closeEvents++; |
| 301 connection.outputStream.close(); |
| 302 } |
| 303 |
| 304 void errorHandler(Exception e) { |
| 305 Expect.fail("Socket error $e"); |
| 306 } |
| 307 |
| 308 _iterations++; |
| 309 |
| 310 connection.inputStream.onData = dataHandler; |
| 311 connection.inputStream.onClosed = closeHandler; |
| 312 connection.onError = errorHandler; |
| 313 } |
| 314 |
| 315 void errorHandlerServer(Exception e) { |
| 316 Expect.fail("Server socket error"); |
| 317 } |
| 318 |
| 319 waitForResult(Timer timer) { |
| 320 // Make sure all iterations have been run. In multiple of these |
| 321 // scenarios it is possible to get the SERVERSHUTDOWN message |
| 322 // before we have received the last close event on the |
| 323 // server. In these cases we wait for the correct number of |
| 324 // close events. |
| 325 if (_iterations == ITERATIONS && |
| 326 (_closeEvents == ITERATIONS || |
| 327 (_mode == 2 || _mode == 3 || _mode == 4))) { |
| 328 switch (_mode) { |
| 329 case 0: |
| 330 Expect.equals(0, _dataEvents); |
| 331 Expect.equals(ITERATIONS, _closeEvents); |
| 332 break; |
| 333 case 1: |
| 334 Expect.equals(ITERATIONS, _dataEvents); |
| 335 Expect.equals(ITERATIONS, _closeEvents); |
| 336 break; |
| 337 case 2: |
| 338 case 3: |
| 339 case 4: |
| 340 Expect.equals(ITERATIONS, _dataEvents); |
| 341 Expect.equals(0, _closeEvents); |
| 342 break; |
| 343 case 5: |
| 344 case 6: |
| 345 case 7: |
| 346 case 8: |
| 347 Expect.equals(ITERATIONS, _dataEvents); |
| 348 Expect.equals(ITERATIONS, _closeEvents); |
| 349 break; |
| 350 default: |
| 351 Expect.fail("Unknown test mode"); |
| 352 } |
| 353 Expect.equals(0, _errorEvents); |
| 354 _server.close(); |
| 355 port.close(); |
| 356 _donePort.send(null); |
| 357 } else { |
| 358 new Timer(100, waitForResult); |
| 359 } |
| 360 } |
| 361 |
| 362 void dispatch(message, replyTo) { |
| 363 _donePort = replyTo; |
| 364 if (message != SERVERSHUTDOWN) { |
| 365 _readBytes = 0; |
| 366 _errorEvents = 0; |
| 367 _dataEvents = 0; |
| 368 _closeEvents = 0; |
| 369 _iterations = 0; |
| 370 _mode = message; |
| 371 _server = new ServerSocket(HOST, 0, 10); |
| 372 Expect.equals(true, _server !== null); |
| 373 _server.onConnection = (connection) { |
| 374 var data = new ConnectionData(connection); |
| 375 connectionHandler(data); |
| 376 }; |
| 377 _server.onError = errorHandlerServer; |
| 378 replyTo.send(_server.port, null); |
| 379 } else { |
| 380 new Timer(0, waitForResult); |
| 381 } |
| 381 } | 382 } |
| 382 | 383 |
| 383 ServerSocket _server; | 384 ServerSocket _server; |
| 384 SendPort _donePort; | 385 SendPort _donePort; |
| 385 int _readBytes; | 386 int _readBytes; |
| 386 int _errorEvents; | 387 int _errorEvents; |
| 387 int _dataEvents; | 388 int _dataEvents; |
| 388 int _closeEvents; | 389 int _closeEvents; |
| 389 int _iterations; | 390 int _iterations; |
| 390 int _mode; | 391 int _mode; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 407 var tests = 9; | 408 var tests = 9; |
| 408 var port = new ReceivePort(); | 409 var port = new ReceivePort(); |
| 409 var completed = 0; | 410 var completed = 0; |
| 410 port.receive((message, ignore) { | 411 port.receive((message, ignore) { |
| 411 if (++completed == tests) port.close(); | 412 if (++completed == tests) port.close(); |
| 412 }); | 413 }); |
| 413 for (var i = 0; i < tests; i++) { | 414 for (var i = 0; i < tests; i++) { |
| 414 new SocketClose.start(i, port.toSendPort()); | 415 new SocketClose.start(i, port.toSendPort()); |
| 415 } | 416 } |
| 416 } | 417 } |
| OLD | NEW |