OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS d.file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS d.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 library pub_tests; | 5 library pub_tests; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:convert'; | 8 import 'dart:convert'; |
9 import 'dart:io'; | 9 import 'dart:io'; |
10 | 10 |
11 import 'package:http/http.dart' as http; | 11 import 'package:http/http.dart' as http; |
12 import 'package:scheduled_test/scheduled_process.dart'; | 12 import 'package:scheduled_test/scheduled_process.dart'; |
13 import 'package:scheduled_test/scheduled_stream.dart'; | 13 import 'package:scheduled_test/scheduled_stream.dart'; |
14 import 'package:scheduled_test/scheduled_test.dart'; | 14 import 'package:scheduled_test/scheduled_test.dart'; |
15 | 15 |
16 import '../../lib/src/utils.dart'; | 16 import '../../lib/src/utils.dart'; |
17 import '../descriptor.dart' as d; | 17 import '../descriptor.dart' as d; |
18 import '../test_pub.dart'; | 18 import '../test_pub.dart'; |
19 | 19 |
20 /// The pub process running "pub serve". | 20 /// The pub process running "pub serve". |
21 ScheduledProcess _pubServer; | 21 ScheduledProcess _pubServer; |
22 | 22 |
| 23 /// The ephemeral port assign to the running admin server. |
| 24 int _adminPort; |
| 25 |
23 /// The ephemeral ports assigned to the running servers, associated with the | 26 /// The ephemeral ports assigned to the running servers, associated with the |
24 /// directories they're serving. | 27 /// directories they're serving. |
25 final _ports = new Map<String, int>(); | 28 final _ports = new Map<String, int>(); |
26 | 29 |
27 /// A completer that completes when the server has been started and the served | 30 /// A completer that completes when the server has been started and the served |
28 /// ports are known. | 31 /// ports are known. |
29 Completer _portsCompleter; | 32 Completer _portsCompleter; |
30 | 33 |
31 /// The web socket connection to the running pub process, or `null` if no | 34 /// The web socket connection to the running pub process, or `null` if no |
32 /// connection has been made. | 35 /// connection has been made. |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 } | 104 } |
102 | 105 |
103 /// Schedules starting the `pub serve` process. | 106 /// Schedules starting the `pub serve` process. |
104 /// | 107 /// |
105 /// Unlike [pubServe], this doesn't determine the port number of the server, and | 108 /// Unlike [pubServe], this doesn't determine the port number of the server, and |
106 /// so may be used to test for errors in the initialization process. | 109 /// so may be used to test for errors in the initialization process. |
107 /// | 110 /// |
108 /// Returns the `pub serve` process. | 111 /// Returns the `pub serve` process. |
109 ScheduledProcess startPubServe({Iterable<String> args, | 112 ScheduledProcess startPubServe({Iterable<String> args, |
110 bool createWebDir: true}) { | 113 bool createWebDir: true}) { |
111 // Use port 0 to get an ephemeral port. | 114 var pubArgs = [ |
112 var pubArgs = ["serve", "--port=0", "--hostname=127.0.0.1", "--force-poll"]; | 115 "serve", |
| 116 "--port=0", // Use port 0 to get an ephemeral port. |
| 117 "--hostname=127.0.0.1", // Force IPv4 on bots. |
| 118 "--force-poll", |
| 119 "--log-admin-url" |
| 120 ]; |
113 | 121 |
114 if (args != null) pubArgs.addAll(args); | 122 if (args != null) pubArgs.addAll(args); |
115 | 123 |
116 // Dart2js can take a long time to compile dart code, so we increase the | 124 // Dart2js can take a long time to compile dart code, so we increase the |
117 // timeout to cope with that. | 125 // timeout to cope with that. |
118 currentSchedule.timeout *= 1.5; | 126 currentSchedule.timeout *= 1.5; |
119 | 127 |
120 if (createWebDir) d.dir(appPath, [d.dir("web")]).create(); | 128 if (createWebDir) d.dir(appPath, [d.dir("web")]).create(); |
121 return startPub(args: pubArgs); | 129 return startPub(args: pubArgs); |
122 } | 130 } |
(...skipping 23 matching lines...) Expand all Loading... |
146 } | 154 } |
147 }); | 155 }); |
148 | 156 |
149 if (shouldGetFirst) { | 157 if (shouldGetFirst) { |
150 _pubServer.stdout.expect(consumeThrough("Got dependencies!")); | 158 _pubServer.stdout.expect(consumeThrough("Got dependencies!")); |
151 } | 159 } |
152 | 160 |
153 _pubServer.stdout.expect(startsWith("Loading source assets...")); | 161 _pubServer.stdout.expect(startsWith("Loading source assets...")); |
154 _pubServer.stdout.expect(consumeWhile(matches("Loading .* transformers..."))); | 162 _pubServer.stdout.expect(consumeWhile(matches("Loading .* transformers..."))); |
155 | 163 |
| 164 _pubServer.stdout.expect(predicate(_parseAdminPort)); |
| 165 |
156 // The server should emit one or more ports. | 166 // The server should emit one or more ports. |
157 _pubServer.stdout.expect( | 167 _pubServer.stdout.expect( |
158 consumeWhile(predicate(_parsePort, 'emits server url'))); | 168 consumeWhile(predicate(_parsePort, 'emits server url'))); |
159 schedule(() { | 169 schedule(() { |
160 expect(_ports, isNot(isEmpty)); | 170 expect(_ports, isNot(isEmpty)); |
161 _portsCompleter.complete(); | 171 _portsCompleter.complete(); |
162 }); | 172 }); |
163 | 173 |
164 return _pubServer; | 174 return _pubServer; |
165 } | 175 } |
166 | 176 |
167 /// The regular expression for parsing pub's output line describing the URL for | 177 /// The regular expression for parsing pub's output line describing the URL for |
168 /// the server. | 178 /// the server. |
169 final _parsePortRegExp = new RegExp(r"([^ ]+) +on http://127\.0\.0\.1:(\d+)"); | 179 final _parsePortRegExp = new RegExp(r"([^ ]+) +on http://127\.0\.0\.1:(\d+)"); |
170 | 180 |
| 181 /// Parses the port number from the "Running admin server on 127.0.0.1:1234" |
| 182 /// line printed by pub serve. |
| 183 bool _parseAdminPort(String line) { |
| 184 var match = _parsePortRegExp.firstMatch(line); |
| 185 if (match == null) return false; |
| 186 _adminPort = int.parse(match[2]); |
| 187 return true; |
| 188 } |
| 189 |
171 /// Parses the port number from the "Serving blah on 127.0.0.1:1234" line | 190 /// Parses the port number from the "Serving blah on 127.0.0.1:1234" line |
172 /// printed by pub serve. | 191 /// printed by pub serve. |
173 bool _parsePort(String line) { | 192 bool _parsePort(String line) { |
174 var match = _parsePortRegExp.firstMatch(line); | 193 var match = _parsePortRegExp.firstMatch(line); |
175 if (match == null) return false; | 194 if (match == null) return false; |
176 _ports[match[1]] = int.parse(match[2]); | 195 _ports[match[1]] = int.parse(match[2]); |
177 return true; | 196 return true; |
178 } | 197 } |
179 | 198 |
180 void endPubServe() { | 199 void endPubServe() { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 _pubServer.stdout.expect(consumeThrough(contains("successfully"))); | 278 _pubServer.stdout.expect(consumeThrough(contains("successfully"))); |
260 | 279 |
261 /// Schedules opening a web socket connection to the currently running pub | 280 /// Schedules opening a web socket connection to the currently running pub |
262 /// serve. | 281 /// serve. |
263 Future _ensureWebSocket() { | 282 Future _ensureWebSocket() { |
264 // Use the existing one if already connected. | 283 // Use the existing one if already connected. |
265 if (_webSocket != null) return new Future.value(); | 284 if (_webSocket != null) return new Future.value(); |
266 | 285 |
267 // Server should already be running. | 286 // Server should already be running. |
268 expect(_pubServer, isNotNull); | 287 expect(_pubServer, isNotNull); |
269 expect(_ports, isNot(isEmpty)); | 288 expect(_adminPort, isNotNull); |
270 | 289 |
271 // TODO(nweiz): once we have a separate port for a web interface into the | 290 return WebSocket.connect("ws://127.0.0.1:$_adminPort").then((socket) { |
272 // server, use that port for the websocket interface. | |
273 var port = _ports.values.first; | |
274 return WebSocket.connect("ws://127.0.0.1:$port").then((socket) { | |
275 _webSocket = socket; | 291 _webSocket = socket; |
276 // TODO(rnystrom): Works around #13913. | 292 // TODO(rnystrom): Works around #13913. |
277 _webSocketBroadcastStream = _webSocket.asBroadcastStream(); | 293 _webSocketBroadcastStream = _webSocket.asBroadcastStream(); |
278 }); | 294 }); |
279 } | 295 } |
280 | 296 |
281 /// Sends [request] (an arbitrary JSON object) to the running pub serve's web | 297 /// Sends [request] (an arbitrary JSON object) to the running pub serve's web |
282 /// socket connection, waits for a reply, then verifies that the reply is | 298 /// socket connection, waits for a reply, then verifies that the reply is |
283 /// either equal to [replyEquals] or matches [replyMatches]. | 299 /// either equal to [replyEquals] or matches [replyMatches]. |
284 /// | 300 /// |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 /// included. Unlike [getServerUrl], this should only be called after the ports | 357 /// included. Unlike [getServerUrl], this should only be called after the ports |
342 /// are known. | 358 /// are known. |
343 String _getServerUrlSync([String root, String path]) { | 359 String _getServerUrlSync([String root, String path]) { |
344 if (root == null) root = 'web'; | 360 if (root == null) root = 'web'; |
345 expect(_ports, contains(root)); | 361 expect(_ports, contains(root)); |
346 var url = "http://127.0.0.1:${_ports[root]}"; | 362 var url = "http://127.0.0.1:${_ports[root]}"; |
347 if (path != null) url = "$url/$path"; | 363 if (path != null) url = "$url/$path"; |
348 return url; | 364 return url; |
349 } | 365 } |
350 | 366 |
OLD | NEW |