OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS 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 scheduled_test.scheduled_process; | 5 library scheduled_test.scheduled_process; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:io'; | 8 import 'dart:io'; |
9 | 9 |
10 import 'scheduled_test.dart'; | 10 import 'scheduled_test.dart'; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 | 88 |
89 _updateDescription(executable, arguments); | 89 _updateDescription(executable, arguments); |
90 | 90 |
91 _scheduleStartProcess(executable, arguments, options); | 91 _scheduleStartProcess(executable, arguments, options); |
92 | 92 |
93 _scheduleExceptionCleanup(); | 93 _scheduleExceptionCleanup(); |
94 | 94 |
95 var stdoutWithCanceller = _lineStreamWithCanceller( | 95 var stdoutWithCanceller = _lineStreamWithCanceller( |
96 _process.then((p) => p.stdout)); | 96 _process.then((p) => p.stdout)); |
97 _stdoutCanceller = stdoutWithCanceller.last; | 97 _stdoutCanceller = stdoutWithCanceller.last; |
98 var stdoutTee = tee(stdoutWithCanceller.first); | 98 _stdoutLog = stdoutWithCanceller.first; |
99 _stdout = stdoutTee.first; | |
100 _stdoutLog = stdoutTee.last; | |
101 | 99 |
102 var stderrWithCanceller = _lineStreamWithCanceller( | 100 var stderrWithCanceller = _lineStreamWithCanceller( |
103 _process.then((p) => p.stderr)); | 101 _process.then((p) => p.stderr)); |
104 _stderrCanceller = stderrWithCanceller.last; | 102 _stderrCanceller = stderrWithCanceller.last; |
105 var stderrTee = tee(stderrWithCanceller.first); | 103 _stderrLog = stderrWithCanceller.first; |
106 _stderr = stderrTee.first; | 104 |
107 _stderrLog = stderrTee.last; | 105 _stdout = stdoutStream(); |
| 106 _stderr = stderrStream(); |
108 } | 107 } |
109 | 108 |
110 /// Updates [_description] to reflect [executable] and [arguments], which are | 109 /// Updates [_description] to reflect [executable] and [arguments], which are |
111 /// the same values as in [start]. | 110 /// the same values as in [start]. |
112 void _updateDescription(executable, arguments) { | 111 void _updateDescription(executable, arguments) { |
113 if (_explicitDescription) return; | 112 if (_explicitDescription) return; |
114 if (executable is Future) { | 113 if (executable is Future) { |
115 _description = "future process"; | 114 _description = "future process"; |
116 } else if (arguments is Future || arguments.any((e) => e is Future)) { | 115 } else if (arguments is Future || arguments.any((e) => e is Future)) { |
117 _description = executable; | 116 _description = executable; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 "with exit code $exitCode."; | 178 "with exit code $exitCode."; |
180 } | 179 } |
181 }), "waiting to reach shouldExit() or kill() for process " | 180 }), "waiting to reach shouldExit() or kill() for process " |
182 "'$description'"); | 181 "'$description'"); |
183 }); | 182 }); |
184 } | 183 } |
185 | 184 |
186 /// Converts a stream of bytes to a stream of lines and returns that along | 185 /// Converts a stream of bytes to a stream of lines and returns that along |
187 /// with a [StreamCanceller] controlling it. | 186 /// with a [StreamCanceller] controlling it. |
188 Pair<Stream<String>, StreamCanceller> _lineStreamWithCanceller( | 187 Pair<Stream<String>, StreamCanceller> _lineStreamWithCanceller( |
189 Future<Stream<int>> streamFuture) { | 188 Future<Stream<List<int>>> streamFuture) { |
190 return streamWithCanceller(futureStream(streamFuture) | 189 return streamWithCanceller(futureStream(streamFuture) |
191 .handleError((e) => currentSchedule.signalError(e)) | 190 .handleError((e) => currentSchedule.signalError(e)) |
192 .transform(new StringDecoder(_encoding)) | 191 .transform(new StringDecoder(_encoding)) |
193 .transform(new LineTransformer())); | 192 .transform(new LineTransformer())); |
194 } | 193 } |
195 | 194 |
196 /// Schedule an exception handler that will clean up the process and provide | 195 /// Schedule an exception handler that will clean up the process and provide |
197 /// debug information if an error occurs. | 196 /// debug information if an error occurs. |
198 void _scheduleExceptionCleanup() { | 197 void _scheduleExceptionCleanup() { |
199 currentSchedule.onException.schedule(() { | 198 currentSchedule.onException.schedule(() { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 Future<String> remainingStderr() { | 258 Future<String> remainingStderr() { |
260 if (!_endScheduled) { | 259 if (!_endScheduled) { |
261 throw new StateError("remainingStderr() should only be called after " | 260 throw new StateError("remainingStderr() should only be called after " |
262 "kill() or shouldExit()."); | 261 "kill() or shouldExit()."); |
263 } | 262 } |
264 | 263 |
265 return schedule(() => _stderr.toList().then((lines) => lines.join("\n")), | 264 return schedule(() => _stderr.toList().then((lines) => lines.join("\n")), |
266 "reading the remaining stderr from process '$description'"); | 265 "reading the remaining stderr from process '$description'"); |
267 } | 266 } |
268 | 267 |
| 268 /// Returns a stream that will emit anything the process emits via the |
| 269 /// process's standard output from now on. |
| 270 /// |
| 271 /// This stream will be independent from any other methods that deal with |
| 272 /// standard output, including other calls to [stdoutStream]. |
| 273 /// |
| 274 /// This can be overridden by subclasses to return a derived standard output |
| 275 /// stream. This stream will then be used for [nextLine], [nextErrLine], |
| 276 /// [remainingStdout], and [remainingStderr]. |
| 277 Stream<String> stdoutStream() { |
| 278 var pair = tee(_stdoutLog); |
| 279 _stdoutLog = pair.first; |
| 280 return pair.last; |
| 281 } |
| 282 |
| 283 /// Returns a stream that will emit anything the process emits via the |
| 284 /// process's standard error from now on. |
| 285 /// |
| 286 /// This stream will be independent from any other methods that deal with |
| 287 /// standard error, including other calls to [stderrStream]. |
| 288 Stream<String> stderrStream() { |
| 289 var pair = tee(_stderrLog); |
| 290 _stderrLog = pair.first; |
| 291 return pair.last; |
| 292 } |
| 293 |
269 /// Writes [line] to the process as stdin. | 294 /// Writes [line] to the process as stdin. |
270 void writeLine(String line) { | 295 void writeLine(String line) { |
271 schedule(() { | 296 schedule(() { |
272 return _process.then((p) => p.stdin.writeln('$line')); | 297 return _process.then((p) => p.stdin.writeln('$line')); |
273 }, "writing '$line' to stdin for process '$description'"); | 298 }, "writing '$line' to stdin for process '$description'"); |
274 } | 299 } |
275 | 300 |
276 /// Closes the process's stdin stream. | 301 /// Closes the process's stdin stream. |
277 void closeStdin() { | 302 void closeStdin() { |
278 schedule(() => _process.then((p) => p.stdin.close()), | 303 schedule(() => _process.then((p) => p.stdin.close()), |
(...skipping 26 matching lines...) Expand all Loading... |
305 schedule(() { | 330 schedule(() { |
306 _endExpected = true; | 331 _endExpected = true; |
307 return _exitCode.then((exitCode) { | 332 return _exitCode.then((exitCode) { |
308 if (expectedExitCode != null) { | 333 if (expectedExitCode != null) { |
309 expect(exitCode, equals(expectedExitCode)); | 334 expect(exitCode, equals(expectedExitCode)); |
310 } | 335 } |
311 }); | 336 }); |
312 }, "waiting for process '$description' to exit"); | 337 }, "waiting for process '$description' to exit"); |
313 } | 338 } |
314 } | 339 } |
OLD | NEW |