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 return outcome.canBeOutcomeOf(expectation); | |
| 545 }); | |
| 509 } | 546 } |
| 510 | 547 |
| 511 String get result => lastCommandOutput.result(this); | 548 Expectation get result => lastCommandOutput.result(this); |
| 512 | 549 |
| 513 CommandOutput get lastCommandOutput { | 550 CommandOutput get lastCommandOutput { |
| 514 if (commandOutputs.length == 0) { | 551 if (commandOutputs.length == 0) { |
| 515 throw new Exception("CommandOutputs is empty, maybe no command was run? (" | 552 throw new Exception("CommandOutputs is empty, maybe no command was run? (" |
| 516 "displayName: '$displayName', " | 553 "displayName: '$displayName', " |
| 517 "configurationString: '$configurationString')"); | 554 "configurationString: '$configurationString')"); |
| 518 } | 555 } |
| 519 return commandOutputs[commands[commandOutputs.length - 1]]; | 556 return commandOutputs[commands[commandOutputs.length - 1]]; |
| 520 } | 557 } |
| 521 | 558 |
| 522 int get timeout { | 559 int get timeout { |
| 523 if (expectedOutcomes.contains(SLOW)) { | 560 if (expectedOutcomes.contains(Expectation.SLOW)) { |
| 524 return configuration['timeout'] * SLOW_TIMEOUT_MULTIPLIER; | 561 return configuration['timeout'] * SLOW_TIMEOUT_MULTIPLIER; |
| 525 } else { | 562 } else { |
| 526 return configuration['timeout']; | 563 return configuration['timeout']; |
| 527 } | 564 } |
| 528 } | 565 } |
| 529 | 566 |
| 530 String get configurationString { | 567 String get configurationString { |
| 531 final compiler = configuration['compiler']; | 568 final compiler = configuration['compiler']; |
| 532 final runtime = configuration['runtime']; | 569 final runtime = configuration['runtime']; |
| 533 final mode = configuration['mode']; | 570 final mode = configuration['mode']; |
| 534 final arch = configuration['arch']; | 571 final arch = configuration['arch']; |
| 535 final checked = configuration['checked'] ? '-checked' : ''; | 572 final checked = configuration['checked'] ? '-checked' : ''; |
| 536 return "$compiler-$runtime$checked ${mode}_$arch"; | 573 return "$compiler-$runtime$checked ${mode}_$arch"; |
| 537 } | 574 } |
| 538 | 575 |
| 539 List<String> get batchTestArguments => commands.last.arguments; | 576 List<String> get batchTestArguments => commands.last.arguments; |
| 540 | 577 |
| 541 bool get usesWebDriver => TestUtils.usesWebDriver(configuration['runtime']); | 578 bool get usesWebDriver => TestUtils.usesWebDriver(configuration['runtime']); |
| 542 | 579 |
| 543 bool get isFlaky { | 580 bool get isFlaky { |
| 544 if (expectedOutcomes.contains(SKIP) || | 581 if (expectedOutcomes.contains(Expectation.SKIP) || |
| 545 expectedOutcomes.contains(SKIP_BY_DESIGN)) { | 582 expectedOutcomes.contains(Expectation.SKIP_BY_DESIGN)) { |
| 546 return false; | 583 return false; |
| 547 } | 584 } |
| 548 | 585 |
| 549 var flags = new Set.from(expectedOutcomes); | 586 return expectedOutcomes |
| 550 flags..remove(OK) | 587 .where((expectation) => !expectation.isMetaExpectation).length > 1; |
| 551 ..remove(SLOW); | |
| 552 return flags.length > 1; | |
| 553 } | 588 } |
| 554 | 589 |
| 555 bool get isFinished { | 590 bool get isFinished { |
| 556 return !lastCommandOutput.successful || | 591 return !lastCommandOutput.successful || |
| 557 commands.length == commandOutputs.length; | 592 commands.length == commandOutputs.length; |
| 558 } | 593 } |
| 559 } | 594 } |
| 560 | 595 |
| 561 | 596 |
| 562 /** | 597 /** |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 578 | 613 |
| 579 /** | 614 /** |
| 580 * CommandOutput records the output of a completed command: the process's exit | 615 * 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, | 616 * 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 | 617 * and the time the process took to run. It also contains a pointer to the |
| 583 * [TestCase] this is the output of. | 618 * [TestCase] this is the output of. |
| 584 */ | 619 */ |
| 585 abstract class CommandOutput { | 620 abstract class CommandOutput { |
| 586 Command get command; | 621 Command get command; |
| 587 | 622 |
| 588 String result(TestCase testCase); | 623 Expectation result(TestCase testCase); |
| 589 | 624 |
| 590 bool get hasCrashed; | 625 bool get hasCrashed; |
| 591 | 626 |
| 592 bool get hasTimedOut; | 627 bool get hasTimedOut; |
| 593 | 628 |
| 594 bool didFail(testcase); | 629 bool didFail(testcase); |
| 595 | 630 |
| 596 bool hasFailed(TestCase testCase); | 631 bool hasFailed(TestCase testCase); |
| 597 | 632 |
| 598 bool get canRunDependendCommands; | 633 bool get canRunDependendCommands; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 633 CommandOutputImpl(Command this.command, | 668 CommandOutputImpl(Command this.command, |
| 634 int this.exitCode, | 669 int this.exitCode, |
| 635 bool this.timedOut, | 670 bool this.timedOut, |
| 636 List<int> this.stdout, | 671 List<int> this.stdout, |
| 637 List<int> this.stderr, | 672 List<int> this.stderr, |
| 638 Duration this.time, | 673 Duration this.time, |
| 639 bool this.compilationSkipped) { | 674 bool this.compilationSkipped) { |
| 640 diagnostics = []; | 675 diagnostics = []; |
| 641 } | 676 } |
| 642 | 677 |
| 643 String result(TestCase testCase) => hasCrashed ? CRASH : | 678 Expectation result(TestCase testCase) { |
| 644 (hasTimedOut ? TIMEOUT : (hasFailed(testCase) ? FAIL : PASS)); | 679 if (hasCrashed) return Expectation.CRASH; |
| 680 if (hasTimedOut) return Expectation.TIMEOUT; | |
| 681 return hasFailed(testCase) ? Expectation.FAIL : Expectation.PASS; | |
| 682 } | |
| 645 | 683 |
| 646 bool get hasCrashed { | 684 bool get hasCrashed { |
| 647 // The Java dartc runner and dart2js exits with code 253 in case | 685 // The Java dartc runner and dart2js exits with code 253 in case |
| 648 // of unhandled exceptions. | 686 // of unhandled exceptions. |
| 649 if (exitCode == 253) return true; | 687 if (exitCode == 253) return true; |
| 650 if (io.Platform.operatingSystem == 'windows') { | 688 if (io.Platform.operatingSystem == 'windows') { |
| 651 // The VM uses std::abort to terminate on asserts. | 689 // The VM uses std::abort to terminate on asserts. |
| 652 // std::abort terminates with exit code 3 on Windows. | 690 // std::abort terminates with exit code 3 on Windows. |
| 653 if (exitCode == 3) { | 691 if (exitCode == 3) { |
| 654 return !timedOut; | 692 return !timedOut; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 680 return !hasTimedOut && exitCode == 0; | 718 return !hasTimedOut && exitCode == 0; |
| 681 } | 719 } |
| 682 | 720 |
| 683 bool get successful { | 721 bool get successful { |
| 684 // FIXME(kustermann): We may need to change this | 722 // FIXME(kustermann): We may need to change this |
| 685 return !hasTimedOut && exitCode == 0; | 723 return !hasTimedOut && exitCode == 0; |
| 686 } | 724 } |
| 687 | 725 |
| 688 // Reverse result of a negative test. | 726 // Reverse result of a negative test. |
| 689 bool hasFailed(TestCase testCase) { | 727 bool hasFailed(TestCase testCase) { |
| 690 // FIXME(kustermann): this is a hack, remove it | 728 return testCase.isNegative ? !didFail(testCase) : didFail(testCase); |
| 691 bool isCompilationCommand = testCase.commands.first == command | 729 } |
| 692 && testCase.commands.length > 1; | 730 |
| 693 if (isCompilationCommand && | 731 Expectation _negateOutcomeIfNegativeTest(Expectation outcome, |
| 694 testCase.info != null && testCase.info.hasRuntimeError) { | 732 bool isNegative) { |
| 695 return exitCode != 0; | 733 if (!isNegative) return outcome; |
| 734 | |
| 735 if (outcome.canBeOutcomeOf(Expectation.FAIL)) { | |
| 736 return Expectation.PASS; | |
| 696 } | 737 } |
| 697 return testCase.isNegative ? !didFail(testCase) : didFail(testCase); | 738 return Expectation.FAIL; |
| 698 } | 739 } |
| 699 } | 740 } |
| 700 | 741 |
| 701 class BrowserCommandOutputImpl extends CommandOutputImpl { | 742 class BrowserCommandOutputImpl extends CommandOutputImpl { |
| 702 bool _failedBecauseOfMissingXDisplay; | 743 bool _failedBecauseOfMissingXDisplay; |
| 703 | 744 |
| 704 BrowserCommandOutputImpl( | 745 BrowserCommandOutputImpl( |
| 705 command, | 746 command, |
| 706 exitCode, | 747 exitCode, |
| 707 timedOut, | 748 timedOut, |
| 708 stdout, | 749 stdout, |
| 709 stderr, | 750 stderr, |
| 710 time, | 751 time, |
| 711 compilationSkipped) : | 752 compilationSkipped) : |
| 712 super(command, | 753 super(command, |
| 713 exitCode, | 754 exitCode, |
| 714 timedOut, | 755 timedOut, |
| 715 stdout, | 756 stdout, |
| 716 stderr, | 757 stderr, |
| 717 time, | 758 time, |
| 718 compilationSkipped) { | 759 compilationSkipped) { |
| 719 _failedBecauseOfMissingXDisplay = _didFailBecauseOfMissingXDisplay(); | 760 _failedBecauseOfMissingXDisplay = _didFailBecauseOfMissingXDisplay(); |
| 720 if (_failedBecauseOfMissingXDisplay) { | 761 if (_failedBecauseOfMissingXDisplay) { |
| 721 DebugLogger.warning("Warning: Test failure because of missing XDisplay"); | 762 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 | 763 // If we get the X server error, or DRT crashes with a core dump, retry |
| 723 // the test. | 764 // the test. |
| 724 } | 765 } |
| 725 } | 766 } |
| 726 | 767 |
| 768 Expectation result(TestCase testCase) { | |
| 769 // Handle crashes and timeouts first | |
| 770 if (hasCrashed) return Expectation.CRASH; | |
| 771 if (hasTimedOut) return Expectation.TIMEOUT; | |
| 772 | |
| 773 var outcome = _getOutcome(); | |
| 774 | |
| 775 if (testCase.info != null && testCase.info.hasRuntimeError) { | |
| 776 if (!outcome.canBeOutcomeOf(Expectation.RUNTIME_ERROR)) { | |
| 777 return Expectation.MISSING_RUNTIME_ERROR; | |
| 778 } | |
| 779 } | |
| 780 | |
| 781 if (testCase.isNegative) { | |
|
ricow1
2013/09/24 09:02:31
use _negateOutcomeIfNegativeTest
kustermann
2013/09/25 12:12:39
Forgot about this one, I'll include it in another
| |
| 782 if (outcome.canBeOutcomeOf(Expectation.FAIL)) return Expectation.PASS; | |
| 783 return Expectation.FAIL; | |
| 784 } | |
| 785 return outcome; | |
| 786 } | |
| 787 | |
| 727 bool get successful => canRunDependendCommands; | 788 bool get successful => canRunDependendCommands; |
| 728 | 789 |
| 729 bool get canRunDependendCommands { | 790 bool get canRunDependendCommands { |
| 730 // We cannot rely on the exit code of content_shell as a method to determine | 791 // We cannot rely on the exit code of content_shell as a method to determine |
| 731 // if we were successful or not. | 792 // if we were successful or not. |
| 732 return super.canRunDependendCommands && !didFail(null); | 793 return super.canRunDependendCommands && !didFail(null); |
| 733 } | 794 } |
| 734 | 795 |
| 735 bool didFail(TestCase _) { | 796 Expectation _getOutcome() { |
| 736 if (_failedBecauseOfMissingXDisplay) { | 797 if (_failedBecauseOfMissingXDisplay) { |
| 737 return true; | 798 return Expectation.FAIL; |
| 738 } | 799 } |
| 739 | 800 |
| 740 if (command.expectedOutputFile != null) { | 801 if (command.expectedOutputFile != null) { |
| 741 // We are either doing a pixel test or a layout test with content shell | 802 // We are either doing a pixel test or a layout test with content shell |
| 742 return _failedBecauseOfUnexpectedDRTOutput; | 803 if (_failedBecauseOfUnexpectedDRTOutput) { |
| 804 return Expectation.FAIL; | |
| 805 } | |
| 743 } | 806 } |
| 744 return _browserTestFailure; | 807 if (_browserTestFailure) { |
| 808 return Expectation.RUNTIME_ERROR; | |
| 809 } | |
| 810 return Expectation.PASS; | |
| 745 } | 811 } |
| 746 | 812 |
| 747 bool _didFailBecauseOfMissingXDisplay() { | 813 bool _didFailBecauseOfMissingXDisplay() { |
| 748 // Browser case: | 814 // Browser case: |
| 749 // If the browser test failed, it may have been because content shell | 815 // 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 | 816 // 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 | 817 // a core dump. Sometimes content shell crashes after it has set the stdout |
| 752 // to PASS, so we have to do this check first. | 818 // to PASS, so we have to do this check first. |
| 753 var stderrLines = decodeUtf8(super.stderr).split("\n"); | 819 var stderrLines = decodeUtf8(super.stderr).split("\n"); |
| 754 for (String line in stderrLines) { | 820 for (String line in stderrLines) { |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1036 field = new StringBuffer(); | 1102 field = new StringBuffer(); |
| 1037 continue; | 1103 continue; |
| 1038 } | 1104 } |
| 1039 field.write(c); | 1105 field.write(c); |
| 1040 } | 1106 } |
| 1041 result.add(field.toString()); | 1107 result.add(field.toString()); |
| 1042 return result; | 1108 return result; |
| 1043 } | 1109 } |
| 1044 } | 1110 } |
| 1045 | 1111 |
| 1112 class VmCommandOutputImpl extends CommandOutputImpl { | |
| 1113 static const DART_VM_EXITCODE_COMPILE_TIME_ERROR = 254; | |
| 1114 static const DART_VM_EXITCODE_UNCAUGHT_EXCEPTION = 255; | |
| 1115 | |
| 1116 VmCommandOutputImpl(Command command, int exitCode, bool timedOut, | |
| 1117 List<int> stdout, List<int> stderr, Duration time) | |
| 1118 : super(command, exitCode, timedOut, stdout, stderr, time, false); | |
| 1119 | |
| 1120 Expectation result(TestCase testCase) { | |
| 1121 // Handle crashes and timeouts first | |
| 1122 if (hasCrashed) return Expectation.CRASH; | |
| 1123 if (hasTimedOut) return Expectation.TIMEOUT; | |
| 1124 | |
| 1125 // Multitests are handled specially | |
| 1126 if (testCase.info != null) { | |
| 1127 if (testCase.info.hasCompileError) { | |
| 1128 if (exitCode == DART_VM_EXITCODE_COMPILE_TIME_ERROR) { | |
| 1129 return Expectation.PASS; | |
| 1130 } | |
| 1131 | |
| 1132 // We're not as strict, if the exitCode indicated an uncaught exception | |
| 1133 // we say it passed nonetheless | |
| 1134 // TODO(kustermann): As soon as the VM team makes sure we get correct | |
| 1135 // exit codes, we should remove this. | |
| 1136 if (exitCode == DART_VM_EXITCODE_UNCAUGHT_EXCEPTION) { | |
| 1137 return Expectation.PASS; | |
| 1138 } | |
| 1139 | |
| 1140 return Expectation.MISSING_COMPILETIME_ERROR; | |
| 1141 } | |
| 1142 if (testCase.info.hasRuntimeError) { | |
| 1143 // TODO(kustermann): Do we consider a "runtimeError" only an uncaught | |
| 1144 // exception or does any nonzero exit code fullfil this requirement? | |
| 1145 if (exitCode != 0) { | |
| 1146 return Expectation.PASS; | |
| 1147 } | |
| 1148 return Expectation.MISSING_RUNTIME_ERROR; | |
| 1149 } | |
| 1150 } | |
| 1151 | |
| 1152 // The actual outcome depends on the exitCode | |
| 1153 Expectation outcome; | |
| 1154 if (exitCode == DART_VM_EXITCODE_COMPILE_TIME_ERROR) { | |
| 1155 outcome = Expectation.COMPILETIME_ERROR; | |
| 1156 } else if (exitCode == DART_VM_EXITCODE_UNCAUGHT_EXCEPTION) { | |
| 1157 outcome = Expectation.RUNTIME_ERROR; | |
| 1158 } else if (exitCode != 0) { | |
| 1159 // This is a general fail, in case we get an unknown nonzero exitcode. | |
| 1160 outcome = Expectation.FAIL; | |
| 1161 } else { | |
| 1162 outcome = Expectation.PASS; | |
| 1163 } | |
| 1164 return _negateOutcomeIfNegativeTest(outcome, testCase.isNegative); | |
| 1165 } | |
| 1166 } | |
| 1167 | |
| 1168 class CompilationCommandOutputImpl extends CommandOutputImpl { | |
| 1169 static const DART2JS_EXITCODE_CRASH = 253; | |
| 1170 | |
| 1171 CompilationCommandOutputImpl(Command command, int exitCode, bool timedOut, | |
| 1172 List<int> stdout, List<int> stderr, Duration time) | |
| 1173 : super(command, exitCode, timedOut, stdout, stderr, time, false); | |
| 1174 | |
| 1175 Expectation result(TestCase testCase) { | |
| 1176 // Handle general crash/timeout detection. | |
| 1177 if (hasCrashed) return Expectation.CRASH; | |
| 1178 if (hasTimedOut) return Expectation.TIMEOUT; | |
| 1179 | |
| 1180 // Handle dart2js/dart2dart specific crash detection | |
| 1181 if (exitCode == DART2JS_EXITCODE_CRASH || | |
| 1182 exitCode == VmCommandOutputImpl.DART_VM_EXITCODE_COMPILE_TIME_ERROR || | |
| 1183 exitCode == VmCommandOutputImpl.DART_VM_EXITCODE_UNCAUGHT_EXCEPTION) { | |
| 1184 return Expectation.CRASH; | |
| 1185 } | |
| 1186 | |
| 1187 // Multitests are handled specially | |
| 1188 if (testCase.info != null) { | |
| 1189 if (testCase.info.hasCompileError) { | |
| 1190 // Nonzero exit code of the compiler means compilation failed | |
| 1191 // TODO(kustermann): Do we have a special exit code in that case??? | |
| 1192 if (exitCode != 0) { | |
| 1193 return Expectation.PASS; | |
| 1194 } | |
| 1195 return Expectation.MISSING_COMPILETIME_ERROR; | |
| 1196 } | |
| 1197 | |
| 1198 // TODO(kustermann): This is a hack, remove it | |
| 1199 if (testCase.info.hasRuntimeError && testCase.commands.length > 1) { | |
| 1200 // We expected to run the test, but we got an compile time error. | |
| 1201 // If the compilation succeeded, we wouldn't be in here! | |
| 1202 assert(exitCode != 0); | |
| 1203 return Expectation.COMPILETIME_ERROR; | |
| 1204 } | |
| 1205 } | |
| 1206 | |
| 1207 Expectation outcome = | |
| 1208 exitCode == 0 ? Expectation.PASS : Expectation.COMPILETIME_ERROR; | |
| 1209 return _negateOutcomeIfNegativeTest(outcome, testCase.isNegative); | |
| 1210 } | |
| 1211 } | |
| 1212 | |
| 1213 class JsCommandlineOutputImpl extends CommandOutputImpl { | |
| 1214 JsCommandlineOutputImpl(Command command, int exitCode, bool timedOut, | |
| 1215 List<int> stdout, List<int> stderr, Duration time) | |
| 1216 : super(command, exitCode, timedOut, stdout, stderr, time, false); | |
| 1217 | |
| 1218 Expectation result(TestCase testCase) { | |
| 1219 // Handle crashes and timeouts first | |
| 1220 if (hasCrashed) return Expectation.CRASH; | |
| 1221 if (hasTimedOut) return Expectation.TIMEOUT; | |
| 1222 | |
| 1223 if (testCase.info != null && testCase.info.hasRuntimeError) { | |
| 1224 if (exitCode != 0) return Expectation.PASS; | |
| 1225 return Expectation.MISSING_RUNTIME_ERROR; | |
| 1226 } | |
| 1227 | |
| 1228 var outcome = exitCode == 0 ? Expectation.PASS : Expectation.RUNTIME_ERROR; | |
| 1229 return _negateOutcomeIfNegativeTest(outcome, testCase.isNegative); | |
| 1230 } | |
| 1231 } | |
| 1046 | 1232 |
| 1047 CommandOutput createCommandOutput(Command command, | 1233 CommandOutput createCommandOutput(Command command, |
| 1048 int exitCode, | 1234 int exitCode, |
| 1049 bool timedOut, | 1235 bool timedOut, |
| 1050 List<int> stdout, | 1236 List<int> stdout, |
| 1051 List<int> stderr, | 1237 List<int> stderr, |
| 1052 Duration time, | 1238 Duration time, |
| 1053 bool compilationSkipped) { | 1239 bool compilationSkipped) { |
| 1054 if (command is ContentShellCommand) { | 1240 if (command is ContentShellCommand) { |
| 1055 return new BrowserCommandOutputImpl( | 1241 return new BrowserCommandOutputImpl( |
| 1056 command, exitCode, timedOut, stdout, stderr, | 1242 command, exitCode, timedOut, stdout, stderr, |
| 1057 time, compilationSkipped); | 1243 time, compilationSkipped); |
| 1058 } else if (command is BrowserTestCommand) { | 1244 } else if (command is BrowserTestCommand) { |
| 1059 return new HTMLBrowserCommandOutputImpl( | 1245 return new HTMLBrowserCommandOutputImpl( |
| 1060 command, exitCode, timedOut, stdout, stderr, | 1246 command, exitCode, timedOut, stdout, stderr, |
| 1061 time, compilationSkipped); | 1247 time, compilationSkipped); |
| 1062 } else if (command is SeleniumTestCommand) { | 1248 } else if (command is SeleniumTestCommand) { |
| 1063 return new BrowserCommandOutputImpl( | 1249 return new BrowserCommandOutputImpl( |
| 1064 command, exitCode, timedOut, stdout, stderr, | 1250 command, exitCode, timedOut, stdout, stderr, |
| 1065 time, compilationSkipped); | 1251 time, compilationSkipped); |
| 1066 } else if (command is AnalysisCommand) { | 1252 } else if (command is AnalysisCommand) { |
| 1067 return new AnalysisCommandOutputImpl( | 1253 return new AnalysisCommandOutputImpl( |
| 1068 command, exitCode, timedOut, stdout, stderr, | 1254 command, exitCode, timedOut, stdout, stderr, |
| 1069 time, compilationSkipped); | 1255 time, compilationSkipped); |
| 1256 } else if (command is VmCommand) { | |
| 1257 return new VmCommandOutputImpl( | |
| 1258 command, exitCode, timedOut, stdout, stderr, time); | |
| 1259 } else if (command is CompilationCommand) { | |
| 1260 return new CompilationCommandOutputImpl( | |
| 1261 command, exitCode, timedOut, stdout, stderr, time); | |
| 1262 } else if (command is JSCommandlineCommand) { | |
| 1263 return new JsCommandlineOutputImpl( | |
| 1264 command, exitCode, timedOut, stdout, stderr, time); | |
| 1070 } | 1265 } |
| 1266 | |
| 1071 return new CommandOutputImpl( | 1267 return new CommandOutputImpl( |
| 1072 command, exitCode, timedOut, stdout, stderr, | 1268 command, exitCode, timedOut, stdout, stderr, |
| 1073 time, compilationSkipped); | 1269 time, compilationSkipped); |
| 1074 } | 1270 } |
| 1075 | 1271 |
| 1076 | 1272 |
| 1077 /** Modifies the --timeout=XX parameter passed to run_selenium.py */ | 1273 /** Modifies the --timeout=XX parameter passed to run_selenium.py */ |
| 1078 List<String> _modifySeleniumTimeout(List<String> arguments, int timeout) { | 1274 List<String> _modifySeleniumTimeout(List<String> arguments, int timeout) { |
| 1079 return arguments.map((argument) { | 1275 return arguments.map((argument) { |
| 1080 if (argument.startsWith('--timeout=')) { | 1276 if (argument.startsWith('--timeout=')) { |
| (...skipping 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2156 } | 2352 } |
| 2157 } | 2353 } |
| 2158 | 2354 |
| 2159 void eventAllTestsDone() { | 2355 void eventAllTestsDone() { |
| 2160 for (var listener in _eventListener) { | 2356 for (var listener in _eventListener) { |
| 2161 listener.allDone(); | 2357 listener.allDone(); |
| 2162 } | 2358 } |
| 2163 _allDone(); | 2359 _allDone(); |
| 2164 } | 2360 } |
| 2165 } | 2361 } |
| OLD | NEW |