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

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

Issue 17633008: Simplify close functionality in the browser controller. (Closed) Base URL: http://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';
11 import 'utils.dart'; 11 import 'utils.dart';
12 12
13 /** Class describing the interface for communicating with browsers. */ 13 /** Class describing the interface for communicating with browsers. */
14 abstract class Browser { 14 abstract class Browser {
15 StringBuffer _stdout = new StringBuffer(); 15 StringBuffer _stdout = new StringBuffer();
16 StringBuffer _stderr = new StringBuffer(); 16 StringBuffer _stderr = new StringBuffer();
17 StringBuffer _usageLog = new StringBuffer(); 17 StringBuffer _usageLog = new StringBuffer();
18 // This function is called when the process is closed. 18 // This is called after the process is closed, before the done future
19 Completer _processClosedCompleter = new Completer(); 19 // is completed.
20 // This is called after the process is closed, after _processClosedCompleter 20 // Subclasses can use this to cleanup any browser specific resources
21 // has been called, but before onExit. Subclasses can use this to cleanup 21 // (temp directories, profiles, etc). The function is expected to do
22 // any browser specific resources (temp directories, profiles, etc) 22 // it's work synchronously.
23 // The function is expected to do it's work synchronously.
24 Function _cleanup; 23 Function _cleanup;
25 24
26 /** The version of the browser - normally set when starting a browser */ 25 /** The version of the browser - normally set when starting a browser */
27 String version = ""; 26 String version = "";
28 /** 27 /**
29 * The underlying process - don't mess directly with this if you don't 28 * The underlying process - don't mess directly with this if you don't
30 * know what you are doing (this is an interactive process that needs 29 * know what you are doing (this is an interactive process that needs
31 * special threatment to not leak). 30 * special threatment to not leak).
32 */ 31 */
33 Process process; 32 Process process;
34 33
35 Function logger; 34 Function logger;
36 35
37 /** 36 /**
38 * Id of the browser 37 * Id of the browser
39 */ 38 */
40 String id; 39 String id;
41 40
42 /** Print everything (stdout, stderr, usageLog) whenever we add to it */ 41 /** Print everything (stdout, stderr, usageLog) whenever we add to it */
43 bool debugPrint = false; 42 bool debugPrint = false;
44 43
45 // This future will be lazily set when calling close() and will complete once 44 // This future returns when the process exits. It is also the return value
46 // the process did exit. 45 // of close()
47 Future browserTerminationFuture; 46 Future done;
48 47
49 Browser(); 48 Browser();
50 49
51 factory Browser.byName(String name) { 50 factory Browser.byName(String name) {
52 if (name == 'ff' || name == 'firefox') { 51 if (name == 'ff' || name == 'firefox') {
53 return new Firefox(); 52 return new Firefox();
54 } else if (name == 'chrome') { 53 } else if (name == 'chrome') {
55 return new Chrome(); 54 return new Chrome();
56 } else if (name == 'safari') { 55 } else if (name == 'safari') {
57 return new Safari(); 56 return new Safari();
(...skipping 25 matching lines...) Expand all
83 _stdout.write(output); 82 _stdout.write(output);
84 } 83 }
85 84
86 void _addStderr(String output) { 85 void _addStderr(String output) {
87 if (debugPrint) print("stderr: $output"); 86 if (debugPrint) print("stderr: $output");
88 _stderr.write(output); 87 _stderr.write(output);
89 } 88 }
90 89
91 Future close() { 90 Future close() {
92 _logEvent("Close called on browser"); 91 _logEvent("Close called on browser");
93 if (browserTerminationFuture == null) { 92 if (process != null) {
94 var completer = new Completer(); 93 if (process.kill(ProcessSignal.SIGKILL)) {
95 browserTerminationFuture = completer.future; 94 _logEvent("Successfully sent kill signal to process.");
96
97 if (process != null) {
98 _processClosedCompleter.future.then((_) {
99 process = null;
100 completer.complete(true);
101 if (_cleanup != null) {
102 _cleanup();
103 }
104 });
105
106 if (process.kill(ProcessSignal.SIGKILL)) {
107 _logEvent("Successfully sent kill signal to process.");
108 } else {
109 _logEvent("Sending kill signal failed.");
110 }
111 } else { 95 } else {
112 _logEvent("The process is already dead."); 96 _logEvent("Sending kill signal failed.");
113 completer.complete(true);
114 } 97 }
98 return done;
99 } else {
100 _logEvent("The process is already dead.");
101 return new Future.immediate(true);
115 } 102 }
116 return browserTerminationFuture;
117 } 103 }
118 104
119 /** 105 /**
120 * Start the browser using the supplied argument. 106 * Start the browser using the supplied argument.
121 * This sets up the error handling and usage logging. 107 * This sets up the error handling and usage logging.
122 */ 108 */
123 Future<bool> startBrowser(String command, List<String> arguments) { 109 Future<bool> startBrowser(String command, List<String> arguments) {
124 return Process.start(command, arguments).then((startedProcess) { 110 return Process.start(command, arguments).then((startedProcess) {
125 process = startedProcess; 111 process = startedProcess;
112 // Used to notify when exiting, and as a return value on calls to
113 // close().
114 var doneCompleter = new Completer();
115 done = doneCompleter.future;
116
126 Completer stdoutDone = new Completer(); 117 Completer stdoutDone = new Completer();
127 Completer stderrDone = new Completer(); 118 Completer stderrDone = new Completer();
128 119
129 process.stdout.transform(new StringDecoder()).listen((data) { 120 process.stdout.transform(new StringDecoder()).listen((data) {
130 _addStdout(data); 121 _addStdout(data);
131 }, onError: (error) { 122 }, onError: (error) {
132 // This should _never_ happen, but we really want this in the log 123 // This should _never_ happen, but we really want this in the log
133 // if it actually does due to dart:io or vm bug. 124 // if it actually does due to dart:io or vm bug.
134 _logEvent("An error occured in the process stdout handling: $error"); 125 _logEvent("An error occured in the process stdout handling: $error");
135 }, onDone: () { 126 }, onDone: () {
136 stdoutDone.complete(true); 127 stdoutDone.complete(true);
137 }); 128 });
138 129
139 process.stderr.transform(new StringDecoder()).listen((data) { 130 process.stderr.transform(new StringDecoder()).listen((data) {
140 _addStderr(data); 131 _addStderr(data);
141 }, onError: (error) { 132 }, onError: (error) {
142 // This should _never_ happen, but we really want this in the log 133 // This should _never_ happen, but we really want this in the log
143 // if it actually does due to dart:io or vm bug. 134 // if it actually does due to dart:io or vm bug.
144 _logEvent("An error occured in the process stderr handling: $error"); 135 _logEvent("An error occured in the process stderr handling: $error");
145 }, onDone: () { 136 }, onDone: () {
146 stderrDone.complete(true); 137 stderrDone.complete(true);
147 }); 138 });
148 139
149 process.exitCode.then((exitCode) { 140 process.exitCode.then((exitCode) {
150 _logEvent("Browser closed with exitcode $exitCode"); 141 _logEvent("Browser closed with exitcode $exitCode");
151 Future.wait([stdoutDone.future, stderrDone.future]).then((_) { 142 Future.wait([stdoutDone.future, stderrDone.future]).then((_) {
152 _processClosedCompleter.complete(exitCode); 143 process = null;
144 if (_cleanup != null) {
145 _cleanup();
146 }
147 doneCompleter.complete(exitCode);
153 }); 148 });
154 }); 149 });
155 return true; 150 return true;
156 }).catchError((error) { 151 }).catchError((error) {
157 _logEvent("Running $command $arguments failed with $error"); 152 _logEvent("Running $command $arguments failed with $error");
158 return false; 153 return false;
159 }); 154 });
160 } 155 }
161 156
162 /** 157 /**
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 } 645 }
651 } 646 }
652 647
653 void handleTimeout(BrowserTestingStatus status) { 648 void handleTimeout(BrowserTestingStatus status) {
654 // We simply kill the browser and starts up a new one! 649 // We simply kill the browser and starts up a new one!
655 // We could be smarter here, but it does not seems like it is worth it. 650 // We could be smarter here, but it does not seems like it is worth it.
656 DebugLogger.info("Handling timeout for browser ${status.browser.id}"); 651 DebugLogger.info("Handling timeout for browser ${status.browser.id}");
657 status.timeout = true; 652 status.timeout = true;
658 timedOut.add(status.currentTest.url); 653 timedOut.add(status.currentTest.url);
659 var id = status.browser.id; 654 var id = status.browser.id;
660 status.browser.close().then((closed) { 655 status.browser.close().then((_) {
661 if (!closed) {
662 // Very bad, we could not kill the browser.
663 print("could not kill browser $id");
664 return;
665 }
666 // We don't want to start a new browser if we are terminating. 656 // We don't want to start a new browser if we are terminating.
667 if (underTermination) return; 657 if (underTermination) return;
668 var browser; 658 var browser;
669 var new_id = id; 659 var new_id = id;
670 if (browserName == 'chromeOnAndroid') { 660 if (browserName == 'chromeOnAndroid') {
671 browser = new AndroidChrome(adbDeviceMapping[id]); 661 browser = new AndroidChrome(adbDeviceMapping[id]);
672 } else { 662 } else {
673 browserStatus.remove(id); 663 browserStatus.remove(id);
674 browser = getInstance(); 664 browser = getInstance();
675 new_id = "BROWSER$browserIdCount"; 665 new_id = "BROWSER$browserIdCount";
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 </head> 1045 </head>
1056 <body onload="startTesting()"> 1046 <body onload="startTesting()">
1057 Dart test driver, number of tests: <div id="number"></div> 1047 Dart test driver, number of tests: <div id="number"></div>
1058 <iframe id="embedded_iframe"></iframe> 1048 <iframe id="embedded_iframe"></iframe>
1059 </body> 1049 </body>
1060 </html> 1050 </html>
1061 """; 1051 """;
1062 return driverContent; 1052 return driverContent;
1063 } 1053 }
1064 } 1054 }
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