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

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

Issue 11638045: Adjust test logging output so what we can separate logging failure explanations from actual test fa… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years 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) 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 } 74 }
75 75
76 76
77 /** A command executed as a step in a test case. */ 77 /** A command executed as a step in a test case. */
78 class Command { 78 class Command {
79 /** Path to the executable of this command. */ 79 /** Path to the executable of this command. */
80 String executable; 80 String executable;
81 81
82 /** Command line arguments to the executable. */ 82 /** Command line arguments to the executable. */
83 List<String> arguments; 83 List<String> arguments;
84 84
85 /** Environment for the command */ 85 /** Environment for the command */
86 Map<String,String> environment; 86 Map<String,String> environment;
87 87
88 /** The actual command line that will be executed. */ 88 /** The actual command line that will be executed. */
89 String commandLine; 89 String commandLine;
90 90
91 Command(this.executable, this.arguments, [this.environment = null]) { 91 Command(this.executable, this.arguments, [this.environment = null]) {
92 if (Platform.operatingSystem == 'windows') { 92 if (Platform.operatingSystem == 'windows') {
93 // Windows can't handle the first command if it is a .bat file or the like 93 // Windows can't handle the first command if it is a .bat file or the like
94 // with the slashes going the other direction. 94 // with the slashes going the other direction.
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 } 194 }
195 195
196 return env; 196 return env;
197 } 197 }
198 198
199 static List<String> _getArguments(List<String> options, String htmlFile) { 199 static List<String> _getArguments(List<String> options, String htmlFile) {
200 var arguments = new List.from(options); 200 var arguments = new List.from(options);
201 arguments.add(htmlFile); 201 arguments.add(htmlFile);
202 return arguments; 202 return arguments;
203 } 203 }
204 204
205 Path get expectedOutputFile => expectedOutputPath; 205 Path get expectedOutputFile => expectedOutputPath;
206 bool get isPixelTest => (expectedOutputFile != null && 206 bool get isPixelTest => (expectedOutputFile != null &&
207 expectedOutputFile.filename.endsWith(".png")); 207 expectedOutputFile.filename.endsWith(".png"));
208 } 208 }
209 209
210 210
211 /** 211 /**
212 * TestCase contains all the information needed to run a test and evaluate 212 * TestCase contains all the information needed to run a test and evaluate
213 * its output. Running a test involves starting a separate process, with 213 * its output. Running a test involves starting a separate process, with
214 * the executable and arguments given by the TestCase, and recording its 214 * the executable and arguments given by the TestCase, and recording its
215 * stdout and stderr output streams, and its exit code. TestCase only 215 * stdout and stderr output streams, and its exit code. TestCase only
216 * contains static information about the test; actually running the test is 216 * contains static information about the test; actually running the test is
217 * performed by [ProcessQueue] using a [RunningProcess] object. 217 * performed by [ProcessQueue] using a [RunningProcess] object.
218 * 218 *
219 * The output information is stored in a [CommandOutput] instance contained 219 * The output information is stored in a [CommandOutput] instance contained
220 * in TestCase.commandOutputs. The last CommandOutput instance is responsible 220 * in TestCase.commandOutputs. The last CommandOutput instance is responsible
221 * for evaluating if the test has passed, failed, crashed, or timed out, and the 221 * for evaluating if the test has passed, failed, crashed, or timed out, and the
222 * TestCase has information about what the expected result of the test should 222 * TestCase has information about what the expected result of the test should
223 * be. 223 * be.
224 * 224 *
225 * The TestCase has a callback function, [completedHandler], that is run when 225 * The TestCase has a callback function, [completedHandler], that is run when
226 * the test is completed. 226 * the test is completed.
227 */ 227 */
228 class TestCase { 228 class TestCase {
229 /** 229 /**
230 * A list of commands to execute. Most test cases have a single command. 230 * A list of commands to execute. Most test cases have a single command.
231 * Dart2js tests have two commands, one to compile the source and another 231 * Dart2js tests have two commands, one to compile the source and another
232 * to execute it. Some isolate tests might even have three, if they require 232 * to execute it. Some isolate tests might even have three, if they require
233 * compiling multiple sources that are run in isolation. 233 * compiling multiple sources that are run in isolation.
234 */ 234 */
235 List<Command> commands; 235 List<Command> commands;
236 Map<Command, CommandOutput> commandOutputs = new Map<Command,CommandOutput>(); 236 Map<Command, CommandOutput> commandOutputs = new Map<Command,CommandOutput>();
237 237
238 Map configuration; 238 Map configuration;
239 String displayName; 239 String displayName;
240 bool isNegative; 240 bool isNegative;
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 * flaky browser tests. 362 * flaky browser tests.
363 */ 363 */
364 int numRetries; 364 int numRetries;
365 365
366 /** 366 /**
367 * True if this test is dependent on another test completing before it can 367 * True if this test is dependent on another test completing before it can
368 * star (for example, we might need to depend on some other test completing 368 * star (for example, we might need to depend on some other test completing
369 * first). 369 * first).
370 */ 370 */
371 bool waitingForOtherTest; 371 bool waitingForOtherTest;
372 372
373 /** 373 /**
374 * The set of test cases that wish to be notified when this test has 374 * The set of test cases that wish to be notified when this test has
375 * completed. 375 * completed.
376 */ 376 */
377 List<BrowserTestCase> observers; 377 List<BrowserTestCase> observers;
378 378
379 BrowserTestCase(displayName, commands, configuration, completedHandler, 379 BrowserTestCase(displayName, commands, configuration, completedHandler,
380 expectedOutcomes, info, isNegative, [this.waitingForOtherTest = false]) 380 expectedOutcomes, info, isNegative, [this.waitingForOtherTest = false])
381 : super(displayName, commands, configuration, completedHandler, 381 : super(displayName, commands, configuration, completedHandler,
382 expectedOutcomes, isNegative: isNegative, info: info) { 382 expectedOutcomes, isNegative: isNegative, info: info) {
(...skipping 19 matching lines...) Expand all
402 */ 402 */
403 void notifyObservers() { 403 void notifyObservers() {
404 for (BrowserTestCase testCase in observers) { 404 for (BrowserTestCase testCase in observers) {
405 testCase.waitingForOtherTest = false; 405 testCase.waitingForOtherTest = false;
406 } 406 }
407 } 407 }
408 } 408 }
409 409
410 410
411 /** 411 /**
412 * CommandOutput records the output of a completed command: the process's exit 412 * CommandOutput records the output of a completed command: the process's exit
413 * code, the standard output and standard error, whether the process timed out, 413 * code, the standard output and standard error, whether the process timed out,
414 * and the time the process took to run. It also contains a pointer to the 414 * and the time the process took to run. It also contains a pointer to the
415 * [TestCase] this is the output of. 415 * [TestCase] this is the output of.
416 */ 416 */
417 abstract class CommandOutput { 417 abstract class CommandOutput {
418 factory CommandOutput.fromCase(TestCase testCase, 418 factory CommandOutput.fromCase(TestCase testCase,
419 Command command, 419 Command command,
420 int exitCode, 420 int exitCode,
421 bool incomplete, 421 bool incomplete,
422 bool timedOut, 422 bool timedOut,
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 // so we have to do this check first. 624 // so we have to do this check first.
625 var stderrLines = new String.fromCharCodes(super.stderr).split("\n"); 625 var stderrLines = new String.fromCharCodes(super.stderr).split("\n");
626 for (String line in stderrLines) { 626 for (String line in stderrLines) {
627 if (line.contains('Gtk-WARNING **: cannot open display: :99') || 627 if (line.contains('Gtk-WARNING **: cannot open display: :99') ||
628 line.contains('Failed to run command. return code=1')) { 628 line.contains('Failed to run command. return code=1')) {
629 // If we get the X server error, or DRT crashes with a core dump, retry 629 // If we get the X server error, or DRT crashes with a core dump, retry
630 // the test. 630 // the test.
631 if ((testCase as BrowserTestCase).numRetries > 0) { 631 if ((testCase as BrowserTestCase).numRetries > 0) {
632 requestRetry = true; 632 requestRetry = true;
633 } 633 }
634 printDebug("Failed because of missing XDisplay"); 634 printDebug("Test failure because of missing XDisplay");
635 return true; 635 return true;
636 } 636 }
637 } 637 }
638 return false; 638 return false;
639 } 639 }
640 640
641 bool get _failedBecauseOfUnexpectedDRTOutput { 641 bool get _failedBecauseOfUnexpectedDRTOutput {
642 /* 642 /*
643 * The output of DumpRenderTree is different for pixel tests than for 643 * The output of DumpRenderTree is different for pixel tests than for
644 * layout tests. 644 * layout tests.
(...skipping 28 matching lines...) Expand all
673 var startPosition = newLineAfterContentLength + 673 var startPosition = newLineAfterContentLength +
674 bytesNewLine.length; 674 bytesNewLine.length;
675 var endPosition = stdout.length - bytesEOF.length; 675 var endPosition = stdout.length - bytesEOF.length;
676 676
677 var _failed = !areByteArraysEqual(expectedContent, 677 var _failed = !areByteArraysEqual(expectedContent,
678 0, 678 0,
679 stdout, 679 stdout,
680 startPosition, 680 startPosition,
681 endPosition - startPosition); 681 endPosition - startPosition);
682 if (_failed) { 682 if (_failed) {
683 printDebug("Failed because command.expectedOutputFile doesn't " 683 printDebug("Test failure because command.expectedOutputFile "
684 "match stdout of DRT"); 684 "doesn't match stdout of DRT");
685 } 685 }
686 return _failed; 686 return _failed;
687 } 687 }
688 } 688 }
689 printDebug("Failed because we didn't find 'Content-Length' in the DRT " 689 printDebug("Test failure because we didn't find 'Content-Length' in the"
690 "output"); 690 " DRT output");
691 return true; 691 return true;
692 } else { 692 } else {
693 var _failed = !areByteArraysEqual(expectedContent, 0, 693 var _failed = !areByteArraysEqual(expectedContent, 0,
694 stdout, 0, 694 stdout, 0,
695 stdout.length); 695 stdout.length);
696 if (_failed) { 696 if (_failed) {
697 printDebug("Failed because command.expectedOutputFile doesn't match " 697 printDebug("Test failure because command.expectedOutputFile doesn't "
698 "stdout of DRT"); 698 "match stdout of DRT");
699 } 699 }
700 return _failed; 700 return _failed;
701 } 701 }
702 } 702 }
703 printDebug("Failed because command.expectedOutputFile doesn't exist"); 703 printDebug("Test failure because command.expectedOutputFile doesn't exist");
704 return true; 704 return true;
705 } 705 }
706 706
707 bool get _browserTestFailure { 707 bool get _browserTestFailure {
708 // Browser tests fail unless stdout contains 708 // Browser tests fail unless stdout contains
709 // 'Content-Type: text/plain' followed by 'PASS'. 709 // 'Content-Type: text/plain' followed by 'PASS'.
710 bool has_content_type = false; 710 bool has_content_type = false;
711 var stdoutLines = new String.fromCharCodes(super.stdout).split("\n"); 711 var stdoutLines = new String.fromCharCodes(super.stdout).split("\n");
712 for (String line in stdoutLines) { 712 for (String line in stdoutLines) {
713 switch (line) { 713 switch (line) {
714 case 'Content-Type: text/plain': 714 case 'Content-Type: text/plain':
715 has_content_type = true; 715 has_content_type = true;
716 break; 716 break;
717 case 'PASS': 717 case 'PASS':
718 if (has_content_type) { 718 if (has_content_type) {
719 var _failed = (exitCode != 0 && !hasCrashed); 719 var _failed = (exitCode != 0 && !hasCrashed);
720 if (_failed) { 720 if (_failed) {
721 printDebug("Failed because '(exitCode != 0 && !hasCrashed) was " 721 printDebug("Test failure because '(exitCode != 0 && !hasCrashed) "
722 "true"); 722 "was true");
723 } 723 }
724 return _failed; 724 return _failed;
725 } 725 }
726 break; 726 break;
727 } 727 }
728 } 728 }
729 printDebug("Failed because content-type: text/plain + PASS was not found"); 729 printDebug("Test failure because content-type: text/plain + PASS was not "
730 "found");
730 return true; 731 return true;
731 } 732 }
732 733
733 void printDebug(String msg) { 734 void printDebug(String msg) {
734 print(""); 735 print("");
735 print("DEBUG(infrastructure): $msg"); 736 print("DEBUG(infrastructure): $msg");
736 print("DEBUG(infrastructure): cmd.executable: '${command.executable}'"); 737 print("DEBUG(infrastructure): cmd.executable: '${command.executable}'");
737 print("DEBUG(infrastructure): cmd.arguments: '${command.arguments}'"); 738 print("DEBUG(infrastructure): cmd.arguments: '${command.arguments}'");
738 print("DEBUG(infrastructure): cmd.environment: '${command.environment}'"); 739 print("DEBUG(infrastructure): cmd.environment: '${command.environment}'");
739 print(""); 740 print("");
(...skipping 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after
1754 // the developer doesn't waste his or her time trying to fix a bunch of 1755 // the developer doesn't waste his or her time trying to fix a bunch of
1755 // tests that appear to be broken but were actually just flakes that 1756 // tests that appear to be broken but were actually just flakes that
1756 // didn't get retried because there had already been one failure. 1757 // didn't get retried because there had already been one failure.
1757 bool allowRetry = _MAX_FAILED_NO_RETRY > _progress.numFailedTests; 1758 bool allowRetry = _MAX_FAILED_NO_RETRY > _progress.numFailedTests;
1758 new RunningProcess(test, allowRetry, this).start(); 1759 new RunningProcess(test, allowRetry, this).start();
1759 } 1760 }
1760 _numProcesses++; 1761 _numProcesses++;
1761 } 1762 }
1762 } 1763 }
1763 } 1764 }
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