| 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 840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 */ | 851 */ |
| 852 class ProcessQueue { | 852 class ProcessQueue { |
| 853 int _numProcesses = 0; | 853 int _numProcesses = 0; |
| 854 int _activeTestListers = 0; | 854 int _activeTestListers = 0; |
| 855 int _maxProcesses; | 855 int _maxProcesses; |
| 856 | 856 |
| 857 /** The number of tests we allow to actually fail before we stop retrying. */ | 857 /** The number of tests we allow to actually fail before we stop retrying. */ |
| 858 int _MAX_FAILED_NO_RETRY = 4; | 858 int _MAX_FAILED_NO_RETRY = 4; |
| 859 bool _verbose; | 859 bool _verbose; |
| 860 bool _listTests; | 860 bool _listTests; |
| 861 bool _keepGeneratedTests; | |
| 862 Function _enqueueMoreWork; | 861 Function _enqueueMoreWork; |
| 863 Queue<TestCase> _tests; | 862 Queue<TestCase> _tests; |
| 864 ProgressIndicator _progress; | 863 ProgressIndicator _progress; |
| 865 String _temporaryDirectory; | |
| 866 | 864 |
| 867 // For dartc/selenium batch processing we keep a list of batch processes. | 865 // For dartc/selenium batch processing we keep a list of batch processes. |
| 868 Map<String, List<BatchRunnerProcess>> _batchProcesses; | 866 Map<String, List<BatchRunnerProcess>> _batchProcesses; |
| 869 | 867 |
| 870 // Cache information about test cases per test suite. For multiple | 868 // Cache information about test cases per test suite. For multiple |
| 871 // configurations there is no need to repeatedly search the file | 869 // configurations there is no need to repeatedly search the file |
| 872 // system, generate tests, and search test files for options. | 870 // system, generate tests, and search test files for options. |
| 873 Map<String, List<TestInformation>> _testCache; | 871 Map<String, List<TestInformation>> _testCache; |
| 874 | 872 |
| 875 /** | 873 /** |
| (...skipping 13 matching lines...) Expand all Loading... |
| 889 | 887 |
| 890 /** True if we find that there is already a selenium jar running. */ | 888 /** True if we find that there is already a selenium jar running. */ |
| 891 bool _seleniumAlreadyRunning = false; | 889 bool _seleniumAlreadyRunning = false; |
| 892 | 890 |
| 893 ProcessQueue(int this._maxProcesses, | 891 ProcessQueue(int this._maxProcesses, |
| 894 String progress, | 892 String progress, |
| 895 Date startTime, | 893 Date startTime, |
| 896 bool printTiming, | 894 bool printTiming, |
| 897 Function this._enqueueMoreWork, | 895 Function this._enqueueMoreWork, |
| 898 [bool verbose = false, | 896 [bool verbose = false, |
| 899 bool listTests = false, | 897 bool listTests = false]) |
| 900 bool keepGeneratedTests = false]) | |
| 901 : _verbose = verbose, | 898 : _verbose = verbose, |
| 902 _listTests = listTests, | 899 _listTests = listTests, |
| 903 _keepGeneratedTests = keepGeneratedTests, | |
| 904 _tests = new Queue<TestCase>(), | 900 _tests = new Queue<TestCase>(), |
| 905 _progress = new ProgressIndicator.fromName(progress, | 901 _progress = new ProgressIndicator.fromName(progress, |
| 906 startTime, | 902 startTime, |
| 907 printTiming), | 903 printTiming), |
| 908 _batchProcesses = new Map<String, List<BatchRunnerProcess>>(), | 904 _batchProcesses = new Map<String, List<BatchRunnerProcess>>(), |
| 909 _testCache = new Map<String, List<TestInformation>>() { | 905 _testCache = new Map<String, List<TestInformation>>() { |
| 910 if (!_enqueueMoreWork(this)) _progress.allDone(); | 906 if (!_enqueueMoreWork(this)) _progress.allDone(); |
| 911 } | 907 } |
| 912 | 908 |
| 913 /** | 909 /** |
| 914 * Registers a TestSuite so that all of its tests will be run. | 910 * Registers a TestSuite so that all of its tests will be run. |
| 915 */ | 911 */ |
| 916 void addTestSuite(TestSuite testSuite) { | 912 void addTestSuite(TestSuite testSuite) { |
| 917 _activeTestListers++; | 913 _activeTestListers++; |
| 918 testSuite.forEachTest(_runTest, _testCache, globalTemporaryDirectory, | 914 testSuite.forEachTest(_runTest, _testCache, _testListerDone); |
| 919 _testListerDone); | |
| 920 } | 915 } |
| 921 | 916 |
| 922 void _testListerDone() { | 917 void _testListerDone() { |
| 923 _activeTestListers--; | 918 _activeTestListers--; |
| 924 _checkDone(); | 919 _checkDone(); |
| 925 } | 920 } |
| 926 | 921 |
| 927 String globalTemporaryDirectory() { | |
| 928 if (_temporaryDirectory != null) return _temporaryDirectory; | |
| 929 | |
| 930 if (Platform.operatingSystem == 'windows') { | |
| 931 throw new Exception( | |
| 932 'Test suite requires temporary directory. Not supported on Windows.'); | |
| 933 } | |
| 934 var tempDir = new Directory('').createTempSync(); | |
| 935 _temporaryDirectory = tempDir.path; | |
| 936 return _temporaryDirectory; | |
| 937 } | |
| 938 | |
| 939 /** | 922 /** |
| 940 * Perform any cleanup needed once all tests in a TestSuite have completed | 923 * Perform any cleanup needed once all tests in a TestSuite have completed |
| 941 * and notify our progress indicator that we are done. | 924 * and notify our progress indicator that we are done. |
| 942 */ | 925 */ |
| 943 void _cleanupAndMarkDone() { | 926 void _cleanupAndMarkDone() { |
| 944 if (browserUsed != '' && _seleniumServer != null) { | 927 if (browserUsed != '' && _seleniumServer != null) { |
| 945 _seleniumServer.kill(); | 928 _seleniumServer.kill(); |
| 946 } else { | 929 } else { |
| 947 _progress.allDone(); | 930 _progress.allDone(); |
| 948 } | 931 } |
| 949 } | 932 } |
| 950 | 933 |
| 951 void _checkDone() { | 934 void _checkDone() { |
| 952 // When there are no more active test listers ask for more work | 935 // When there are no more active test listers ask for more work |
| 953 // from process queue users. | 936 // from process queue users. |
| 954 if (_activeTestListers == 0 && !_enqueueMoreWork(this)) { | 937 if (_activeTestListers == 0 && !_enqueueMoreWork(this)) { |
| 955 _progress.allTestsKnown(); | 938 _progress.allTestsKnown(); |
| 956 if (_tests.isEmpty() && _numProcesses == 0) { | 939 if (_tests.isEmpty() && _numProcesses == 0) { |
| 957 _terminateBatchRunners(); | 940 _terminateBatchRunners(); |
| 958 if (_keepGeneratedTests || _temporaryDirectory == null) { | 941 _cleanupAndMarkDone(); |
| 959 _cleanupAndMarkDone(); | |
| 960 } else if (!_temporaryDirectory.startsWith('/tmp/') || | |
| 961 _temporaryDirectory.contains('/../')) { | |
| 962 // Let's be extra careful, since rm -rf is so dangerous. | |
| 963 print('Temporary directory $_temporaryDirectory unsafe to delete!'); | |
| 964 _cleanupAndMarkDone(); | |
| 965 } else { | |
| 966 Directory dir = new Directory(_temporaryDirectory); | |
| 967 dir.deleteRecursively(() { | |
| 968 _cleanupAndMarkDone(); | |
| 969 }); | |
| 970 dir.onError = (err) { | |
| 971 print('\nDeletion of temp dir $_temporaryDirectory failed: $err'); | |
| 972 }; | |
| 973 } | |
| 974 } | 942 } |
| 975 } | 943 } |
| 976 } | 944 } |
| 977 | 945 |
| 978 /** | 946 /** |
| 979 * True if we are using a browser + platform combination that needs the | 947 * True if we are using a browser + platform combination that needs the |
| 980 * Selenium server jar. | 948 * Selenium server jar. |
| 981 */ | 949 */ |
| 982 bool get _needsSelenium() => Platform.operatingSystem == 'macos' && | 950 bool get _needsSelenium() => Platform.operatingSystem == 'macos' && |
| 983 browserUsed == 'safari'; | 951 browserUsed == 'safari'; |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1168 // the developer doesn't waste his or her time trying to fix a bunch of | 1136 // the developer doesn't waste his or her time trying to fix a bunch of |
| 1169 // tests that appear to be broken but were actually just flakes that | 1137 // tests that appear to be broken but were actually just flakes that |
| 1170 // didn't get retried because there had already been one failure. | 1138 // didn't get retried because there had already been one failure. |
| 1171 bool allowRetry = _MAX_FAILED_NO_RETRY > _progress.numFailedTests; | 1139 bool allowRetry = _MAX_FAILED_NO_RETRY > _progress.numFailedTests; |
| 1172 new RunningProcess(test, allowRetry, this).start(); | 1140 new RunningProcess(test, allowRetry, this).start(); |
| 1173 } | 1141 } |
| 1174 _numProcesses++; | 1142 _numProcesses++; |
| 1175 } | 1143 } |
| 1176 } | 1144 } |
| 1177 } | 1145 } |
| OLD | NEW |