| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 import 'dart:io'; | 10 import 'dart:io'; |
| 11 import 'dart:isolate'; | 11 import 'dart:isolate'; |
| 12 import 'dart:convert'; | 12 import 'dart:convert'; |
| 13 import 'package:expect/expect.dart'; | 13 import 'package:expect/expect.dart'; |
| 14 import '../chat_server_lib.dart'; | 14 import '../chat_server_lib.dart'; |
| 15 | 15 |
| 16 // Message to start chat test client running in an isolate. | 16 // Message to start chat test client running in an isolate. |
| 17 class ChatTestClientStart { | 17 class ChatTestClientStart { |
| 18 ChatTestClientStart(int this.totalClients, | 18 ChatTestClientStart(int this.totalClients, |
| 19 int this.messagesToSend, | 19 int this.messagesToSend, |
| 20 int this.messagesToReceive, | 20 int this.messagesToReceive, |
| 21 int this.port); | 21 int this.port); |
| 22 | 22 |
| 23 int totalClients; | 23 int totalClients; |
| 24 int messagesToSend; | 24 int messagesToSend; |
| 25 int messagesToReceive; | 25 int messagesToReceive; |
| 26 int port; | 26 int port; |
| 27 } | 27 } |
| 28 | 28 |
| 29 Future<SendPort> spawnChatTestClient() { |
| 30 var response = new ReceivePort(); |
| 31 return Isolate.spawn(startChatTestClient, response.sendPort) |
| 32 .then((remoteIsolate) => response.first) |
| 33 .whenComplete(() { response.close(); }); // Make sure the port is closed. |
| 34 } |
| 29 | 35 |
| 30 void startChatTestClient() { | 36 void startChatTestClient(SendPort replyTo) { |
| 31 var client = new ChatTestClient(); | 37 var client = new ChatTestClient(); |
| 32 port.receive(client.dispatch); | 38 replyTo.send(client.dispatchSendPort); |
| 33 } | 39 } |
| 34 | 40 |
| 35 | 41 |
| 36 // Chat server test client for running in a separate isolate. When | 42 // Chat server test client for running in a separate isolate. When |
| 37 // this test client is started it will join the chat topic, send a | 43 // this test client is started it will join the chat topic, send a |
| 38 // number of messages, receive the expected number of messages and | 44 // number of messages, receive the expected number of messages and |
| 39 // leave the topic. | 45 // leave the topic. |
| 40 class ChatTestClient { | 46 class ChatTestClient { |
| 47 ReceivePort _dispatchReceivePort; // Port that is linked to dispatch. |
| 41 SendPort statusPort; // Port to reply to when test has finished. | 48 SendPort statusPort; // Port to reply to when test has finished. |
| 42 HttpClient httpClient; // HTTP client connection factory. | 49 HttpClient httpClient; // HTTP client connection factory. |
| 43 | 50 |
| 44 int totalClients; // Total number of clients in the test. | 51 int totalClients; // Total number of clients in the test. |
| 45 int messagesToSend; // Number of messages to send. | 52 int messagesToSend; // Number of messages to send. |
| 46 int messagesToReceive; // Numbe rof messages expected to be received. | 53 int messagesToReceive; // Numbe rof messages expected to be received. |
| 47 int port; // TCP/IP port for server. | 54 int port; // TCP/IP port for server. |
| 48 | 55 |
| 49 String sessionId; // Session id when connected. | 56 String sessionId; // Session id when connected. |
| 50 int sendMessageNumber; // Number of messages sent. | 57 int sendMessageNumber; // Number of messages sent. |
| 51 int joinCount; | 58 int joinCount; |
| 52 int messageCount; | 59 int messageCount; |
| 53 int receiveMessageNumber; // Number of messages received. | 60 int receiveMessageNumber; // Number of messages received. |
| 54 | 61 |
| 62 ChatTestClient() : _dispatchReceivePort = new ReceivePort() { |
| 63 _dispatchReceivePort.listen(dispatch); |
| 64 } |
| 65 |
| 66 SendPort get dispatchSendPort => _dispatchReceivePort.sendPort; |
| 67 |
| 68 void close() { |
| 69 _dispatchReceivePort.close(); |
| 70 } |
| 71 |
| 55 void leave() { | 72 void leave() { |
| 56 void leaveResponseHandler(response, String data) { | 73 void leaveResponseHandler(response, String data) { |
| 57 Expect.equals(HttpStatus.OK, response.statusCode); | 74 Expect.equals(HttpStatus.OK, response.statusCode); |
| 58 var responseData = JSON.decode(data); | 75 var responseData = JSON.decode(data); |
| 59 Expect.equals("leave", responseData["response"]); | 76 Expect.equals("leave", responseData["response"]); |
| 60 | 77 |
| 61 // Test done. | 78 // Test done. |
| 62 statusPort.send("Test succeeded", null); | 79 statusPort.send("Test succeeded"); |
| 80 close(); |
| 63 } | 81 } |
| 64 | 82 |
| 65 Map leaveRequest = new Map(); | 83 Map leaveRequest = new Map(); |
| 66 leaveRequest["request"] = "leave"; | 84 leaveRequest["request"] = "leave"; |
| 67 leaveRequest["sessionId"] = sessionId; | 85 leaveRequest["sessionId"] = sessionId; |
| 68 httpClient.post("127.0.0.1", port, "/leave") | 86 httpClient.post("127.0.0.1", port, "/leave") |
| 69 .then((HttpClientRequest request) { | 87 .then((HttpClientRequest request) { |
| 70 request.write(JSON.encode(leaveRequest)); | 88 request.write(JSON.encode(leaveRequest)); |
| 71 return request.close(); | 89 return request.close(); |
| 72 }) | 90 }) |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 return request.close(); | 206 return request.close(); |
| 189 }) | 207 }) |
| 190 .then((HttpClientResponse response) { | 208 .then((HttpClientResponse response) { |
| 191 StringBuffer body = new StringBuffer(); | 209 StringBuffer body = new StringBuffer(); |
| 192 response.listen( | 210 response.listen( |
| 193 (data) => body.write(new String.fromCharCodes(data)), | 211 (data) => body.write(new String.fromCharCodes(data)), |
| 194 onDone: () => joinResponseHandler(response, body.toString())); | 212 onDone: () => joinResponseHandler(response, body.toString())); |
| 195 }); | 213 }); |
| 196 } | 214 } |
| 197 | 215 |
| 198 void dispatch(message, replyTo) { | 216 void dispatch(message) { |
| 199 totalClients = message.totalClients; | 217 var chatMessage = message[0]; |
| 200 messagesToSend = message.messagesToSend; | 218 var replyTo = message[1]; |
| 201 messagesToReceive = message.messagesToReceive; | 219 totalClients = chatMessage.totalClients; |
| 202 port = message.port; | 220 messagesToSend = chatMessage.messagesToSend; |
| 221 messagesToReceive = chatMessage.messagesToReceive; |
| 222 port = chatMessage.port; |
| 203 statusPort = replyTo; | 223 statusPort = replyTo; |
| 204 | 224 |
| 205 // Create a HTTP client factory. | 225 // Create a HTTP client factory. |
| 206 httpClient = new HttpClient(); | 226 httpClient = new HttpClient(); |
| 207 | 227 |
| 208 // Start the client by joining the chat topic. | 228 // Start the client by joining the chat topic. |
| 209 join(); | 229 join(); |
| 210 } | 230 } |
| 211 } | 231 } |
| 212 | 232 |
| 213 | 233 |
| 214 class TestMain { | 234 class TestMain { |
| 215 TestMain.run(int this.clientCount, int this.messageCount) | 235 TestMain.run(int this.clientCount, int this.messageCount) |
| 216 : serverStatusPort = new ReceivePort(), | 236 : serverStatusPort = new ReceivePort(), |
| 217 serverPort = null, | 237 serverPort = null, |
| 218 finishedClients = 0 { | 238 finishedClients = 0 { |
| 219 serverPort = spawnFunction(startChatServer); | 239 spawnChatServer().then((serverPort) { |
| 220 start(); | 240 this.serverPort = serverPort; |
| 241 start(); |
| 242 }); |
| 221 } | 243 } |
| 222 | 244 |
| 223 void start() { | 245 void start() { |
| 224 // Handle status messages from the server. | 246 // Handle status messages from the server. |
| 225 serverStatusPort.receive( | 247 serverStatusPort.listen((var message) { |
| 226 (var message, SendPort replyTo) { | |
| 227 if (message.isStarted) { | 248 if (message.isStarted) { |
| 228 // When the server is started start all test clients. | 249 // When the server is started start all test clients. |
| 229 for (int i = 0; i < clientCount; i++) { | 250 for (int i = 0; i < clientCount; i++) { |
| 230 ChatTestClientStart command = | 251 ChatTestClientStart command = |
| 231 new ChatTestClientStart(clientCount, | 252 new ChatTestClientStart(clientCount, |
| 232 messageCount, | 253 messageCount, |
| 233 messageCount * this.clientCount, | 254 messageCount * this.clientCount, |
| 234 message.port); | 255 message.port); |
| 235 clientPorts[i].send(command, clientStatusPorts[i].toSendPort()); | 256 clientPorts[i].send([command, clientStatusPorts[i].sendPort]); |
| 236 } | 257 } |
| 237 } else if (message.isError) { | 258 } else if (message.isError) { |
| 238 print("Could not start server - probably error \"Address already in
use\" from bind."); | 259 print("Could not start server - probably error \"Address already in
use\" from bind."); |
| 239 serverStatusPort.close(); | 260 serverStatusPort.close(); |
| 240 } | 261 } |
| 241 }); | 262 }); |
| 242 | 263 |
| 243 // Prepare the requested number of clients. | 264 // Prepare the requested number of clients. |
| 244 clientPorts = new List<SendPort>(clientCount); | 265 clientPorts = new List<SendPort>(clientCount); |
| 245 int liveClientsCount = 0; | 266 int liveClientsCount = 0; |
| 246 clientStatusPorts = new List<ReceivePort>(clientCount); | 267 clientStatusPorts = new List<ReceivePort>(clientCount); |
| 247 for (int i = 0; i < clientCount; i++) { | 268 for (int i = 0; i < clientCount; i++) { |
| 248 ReceivePort statusPort = new ReceivePort(); | 269 ReceivePort statusPort = new ReceivePort(); |
| 249 statusPort.receive((var message, SendPort replyTo) { | 270 statusPort.listen((var message) { |
| 250 // First and only message from the client indicates that | 271 // First and only message from the client indicates that |
| 251 // the test is done. | 272 // the test is done. |
| 252 Expect.equals("Test succeeded", message); | 273 Expect.equals("Test succeeded", message); |
| 253 statusPort.close(); | 274 statusPort.close(); |
| 254 finishedClients++; | 275 finishedClients++; |
| 255 | 276 |
| 256 // If all clients are finished shutdown the server. | 277 // If all clients are finished shutdown the server. |
| 257 if (finishedClients == clientCount) { | 278 if (finishedClients == clientCount) { |
| 258 // Send server stop message to the server. | 279 // Send server stop message to the server. |
| 259 serverPort.send(new ChatServerCommand.stop(), | 280 serverPort.send([new ChatServerCommand.stop(), |
| 260 serverStatusPort.toSendPort()); | 281 serverStatusPort.sendPort]); |
| 261 | 282 |
| 262 // Close the last port to terminate the test. | 283 // Close the last port to terminate the test. |
| 263 serverStatusPort.close(); | 284 serverStatusPort.close(); |
| 264 } | 285 } |
| 265 }); | 286 }); |
| 266 | 287 |
| 267 clientStatusPorts[i] = statusPort; | 288 clientStatusPorts[i] = statusPort; |
| 268 clientPorts[i] = spawnFunction(startChatTestClient); | 289 spawnChatTestClient().then((clientPort) { |
| 269 liveClientsCount++; | 290 clientPorts[i] = clientPort; |
| 270 if (liveClientsCount == clientCount) { | 291 liveClientsCount++; |
| 271 // Once all clients are running send server start message to | 292 if (liveClientsCount == clientCount) { |
| 272 // the server. Use port 0 for an ephemeral port. The actual | 293 // Once all clients are running send server start message to |
| 273 // port will be returned with the server started | 294 // the server. Use port 0 for an ephemeral port. The actual |
| 274 // message. Use a backlog equal to the client count to avoid | 295 // port will be returned with the server started |
| 275 // connection issues. | 296 // message. Use a backlog equal to the client count to avoid |
| 276 serverPort.send(new ChatServerCommand.start("127.0.0.1", 0), | 297 // connection issues. |
| 277 serverStatusPort.toSendPort()); | 298 serverPort.send([new ChatServerCommand.start("127.0.0.1", 0), |
| 278 } | 299 serverStatusPort.sendPort]); |
| 300 } |
| 301 }); |
| 279 } | 302 } |
| 280 } | 303 } |
| 281 | 304 |
| 282 int clientCount; // Number of clients to run. | 305 int clientCount; // Number of clients to run. |
| 283 int messageCount; // Number of messages per clients to send. | 306 int messageCount; // Number of messages per clients to send. |
| 284 int finishedClients; // Number of clients finished. | 307 int finishedClients; // Number of clients finished. |
| 285 | 308 |
| 286 // Ports for communicating with the server. | 309 // Ports for communicating with the server. |
| 287 SendPort serverPort; | 310 SendPort serverPort; |
| 288 ReceivePort serverStatusPort; | 311 ReceivePort serverStatusPort; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 311 TestMain testMain = new TestMain.run(10, 2); | 334 TestMain testMain = new TestMain.run(10, 2); |
| 312 } | 335 } |
| 313 | 336 |
| 314 | 337 |
| 315 void main() { | 338 void main() { |
| 316 testOneClient(); | 339 testOneClient(); |
| 317 testTwoClients(); | 340 testTwoClients(); |
| 318 testTwoClientsMoreMessages(); | 341 testTwoClientsMoreMessages(); |
| 319 testTenClients(); | 342 testTenClients(); |
| 320 } | 343 } |
| OLD | NEW |