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

Side by Side Diff: pkg/scheduled_test/lib/scheduled_process.dart

Issue 24973002: Use SIGKILL in scheduled_process, to get around an Mac OS X bug. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 2 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 | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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:convert'; 8 import 'dart:convert';
9 import 'dart:io'; 9 import 'dart:io';
10 10
11 import 'scheduled_test.dart'; 11 import 'scheduled_test.dart';
12 import 'src/utils.dart'; 12 import 'src/utils.dart';
13 import 'src/value_future.dart'; 13 import 'src/value_future.dart';
14 14
15 /// A class representing a [Process] that is scheduled to run in the course of 15 /// A class representing a [Process] that is scheduled to run in the course of
16 /// the test. This class allows actions on the process to be scheduled 16 /// the test. This class allows actions on the process to be scheduled
17 /// synchronously. All operations on this class are scheduled. 17 /// synchronously. All operations on this class are scheduled.
18 /// 18 ///
19 /// Before running the test, either [shouldExit] or [kill] must be called on 19 /// Before running the test, either [shouldExit] or [kill] must be called on
20 /// this to ensure that the process terminates when expected. 20 /// this to ensure that the process terminates when expected. Note that [kill]
21 /// is using SIGKILL, to ensure the process is killed on Mac OS X (an early
22 /// SIGTERM on Mac OS X may be ignore).
Bob Nystrom 2013/09/27 18:03:54 "ignore" -> "ignored".
Anders Johnsen 2013/09/30 14:59:55 Nice catch, fixed.
21 /// 23 ///
22 /// If the test fails, this will automatically print out any stdout and stderr 24 /// If the test fails, this will automatically print out any stdout and stderr
23 /// from the process to aid debugging. 25 /// from the process to aid debugging.
24 class ScheduledProcess { 26 class ScheduledProcess {
25 /// A description of the process. Used for error reporting. 27 /// A description of the process. Used for error reporting.
26 String get description => _description; 28 String get description => _description;
27 String _description; 29 String _description;
28 30
29 /// Whether a description was passed explicitly by the user. 31 /// Whether a description was passed explicitly by the user.
30 bool _explicitDescription; 32 bool _explicitDescription;
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 currentSchedule.onException.schedule(() { 215 currentSchedule.onException.schedule(() {
214 _stdoutCanceller(); 216 _stdoutCanceller();
215 _stderrCanceller(); 217 _stderrCanceller();
216 218
217 if (!_process.hasValue) return; 219 if (!_process.hasValue) return;
218 220
219 var killedPrematurely = false; 221 var killedPrematurely = false;
220 if (!_exitCode.hasValue) { 222 if (!_exitCode.hasValue) {
221 killedPrematurely = true; 223 killedPrematurely = true;
222 _endExpected = true; 224 _endExpected = true;
223 _process.value.kill(); 225 _process.value.kill(ProcessSignal.SIGKILL);
224 // Ensure that the onException queue waits for the process to actually 226 // Ensure that the onException queue waits for the process to actually
225 // exit after being killed. 227 // exit after being killed.
226 wrapFuture(_process.value.exitCode, "waiting for process " 228 wrapFuture(_process.value.exitCode, "waiting for process "
227 "'$description' to die"); 229 "'$description' to die");
228 } 230 }
229 231
230 return Future.wait([ 232 return Future.wait([
231 _stdoutLog.toList(), 233 _stdoutLog.toList(),
232 _stderrLog.toList() 234 _stderrLog.toList()
233 ]).then((results) { 235 ]).then((results) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 /// Kills the process, and waits until it's dead. 323 /// Kills the process, and waits until it's dead.
322 void kill() { 324 void kill() {
323 if (_endScheduled) { 325 if (_endScheduled) {
324 throw new StateError("shouldExit() or kill() already called."); 326 throw new StateError("shouldExit() or kill() already called.");
325 } 327 }
326 328
327 _endScheduled = true; 329 _endScheduled = true;
328 _taskBeforeEnd = currentSchedule.tasks.contents.last; 330 _taskBeforeEnd = currentSchedule.tasks.contents.last;
329 schedule(() { 331 schedule(() {
330 _endExpected = true; 332 _endExpected = true;
331 return _process.then((p) => p.kill()).then((_) => _exitCode); 333 return _process
334 .then((p) => p.kill(ProcessSignal.SIGKILL))
335 .then((_) => _exitCode);
332 }, "waiting for process '$description' to die"); 336 }, "waiting for process '$description' to die");
333 } 337 }
334 338
335 /// Waits for the process to exit, and verifies that the exit code matches 339 /// Waits for the process to exit, and verifies that the exit code matches
336 /// [expectedExitCode] (if given). 340 /// [expectedExitCode] (if given).
337 void shouldExit([int expectedExitCode]) { 341 void shouldExit([int expectedExitCode]) {
338 if (_endScheduled) { 342 if (_endScheduled) {
339 throw new StateError("shouldExit() or kill() already called."); 343 throw new StateError("shouldExit() or kill() already called.");
340 } 344 }
341 345
342 _endScheduled = true; 346 _endScheduled = true;
343 _taskBeforeEnd = currentSchedule.tasks.contents.last; 347 _taskBeforeEnd = currentSchedule.tasks.contents.last;
344 schedule(() { 348 schedule(() {
345 _endExpected = true; 349 _endExpected = true;
346 return _exitCode.then((exitCode) { 350 return _exitCode.then((exitCode) {
347 if (expectedExitCode != null) { 351 if (expectedExitCode != null) {
348 expect(exitCode, equals(expectedExitCode)); 352 expect(exitCode, equals(expectedExitCode));
349 } 353 }
350 }); 354 });
351 }, "waiting for process '$description' to exit"); 355 }, "waiting for process '$description' to exit");
352 } 356 }
353 } 357 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698