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 #import("test_suite.dart"); | 9 #import("test_suite.dart"); |
| 10 | 10 |
| 11 /** | 11 /** |
| 12 * Classes and methods for executing tests. | 12 * Classes and methods for executing tests. |
| 13 * | 13 * |
| 14 * This module includes: | 14 * This module includes: |
| 15 * - Managing parallel execution of tests, including timeout checks. | 15 * - Managing parallel execution of tests, including timeout checks. |
| 16 * - Evaluating the output of each test as pass/fail/crash/timeout. | 16 * - Evaluating the output of each test as pass/fail/crash/timeout. |
| 17 */ | 17 */ |
| 18 | 18 |
| 19 final int NO_TIMEOUT = 0; | 19 final int NO_TIMEOUT = 0; |
| 20 | 20 |
| 21 | 21 |
| 22 class TestCase { | 22 class TestCase { |
| 23 String executablePath; | 23 String executablePath; |
| 24 List<String> arguments; | 24 List<String> arguments; |
| 25 int timeout; | 25 Map configuration; |
| 26 String commandLine; | 26 String commandLine; |
| 27 String displayName; | 27 String displayName; |
| 28 TestOutput output; | 28 TestOutput output; |
| 29 bool isNegative; | 29 bool isNegative; |
| 30 Set<String> expectedOutcomes; | 30 Set<String> expectedOutcomes; |
| 31 Function completedHandler; | 31 Function completedHandler; |
| 32 | 32 |
| 33 TestCase(this.displayName, | 33 TestCase(this.displayName, |
| 34 this.executablePath, | 34 this.executablePath, |
| 35 this.arguments, | 35 this.arguments, |
| 36 this.timeout, | 36 this.configuration, |
| 37 this.completedHandler, | 37 this.completedHandler, |
| 38 this.expectedOutcomes, | 38 this.expectedOutcomes, |
| 39 [this.isNegative = false]) { | 39 [this.isNegative = false]) { |
| 40 if (!isNegative) { | 40 if (!isNegative) { |
| 41 this.isNegative = displayName.contains("NegativeTest"); | 41 this.isNegative = displayName.contains("NegativeTest"); |
| 42 } | 42 } |
| 43 commandLine = executablePath; | 43 commandLine = "$executablePath ${Strings.join(arguments, ' ')}"; |
| 44 for (var arg in arguments) { | 44 |
| 45 commandLine += " " + arg; | 45 // Special command handling. If a special command is specified |
| 46 // we have to completely rewrite the command that we are using. | |
| 47 // We generate a new command-line that is the special command | |
| 48 // where we replace '@' with the original command. | |
| 49 var specialCommand = configuration['special-command']; | |
| 50 if (!specialCommand.isEmpty()) { | |
| 51 Expect.isTrue(specialCommand.contains('@'), | |
| 52 "special-command must contain a '@' char"); | |
| 53 var specialCommandSplit = specialCommand.split('@'); | |
| 54 var prefix = specialCommandSplit[0]; | |
| 55 var suffix = specialCommandSplit[1]; | |
| 56 commandLine = '$prefix $commandLine $suffix'; | |
| 57 var newArguments = []; | |
| 58 if (prefix.length > 0) { | |
| 59 var prefixSplit = prefix.split(' '); | |
| 60 var newExcecutablePath = prefixSplit[0]; | |
|
Bill Hesse
2011/12/07 13:14:14
newExecutablePath.
Mads Ager (google)
2011/12/07 13:23:02
Thanks. Done!
| |
| 61 for (int i = 1; i < prefixSplit.length; i++) { | |
| 62 var current = prefixSplit[i]; | |
| 63 if (!current.isEmpty()) newArguments.add(current); | |
| 64 } | |
| 65 newArguments.add(executablePath); | |
| 66 executablePath = newExcecutablePath; | |
| 67 } | |
| 68 newArguments.addAll(arguments); | |
| 69 var suffixSplit = prefix.split(' '); | |
|
Bill Hesse
2011/12/07 13:14:14
This will not handle arguments with embedded space
Mads Ager (google)
2011/12/07 13:23:02
At this point I don't think that can happen. All t
| |
| 70 suffixSplit.forEach((e) { | |
| 71 if (!e.isEmpty()) newArguments.add(e); | |
| 72 }); | |
| 73 arguments = newArguments; | |
| 46 } | 74 } |
| 47 } | 75 } |
| 48 | 76 |
| 77 int get timeout() => configuration['timeout']; | |
| 78 | |
| 49 void completed() { completedHandler(this); } | 79 void completed() { completedHandler(this); } |
| 50 } | 80 } |
| 51 | 81 |
| 52 | 82 |
| 53 class TestOutput { | 83 class TestOutput { |
| 54 // The TestCase this is the output from. | 84 // The TestCase this is the output from. |
| 55 TestCase testCase; | 85 TestCase testCase; |
| 56 int exitCode; | 86 int exitCode; |
| 57 bool timedOut; | 87 bool timedOut; |
| 58 bool failed = false; | 88 bool failed = false; |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 350 } | 380 } |
| 351 | 381 |
| 352 DartcBatchRunnerProcess _getDartcBatchRunnerProcess() { | 382 DartcBatchRunnerProcess _getDartcBatchRunnerProcess() { |
| 353 for (int i = 0; i < _batchProcesses.length; i++) { | 383 for (int i = 0; i < _batchProcesses.length; i++) { |
| 354 var runner = _batchProcesses[i]; | 384 var runner = _batchProcesses[i]; |
| 355 if (!runner.active) return runner; | 385 if (!runner.active) return runner; |
| 356 } | 386 } |
| 357 throw new Exception('Unable to find inactive batch runner.'); | 387 throw new Exception('Unable to find inactive batch runner.'); |
| 358 } | 388 } |
| 359 | 389 |
| 360 void _printTestCase(TestCase testCase) { | |
| 361 var path = testCase.executablePath; | |
| 362 var args = Strings.join(testCase.arguments, ' '); | |
| 363 print('# $path $args'); | |
| 364 } | |
| 365 | |
| 366 void _tryRunTest() { | 390 void _tryRunTest() { |
| 367 _checkDone(); | 391 _checkDone(); |
| 368 if (_numProcesses < _maxProcesses && !_tests.isEmpty()) { | 392 if (_numProcesses < _maxProcesses && !_tests.isEmpty()) { |
| 369 TestCase test = _tests.removeFirst(); | 393 TestCase test = _tests.removeFirst(); |
| 370 if (_verbose) _printTestCase(test); | 394 if (_verbose) print(test.commandLine); |
| 371 _progress.start(test); | 395 _progress.start(test); |
| 372 Function oldCallback = test.completedHandler; | 396 Function oldCallback = test.completedHandler; |
| 373 Function wrapper = (TestCase test_arg) { | 397 Function wrapper = (TestCase test_arg) { |
| 374 _numProcesses--; | 398 _numProcesses--; |
| 375 _progress.done(test_arg); | 399 _progress.done(test_arg); |
| 376 _tryRunTest(); | 400 _tryRunTest(); |
| 377 oldCallback(test_arg); | 401 oldCallback(test_arg); |
| 378 }; | 402 }; |
| 379 test.completedHandler = wrapper; | 403 test.completedHandler = wrapper; |
| 380 if (test.executablePath.contains('compiler')) { | 404 if (test.executablePath.contains('compiler')) { |
| 381 _ensureDartcBatchRunnersStarted(test.executablePath); | 405 _ensureDartcBatchRunnersStarted(test.executablePath); |
| 382 _getDartcBatchRunnerProcess().startTest(test); | 406 _getDartcBatchRunnerProcess().startTest(test); |
| 383 } else { | 407 } else { |
| 384 new RunningProcess(test).start(); | 408 new RunningProcess(test).start(); |
| 385 } | 409 } |
| 386 _numProcesses++; | 410 _numProcesses++; |
| 387 } | 411 } |
| 388 } | 412 } |
| 389 } | 413 } |
| OLD | NEW |