Chromium Code Reviews| Index: tools/testing/dart/test_runner.dart |
| diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart |
| index 7eddd3f73339cc679b4a7c3b8698506c21829d74..1ce493085ef411f46eec55e04283193ed4325945 100644 |
| --- a/tools/testing/dart/test_runner.dart |
| +++ b/tools/testing/dart/test_runner.dart |
| @@ -162,7 +162,44 @@ class BrowserTestCase extends TestCase { |
| * the time the process took to run. It also contains a pointer to the |
| * [TestCase] this is the output of. |
| */ |
| -class TestOutput { |
| + |
| +// TODO(zundel): should be abstract? |
| +class TestOutput { |
| + |
|
Bill Hesse
2012/02/28 14:06:38
Could this be an interface? Do interfaces have fa
zundel
2012/02/28 14:12:09
you can put a constructor and provide a default im
|
| + TestOutput() { |
| + } |
|
Bill Hesse
2012/02/28 14:06:38
Is the split between TestOutput and TestOutputImpl
zundel
2012/02/28 14:12:09
On 2012/02/28 14:06:38, Bill Hesse wrote:
> Is the
|
| + |
|
Bill Hesse
2012/02/28 14:06:38
I think the factory should just be called TestOutp
zundel
2012/02/28 14:12:09
I agree, BUT it turns out that there is an implici
zundel
2012/02/28 14:22:35
I meant factory constructor. Like this:
class Fo
|
| + factory TestOutput.fromCase (testCase, exitCode, timedOut, stdout, stderr, |
| + time) { |
| + if (testCase is BrowserTestCase) { |
| + return new BrowserTestOutputImpl(testCase, exitCode, timedOut, |
| + stdout, stderr, time); |
| + } else if (testCase.configuration['component'] == 'dartc') { |
| + return new AnalysisTestOutputImpl(testCase, exitCode, timedOut, |
| + stdout, stderr, time); |
| + } |
| + return new TestOutputImpl(testCase, exitCode, timedOut, |
| + stdout, stderr, time); |
| + } |
| + |
| + abstract String get result(); |
| + |
| + abstract bool get unexpectedOutput(); |
| + |
| + abstract bool get hasCrashed(); |
| + |
| + abstract bool get hasTimedOut(); |
| + |
| + abstract bool get didFail(); |
| + |
| + List<String> get errors() { return []; } |
| + |
| + List<String> get staticWarnings() { return []; } |
| + |
| + List<String> get warnings() { return []; } |
| +} |
| + |
| +class TestOutputImpl extends TestOutput { |
| TestCase testCase; |
| int exitCode; |
| bool timedOut; |
| @@ -170,13 +207,14 @@ class TestOutput { |
| List<String> stdout; |
| List<String> stderr; |
| Duration time; |
| + |
| /** |
| * Set to true if we encounter a condition in the output that indicates we |
| * need to rerun this test. |
| */ |
| bool requestRetry; |
| - TestOutput(this.testCase, this.exitCode, this.timedOut, this.stdout, |
| + TestOutputImpl(this.testCase, this.exitCode, this.timedOut, this.stdout, |
| this.stderr, this.time) { |
| testCase.output = this; |
| requestRetry = false; |
| @@ -204,8 +242,18 @@ class TestOutput { |
| bool get hasTimedOut() => timedOut; |
| bool get didFail() { |
| - if (testCase is !BrowserTestCase) return (exitCode != 0 && !hasCrashed); |
| + return (exitCode != 0 && !hasCrashed); |
| + } |
| + |
| + // Reverse result of a negative test. |
| + bool get hasFailed() => (testCase.isNegative ? !didFail : didFail); |
| +} |
| +class BrowserTestOutputImpl extends TestOutputImpl { |
|
Bill Hesse
2012/02/28 14:06:38
This is good. A step towards a final refactoring,
|
| + BrowserTestOutputImpl(testCase, exitCode, timedOut, stdout, stderr, time) : |
| + super(testCase, exitCode, timedOut, stdout, stderr, time); |
| + |
| + bool get didFail() { |
| // Browser case: |
| // If the browser test failed, it may have been because DumpRenderTree |
| // and the virtual framebuffer X server didn't hook up, or DRT crashed with |
| @@ -230,12 +278,80 @@ class TestOutput { |
| } |
| previous_line = line; |
| } |
| - |
| return true; |
| } |
| +} |
| - // Reverse result of a negative test. |
| - bool get hasFailed() => (testCase.isNegative ? !didFail : didFail); |
| +class AnalysisTestOutputImpl extends TestOutputImpl { |
| + final errors; |
| + final warnings; |
| + final staticWarnings; |
| + |
| + AnalysisTestOutputImpl(testCase, exitCode, timedOut, stdout, stderr, time) : |
| + super(testCase, exitCode, timedOut, stdout, stderr, time), |
| + errors = new Map<int, String>(), |
| + warnings = new Map<int, String>(), |
| + staticWarnings = new Map<int, String>() { |
| + |
| + // read the returned list of errors and stuff them away. |
| + for (String line in stderr) { |
| + if (line.length == 0) continue; |
| + List<String> fields = splitMachineError(line); |
| + switch(fields[0]) { |
| + case "ERROR": |
| + errors[fields[4]] = fields; |
| + break; |
| + case "WARNING": |
| + if (fields[1] == "STATIC_TYPE") { |
| + staticWarnings[fields[4]] = fields; |
| + } else { |
| + warnings[fields[4]] = fields; |
| + } |
| + break; |
| + } |
|
Bill Hesse
2012/02/28 14:06:38
Do you want a default case here, or an assert?
zundel
2012/02/28 14:12:09
There is some output to stderr that needs to be ig
|
| + } |
| + } |
| + |
| + bool get didFail() { |
| + if (hasCrashed) return false; |
| + |
| + if (this.testCase.commandLine.contains('--fatal-type-errors')) { |
| + if (staticWarnings.length != 0) { |
| + return true; |
| + } |
| + } else if (errors.length != 0) { |
| + return true; |
| + } |
| + |
| + // TODO(zundel): more sophisticated analysis |
| + |
| + return false; |
| + //return exitCode != 0; |
| + } |
| + |
| + // Parse a line delimited by the | character using \ as an escape charager |
| + // like: FOO|BAR|FOO\|BAR|FOO\\BAZ as 4 fields: FOO BAR FOO|BAR FOO\BAZ |
| + List<String> splitMachineError(String line) { |
| + StringBuffer field = new StringBuffer(); |
| + List<String> result = []; |
| + bool escaped = false; |
| + for (var i = 0 ; i < line.length; i++) { |
| + var c = line[i]; |
| + if (!escaped && c == '\\') { |
| + escaped = true; |
| + continue; |
| + } |
| + escaped = false; |
| + if (c == '|') { |
| + result.add(field.toString()); |
| + field.clear(); |
| + continue; |
| + } |
| + field.add(c); |
| + } |
| + result.add(field.toString()); |
| + return result; |
| + } |
| } |
| /** |
| @@ -264,8 +380,8 @@ class RunningProcess { |
| [this.allowRetries, this.processQueue]); |
| void exitHandler(int exitCode) { |
| - new TestOutput(testCase, exitCode, timedOut, stdout, |
| - stderr, new Date.now().difference(startTime)); |
| + new TestOutput.fromCase(testCase, exitCode, timedOut, stdout, |
| + stderr, new Date.now().difference(startTime)); |
| process.close(); |
| timeoutTimer.cancel(); |
| if (testCase.output.unexpectedOutput && testCase.configuration['verbose']) { |
| @@ -456,8 +572,8 @@ class BatchRunnerProcess { |
| var exitCode = 0; |
| if (outcome == "CRASH") exitCode = -10; |
| if (outcome == "FAIL" || outcome == "TIMEOUT") exitCode = 1; |
| - new TestOutput(test, exitCode, outcome == "TIMEOUT", _testStdout, |
| - _testStderr, new Date.now().difference(_startTime)); |
| + new TestOutput.fromCase(test, exitCode, outcome == "TIMEOUT", _testStdout, |
| + _testStderr, new Date.now().difference(_startTime)); |
| test.completed(); |
| } |