Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 372 } | 372 } |
| 373 | 373 |
| 374 bool _equal(Command other) { | 374 bool _equal(Command other) { |
| 375 return | 375 return |
| 376 other is AnalysisCommand && | 376 other is AnalysisCommand && |
| 377 super._equal(other) && | 377 super._equal(other) && |
| 378 flavor == other.flavor; | 378 flavor == other.flavor; |
| 379 } | 379 } |
| 380 } | 380 } |
| 381 | 381 |
| 382 class VmCommand extends Command { | |
| 383 VmCommand._(String executable, | |
| 384 List<String> arguments, | |
| 385 String configurationDir) | |
| 386 : super._("vm", executable, arguments, configurationDir); | |
| 387 } | |
| 388 | |
| 389 class JSCommandlineCommand extends Command { | |
| 390 JSCommandlineCommand._(String displayName, | |
| 391 String executable, | |
| 392 List<String> arguments, | |
| 393 String configurationDir, | |
| 394 [Map<String, String> environmentOverrides = null]) | |
| 395 : super._(displayName, | |
| 396 executable, | |
| 397 arguments, | |
| 398 configurationDir, | |
| 399 environmentOverrides); | |
| 400 } | |
| 401 | |
| 382 class CommandBuilder { | 402 class CommandBuilder { |
| 383 static final instance = new CommandBuilder._(); | 403 static final instance = new CommandBuilder._(); |
| 384 | 404 |
| 385 final _cachedCommands = new Map<Command, Command>(); | 405 final _cachedCommands = new Map<Command, Command>(); |
| 386 | 406 |
| 387 CommandBuilder._(); | 407 CommandBuilder._(); |
| 388 | 408 |
| 389 ContentShellCommand getContentShellCommand(String executable, | 409 ContentShellCommand getContentShellCommand(String executable, |
| 390 String htmlFile, | 410 String htmlFile, |
| 391 List<String> options, | 411 List<String> options, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 433 } | 453 } |
| 434 | 454 |
| 435 AnalysisCommand getAnalysisCommand( | 455 AnalysisCommand getAnalysisCommand( |
| 436 String displayName, executable, arguments, String configurationDir, | 456 String displayName, executable, arguments, String configurationDir, |
| 437 {String flavor: 'dartanalyzer'}) { | 457 {String flavor: 'dartanalyzer'}) { |
| 438 var command = new AnalysisCommand._( | 458 var command = new AnalysisCommand._( |
| 439 flavor, displayName, executable, arguments, configurationDir); | 459 flavor, displayName, executable, arguments, configurationDir); |
| 440 return _getUniqueCommand(command); | 460 return _getUniqueCommand(command); |
| 441 } | 461 } |
| 442 | 462 |
| 463 VmCommand getVmCommand(String executable, | |
| 464 List<String> arguments, | |
| 465 String configurationDir) { | |
| 466 var command = new VmCommand._(executable, arguments, configurationDir); | |
| 467 return _getUniqueCommand(command); | |
| 468 } | |
| 469 | |
| 470 Command getJSCommandlineCommand(String displayName, executable, arguments, | |
| 471 String configurationDir, [environment = null]) { | |
| 472 var command = new JSCommandlineCommand._(displayName, executable, arguments, | |
| 473 configurationDir, environment); | |
| 474 return _getUniqueCommand(command); | |
| 475 } | |
| 476 | |
| 443 Command getCommand(String displayName, executable, arguments, | 477 Command getCommand(String displayName, executable, arguments, |
| 444 String configurationDir, [environment = null]) { | 478 String configurationDir, [environment = null]) { |
| 445 var command = new Command._(displayName, executable, arguments, | 479 var command = new Command._(displayName, executable, arguments, |
| 446 configurationDir, environment); | 480 configurationDir, environment); |
| 447 return _getUniqueCommand(command); | 481 return _getUniqueCommand(command); |
| 448 } | 482 } |
| 449 | 483 |
| 450 Command _getUniqueCommand(Command command) { | 484 Command _getUniqueCommand(Command command) { |
| 451 // All Command classes have hashCode/operator==, so we check if this command | 485 // All Command classes have hashCode/operator==, so we check if this command |
| 452 // has already been build, if so we return the cached one, otherwise we | 486 // has already been build, if so we return the cached one, otherwise we |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 483 * Dart2js tests have two commands, one to compile the source and another | 517 * Dart2js tests have two commands, one to compile the source and another |
| 484 * to execute it. Some isolate tests might even have three, if they require | 518 * to execute it. Some isolate tests might even have three, if they require |
| 485 * compiling multiple sources that are run in isolation. | 519 * compiling multiple sources that are run in isolation. |
| 486 */ | 520 */ |
| 487 List<Command> commands; | 521 List<Command> commands; |
| 488 Map<Command, CommandOutput> commandOutputs = new Map<Command,CommandOutput>(); | 522 Map<Command, CommandOutput> commandOutputs = new Map<Command,CommandOutput>(); |
| 489 | 523 |
| 490 Map configuration; | 524 Map configuration; |
| 491 String displayName; | 525 String displayName; |
| 492 bool isNegative; | 526 bool isNegative; |
| 493 Set<String> expectedOutcomes; | 527 Set<Expectation> expectedOutcomes; |
| 494 TestInformation info; | 528 TestInformation info; |
| 495 | 529 |
| 496 TestCase(this.displayName, | 530 TestCase(this.displayName, |
| 497 this.commands, | 531 this.commands, |
| 498 this.configuration, | 532 this.configuration, |
| 499 this.expectedOutcomes, | 533 this.expectedOutcomes, |
| 500 {this.isNegative: false, | 534 {this.isNegative: false, |
| 501 this.info: null}) { | 535 this.info: null}) { |
| 502 if (!isNegative) { | 536 if (!isNegative) { |
| 503 this.isNegative = displayName.contains("negative_test"); | 537 this.isNegative = displayName.contains("negative_test"); |
| 504 } | 538 } |
| 505 } | 539 } |
| 506 | 540 |
| 507 bool get unexpectedOutput { | 541 bool get unexpectedOutput { |
| 508 return !expectedOutcomes.contains(lastCommandOutput.result(this)); | 542 var outcome = lastCommandOutput.result(this); |
| 543 return !expectedOutcomes.any((expectation) { | |
| 544 var result = outcome.canBeOutcomeOf(expectation); | |
| 545 if (result) { | |
| 546 if (outcome != expectation) { | |
| 547 // FIXME/TODO(kustermann): We should bubble this up a bit smarter | |
| 548 //print("Could narrow Expected: $expectation to $outcome"); | |
|
ricow1
2013/09/23 12:07:32
you don't do anything + no FIXME
kustermann
2013/09/23 15:31:34
This was actually intentional -- I left this comme
| |
| 549 } | |
| 550 } | |
| 551 return result; | |
| 552 }); | |
| 509 } | 553 } |
| 510 | 554 |
| 511 String get result => lastCommandOutput.result(this); | 555 Expectation get result => lastCommandOutput.result(this); |
| 512 | 556 |
| 513 CommandOutput get lastCommandOutput { | 557 CommandOutput get lastCommandOutput { |
| 514 if (commandOutputs.length == 0) { | 558 if (commandOutputs.length == 0) { |
| 515 throw new Exception("CommandOutputs is empty, maybe no command was run? (" | 559 throw new Exception("CommandOutputs is empty, maybe no command was run? (" |
| 516 "displayName: '$displayName', " | 560 "displayName: '$displayName', " |
| 517 "configurationString: '$configurationString')"); | 561 "configurationString: '$configurationString')"); |
| 518 } | 562 } |
| 519 return commandOutputs[commands[commandOutputs.length - 1]]; | 563 return commandOutputs[commands[commandOutputs.length - 1]]; |
| 520 } | 564 } |
| 521 | 565 |
| 522 int get timeout { | 566 int get timeout { |
| 523 if (expectedOutcomes.contains(SLOW)) { | 567 if (expectedOutcomes.contains(Expectation.SLOW)) { |
| 524 return configuration['timeout'] * SLOW_TIMEOUT_MULTIPLIER; | 568 return configuration['timeout'] * SLOW_TIMEOUT_MULTIPLIER; |
| 525 } else { | 569 } else { |
| 526 return configuration['timeout']; | 570 return configuration['timeout']; |
| 527 } | 571 } |
| 528 } | 572 } |
| 529 | 573 |
| 530 String get configurationString { | 574 String get configurationString { |
| 531 final compiler = configuration['compiler']; | 575 final compiler = configuration['compiler']; |
| 532 final runtime = configuration['runtime']; | 576 final runtime = configuration['runtime']; |
| 533 final mode = configuration['mode']; | 577 final mode = configuration['mode']; |
| 534 final arch = configuration['arch']; | 578 final arch = configuration['arch']; |
| 535 final checked = configuration['checked'] ? '-checked' : ''; | 579 final checked = configuration['checked'] ? '-checked' : ''; |
| 536 return "$compiler-$runtime$checked ${mode}_$arch"; | 580 return "$compiler-$runtime$checked ${mode}_$arch"; |
| 537 } | 581 } |
| 538 | 582 |
| 539 List<String> get batchTestArguments => commands.last.arguments; | 583 List<String> get batchTestArguments => commands.last.arguments; |
| 540 | 584 |
| 541 bool get usesWebDriver => TestUtils.usesWebDriver(configuration['runtime']); | 585 bool get usesWebDriver => TestUtils.usesWebDriver(configuration['runtime']); |
| 542 | 586 |
| 543 bool get isFlaky { | 587 bool get isFlaky { |
| 544 if (expectedOutcomes.contains(SKIP) || | 588 if (expectedOutcomes.contains(Expectation.SKIP) || |
| 545 expectedOutcomes.contains(SKIP_BY_DESIGN)) { | 589 expectedOutcomes.contains(Expectation.SKIP_BY_DESIGN)) { |
| 546 return false; | 590 return false; |
| 547 } | 591 } |
| 548 | 592 |
| 549 var flags = new Set.from(expectedOutcomes); | 593 return expectedOutcomes |
| 550 flags..remove(OK) | 594 .where((expectation) => !expectation.isMetaExpectation).length > 1; |
| 551 ..remove(SLOW); | |
| 552 return flags.length > 1; | |
| 553 } | 595 } |
| 554 | 596 |
| 555 bool get isFinished { | 597 bool get isFinished { |
| 556 return !lastCommandOutput.successful || | 598 return !lastCommandOutput.successful || |
| 557 commands.length == commandOutputs.length; | 599 commands.length == commandOutputs.length; |
| 558 } | 600 } |
| 559 } | 601 } |
| 560 | 602 |
| 561 | 603 |
| 562 /** | 604 /** |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 578 | 620 |
| 579 /** | 621 /** |
| 580 * CommandOutput records the output of a completed command: the process's exit | 622 * CommandOutput records the output of a completed command: the process's exit |
| 581 * code, the standard output and standard error, whether the process timed out, | 623 * code, the standard output and standard error, whether the process timed out, |
| 582 * and the time the process took to run. It also contains a pointer to the | 624 * and the time the process took to run. It also contains a pointer to the |
| 583 * [TestCase] this is the output of. | 625 * [TestCase] this is the output of. |
| 584 */ | 626 */ |
| 585 abstract class CommandOutput { | 627 abstract class CommandOutput { |
| 586 Command get command; | 628 Command get command; |
| 587 | 629 |
| 588 String result(TestCase testCase); | 630 Expectation result(TestCase testCase); |
| 589 | 631 |
| 590 bool get hasCrashed; | 632 bool get hasCrashed; |
| 591 | 633 |
| 592 bool get hasTimedOut; | 634 bool get hasTimedOut; |
| 593 | 635 |
| 594 bool didFail(testcase); | 636 bool didFail(testcase); |
| 595 | 637 |
| 596 bool hasFailed(TestCase testCase); | 638 bool hasFailed(TestCase testCase); |
| 597 | 639 |
| 598 bool get canRunDependendCommands; | 640 bool get canRunDependendCommands; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 633 CommandOutputImpl(Command this.command, | 675 CommandOutputImpl(Command this.command, |
| 634 int this.exitCode, | 676 int this.exitCode, |
| 635 bool this.timedOut, | 677 bool this.timedOut, |
| 636 List<int> this.stdout, | 678 List<int> this.stdout, |
| 637 List<int> this.stderr, | 679 List<int> this.stderr, |
| 638 Duration this.time, | 680 Duration this.time, |
| 639 bool this.compilationSkipped) { | 681 bool this.compilationSkipped) { |
| 640 diagnostics = []; | 682 diagnostics = []; |
| 641 } | 683 } |
| 642 | 684 |
| 643 String result(TestCase testCase) => hasCrashed ? CRASH : | 685 Expectation result(TestCase testCase) { |
| 644 (hasTimedOut ? TIMEOUT : (hasFailed(testCase) ? FAIL : PASS)); | 686 if (hasCrashed) return Expectation.CRASH; |
| 687 if (hasTimedOut) return Expectation.TIMEOUT; | |
| 688 return hasFailed(testCase) ? Expectation.FAIL : Expectation.PASS; | |
| 689 } | |
| 645 | 690 |
| 646 bool get hasCrashed { | 691 bool get hasCrashed { |
| 647 // The Java dartc runner and dart2js exits with code 253 in case | 692 // The Java dartc runner and dart2js exits with code 253 in case |
| 648 // of unhandled exceptions. | 693 // of unhandled exceptions. |
| 649 if (exitCode == 253) return true; | 694 if (exitCode == 253) return true; |
| 650 if (io.Platform.operatingSystem == 'windows') { | 695 if (io.Platform.operatingSystem == 'windows') { |
| 651 // The VM uses std::abort to terminate on asserts. | 696 // The VM uses std::abort to terminate on asserts. |
| 652 // std::abort terminates with exit code 3 on Windows. | 697 // std::abort terminates with exit code 3 on Windows. |
| 653 if (exitCode == 3) { | 698 if (exitCode == 3) { |
| 654 return !timedOut; | 699 return !timedOut; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 680 return !hasTimedOut && exitCode == 0; | 725 return !hasTimedOut && exitCode == 0; |
| 681 } | 726 } |
| 682 | 727 |
| 683 bool get successful { | 728 bool get successful { |
| 684 // FIXME(kustermann): We may need to change this | 729 // FIXME(kustermann): We may need to change this |
| 685 return !hasTimedOut && exitCode == 0; | 730 return !hasTimedOut && exitCode == 0; |
| 686 } | 731 } |
| 687 | 732 |
| 688 // Reverse result of a negative test. | 733 // Reverse result of a negative test. |
| 689 bool hasFailed(TestCase testCase) { | 734 bool hasFailed(TestCase testCase) { |
| 690 // FIXME(kustermann): this is a hack, remove it | |
| 691 bool isCompilationCommand = testCase.commands.first == command | |
| 692 && testCase.commands.length > 1; | |
| 693 if (isCompilationCommand && | |
| 694 testCase.info != null && testCase.info.hasRuntimeError) { | |
| 695 return exitCode != 0; | |
| 696 } | |
| 697 return testCase.isNegative ? !didFail(testCase) : didFail(testCase); | 735 return testCase.isNegative ? !didFail(testCase) : didFail(testCase); |
| 698 } | 736 } |
| 699 } | 737 } |
| 700 | 738 |
| 701 class BrowserCommandOutputImpl extends CommandOutputImpl { | 739 class BrowserCommandOutputImpl extends CommandOutputImpl { |
| 702 bool _failedBecauseOfMissingXDisplay; | 740 bool _failedBecauseOfMissingXDisplay; |
| 703 | 741 |
| 704 BrowserCommandOutputImpl( | 742 BrowserCommandOutputImpl( |
| 705 command, | 743 command, |
| 706 exitCode, | 744 exitCode, |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 717 time, | 755 time, |
| 718 compilationSkipped) { | 756 compilationSkipped) { |
| 719 _failedBecauseOfMissingXDisplay = _didFailBecauseOfMissingXDisplay(); | 757 _failedBecauseOfMissingXDisplay = _didFailBecauseOfMissingXDisplay(); |
| 720 if (_failedBecauseOfMissingXDisplay) { | 758 if (_failedBecauseOfMissingXDisplay) { |
| 721 DebugLogger.warning("Warning: Test failure because of missing XDisplay"); | 759 DebugLogger.warning("Warning: Test failure because of missing XDisplay"); |
| 722 // If we get the X server error, or DRT crashes with a core dump, retry | 760 // If we get the X server error, or DRT crashes with a core dump, retry |
| 723 // the test. | 761 // the test. |
| 724 } | 762 } |
| 725 } | 763 } |
| 726 | 764 |
| 765 Expectation result(TestCase testCase) { | |
| 766 // Handle crashes and timeouts first | |
| 767 if (hasCrashed) return Expectation.CRASH; | |
| 768 if (hasTimedOut) return Expectation.TIMEOUT; | |
| 769 | |
| 770 var outcome = _getOutcome(); | |
| 771 | |
| 772 if (testCase.info != null && testCase.info.hasRuntimeError) { | |
| 773 if (!outcome.canBeOutcomeOf(Expectation.RUNTIME_ERROR)) { | |
| 774 return Expectation.MISSING_RUNTIME_ERROR; | |
| 775 } | |
| 776 } | |
| 777 | |
| 778 if (testCase.isNegative) { | |
| 779 if (outcome.canBeOutcomeOf(Expectation.FAIL)) return Expectation.PASS; | |
| 780 return Expectation.FAIL; | |
| 781 } | |
| 782 return outcome; | |
| 783 } | |
| 784 | |
| 727 bool get successful => canRunDependendCommands; | 785 bool get successful => canRunDependendCommands; |
| 728 | 786 |
| 729 bool get canRunDependendCommands { | 787 bool get canRunDependendCommands { |
| 730 // We cannot rely on the exit code of content_shell as a method to determine | 788 // We cannot rely on the exit code of content_shell as a method to determine |
| 731 // if we were successful or not. | 789 // if we were successful or not. |
| 732 return super.canRunDependendCommands && !didFail(null); | 790 return super.canRunDependendCommands && !didFail(null); |
| 733 } | 791 } |
| 734 | 792 |
| 735 bool didFail(TestCase _) { | 793 Expectation _getOutcome() { |
| 736 if (_failedBecauseOfMissingXDisplay) { | 794 if (_failedBecauseOfMissingXDisplay) { |
| 737 return true; | 795 return Expectation.FAIL; |
| 738 } | 796 } |
| 739 | 797 |
| 740 if (command.expectedOutputFile != null) { | 798 if (command.expectedOutputFile != null) { |
| 741 // We are either doing a pixel test or a layout test with content shell | 799 // We are either doing a pixel test or a layout test with content shell |
| 742 return _failedBecauseOfUnexpectedDRTOutput; | 800 if (_failedBecauseOfUnexpectedDRTOutput) { |
| 801 return Expectation.FAIL; | |
| 802 } | |
| 743 } | 803 } |
| 744 return _browserTestFailure; | 804 if (_browserTestFailure) { |
| 805 return Expectation.RUNTIME_ERROR; | |
| 806 } | |
| 807 return Expectation.PASS; | |
| 745 } | 808 } |
| 746 | 809 |
| 747 bool _didFailBecauseOfMissingXDisplay() { | 810 bool _didFailBecauseOfMissingXDisplay() { |
| 748 // Browser case: | 811 // Browser case: |
| 749 // If the browser test failed, it may have been because content shell | 812 // If the browser test failed, it may have been because content shell |
| 750 // and the virtual framebuffer X server didn't hook up, or it crashed with | 813 // and the virtual framebuffer X server didn't hook up, or it crashed with |
| 751 // a core dump. Sometimes content shell crashes after it has set the stdout | 814 // a core dump. Sometimes content shell crashes after it has set the stdout |
| 752 // to PASS, so we have to do this check first. | 815 // to PASS, so we have to do this check first. |
| 753 var stderrLines = decodeUtf8(super.stderr).split("\n"); | 816 var stderrLines = decodeUtf8(super.stderr).split("\n"); |
| 754 for (String line in stderrLines) { | 817 for (String line in stderrLines) { |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1036 field = new StringBuffer(); | 1099 field = new StringBuffer(); |
| 1037 continue; | 1100 continue; |
| 1038 } | 1101 } |
| 1039 field.write(c); | 1102 field.write(c); |
| 1040 } | 1103 } |
| 1041 result.add(field.toString()); | 1104 result.add(field.toString()); |
| 1042 return result; | 1105 return result; |
| 1043 } | 1106 } |
| 1044 } | 1107 } |
| 1045 | 1108 |
| 1109 class VmCommandOutputImpl extends CommandOutputImpl { | |
| 1110 static const DART_VM_EXITCODE_COMPILE_TIME_ERROR = 254; | |
| 1111 static const DART_VM_EXITCODE_UNCAUGHT_EXCEPTION = 255; | |
| 1112 | |
| 1113 VmCommandOutputImpl(Command command, int exitCode, bool timedOut, | |
| 1114 List<int> stdout, List<int> stderr, Duration time) | |
| 1115 : super(command, exitCode, timedOut, stdout, stderr, time, false); | |
| 1116 | |
| 1117 Expectation result(TestCase testCase) { | |
| 1118 // Handle crashes and timeouts first | |
| 1119 if (hasCrashed) return Expectation.CRASH; | |
| 1120 if (hasTimedOut) return Expectation.TIMEOUT; | |
| 1121 | |
| 1122 // Multitests are handled specially | |
| 1123 if (testCase.info != null) { | |
| 1124 if (testCase.info.hasCompileError) { | |
| 1125 if (exitCode == DART_VM_EXITCODE_COMPILE_TIME_ERROR) { | |
| 1126 return Expectation.PASS; | |
| 1127 } | |
| 1128 | |
| 1129 // We're not as strict, if the exitCode indicated an uncaught exception | |
| 1130 // we say it passed nonetheless | |
| 1131 // TODO(kustermann): As soon as the VM team makes sure we get correct | |
| 1132 // exit codes, we should remove this. | |
| 1133 if (exitCode == DART_VM_EXITCODE_UNCAUGHT_EXCEPTION) { | |
| 1134 return Expectation.PASS; | |
| 1135 } | |
| 1136 | |
| 1137 return Expectation.MISSING_COMPILETIME_ERROR; | |
| 1138 } | |
| 1139 if (testCase.info.hasRuntimeError) { | |
| 1140 // FIXME(kustermann): Do we consider a "runtimeError" only an uncaught | |
|
ricow1
2013/09/23 12:07:32
FIXME->TODO
kustermann
2013/09/23 15:31:34
Done.
| |
| 1141 // exception or does any nonzero exit code fullfil this requirement? | |
| 1142 if (exitCode != 0) { | |
|
ricow1
2013/09/23 12:07:32
well I guess at least DART_VM_EXITCODE_COMPILE_TIM
kustermann
2013/09/23 15:31:34
I can't do that because some tests will start fail
| |
| 1143 return Expectation.PASS; | |
| 1144 } | |
| 1145 return Expectation.MISSING_RUNTIME_ERROR; | |
| 1146 } | |
| 1147 } | |
| 1148 | |
| 1149 // The actual outcome depends on the exitCode | |
| 1150 Expectation outcome; | |
| 1151 if (exitCode == DART_VM_EXITCODE_COMPILE_TIME_ERROR) { | |
| 1152 outcome = Expectation.COMPILETIME_ERROR; | |
| 1153 } else if (exitCode == DART_VM_EXITCODE_UNCAUGHT_EXCEPTION) { | |
| 1154 outcome = Expectation.RUNTIME_ERROR; | |
| 1155 } else if (exitCode != 0) { | |
| 1156 // This is a general fail, in case we get an unknown nonzero exitcode. | |
| 1157 outcome = Expectation.FAIL; | |
| 1158 } else { | |
| 1159 outcome = Expectation.PASS; | |
| 1160 } | |
| 1161 | |
| 1162 // In case it's a negative test, reverse the result | |
| 1163 if (outcome.canBeOutcomeOf(Expectation.FAIL)) { | |
| 1164 if (testCase.isNegative) outcome = Expectation.PASS; | |
| 1165 } else { | |
| 1166 if (testCase.isNegative) outcome = Expectation.FAIL; | |
| 1167 } | |
| 1168 return outcome; | |
| 1169 } | |
| 1170 } | |
| 1171 | |
| 1172 class CompilationCommandOutputImpl extends CommandOutputImpl { | |
| 1173 static const DART2JS_EXITCODE_CRASH = 253; | |
| 1174 | |
| 1175 CompilationCommandOutputImpl(Command command, int exitCode, bool timedOut, | |
| 1176 List<int> stdout, List<int> stderr, Duration time) | |
| 1177 : super(command, exitCode, timedOut, stdout, stderr, time, false); | |
| 1178 | |
| 1179 Expectation result(TestCase testCase) { | |
| 1180 // Handle general crash/timeout detection. | |
| 1181 if (hasCrashed) return Expectation.CRASH; | |
| 1182 if (hasTimedOut) return Expectation.TIMEOUT; | |
| 1183 | |
| 1184 // Handle dart2js/dart2dart specific crash detection | |
| 1185 if (exitCode == DART2JS_EXITCODE_CRASH || | |
| 1186 exitCode == VmCommandOutputImpl.DART_VM_EXITCODE_COMPILE_TIME_ERROR || | |
|
ricow1
2013/09/23 12:07:32
If seems a little strange to reference constants i
kustermann
2013/09/23 15:31:34
IMHO it's not strange at all. The VmCommandOutputI
| |
| 1187 exitCode == VmCommandOutputImpl.DART_VM_EXITCODE_UNCAUGHT_EXCEPTION) { | |
| 1188 return Expectation.CRASH; | |
| 1189 } | |
| 1190 | |
| 1191 // Multitests are handled specially | |
| 1192 if (testCase.info != null) { | |
| 1193 if (testCase.info.hasCompileError) { | |
| 1194 // Nonzero exit code of the compiler means compilation failed | |
| 1195 // FIXME(kustermann): Do we have a special exit code in that case??? | |
|
ricow1
2013/09/23 12:07:32
fixme->todo
kustermann
2013/09/23 15:31:34
Done.
| |
| 1196 if (exitCode != 0) { | |
| 1197 return Expectation.PASS; | |
| 1198 } | |
| 1199 return Expectation.MISSING_COMPILETIME_ERROR; | |
| 1200 } | |
| 1201 | |
| 1202 // FIXME(kustermann): this is a hack, remove it | |
|
ricow1
2013/09/23 12:07:32
fixme -> todo
kustermann
2013/09/23 15:31:34
Done.
| |
| 1203 if (testCase.info.hasRuntimeError && testCase.commands.length > 1) { | |
| 1204 // We expected to run the test, but we got an compile time error. | |
| 1205 // If the compilation succeeded, we wouldn't be in here! | |
| 1206 assert(exitCode != 0); | |
| 1207 return Expectation.COMPILETIME_ERROR; | |
| 1208 } | |
| 1209 } | |
| 1210 | |
| 1211 Expectation outcome = | |
| 1212 exitCode == 0 ? Expectation.PASS : Expectation.COMPILETIME_ERROR; | |
| 1213 // In case it's a negative test, reverse the result | |
| 1214 if (outcome.canBeOutcomeOf(Expectation.FAIL)) { | |
|
ricow1
2013/09/23 12:07:32
this code is duplicated here, above and below, cou
kustermann
2013/09/23 15:31:34
I thought about this as well. I moved it now up to
| |
| 1215 if (testCase.isNegative) outcome = Expectation.PASS; | |
| 1216 } else { | |
| 1217 if (testCase.isNegative) outcome = Expectation.FAIL; | |
| 1218 } | |
| 1219 return outcome; | |
| 1220 } | |
| 1221 } | |
| 1222 | |
| 1223 class JsCommandlineOutputImpl extends CommandOutputImpl { | |
| 1224 JsCommandlineOutputImpl(Command command, int exitCode, bool timedOut, | |
| 1225 List<int> stdout, List<int> stderr, Duration time) | |
| 1226 : super(command, exitCode, timedOut, stdout, stderr, time, false); | |
| 1227 | |
| 1228 Expectation result(TestCase testCase) { | |
| 1229 // Handle crashes and timeouts first | |
| 1230 if (hasCrashed) return Expectation.CRASH; | |
| 1231 if (hasTimedOut) return Expectation.TIMEOUT; | |
| 1232 | |
| 1233 if (testCase.info != null && testCase.info.hasRuntimeError) { | |
| 1234 if (exitCode != 0) return Expectation.PASS; | |
| 1235 return Expectation.MISSING_RUNTIME_ERROR; | |
| 1236 } | |
| 1237 | |
| 1238 var outcome = exitCode == 0 ? Expectation.PASS : Expectation.RUNTIME_ERROR; | |
| 1239 // Handle negative tests | |
| 1240 if (testCase.isNegative) { | |
| 1241 if (outcome.canBeOutcomeOf(Expectation.FAIL)) return Expectation.PASS; | |
| 1242 return Expectation.FAIL; | |
| 1243 } | |
| 1244 return outcome; | |
| 1245 } | |
| 1246 } | |
| 1046 | 1247 |
| 1047 CommandOutput createCommandOutput(Command command, | 1248 CommandOutput createCommandOutput(Command command, |
| 1048 int exitCode, | 1249 int exitCode, |
| 1049 bool timedOut, | 1250 bool timedOut, |
| 1050 List<int> stdout, | 1251 List<int> stdout, |
| 1051 List<int> stderr, | 1252 List<int> stderr, |
| 1052 Duration time, | 1253 Duration time, |
| 1053 bool compilationSkipped) { | 1254 bool compilationSkipped) { |
| 1054 if (command is ContentShellCommand) { | 1255 if (command is ContentShellCommand) { |
| 1055 return new BrowserCommandOutputImpl( | 1256 return new BrowserCommandOutputImpl( |
| 1056 command, exitCode, timedOut, stdout, stderr, | 1257 command, exitCode, timedOut, stdout, stderr, |
| 1057 time, compilationSkipped); | 1258 time, compilationSkipped); |
| 1058 } else if (command is BrowserTestCommand) { | 1259 } else if (command is BrowserTestCommand) { |
| 1059 return new HTMLBrowserCommandOutputImpl( | 1260 return new HTMLBrowserCommandOutputImpl( |
| 1060 command, exitCode, timedOut, stdout, stderr, | 1261 command, exitCode, timedOut, stdout, stderr, |
| 1061 time, compilationSkipped); | 1262 time, compilationSkipped); |
| 1062 } else if (command is SeleniumTestCommand) { | 1263 } else if (command is SeleniumTestCommand) { |
| 1063 return new BrowserCommandOutputImpl( | 1264 return new BrowserCommandOutputImpl( |
| 1064 command, exitCode, timedOut, stdout, stderr, | 1265 command, exitCode, timedOut, stdout, stderr, |
| 1065 time, compilationSkipped); | 1266 time, compilationSkipped); |
| 1066 } else if (command is AnalysisCommand) { | 1267 } else if (command is AnalysisCommand) { |
| 1067 return new AnalysisCommandOutputImpl( | 1268 return new AnalysisCommandOutputImpl( |
| 1068 command, exitCode, timedOut, stdout, stderr, | 1269 command, exitCode, timedOut, stdout, stderr, |
| 1069 time, compilationSkipped); | 1270 time, compilationSkipped); |
| 1271 } else if (command is VmCommand) { | |
| 1272 return new VmCommandOutputImpl( | |
| 1273 command, exitCode, timedOut, stdout, stderr, time); | |
| 1274 } else if (command is CompilationCommand) { | |
| 1275 return new CompilationCommandOutputImpl( | |
| 1276 command, exitCode, timedOut, stdout, stderr, time); | |
| 1277 } else if (command is JSCommandlineCommand) { | |
| 1278 return new JsCommandlineOutputImpl( | |
| 1279 command, exitCode, timedOut, stdout, stderr, time); | |
| 1070 } | 1280 } |
| 1281 | |
| 1071 return new CommandOutputImpl( | 1282 return new CommandOutputImpl( |
| 1072 command, exitCode, timedOut, stdout, stderr, | 1283 command, exitCode, timedOut, stdout, stderr, |
| 1073 time, compilationSkipped); | 1284 time, compilationSkipped); |
| 1074 } | 1285 } |
| 1075 | 1286 |
| 1076 | 1287 |
| 1077 /** Modifies the --timeout=XX parameter passed to run_selenium.py */ | 1288 /** Modifies the --timeout=XX parameter passed to run_selenium.py */ |
| 1078 List<String> _modifySeleniumTimeout(List<String> arguments, int timeout) { | 1289 List<String> _modifySeleniumTimeout(List<String> arguments, int timeout) { |
| 1079 return arguments.map((argument) { | 1290 return arguments.map((argument) { |
| 1080 if (argument.startsWith('--timeout=')) { | 1291 if (argument.startsWith('--timeout=')) { |
| (...skipping 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2156 } | 2367 } |
| 2157 } | 2368 } |
| 2158 | 2369 |
| 2159 void eventAllTestsDone() { | 2370 void eventAllTestsDone() { |
| 2160 for (var listener in _eventListener) { | 2371 for (var listener in _eventListener) { |
| 2161 listener.allDone(); | 2372 listener.allDone(); |
| 2162 } | 2373 } |
| 2163 _allDone(); | 2374 _allDone(); |
| 2164 } | 2375 } |
| 2165 } | 2376 } |
| OLD | NEW |