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

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

Issue 11293019: Run large html tests individually. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 /** 5 /**
6 * Classes and methods for executing tests. 6 * Classes and methods for executing tests.
7 * 7 *
8 * This module includes: 8 * This module includes:
9 * - Managing parallel execution of tests, including timeout checks. 9 * - Managing parallel execution of tests, including timeout checks.
10 * - Evaluating the output of each test as pass/fail/crash/timeout. 10 * - Evaluating the output of each test as pass/fail/crash/timeout.
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 * process, before the regular test is run as in the base class [TestCase]. 175 * process, before the regular test is run as in the base class [TestCase].
176 * If the compilation command fails, then the rest of the test is not run. 176 * If the compilation command fails, then the rest of the test is not run.
177 */ 177 */
178 class BrowserTestCase extends TestCase { 178 class BrowserTestCase extends TestCase {
179 /** 179 /**
180 * Indicates the number of potential retries remaining, to compensate for 180 * Indicates the number of potential retries remaining, to compensate for
181 * flaky browser tests. 181 * flaky browser tests.
182 */ 182 */
183 int numRetries; 183 int numRetries;
184 184
185 /**
186 * True if this test is dependent on another test completing before it can
187 * star (for example, we might need to depend on some other test completing
188 * first).
189 */
190 bool waitingForOtherTest;
191
192 /**
193 * The set of test cases that wish to be notified when this test has
194 * completed.
195 */
196 List<BrowserTestCase> observers;
197
185 BrowserTestCase(displayName, commands, configuration, completedHandler, 198 BrowserTestCase(displayName, commands, configuration, completedHandler,
186 expectedOutcomes, info, isNegative) 199 expectedOutcomes, info, isNegative, [this.waitingForOtherTest = false])
187 : super(displayName, commands, configuration, completedHandler, 200 : super(displayName, commands, configuration, completedHandler,
188 expectedOutcomes, isNegative: isNegative, info: info) { 201 expectedOutcomes, isNegative: isNegative, info: info) {
189 numRetries = 2; // Allow two retries to compensate for flaky browser tests. 202 numRetries = 2; // Allow two retries to compensate for flaky browser tests.
203 observers = [];
190 } 204 }
191 205
192 List<String> get _lastArguments => commands.last.arguments; 206 List<String> get _lastArguments => commands.last.arguments;
193 207
194 List<String> get batchRunnerArguments => [_lastArguments[0], '--batch']; 208 List<String> get batchRunnerArguments => [_lastArguments[0], '--batch'];
195 209
196 List<String> get batchTestArguments => 210 List<String> get batchTestArguments =>
197 _lastArguments.getRange(1, _lastArguments.length - 1); 211 _lastArguments.getRange(1, _lastArguments.length - 1);
212
213 /** Add a test case to listen for when this current test has completed. */
214 void addObserver(BrowserTestCase testCase) {
215 observers.add(testCase);
216 }
217
218 /**
219 * Notify all of the test cases that are dependent on this one that they can
220 * proceed.
221 */
222 void notifyObservers() {
223 for (BrowserTestCase testCase in observers) {
224 testCase.waitingForOtherTest = false;
225 }
226 }
198 } 227 }
199 228
200 229
201 /** 230 /**
202 * TestOutput records the output of a completed test: the process's exit code, 231 * TestOutput records the output of a completed test: the process's exit code,
203 * the standard output and standard error, whether the process timed out, and 232 * the standard output and standard error, whether the process timed out, and
204 * the time the process took to run. It also contains a pointer to the 233 * the time the process took to run. It also contains a pointer to the
205 * [TestCase] this is the output of. 234 * [TestCase] this is the output of.
206 */ 235 */
207 abstract class TestOutput { 236 abstract class TestOutput {
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 } 684 }
656 return handler; 685 return handler;
657 } 686 }
658 687
659 void start() { 688 void start() {
660 Expect.isFalse(testCase.expectedOutcomes.contains(SKIP)); 689 Expect.isFalse(testCase.expectedOutcomes.contains(SKIP));
661 stdout = new List<String>(); 690 stdout = new List<String>();
662 stderr = new List<String>(); 691 stderr = new List<String>();
663 currentStep = 0; 692 currentStep = 0;
664 startTime = new Date.now(); 693 startTime = new Date.now();
665 runCommand(testCase.commands[currentStep++], stepExitHandler); 694 if (testCase.commands.length == 1 && testCase.usesWebDriver &&
695 !testCase.configuration['noBatch']) {
696 // Browser test cases that do not require a precompilation step, start
697 // with the batch runner right away.
698 processQueue._getBatchRunner(testCase).startTest(testCase);
699 } else {
700 runCommand(testCase.commands[currentStep++], stepExitHandler);
701 }
666 } 702 }
667 703
668 void runCommand(Command command, void exitHandler(int exitCode)) { 704 void runCommand(Command command, void exitHandler(int exitCode)) {
669 Future processFuture = Process.start(command.executable, command.arguments); 705 Future processFuture = Process.start(command.executable, command.arguments);
670 processFuture.then((Process p) { 706 processFuture.then((Process p) {
671 process = p; 707 process = p;
672 process.onExit = exitHandler; 708 process.onExit = exitHandler;
673 var stdoutStringStream = new StringInputStream(process.stdout); 709 var stdoutStringStream = new StringInputStream(process.stdout);
674 var stderrStringStream = new StringInputStream(process.stderr); 710 var stderrStringStream = new StringInputStream(process.stderr);
675 stdoutStringStream.onLine = 711 stdoutStringStream.onLine =
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 if (_tests.isEmpty && _numProcesses == 0) { 1105 if (_tests.isEmpty && _numProcesses == 0) {
1070 _terminateBatchRunners().then((_) => _cleanupAndMarkDone()); 1106 _terminateBatchRunners().then((_) => _cleanupAndMarkDone());
1071 } 1107 }
1072 } 1108 }
1073 } 1109 }
1074 1110
1075 /** 1111 /**
1076 * True if we are using a browser + platform combination that needs the 1112 * True if we are using a browser + platform combination that needs the
1077 * Selenium server jar. 1113 * Selenium server jar.
1078 */ 1114 */
1079 bool get _needsSelenium => Platform.operatingSystem == 'macos' && 1115 bool get _needsSelenium => (Platform.operatingSystem == 'macos' &&
1080 browserUsed == 'safari'; 1116 browserUsed == 'safari') || browserUsed == 'opera';
1081 1117
1082 /** True if the Selenium Server is ready to be used. */ 1118 /** True if the Selenium Server is ready to be used. */
1083 bool get _isSeleniumAvailable => _seleniumServer != null || 1119 bool get _isSeleniumAvailable => _seleniumServer != null ||
1084 _seleniumAlreadyRunning; 1120 _seleniumAlreadyRunning;
1085 1121
1086 /** 1122 /**
1087 * Restart all the processes that have been waiting/stopped for the server to 1123 * Restart all the processes that have been waiting/stopped for the server to
1088 * start up. If we just call this once we end up with a single-"threaded" run. 1124 * start up. If we just call this once we end up with a single-"threaded" run.
1089 */ 1125 */
1090 void resumeTesting() { 1126 void resumeTesting() {
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1242 if (_numProcesses < _maxProcesses && !_tests.isEmpty) { 1278 if (_numProcesses < _maxProcesses && !_tests.isEmpty) {
1243 TestCase test = _tests.removeFirst(); 1279 TestCase test = _tests.removeFirst();
1244 if (_listTests) { 1280 if (_listTests) {
1245 var fields = [test.displayName, 1281 var fields = [test.displayName,
1246 Strings.join(new List.from(test.expectedOutcomes), ','), 1282 Strings.join(new List.from(test.expectedOutcomes), ','),
1247 test.isNegative.toString()]; 1283 test.isNegative.toString()];
1248 fields.addAll(test.commands.last.arguments); 1284 fields.addAll(test.commands.last.arguments);
1249 print(Strings.join(fields, '\t')); 1285 print(Strings.join(fields, '\t'));
1250 return; 1286 return;
1251 } 1287 }
1252 if (test.usesWebDriver && _needsSelenium && !_isSeleniumAvailable) { 1288 if (test.usesWebDriver && _needsSelenium && !_isSeleniumAvailable || (test
1253 // The server is not ready to run Selenium tests. Put the test back in 1289 is BrowserTestCase && test.waitingForOtherTest)) {
1290 // The test is not yet ready to run. Put the test back in
1254 // the queue. Avoid spin-polling by using a timeout. 1291 // the queue. Avoid spin-polling by using a timeout.
1255 _tests.add(test); 1292 _tests.add(test);
1256 new Timer(1000, (timer) {_tryRunTest();}); // Don't lose a process. 1293 new Timer(100, (timer) {_tryRunTest();}); // Don't lose a process.
1257 return; 1294 return;
1258 } 1295 }
1259 if (_verbose) { 1296 if (_verbose) {
1260 int i = 1; 1297 int i = 1;
1261 for (Command command in test.commands) { 1298 for (Command command in test.commands) {
1262 print('$i. ${command.commandLine}'); 1299 print('$i. ${command.commandLine}');
1263 i++; 1300 i++;
1264 } 1301 }
1265 } 1302 }
1266 _progress.start(test); 1303 _progress.start(test);
1267 TestCaseEvent oldCallback = test.completedHandler; 1304 TestCaseEvent oldCallback = test.completedHandler;
1268 void wrapper(TestCase test_arg) { 1305 void wrapper(TestCase test_arg) {
1306 if (test_arg is BrowserTestCase) test_arg.notifyObservers();
1269 _numProcesses--; 1307 _numProcesses--;
1270 _progress.done(test_arg); 1308 _progress.done(test_arg);
1271 _tryRunTest(); 1309 _tryRunTest();
1272 oldCallback(test_arg); 1310 oldCallback(test_arg);
1273 }; 1311 };
1274 test.completedHandler = wrapper; 1312 test.completedHandler = wrapper;
1275 if (test.configuration['compiler'] == 'dartc' && 1313 if (test.configuration['compiler'] == 'dartc' &&
1276 test.displayName != 'dartc/junit_tests') { 1314 test.displayName != 'dartc/junit_tests') {
1277 _getBatchRunner(test).startTest(test); 1315 _getBatchRunner(test).startTest(test);
1278 } else { 1316 } else {
1279 // Once we've actually failed a test, technically, we wouldn't need to 1317 // Once we've actually failed a test, technically, we wouldn't need to
1280 // bother retrying any subsequent tests since the bot is already red. 1318 // bother retrying any subsequent tests since the bot is already red.
1281 // However, we continue to retry tests until we have actually failed 1319 // However, we continue to retry tests until we have actually failed
1282 // four tests (arbitrarily chosen) for more debugable output, so that 1320 // four tests (arbitrarily chosen) for more debugable output, so that
1283 // the developer doesn't waste his or her time trying to fix a bunch of 1321 // the developer doesn't waste his or her time trying to fix a bunch of
1284 // tests that appear to be broken but were actually just flakes that 1322 // tests that appear to be broken but were actually just flakes that
1285 // didn't get retried because there had already been one failure. 1323 // didn't get retried because there had already been one failure.
1286 bool allowRetry = _MAX_FAILED_NO_RETRY > _progress.numFailedTests; 1324 bool allowRetry = _MAX_FAILED_NO_RETRY > _progress.numFailedTests;
1287 new RunningProcess(test, allowRetry, this).start(); 1325 new RunningProcess(test, allowRetry, this).start();
1288 } 1326 }
1289 _numProcesses++; 1327 _numProcesses++;
1290 } 1328 }
1291 } 1329 }
1292 } 1330 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698