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

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 SocketImpl implements Socket {
Søren Gjesse 2012/04/02 10:26:29 Maybe call this ScoketMock. Same for ServerSocketI
Anders Johnsen 2012/04/02 10:40:31 Done.
56 SocketImpl(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) _onError(new Exception("Socket closed unexpected"));
Søren Gjesse 2012/04/02 10:26:29 Please format with {}s
Anders Johnsen 2012/04/02 10:40:31 Done.
75 else _onClosed();
76 }
77
78 int readList(List<int> buffer, int offset, int count) {
79 int max = Math.min(count, _data.length);
80 buffer.setRange(offset, max, _data);
81 _data = _data.getRange(max, _data.length - max);
82 return max;
83 }
84
Søren Gjesse 2012/04/02 10:26:29 Maybe add an implementation of writeList which thr
Anders Johnsen 2012/04/02 10:40:31 There's quite a few methods that I have not implem
85 void close([bool halfClose = false]) {
86 if (!halfClose && !_closed) _closeInternal();
87 }
88
89 void set onData(void callback()) {
90 _onData = callback;
91 }
92
93 void set onClosed(void callback()) {
94 _onClosed = callback;
95 }
96
97 void set onError(void callback(Exception error)) {
98 _onError = callback;
99 }
100
101 OutputStream get outputStream() => _outputStream;
102
103 int hashCode() => _hashCode;
104
105 List<int> _read;
106 bool _closed = false;
107 int _hashCode;
108 Function _onData;
109 Function _onClosed;
110 Function _onError;
111 Function _onClosedInternal;
112 List<int> _data;
113 ExpectedDataOutputStream _outputStream;
114 }
115
116 class ServerSocketImpl implements ServerSocket {
117 ServerSocketImpl(String addr, int this._port, int backlog) :
118 _sockets = new Set<Socket>();
119
120 void spawnSocket(var data, String response, int cutOff, bool closeAsError) {
121 if (data is String) data = data.charCodes();
122 SocketImpl socket = new SocketImpl(data,
123 response.charCodes(),
124 cutOff,
125 closeAsError);
126 _sockets.add(socket);
127 ReceivePort port = new ReceivePort();
128 socket._onClosedInternal = () {
129 // The server should always close the connection.
130 _sockets.remove(socket);
131 port.close();
132 };
133 // Tell HttpServer that a connection have come to life.
134 _onConnection(socket);
135 // Start 'sending' data.
136 socket._onData();
137 }
138
139 void close() {
140 Expect.fail("Don't close the connection, we attach to this socket");
141 }
142
143 void set onConnection(void callback(Socket connection)) {
144 _onConnection = callback;
145 }
146
147 void set onError(void callback()) {
148 _onError = callback;
149 }
150
151 int get port() => _port;
152
153 int _port;
154 Function _onConnection;
155 Function _onError;
156 Set<Socket> _sockets;
157 }
158
159 void testSocketClose() {
160 ServerSocketImpl serverSocket = new ServerSocketImpl("0.0.0.0", 5432, 5);
161
162 void testContent(String request,
163 String response,
164 [int okayFrom = 0,
165 bool expectError = true]) {
166 // Inner callback to actually run a given setting.
167 void runSettings(int cutoff,
168 bool closeAsError,
169 bool expectError) {
170 HttpServer server = new HttpServer();
Søren Gjesse 2012/04/02 10:26:29 You should be able to have the http server outside
Anders Johnsen 2012/04/02 10:40:31 I agree, let's take it out. It may expose some int
171 server.onRequest = (HttpRequest request, HttpResponse response) {
172 request.inputStream.onData = () {
173 };
174 request.inputStream.onClosed = () {
175 response.outputStream.close();
176 };
177 };
178
179 if (expectError) {
180 ReceivePort port = new ReceivePort();
181 server.onError = (Exception error) {
182 port.close();
183 };
184 } else {
185 server.onError = (Exception error) {
186 Expect.fail("An error was not expected: $error");
187 };
188 }
189
190 server.listenOn(serverSocket);
191 serverSocket.spawnSocket(request, response, cutoff, closeAsError);
192 server.close();
193 // TODO(ajohnsen): Validate HttpServers number of connections.
194 }
195 for (int i = 1; i < response.length; i++) {
196 bool _expectError = expectError && i < response.length - okayFrom;
197 runSettings(i, false, _expectError);
198 runSettings(i, true, _expectError);
199 }
200 }
201 testContent(
202 "GET / HTTP/1.1\r\nKeep-Alive: False\r\n\r\n",
203 "HTTP/1.1 200 OK\r\ntransfer-encoding: chunked\r\nconnection: close" +
204 "\r\n\r\n0\r\n\r\n");
205 }
206
207 void main() {
208 testSocketClose();
209 }
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