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

Side by Side Diff: tools/testing/dart/browser_controller.dart

Issue 15649021: Simplified the killing mechanism in browser_controller.dart (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 6 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 library browser; 4 library browser;
5 5
6 import "dart:async"; 6 import "dart:async";
7 import "dart:core"; 7 import "dart:core";
8 import "dart:io"; 8 import "dart:io";
9 9
10 import 'android.dart'; 10 import 'android.dart';
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 * Id of the browser 43 * Id of the browser
44 */ 44 */
45 String id; 45 String id;
46 46
47 /** Callback that will be executed when the browser has closed */ 47 /** Callback that will be executed when the browser has closed */
48 Function onClose; 48 Function onClose;
49 49
50 /** Print everything (stdout, stderr, usageLog) whenever we add to it */ 50 /** Print everything (stdout, stderr, usageLog) whenever we add to it */
51 bool debugPrint = false; 51 bool debugPrint = false;
52 52
53 // We use this to gracefully handle double calls to close. 53 // This future will be lazily set when calling close() and will complete once
54 bool underTermination = false; 54 // the process did exit.
55 Future browserTerminationFuture;
55 56
56 Browser(); 57 Browser();
57 58
58 factory Browser.byName(String name) { 59 factory Browser.byName(String name) {
59 if (name == 'ff' || name == 'firefox') { 60 if (name == 'ff' || name == 'firefox') {
60 return new Firefox(); 61 return new Firefox();
61 } else if (name == 'chrome') { 62 } else if (name == 'chrome') {
62 return new Chrome(); 63 return new Chrome();
63 } else if (name == 'safari') { 64 } else if (name == 'safari') {
64 return new Safari(); 65 return new Safari();
(...skipping 23 matching lines...) Expand all
88 void _addStdout(String output) { 89 void _addStdout(String output) {
89 if (debugPrint) print("stdout: $output"); 90 if (debugPrint) print("stdout: $output");
90 _stdout.write(output); 91 _stdout.write(output);
91 } 92 }
92 93
93 void _addStderr(String output) { 94 void _addStderr(String output) {
94 if (debugPrint) print("stderr: $output"); 95 if (debugPrint) print("stderr: $output");
95 _stderr.write(output); 96 _stderr.write(output);
96 } 97 }
97 98
98 // Kill the underlying process using the supplied kill function 99 Future close() {
99 // If there is a alternativeKillFunction we will use that after trying 100 _logEvent("Close called on browser");
100 // the default killFunction. 101 if (browserTerminationFuture == null) {
101 Future _killIt(killFunction, retries, [alternativeKillFunction = null]) { 102 var completer = new Completer();
102 Completer<bool> completer = new Completer<bool>(); 103 browserTerminationFuture = completer.future;
103 104
104 // To capture non successfull attempts we set up a timer that will 105 if (process != null) {
105 // trigger a retry (using the alternativeKillFunction if supplied). 106 // Make sure we intercept onExit calls and complete.
106 Timer timer = new Timer(killRepeatInternal, () { 107 _processClosed = () {
107 // Remove the handler, we will set this again in the call to killIt 108 _processClosed = null;
108 // below 109 process = null;
109 if (retries <= 0) { 110 completer.complete(true);
110 _logEvent("Could not kill the process, not trying anymore"); 111 };
111 // TODO(ricow): Should we crash the test script here and 112
112 // write out all our log. This is basically not a situation 113 if (process.kill(ProcessSignal.SIGKILL)) {
113 // that we want to ignore. We could potentially have a handler we 114 _logEvent("Successfully sent kill signal to process.");
114 // can call if this happens, which will shutdown the main process 115 } else {
115 // with info that people should contact [ricow,kustermann,?] 116 _logEvent("Sending kill signal failed.");
116 completer.complete(false); 117 }
118 } else {
119 _logEvent("The process is already dead.");
120 completer.complete(true);
117 } 121 }
118 _logEvent("Could not kill the process, retrying");
119 var nextKillFunction = killFunction;
120 if (alternativeKillFunction != null) {
121 nextKillFunction = alternativeKillFunction;
122 }
123 _killIt(nextKillFunction, retries - 1).then((success) {
124 completer.complete(success);
125 });
126 });
127
128 // Make sure we intercept onExit calls and eliminate the timer.
129 _processClosed = () {
130 timer.cancel();
131 _logEvent("Proccess exited, cancel timer in kill loop");
132 _processClosed = null;
133 process = null;
134 completer.complete(true);
135 };
136
137
138 _logEvent("calling kill function");
139 if (process != null && killFunction()) {
140 // We successfully sent the signal.
141 _logEvent("killing signal sent");
142 } else {
143 _logEvent("The process is already dead, kill signal could not be send");
144 completer.complete(true);
145 } 122 }
146 return completer.future; 123 return browserTerminationFuture;
147 }
148
149
150 /** Close the browser */
151 Future<bool> close() {
152 _logEvent("Close called on browser");
153 if (underTermination) {
154 _logEvent("Browser already under termination.");
155 return new Future.immediate(true);
156 }
157 underTermination = true;
158 if (process == null) {
159 _logEvent("No process open, nothing to kill.");
160 return new Future.immediate(true);
161 }
162 var killFunction = process.kill;
163 // We use a SIGKILL signal if we don't kill the process in the first go.
164 var alternativeKillFunction =
165 () { return process.kill(ProcessSignal.SIGKILL);};
166 return _killIt(killFunction, killRetries, alternativeKillFunction);
167 } 124 }
168 125
169 /** 126 /**
170 * Start the browser using the supplied argument. 127 * Start the browser using the supplied argument.
171 * This sets up the error handling and usage logging. 128 * This sets up the error handling and usage logging.
172 */ 129 */
173 Future<bool> startBrowser(String command, List<String> arguments) { 130 Future<bool> startBrowser(String command, List<String> arguments) {
174 return Process.start(command, arguments).then((startedProcess) { 131 return Process.start(command, arguments).then((startedProcess) {
175 process = startedProcess; 132 process = startedProcess;
176 process.stdout.transform(new StringDecoder()).listen((data) { 133 process.stdout.transform(new StringDecoder()).listen((data) {
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 </head> 917 </head>
961 <body onload="startTesting()"> 918 <body onload="startTesting()">
962 Dart test driver, number of tests: <div id="number"></div> 919 Dart test driver, number of tests: <div id="number"></div>
963 <iframe id="embedded_iframe"></iframe> 920 <iframe id="embedded_iframe"></iframe>
964 </body> 921 </body>
965 </html> 922 </html>
966 """; 923 """;
967 return driverContent; 924 return driverContent;
968 } 925 }
969 } 926 }
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