Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(203)

Side by Side Diff: tests/standalone/src/io/HttpServerSocketTest.dart

Issue 9963048: Add test for testing Socket close/error while sending response to HttpClient from HttpServer. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/standalone/standalone.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 #import("dart:io");
6 #import("dart:isolate");
7
8 class ExpectedDataOutputStream implements OutputStream {
9 ExpectedDataOutputStream(List<int> this._data,
10 int this._cutoff,
11 bool this._closeAsError,
12 SocketImpl this._socket);
13
14 void set onNoPendingWrites(void callback()) {
15 _onNoPendingWrites = callback;
16 }
17
18 bool write(List data, [bool copyBuffer = true]) {
19 _onData(data);
20 return true;
21 }
22
23 bool writeFrom(List data, [int offset = 0, int len]) {
24 if (len === null) len = data.length - offset;
25 _onData(data.getRange(offset, len));
26 return true;
27 }
28
29 void close() {
30 _socket.close(true);
31 }
32
33 void _onData(List<int> data) {
34 // TODO(ajohnsen): To be removed, since the socket should not be written to
35 // after close.
36 if (_socket._closed) return;
37 Expect.isFalse(_written > _cutoff);
38 Expect.listEquals(data, _data.getRange(0, data.length));
39 _data = _data.getRange(data.length, _data.length - data.length);
40 _written += data.length;
41 if (_written >= _cutoff) {
42 // Tell HttpServer that the socket have closed.
43 _socket._closeInternal(_closeAsError);
44 }
45 }
46
47 Function _onNoPendingWrites;
48 List<int> _data;
49 int _written = 0;
50 int _cutoff;
51 bool _closeAsError;
52 SocketImpl _socket;
53 }
54
55 class SocketMock implements Socket {
56 SocketMock(List<int> this._data,
57 List<int> expected,
58 int cutoff,
59 bool closeAsError) :
60 _hashCode = (Math.random() * (1 << 32)).toInt(),
61 _read = [] {
62 _outputStream =
63 new ExpectedDataOutputStream(expected, cutoff, closeAsError, this);
64 }
65
66 int available() {
67 return _data.length;
68 }
69
70 void _closeInternal([bool asError = false]) {
71 Expect.isFalse(_closed);
72 _closed = true;
73 _onClosedInternal();
74 if (asError) {
75 _onError(new Exception("Socket closed unexpected"));
76 } else {
77 _onClosed();
78 }
79 }
80
81 int readList(List<int> buffer, int offset, int count) {
82 int max = Math.min(count, _data.length);
83 buffer.setRange(offset, max, _data);
84 _data = _data.getRange(max, _data.length - max);
85 return max;
86 }
87
88 void close([bool halfClose = false]) {
89 if (!halfClose && !_closed) _closeInternal();
90 }
91
92 void set onData(void callback()) {
93 _onData = callback;
94 }
95
96 void set onClosed(void callback()) {
97 _onClosed = callback;
98 }
99
100 void set onError(void callback(Exception error)) {
101 _onError = callback;
102 }
103
104 OutputStream get outputStream() => _outputStream;
105
106 int hashCode() => _hashCode;
107
108 List<int> _read;
109 bool _closed = false;
110 int _hashCode;
111 Function _onData;
112 Function _onClosed;
113 Function _onError;
114 Function _onClosedInternal;
115 List<int> _data;
116 ExpectedDataOutputStream _outputStream;
117 }
118
119 class ServerSocketMock implements ServerSocket {
120 ServerSocketMock(String addr, int this._port, int backlog) :
121 _sockets = new Set<Socket>();
122
123 void spawnSocket(var data, String response, int cutOff, bool closeAsError) {
124 if (data is String) data = data.charCodes();
125 SocketMock socket = new SocketMock(data,
126 response.charCodes(),
127 cutOff,
128 closeAsError);
129 _sockets.add(socket);
130 ReceivePort port = new ReceivePort();
131 socket._onClosedInternal = () {
132 // The server should always close the connection.
133 _sockets.remove(socket);
134 port.close();
135 };
136 // Tell HttpServer that a connection have come to life.
137 _onConnection(socket);
138 // Start 'sending' data.
139 socket._onData();
140 }
141
142 void close() {
143 Expect.fail("Don't close the connection, we attach to this socket");
144 }
145
146 void set onConnection(void callback(Socket connection)) {
147 _onConnection = callback;
148 }
149
150 void set onError(void callback()) {
151 _onError = callback;
152 }
153
154 int get port() => _port;
155
156 int _port;
157 Function _onConnection;
158 Function _onError;
159 Set<Socket> _sockets;
160 }
161
162 void testSocketClose() {
163 ServerSocketMock serverSocket = new ServerSocketMock("0.0.0.0", 5432, 5);
164
165 HttpServer server = new HttpServer();
166 server.listenOn(serverSocket);
167 void testContent(String request,
168 String response,
169 [int okayFrom = 0,
170 bool expectError = true]) {
171 // Inner callback to actually run a given setting.
172 void runSettings(int cutoff,
173 bool closeAsError,
174 bool expectError) {
175 server.onRequest = (HttpRequest request, HttpResponse response) {
176 request.inputStream.onData = () {
177 };
178 request.inputStream.onClosed = () {
179 response.outputStream.close();
180 };
181 };
182
183 if (expectError) {
184 ReceivePort port = new ReceivePort();
185 server.onError = (Exception error) {
186 port.close();
187 };
188 } else {
189 server.onError = (Exception error) {
190 Expect.fail("An error was not expected: $error");
191 };
192 }
193
194 serverSocket.spawnSocket(request, response, cutoff, closeAsError);
195 // TODO(ajohnsen): Validate HttpServers number of connections.
196 }
197 for (int i = 1; i < response.length; i++) {
198 bool _expectError = expectError && i < response.length - okayFrom;
199 runSettings(i, false, _expectError);
200 runSettings(i, true, _expectError);
201 }
202 }
203 testContent(
204 "GET / HTTP/1.1\r\nKeep-Alive: False\r\n\r\n",
205 "HTTP/1.1 200 OK\r\ntransfer-encoding: chunked\r\nconnection: close" +
206 "\r\n\r\n0\r\n\r\n");
207
208 server.close();
209 }
210
211 void main() {
212 testSocketClose();
213 }
OLDNEW
« no previous file with comments | « no previous file | tests/standalone/standalone.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698