Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
|
bkonyi
2017/04/19 16:37:52
I'll change the copyright date.
zra
2017/04/19 17:46:13
tests should go under the test/ directory.
bkonyi
2017/04/19 21:29:50
Done.
bkonyi
2017/04/19 21:29:50
Done.
| |
| 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:isolate"; | |
| 6 import "dart:io"; | |
| 7 import "../sync_http.dart"; | |
|
zra
2017/04/19 17:46:13
This should be a package: import, like:
import "p
bkonyi
2017/04/19 21:29:50
Tried this before, didn't realize I needed to run
| |
| 8 import "../../../sdk/pkg/expect/lib/expect.dart"; | |
|
bkonyi
2017/04/19 16:37:52
This needs to be changed to not use an explicit pa
zra
2017/04/19 17:46:13
Use the "test" package. Add it under "dev_dependen
bkonyi
2017/04/19 21:29:50
Done.
| |
| 9 | |
| 10 class TestServerMain { | |
| 11 TestServerMain() | |
| 12 : _statusPort = new ReceivePort(), | |
| 13 _serverPort = null; | |
|
zra
2017/04/19 17:46:13
not needed
bkonyi
2017/04/19 21:29:50
Removed.
| |
| 14 | |
| 15 void setServerStartedHandler(void startedCallback(int port)) { | |
| 16 _startedCallback = startedCallback; | |
| 17 } | |
| 18 | |
| 19 void start([bool chunkedEncoding = false]) { | |
| 20 ReceivePort receivePort = new ReceivePort(); | |
| 21 var remote = Isolate.spawn(startTestServer, receivePort.sendPort); | |
|
zra
2017/04/19 17:46:13
remote is unused
bkonyi
2017/04/19 21:29:50
Removed.
| |
| 22 receivePort.first.then((port) { | |
| 23 _serverPort = port; | |
| 24 | |
| 25 if (chunkedEncoding) { | |
| 26 // Send chunked encoding message to the server. | |
| 27 port.send( | |
| 28 [new TestServerCommand.chunkedEncoding(), _statusPort.sendPort]); | |
| 29 } | |
| 30 | |
| 31 // Send server start message to the server. | |
| 32 var command = new TestServerCommand.start(); | |
| 33 port.send([command, _statusPort.sendPort]); | |
| 34 }); | |
| 35 | |
| 36 // Handle status messages from the server. | |
| 37 _statusPort.listen((var status) { | |
| 38 if (status.isStarted) { | |
| 39 _startedCallback(status.port); | |
| 40 } | |
| 41 }); | |
| 42 } | |
| 43 | |
| 44 void close() { | |
| 45 // Send server stop message to the server. | |
| 46 _serverPort.send([new TestServerCommand.stop(), _statusPort.sendPort]); | |
| 47 _statusPort.close(); | |
| 48 } | |
| 49 | |
| 50 ReceivePort _statusPort; // Port for receiving messages from the server. | |
|
zra
2017/04/19 17:46:13
I think Dart style tends towards putting these at
bkonyi
2017/04/19 21:29:50
Good point. Moved.
| |
| 51 SendPort _serverPort; // Port for sending messages to the server. | |
| 52 var _startedCallback; | |
|
zra
2017/04/19 17:46:13
You can make a typedef for the function type and u
bkonyi
2017/04/19 21:29:50
Done.
| |
| 53 } | |
| 54 | |
| 55 class TestServerCommand { | |
|
zra
2017/04/19 17:46:13
How about an enum?
bkonyi
2017/04/19 21:29:50
Done.
| |
| 56 static const START = 0; | |
|
zra
2017/04/19 17:46:13
Check the Dart style guide fro naming constants. A
bkonyi
2017/04/19 21:29:50
Replaced with enum.
| |
| 57 static const STOP = 1; | |
| 58 static const CHUNKED_ENCODING = 2; | |
| 59 | |
| 60 TestServerCommand.start() : _command = START; | |
| 61 TestServerCommand.stop() : _command = STOP; | |
| 62 TestServerCommand.chunkedEncoding() : _command = CHUNKED_ENCODING; | |
| 63 | |
| 64 bool get isStart => _command == START; | |
| 65 bool get isStop => _command == STOP; | |
| 66 bool get isChunkedEncoding => _command == CHUNKED_ENCODING; | |
| 67 | |
| 68 int _command; | |
| 69 } | |
| 70 | |
| 71 class TestServerStatus { | |
|
zra
2017/04/19 17:46:13
Maybe split the state off into an enum.
bkonyi
2017/04/19 21:29:50
Done.
| |
| 72 static const STARTED = 0; | |
| 73 static const STOPPED = 1; | |
| 74 static const ERROR = 2; | |
| 75 | |
| 76 TestServerStatus.started(this._port) : _state = STARTED; | |
| 77 TestServerStatus.stopped() : _state = STOPPED; | |
| 78 TestServerStatus.error() : _state = ERROR; | |
| 79 | |
| 80 bool get isStarted => _state == STARTED; | |
| 81 bool get isStopped => _state == STOPPED; | |
| 82 bool get isError => _state == ERROR; | |
| 83 | |
| 84 int get port => _port; | |
| 85 | |
| 86 int _state; | |
| 87 int _port; | |
| 88 } | |
| 89 | |
| 90 void startTestServer(SendPort replyTo) { | |
| 91 var server = new TestServer(); | |
| 92 server.init(); | |
| 93 replyTo.send(server.dispatchSendPort); | |
| 94 } | |
| 95 | |
| 96 class TestServer { | |
| 97 // Echo the request content back to the response. | |
| 98 void _echoHandler(HttpRequest request) { | |
| 99 var response = request.response; | |
| 100 Expect.equals("POST", request.method); | |
| 101 response.contentLength = request.contentLength; | |
| 102 request.listen((List<int> data) { | |
| 103 var string = new String.fromCharCodes(data); | |
| 104 response.write(string); | |
| 105 response.close(); | |
| 106 }); | |
| 107 } | |
| 108 | |
| 109 // Echo the request content back to the response. | |
| 110 void _zeroToTenHandler(HttpRequest request) { | |
| 111 var response = request.response; | |
| 112 String msg = "01234567890"; | |
| 113 Expect.equals("GET", request.method); | |
| 114 response.contentLength = msg.length; | |
| 115 response.write(msg); | |
| 116 response.close(); | |
| 117 } | |
| 118 | |
| 119 // Return a 404. | |
| 120 void _notFoundHandler(HttpRequest request) { | |
| 121 var response = request.response; | |
| 122 response.statusCode = HttpStatus.NOT_FOUND; | |
| 123 String msg = "Page not found"; | |
| 124 response.contentLength = msg.length; | |
| 125 response.headers.set("Content-Type", "text/html; charset=UTF-8"); | |
| 126 response.write(msg); | |
| 127 response.close(); | |
| 128 } | |
| 129 | |
| 130 // Return a 301 with a custom reason phrase. | |
| 131 void _reasonForMovingHandler(HttpRequest request) { | |
| 132 var response = request.response; | |
| 133 response.statusCode = HttpStatus.MOVED_PERMANENTLY; | |
| 134 response.reasonPhrase = "Don't come looking here any more"; | |
| 135 response.close(); | |
| 136 } | |
| 137 | |
| 138 // Check the "Host" header. | |
| 139 void _hostHandler(HttpRequest request) { | |
| 140 var response = request.response; | |
| 141 Expect.equals(1, request.headers["Host"].length); | |
| 142 Expect.equals("www.dartlang.org:1234", request.headers["Host"][0]); | |
| 143 Expect.equals("www.dartlang.org", request.headers.host); | |
| 144 Expect.equals(1234, request.headers.port); | |
| 145 response.statusCode = HttpStatus.OK; | |
| 146 response.close(); | |
| 147 } | |
| 148 | |
| 149 void init() { | |
| 150 // Setup request handlers. | |
| 151 _requestHandlers = new Map(); | |
| 152 _requestHandlers["/echo"] = _echoHandler; | |
| 153 _requestHandlers["/0123456789"] = _zeroToTenHandler; | |
| 154 _requestHandlers["/reasonformoving"] = _reasonForMovingHandler; | |
| 155 _requestHandlers["/host"] = _hostHandler; | |
| 156 _dispatchPort = new ReceivePort(); | |
| 157 _dispatchPort.listen(dispatch); | |
| 158 } | |
| 159 | |
| 160 SendPort get dispatchSendPort => _dispatchPort.sendPort; | |
| 161 | |
| 162 void dispatch(var message) { | |
| 163 TestServerCommand command = message[0]; | |
| 164 SendPort replyTo = message[1]; | |
| 165 if (command.isStart) { | |
| 166 try { | |
| 167 HttpServer.bind("127.0.0.1", 0).then((server) { | |
| 168 _server = server; | |
| 169 _server.listen(_requestReceivedHandler); | |
| 170 replyTo.send(new TestServerStatus.started(_server.port)); | |
| 171 }); | |
| 172 } catch (e) { | |
| 173 replyTo.send(new TestServerStatus.error()); | |
| 174 } | |
| 175 } else if (command.isStop) { | |
| 176 _server.close(); | |
| 177 _dispatchPort.close(); | |
| 178 replyTo.send(new TestServerStatus.stopped()); | |
| 179 } else if (command.isChunkedEncoding) { | |
| 180 _chunkedEncoding = true; | |
| 181 } | |
| 182 } | |
| 183 | |
| 184 void _requestReceivedHandler(HttpRequest request) { | |
| 185 var requestHandler = _requestHandlers[request.uri.path]; | |
| 186 if (requestHandler != null) { | |
| 187 requestHandler(request); | |
| 188 } else { | |
| 189 _notFoundHandler(request); | |
| 190 } | |
| 191 } | |
| 192 | |
| 193 HttpServer _server; // HTTP server instance. | |
| 194 ReceivePort _dispatchPort; | |
| 195 Map _requestHandlers; | |
| 196 bool _chunkedEncoding = false; | |
| 197 } | |
| 198 | |
| 199 void testStartStop() { | |
|
zra
2017/04/19 17:46:13
These tests are asynchronous, and you'll probably
bkonyi
2017/04/19 21:29:50
Done.
| |
| 200 TestServerMain testServerMain = new TestServerMain(); | |
| 201 testServerMain.setServerStartedHandler((int port) { | |
| 202 testServerMain.close(); | |
| 203 }); | |
| 204 testServerMain.start(); | |
| 205 } | |
| 206 | |
| 207 void testGET() { | |
| 208 TestServerMain testServerMain = new TestServerMain(); | |
| 209 testServerMain.setServerStartedHandler((int port) { | |
| 210 HttpClientSync httpClient = new HttpClientSync(); | |
| 211 var request = | |
| 212 httpClient.getUrl(new Uri.http("127.0.0.1:$port", "/0123456789")); | |
| 213 var response = request.close(); | |
| 214 Expect.equals(HttpStatus.OK, response.statusCode); | |
| 215 Expect.equals(11, response.contentLength); | |
| 216 Expect.equals("01234567890", response.body); | |
| 217 testServerMain.close(); | |
| 218 }); | |
| 219 testServerMain.start(); | |
| 220 } | |
| 221 | |
| 222 void testPOST(bool chunkedEncoding) { | |
| 223 String data = "ABCDEFGHIJKLMONPQRSTUVWXYZ"; | |
| 224 final int kMessageCount = 10; | |
| 225 | |
| 226 TestServerMain testServerMain = new TestServerMain(); | |
| 227 | |
| 228 void runTest(int port) { | |
| 229 int count = 0; | |
| 230 HttpClientSync httpClient = new HttpClientSync(); | |
| 231 void sendRequest() { | |
| 232 var request = | |
| 233 httpClient.postUrl(new Uri.http("127.0.0.1:$port", "/echo")); | |
| 234 if (chunkedEncoding) { | |
| 235 request.write(data.substring(0, 10)); | |
| 236 request.write(data.substring(10, data.length)); | |
| 237 } else { | |
| 238 request.write(data); | |
| 239 } | |
| 240 var response = request.close(); | |
| 241 Expect.equals(HttpStatus.OK, response.statusCode); | |
| 242 Expect.equals(data, response.body); | |
| 243 count++; | |
| 244 if (count < kMessageCount) { | |
| 245 sendRequest(); | |
| 246 } else { | |
| 247 testServerMain.close(); | |
| 248 } | |
| 249 } | |
| 250 | |
| 251 sendRequest(); | |
| 252 } | |
| 253 | |
| 254 testServerMain.setServerStartedHandler(runTest); | |
| 255 testServerMain.start(chunkedEncoding); | |
| 256 } | |
| 257 | |
| 258 void test404() { | |
| 259 TestServerMain testServerMain = new TestServerMain(); | |
| 260 testServerMain.setServerStartedHandler((int port) { | |
| 261 HttpClientSync httpClient = new HttpClientSync(); | |
| 262 var request = | |
| 263 httpClient.getUrl(new Uri.http("127.0.0.1:$port", "/thisisnotfound")); | |
| 264 var response = request.close(); | |
| 265 Expect.equals(HttpStatus.NOT_FOUND, response.statusCode); | |
| 266 Expect.equals("Page not found", response.body); | |
| 267 testServerMain.close(); | |
| 268 }); | |
| 269 testServerMain.start(); | |
| 270 } | |
| 271 | |
| 272 void testReasonPhrase() { | |
| 273 TestServerMain testServerMain = new TestServerMain(); | |
| 274 testServerMain.setServerStartedHandler((int port) { | |
| 275 HttpClientSync httpClient = new HttpClientSync(); | |
| 276 var request = | |
| 277 httpClient.getUrl(new Uri.http("127.0.0.1:$port", "/reasonformoving")); | |
| 278 var response = request.close(); | |
| 279 Expect.equals(HttpStatus.MOVED_PERMANENTLY, response.statusCode); | |
| 280 Expect.equals( | |
| 281 "Don't come looking here any more\r\n", response.reasonPhrase); | |
| 282 testServerMain.close(); | |
| 283 }); | |
| 284 testServerMain.start(); | |
| 285 } | |
| 286 | |
| 287 void main() { | |
| 288 testStartStop(); | |
| 289 testGET(); | |
| 290 testPOST(true); | |
| 291 testPOST(false); | |
| 292 test404(); | |
| 293 testReasonPhrase(); | |
| 294 } | |
| OLD | NEW |