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 |