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 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 timedOut = true; | 594 timedOut = true; |
595 process.kill(); | 595 process.kill(); |
596 } | 596 } |
597 } | 597 } |
598 | 598 |
599 class BatchRunnerProcess { | 599 class BatchRunnerProcess { |
600 String _executable; | 600 String _executable; |
601 List<String> _batchArguments; | 601 List<String> _batchArguments; |
602 | 602 |
603 Process _process; | 603 Process _process; |
| 604 bool _processDone = true; |
604 StringInputStream _stdoutStream; | 605 StringInputStream _stdoutStream; |
605 StringInputStream _stderrStream; | 606 StringInputStream _stderrStream; |
606 | 607 |
607 TestCase _currentTest; | 608 TestCase _currentTest; |
608 List<String> _testStdout; | 609 List<String> _testStdout; |
609 List<String> _testStderr; | 610 List<String> _testStderr; |
610 bool _stdoutDrained = false; | 611 bool _stdoutDrained = false; |
611 bool _stderrDrained = false; | 612 bool _stderrDrained = false; |
| 613 String _status; |
612 Date _startTime; | 614 Date _startTime; |
613 Timer _timer; | 615 Timer _timer; |
614 | 616 |
615 bool _isWebDriver; | 617 bool _isWebDriver; |
616 | 618 |
617 BatchRunnerProcess(TestCase testCase) { | 619 BatchRunnerProcess(TestCase testCase) { |
618 _executable = testCase.commands.last().executable; | 620 _executable = testCase.commands.last().executable; |
619 _batchArguments = testCase.batchRunnerArguments; | 621 _batchArguments = testCase.batchRunnerArguments; |
620 _isWebDriver = testCase.usesWebDriver; | 622 _isWebDriver = testCase.usesWebDriver; |
621 } | 623 } |
622 | 624 |
623 bool get active() => _currentTest != null; | 625 bool get active() => _currentTest != null; |
624 | 626 |
625 void startTest(TestCase testCase) { | 627 void startTest(TestCase testCase) { |
626 _currentTest = testCase; | 628 _currentTest = testCase; |
627 if (_process === null) { | 629 if (_processDone) { |
628 // Start process if not yet started. | 630 // Start process if not yet started. |
629 _executable = testCase.commands.last().executable; | 631 _executable = testCase.commands.last().executable; |
630 _startProcess(() { | 632 _startProcess(() { |
631 doStartTest(testCase); | 633 doStartTest(testCase); |
632 }); | 634 }); |
633 } else if (testCase.commands.last().executable != _executable) { | 635 } else if (testCase.commands.last().executable != _executable) { |
634 // Restart this runner with the right executable for this test | 636 // Restart this runner with the right executable for this test |
635 // if needed. | 637 // if needed. |
636 _executable = testCase.commands.last().executable; | 638 _executable = testCase.commands.last().executable; |
637 _batchArguments = testCase.batchRunnerArguments; | 639 _batchArguments = testCase.batchRunnerArguments; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
686 return Strings.join(arguments, ' ') + '\n'; | 688 return Strings.join(arguments, ' ') + '\n'; |
687 } | 689 } |
688 | 690 |
689 void _testCompleted() { | 691 void _testCompleted() { |
690 var test = _currentTest; | 692 var test = _currentTest; |
691 _currentTest = null; | 693 _currentTest = null; |
692 test.completed(); | 694 test.completed(); |
693 } | 695 } |
694 | 696 |
695 int _reportResult(String output) { | 697 int _reportResult(String output) { |
696 _stdoutDrained = true; | |
697 // output = '>>> TEST {PASS, FAIL, OK, CRASH, FAIL, TIMEOUT}' | 698 // output = '>>> TEST {PASS, FAIL, OK, CRASH, FAIL, TIMEOUT}' |
698 var outcome = output.split(" ")[2]; | 699 var outcome = output.split(" ")[2]; |
699 var exitCode = 0; | 700 var exitCode = 0; |
700 if (outcome == "CRASH") exitCode = -10; | 701 if (outcome == "CRASH") exitCode = -10; |
701 if (outcome == "FAIL" || outcome == "TIMEOUT") exitCode = 1; | 702 if (outcome == "FAIL" || outcome == "TIMEOUT") exitCode = 1; |
702 new TestOutput.fromCase(_currentTest, exitCode, outcome == "TIMEOUT", | 703 new TestOutput.fromCase(_currentTest, exitCode, outcome == "TIMEOUT", |
703 _testStdout, _testStderr, new Date.now().difference(_startTim
e)); | 704 _testStdout, _testStderr, new Date.now().difference(_startTim
e)); |
704 // Move on when both stdout and stderr has been drained. If the test | 705 // Move on when both stdout and stderr has been drained. If the test |
705 // crashed, we restarted the process and therefore do not attempt to | 706 // crashed, we restarted the process and therefore do not attempt to |
706 // drain stderr. | 707 // drain stderr. |
707 if (_stderrDrained || (_currentTest.output.hasCrashed)) _testCompleted(); | 708 if (_stderrDrained) _testCompleted(); |
708 } | |
709 | |
710 void _stderrDone() { | |
711 _stderrDrained = true; | |
712 // Move on when both stdout and stderr has been drained. | |
713 if (_stdoutDrained) _testCompleted(); | |
714 } | 709 } |
715 | 710 |
716 Function _readStdout(StringInputStream stream, List<String> buffer) { | 711 Function _readStdout(StringInputStream stream, List<String> buffer) { |
717 return () { | 712 return () { |
718 var status; | 713 var status; |
719 var line = stream.readLine(); | 714 var line = stream.readLine(); |
720 while (line != null) { | 715 while (line != null) { |
721 if (line.startsWith('>>> TEST')) { | 716 if (line.startsWith('>>> TEST')) { |
722 status = line; | 717 status = line; |
| 718 _stdoutDrained = true; |
723 } else if (line.startsWith('>>> BATCH START')) { | 719 } else if (line.startsWith('>>> BATCH START')) { |
724 // ignore | 720 // ignore |
725 } else if (line.startsWith('>>> ')) { | 721 } else if (line.startsWith('>>> ')) { |
726 throw new Exception('Unexpected command from dartc batch runner.'); | 722 throw new Exception('Unexpected command from dartc batch runner.'); |
727 } else { | 723 } else { |
728 buffer.add(line); | 724 buffer.add(line); |
729 } | 725 } |
730 line = stream.readLine(); | 726 line = stream.readLine(); |
731 } | 727 } |
732 if (status != null) { | 728 if (status != null) { |
733 _timer.cancel(); | 729 _timer.cancel(); |
734 // For crashing processes, let the exit handler deal with it. | 730 this._status = status; |
735 if (!status.contains("CRASH")) { | 731 if (_stderrDrained) { |
736 _reportResult(status); | 732 _reportResult(status); |
| 733 if (_processDone) { |
| 734 _startProcess(); |
| 735 } |
737 } | 736 } |
738 } | 737 } |
739 }; | 738 }; |
740 } | 739 } |
741 | 740 |
742 Function _readStderr(StringInputStream stream, List<String> buffer) { | 741 Function _readStderr(StringInputStream stream, List<String> buffer) { |
743 return () { | 742 return () { |
744 var line = stream.readLine(); | 743 var line = stream.readLine(); |
745 while (line != null) { | 744 while (line != null) { |
| 745 var status; |
746 if (line.startsWith('>>> EOF STDERR')) { | 746 if (line.startsWith('>>> EOF STDERR')) { |
747 _stderrDone(); | 747 _stderrDrained = true; |
| 748 if (_stdoutDrained) { |
| 749 _reportResult(this._status); |
| 750 if (_processDone) { |
| 751 _startProcess(); |
| 752 } |
| 753 } |
748 } else { | 754 } else { |
749 buffer.add(line); | 755 buffer.add(line); |
750 } | 756 } |
751 line = stream.readLine(); | 757 line = stream.readLine(); |
752 } | 758 } |
753 }; | 759 }; |
754 } | 760 } |
755 | 761 |
756 void _exitHandler(exitCode) { | 762 void _exitHandler(exitCode) { |
757 if (_timer != null) _timer.cancel(); | 763 if (_timer != null) _timer.cancel(); |
758 _process.close(); | 764 _process.close(); |
759 _startProcess(() { | 765 _processDone = true; |
760 _reportResult(">>> TEST CRASH"); | 766 if (_stdoutDrained && _stderrDrained) { |
761 }); | 767 _startProcess(); |
| 768 } |
762 } | 769 } |
763 | 770 |
764 void _timeoutHandler(ignore) { | 771 void _timeoutHandler(ignore) { |
765 _process.onExit = (exitCode) { | 772 _process.onExit = (exitCode) { |
766 _process.close(); | 773 _process.close(); |
767 _startProcess(() { | 774 _startProcess(() { |
768 _reportResult(">>> TEST TIMEOUT"); | 775 _reportResult(">>> TEST TIMEOUT"); |
769 }); | 776 }); |
770 }; | 777 }; |
771 _process.kill(); | 778 _process.kill(); |
772 } | 779 } |
773 | 780 |
774 void _startProcess(then) { | 781 void _startProcess([then = null]) { |
775 _process = new Process.start(_executable, _batchArguments); | 782 _process = new Process.start(_executable, _batchArguments); |
| 783 _processDone = false; |
776 _stdoutStream = new StringInputStream(_process.stdout); | 784 _stdoutStream = new StringInputStream(_process.stdout); |
777 _stderrStream = new StringInputStream(_process.stderr); | 785 _stderrStream = new StringInputStream(_process.stderr); |
778 _testStdout = new List<String>(); | 786 _testStdout = new List<String>(); |
779 _testStderr = new List<String>(); | 787 _testStderr = new List<String>(); |
780 _stdoutDrained = false; | 788 _stdoutDrained = false; |
781 _stderrDrained = false; | 789 _stderrDrained = false; |
782 _stdoutStream.onLine = _readStdout(_stdoutStream, _testStdout); | 790 _stdoutStream.onLine = _readStdout(_stdoutStream, _testStdout); |
783 _stderrStream.onLine = _readStderr(_stderrStream, _testStderr); | 791 _stderrStream.onLine = _readStderr(_stderrStream, _testStderr); |
784 _process.onExit = _exitHandler; | 792 _process.onExit = _exitHandler; |
785 _process.onStart = then; | 793 _process.onStart = then; |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1110 // the developer doesn't waste his or her time trying to fix a bunch of | 1118 // the developer doesn't waste his or her time trying to fix a bunch of |
1111 // tests that appear to be broken but were actually just flakes that | 1119 // tests that appear to be broken but were actually just flakes that |
1112 // didn't get retried because there had already been one failure. | 1120 // didn't get retried because there had already been one failure. |
1113 bool allowRetry = _MAX_FAILED_NO_RETRY > _progress.numFailedTests; | 1121 bool allowRetry = _MAX_FAILED_NO_RETRY > _progress.numFailedTests; |
1114 new RunningProcess(test, allowRetry, this).start(); | 1122 new RunningProcess(test, allowRetry, this).start(); |
1115 } | 1123 } |
1116 _numProcesses++; | 1124 _numProcesses++; |
1117 } | 1125 } |
1118 } | 1126 } |
1119 } | 1127 } |
OLD | NEW |