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

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

Issue 9426005: Don't retry browser tests if the bot is pretty red. Also, retry properly all (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 10 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 | « tools/testing/dart/test_progress.dart ('k') | 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) 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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 // exceptions. 193 // exceptions.
194 return (!timedOut && ((exitCode < 0) || (exitCode == 253))); 194 return (!timedOut && ((exitCode < 0) || (exitCode == 253)));
195 } 195 }
196 196
197 bool get hasTimedOut() => timedOut; 197 bool get hasTimedOut() => timedOut;
198 198
199 bool get didFail() { 199 bool get didFail() {
200 if (testCase is !BrowserTestCase) return (exitCode != 0 && !hasCrashed); 200 if (testCase is !BrowserTestCase) return (exitCode != 0 && !hasCrashed);
201 201
202 // Browser case: 202 // Browser case:
203 // Browser tests fail unless stdout contains
204 // 'Content-Type: text/plain\nPASS'.
205 String previous_line = '';
206 for (String line in stdout) {
207 if (line == 'PASS' && previous_line == 'Content-Type: text/plain') {
208 return (exitCode != 0 && !hasCrashed);
Emily Fortuna 2012/02/17 19:34:24 Sometimes when DRT crashes with a memory dump, and
Siggi Cherem (dart-lang) 2012/02/17 19:51:38 I thought in that case we wouldn't have PASS in th
Emily Fortuna 2012/02/17 21:03:03 Sometimes it does, and sometimes it doesn't when D
209 }
210 previous_line = line;
211 }
212
213 // If the browser test failed, it may have been because DumpRenderTree 203 // If the browser test failed, it may have been because DumpRenderTree
214 // and the virtual framebuffer X server didn't hook up, or DRT crashed with 204 // and the virtual framebuffer X server didn't hook up, or DRT crashed with
215 // a core dump. 205 // a core dump.
216 for (String line in stderr) { 206 for (String line in stderr) {
217 if (line.contains('Gtk-WARNING **: cannot open display: :99') || 207 if (line.contains('Gtk-WARNING **: cannot open display: :99') ||
218 line.contains('Failed to run command. return code=1')) { 208 line.contains('Failed to run command. return code=1')) {
219 // If we get the X server error, or DRT crashes with a core dump, retry 209 // If we get the X server error, or DRT crashes with a core dump, retry
220 // the test. 210 // the test.
221 requestRetry = true; 211 requestRetry = true;
222 return true; 212 return true;
223 } 213 }
224 } 214 }
215
216 // Browser tests fail unless stdout contains
217 // 'Content-Type: text/plain\nPASS'.
218 String previous_line = '';
219 for (String line in stdout) {
220 if (line == 'PASS' && previous_line == 'Content-Type: text/plain') {
221 return (exitCode != 0 && !hasCrashed);
222 }
223 previous_line = line;
224 }
225
225 return true; 226 return true;
226 } 227 }
227 228
228 // Reverse result of a negative test. 229 // Reverse result of a negative test.
229 bool get hasFailed() => (testCase.isNegative ? !didFail : didFail); 230 bool get hasFailed() => (testCase.isNegative ? !didFail : didFail);
230 } 231 }
231 232
232 /** 233 /**
233 * A RunningProcess actually runs a test, getting the command lines from 234 * A RunningProcess actually runs a test, getting the command lines from
234 * its [TestCase], starting the test process (and first, a compilation 235 * its [TestCase], starting the test process (and first, a compilation
235 * process if the TestCase is a [BrowserTestCase]), creating a timeout 236 * process if the TestCase is a [BrowserTestCase]), creating a timeout
236 * timer, and recording the results in a new [TestOutput] object, which it 237 * timer, and recording the results in a new [TestOutput] object, which it
237 * attaches to the TestCase. The lifetime of the RunningProcess is limited 238 * attaches to the TestCase. The lifetime of the RunningProcess is limited
238 * to the time it takes to start the process, run the process, and record 239 * to the time it takes to start the process, run the process, and record
239 * the result; there are no pointers to it, so it should be available to 240 * the result; there are no pointers to it, so it should be available to
240 * be garbage collected as soon as it is done. 241 * be garbage collected as soon as it is done.
241 */ 242 */
242 class RunningProcess { 243 class RunningProcess {
243 Process process; 244 Process process;
244 TestCase testCase; 245 TestCase testCase;
245 bool timedOut = false; 246 bool timedOut = false;
246 Date startTime; 247 Date startTime;
247 Timer timeoutTimer; 248 Timer timeoutTimer;
248 List<String> stdout; 249 List<String> stdout;
249 List<String> stderr; 250 List<String> stderr;
250 List<Function> handlers; 251 List<Function> handlers;
252 bool allowRetries;
251 253
252 RunningProcess(TestCase this.testCase); 254 RunningProcess(TestCase this.testCase, bool this.allowRetries);
Siggi Cherem (dart-lang) 2012/02/17 19:51:38 I think when using this.xxx our style is to omit t
Emily Fortuna 2012/02/17 21:03:03 Done.
253 255
254 void exitHandler(int exitCode) { 256 void exitHandler(int exitCode) {
255 new TestOutput(testCase, exitCode, timedOut, stdout, 257 new TestOutput(testCase, exitCode, timedOut, stdout,
256 stderr, new Date.now().difference(startTime)); 258 stderr, new Date.now().difference(startTime));
257 process.close(); 259 process.close();
258 timeoutTimer.cancel(); 260 timeoutTimer.cancel();
259 if (testCase.output.unexpectedOutput && testCase.configuration['verbose']) { 261 if (testCase.output.unexpectedOutput && testCase.configuration['verbose']) {
260 print(testCase.displayName); 262 print(testCase.displayName);
261 for (var line in testCase.output.stderr) print(line); 263 for (var line in testCase.output.stderr) print(line);
262 for (var line in testCase.output.stdout) print(line); 264 for (var line in testCase.output.stdout) print(line);
263 } 265 }
264 if (testCase.configuration['component'] == 'webdriver' && 266 if (allowRetries && testCase.configuration['component'] == 'webdriver' &&
265 testCase.output.unexpectedOutput && testCase.numRetries > 0) { 267 testCase.output.unexpectedOutput && testCase.numRetries > 0) {
266 // Selenium tests can be flaky. Try rerunning. 268 // Selenium tests can be flaky. Try rerunning.
267 testCase.output.requestRetry = true; 269 testCase.output.requestRetry = true;
268 } 270 }
269 if (testCase.output.requestRetry) { 271 if (testCase.output.requestRetry) {
270 testCase.output.requestRetry = false; 272 testCase.output.requestRetry = false;
271 this.timedOut = false; 273 this.timedOut = false;
272 testCase.dynamic.numRetries--; 274 testCase.dynamic.numRetries--;
273 print("Potential flake. Re-running " + testCase.displayName); 275 print("Potential flake. Re-running " + testCase.displayName);
274 this.start(); 276 this.start();
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 _progress.done(test_arg); 699 _progress.done(test_arg);
698 _tryRunTest(); 700 _tryRunTest();
699 oldCallback(test_arg); 701 oldCallback(test_arg);
700 }; 702 };
701 test.completedHandler = wrapper; 703 test.completedHandler = wrapper;
702 if (test.configuration['component'] == 'dartc' && 704 if (test.configuration['component'] == 'dartc' &&
703 test.displayName != 'dartc/junit_tests') { 705 test.displayName != 'dartc/junit_tests') {
704 _ensureDartcBatchRunnersStarted(test.executablePath); 706 _ensureDartcBatchRunnersStarted(test.executablePath);
705 _getDartcBatchRunnerProcess().startTest(test); 707 _getDartcBatchRunnerProcess().startTest(test);
706 } else { 708 } else {
707 new RunningProcess(test).start(); 709 // If we've failed more than four tests, a lot of tests are likely
Siggi Cherem (dart-lang) 2012/02/17 19:51:38 When is numFailedTest incremented? I thought that
Emily Fortuna 2012/02/17 21:03:03 The progress counter keeps track of the *actual* f
Emily Fortuna 2012/02/17 21:04:45 *Edit to last paragraph: Yes, numFailedTests is n
710 // broken. Don't continue to retry running tests if our tree is already
711 // red. At this point rerunning to test for flakes takes more time than
712 // it's worth.
713 new RunningProcess(test, _progress.numFailedTests < 5).start();
Emily Fortuna 2012/02/17 19:34:24 Magic number... no me gusta :-(
Siggi Cherem (dart-lang) 2012/02/17 19:51:38 maybe we can do != 0?
708 } 714 }
709 _numProcesses++; 715 _numProcesses++;
710 } 716 }
711 } 717 }
712 } 718 }
OLDNEW
« no previous file with comments | « tools/testing/dart/test_progress.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698