Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 #library("test_runner"); | 5 #library("test_runner"); |
| 6 | 6 |
| 7 #import("status_file_parser.dart"); | 7 #import("status_file_parser.dart"); |
| 8 #import("test_progress.dart"); | 8 #import("test_progress.dart"); |
| 9 | 9 |
| 10 /** | 10 /** |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 } else if (os == 'macos') { | 26 } else if (os == 'macos') { |
| 27 buildDir = 'xcodebuild/'; | 27 buildDir = 'xcodebuild/'; |
| 28 } | 28 } |
| 29 buildDir += (configuration['mode'] == 'debug') ? 'Debug_' : 'Release_'; | 29 buildDir += (configuration['mode'] == 'debug') ? 'Debug_' : 'Release_'; |
| 30 buildDir += configuration['architecture'] + '/'; | 30 buildDir += configuration['architecture'] + '/'; |
| 31 return buildDir; | 31 return buildDir; |
| 32 } | 32 } |
| 33 | 33 |
| 34 | 34 |
| 35 String getExecutableName(Map configuration) { | 35 String getExecutableName(Map configuration) { |
| 36 if (configuration['component'] == 'vm') { | 36 switch (configuration['component']) { |
| 37 return 'dart_bin'; | 37 case 'vm': |
| 38 } else if (configuration['component'] == 'dartc') { | 38 return 'dart_bin'; |
| 39 return 'dartc'; | 39 case 'dartc': |
| 40 } else { | 40 return 'dartc'; |
| 41 throw "Unknown executable for: ${configuration['component']}"; | 41 case 'frog': |
| 42 case 'leg': | |
| 43 return 'frog/bin/frog'; | |
| 44 case 'frogsh': | |
| 45 return 'frog/bin/frogsh'; | |
| 46 default: | |
| 47 throw "Unknown executable for: ${configuration['component']}"; | |
| 42 } | 48 } |
| 43 } | 49 } |
| 44 | 50 |
| 45 | 51 |
| 46 String getDartShellFileName(Map configuration) { | 52 String getDartShellFileName(Map configuration) { |
| 47 var name = getBuildDir(configuration) + getExecutableName(configuration); | 53 var name = getBuildDir(configuration) + getExecutableName(configuration); |
| 48 if (!(new File(name)).existsSync()) { | 54 if (!(new File(name)).existsSync()) { |
| 49 throw "Executable '$name' does not exist"; | 55 throw "Executable '$name' does not exist"; |
| 50 } | 56 } |
| 51 return name; | 57 return name; |
| 52 } | 58 } |
| 53 | 59 |
| 54 | 60 |
| 55 class TestCase { | 61 class TestCase { |
| 56 String executablePath; | 62 String executablePath; |
| 57 List<String> arguments; | 63 List<String> arguments; |
| 64 int timeout; | |
| 58 String commandLine; | 65 String commandLine; |
| 59 String displayName; | 66 String displayName; |
| 60 TestOutput output; | 67 TestOutput output; |
| 61 Set<String> expectedOutcomes; | 68 Set<String> expectedOutcomes; |
| 62 Function completedHandler; | 69 Function completedHandler; |
| 63 | 70 |
| 64 TestCase(this.displayName, this.executablePath, this.arguments, | 71 TestCase(this.displayName, this.executablePath, this.arguments, |
| 65 this.completedHandler, this.expectedOutcomes) { | 72 this.timeout, this.completedHandler, this.expectedOutcomes) { |
| 66 commandLine = executablePath; | 73 commandLine = executablePath; |
| 67 for (var arg in arguments) { | 74 for (var arg in arguments) { |
| 68 commandLine += " " + arg; | 75 commandLine += " " + arg; |
| 69 } | 76 } |
| 70 } | 77 } |
| 71 | 78 |
| 72 bool get isNegative() => displayName.contains("NegativeTest"); | 79 bool get isNegative() => displayName.contains("NegativeTest"); |
| 73 | 80 |
| 74 void completed() { completedHandler(this); } | 81 void completed() { completedHandler(this); } |
| 75 } | 82 } |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 88 TestOutput(this.testCase, this.exitCode, this.timedOut, this.stdout, | 95 TestOutput(this.testCase, this.exitCode, this.timedOut, this.stdout, |
| 89 this.stderr, this.time) { | 96 this.stderr, this.time) { |
| 90 testCase.output = this; | 97 testCase.output = this; |
| 91 } | 98 } |
| 92 | 99 |
| 93 String get result() => | 100 String get result() => |
| 94 hasCrashed ? CRASH : (hasTimedOut ? TIMEOUT : (hasFailed ? FAIL : PASS)); | 101 hasCrashed ? CRASH : (hasTimedOut ? TIMEOUT : (hasFailed ? FAIL : PASS)); |
| 95 | 102 |
| 96 bool get unexpectedOutput() => !testCase.expectedOutcomes.contains(result); | 103 bool get unexpectedOutput() => !testCase.expectedOutcomes.contains(result); |
| 97 | 104 |
| 98 bool get hasCrashed() => !timedOut && exitCode != -1 && exitCode != 0; | 105 bool get hasCrashed() { |
| 106 return !timedOut && exitCode != -1 && exitCode < 0; | |
|
Bill Hesse
2011/11/11 13:42:52
Why the curly braces?
Mads Ager (google)
2011/11/11 14:02:07
Thanks. I'll get rid of them. I added that while d
| |
| 107 } | |
| 99 | 108 |
| 100 bool get hasTimedOut() => timedOut; | 109 bool get hasTimedOut() => timedOut; |
| 101 | 110 |
| 102 bool get didFail() => exitCode != 0 && !hasCrashed; | 111 bool get didFail() => exitCode != 0 && !hasCrashed; |
| 103 | 112 |
| 104 // Reverse result of a negative test. | 113 // Reverse result of a negative test. |
| 105 bool get hasFailed() => (testCase.isNegative ? !didFail : didFail); | 114 bool get hasFailed() => (testCase.isNegative ? !didFail : didFail); |
| 106 } | 115 } |
| 107 | 116 |
| 108 | 117 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 165 process.kill(); | 174 process.kill(); |
| 166 } | 175 } |
| 167 } | 176 } |
| 168 | 177 |
| 169 | 178 |
| 170 class ProcessQueue { | 179 class ProcessQueue { |
| 171 int numProcesses = 0; | 180 int numProcesses = 0; |
| 172 final int maxProcesses; | 181 final int maxProcesses; |
| 173 Queue<TestCase> tests; | 182 Queue<TestCase> tests; |
| 174 ProgressIndicator progress; | 183 ProgressIndicator progress; |
| 184 var onDone; | |
| 175 | 185 |
| 176 ProcessQueue(this.maxProcesses, this.progress) | 186 ProcessQueue(Map configuration, this.onDone) |
| 177 : tests = new Queue<TestCase>(); | 187 : tests = new Queue<TestCase>(), |
| 188 maxProcesses = configuration['tasks'], | |
| 189 progress = new CompactProgressIndicator(); | |
| 178 | 190 |
| 179 tryRunTest() { | 191 tryRunTest() { |
| 192 if (tests.isEmpty() && numProcesses == 0) { | |
| 193 onDone(); | |
| 194 } | |
|
Bill Hesse
2011/11/11 13:42:52
This looks like a race condition - if one test is
Mads Ager (google)
2011/11/11 14:02:07
That is true. This is all temporary. I will rip it
| |
| 180 if (numProcesses < maxProcesses && !tests.isEmpty()) { | 195 if (numProcesses < maxProcesses && !tests.isEmpty()) { |
| 181 TestCase test = tests.removeFirst(); | 196 TestCase test = tests.removeFirst(); |
| 182 progress.start(test); | 197 progress.start(test); |
| 183 // TODO(whesse): Refactor into various test output methods. | |
| 184 Function old_callback = test.completedHandler; | 198 Function old_callback = test.completedHandler; |
| 185 Function wrapper = (TestCase test_arg) { | 199 Function wrapper = (TestCase test_arg) { |
| 186 numProcesses--; | 200 numProcesses--; |
| 187 progress.done(test_arg); | 201 progress.done(test_arg); |
| 188 tryRunTest(); | 202 tryRunTest(); |
| 189 old_callback(test_arg); | 203 old_callback(test_arg); |
| 190 }; | 204 }; |
| 191 test.completedHandler = wrapper; | 205 test.completedHandler = wrapper; |
| 192 | 206 new RunningProcess(test, test.timeout).start(); |
| 193 // TODO(whesse): Add timeout information to TestCase, use it here. | |
| 194 new RunningProcess(test, 60).start(); | |
| 195 numProcesses++; | 207 numProcesses++; |
| 196 } | 208 } |
| 197 } | 209 } |
| 198 | 210 |
| 199 runTest(TestCase test) { | 211 runTest(TestCase test) { |
| 200 progress.testAdded(); | 212 progress.testAdded(); |
| 201 tests.add(test); | 213 tests.add(test); |
| 202 tryRunTest(); | 214 tryRunTest(); |
| 203 } | 215 } |
| 204 } | 216 } |
| OLD | NEW |