Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/test/launcher/test_launcher.h" | 5 #include "base/test/launcher/test_launcher.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 819 fprintf(stdout, "Using %" PRIuS " parallel jobs.\n", parallel_jobs_); | 819 fprintf(stdout, "Using %" PRIuS " parallel jobs.\n", parallel_jobs_); |
| 820 fflush(stdout); | 820 fflush(stdout); |
| 821 if (parallel_jobs_ > 1U) { | 821 if (parallel_jobs_ > 1U) { |
| 822 worker_pool_owner_ = MakeUnique<SequencedWorkerPoolOwner>( | 822 worker_pool_owner_ = MakeUnique<SequencedWorkerPoolOwner>( |
| 823 parallel_jobs_, "test_launcher"); | 823 parallel_jobs_, "test_launcher"); |
| 824 } else { | 824 } else { |
| 825 worker_thread_ = MakeUnique<Thread>("test_launcher"); | 825 worker_thread_ = MakeUnique<Thread>("test_launcher"); |
| 826 worker_thread_->Start(); | 826 worker_thread_->Start(); |
| 827 } | 827 } |
| 828 | 828 |
| 829 if (command_line->HasSwitch(switches::kTestLauncherFilterFile) && | |
| 830 command_line->HasSwitch(kGTestFilterFlag)) { | |
| 831 LOG(ERROR) << "Only one of --test-launcher-filter-file and --gtest_filter " | |
| 832 << "at a time is allowed."; | |
| 833 return false; | |
| 834 } | |
| 835 | |
| 836 if (command_line->HasSwitch(switches::kTestLauncherFilterFile)) { | 829 if (command_line->HasSwitch(switches::kTestLauncherFilterFile)) { |
| 837 base::FilePath filter_file_path = base::MakeAbsoluteFilePath( | 830 base::FilePath filter_file_path = base::MakeAbsoluteFilePath( |
| 838 command_line->GetSwitchValuePath(switches::kTestLauncherFilterFile)); | 831 command_line->GetSwitchValuePath(switches::kTestLauncherFilterFile)); |
| 839 std::string filter; | 832 std::string filter; |
| 840 if (!ReadFileToString(filter_file_path, &filter)) { | 833 if (!ReadFileToString(filter_file_path, &filter)) { |
| 841 LOG(ERROR) << "Failed to read the filter file."; | 834 LOG(ERROR) << "Failed to read the filter file."; |
| 842 return false; | 835 return false; |
| 843 } | 836 } |
| 844 | 837 |
| 845 // Parse the file contents (see //testing/buildbot/filters/README.md | 838 // Parse the file contents (see //testing/buildbot/filters/README.md |
| 846 // for file syntax and other info). | 839 // for file syntax and other info). |
| 847 std::vector<std::string> filter_lines = SplitString( | 840 std::vector<std::string> filter_lines = SplitString( |
| 848 filter, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | 841 filter, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
| 849 for (const std::string& filter_line : filter_lines) { | 842 for (const std::string& filter_line : filter_lines) { |
| 850 if (filter_line.empty() || filter_line[0] == '#') | 843 if (filter_line.empty() || filter_line[0] == '#') |
| 851 continue; | 844 continue; |
| 852 | 845 |
| 853 if (filter_line[0] == '-') | 846 if (filter_line[0] == '-') |
| 854 negative_test_filter_.push_back(filter_line.substr(1)); | 847 negative_test_filter_.push_back(filter_line.substr(1)); |
| 855 else | 848 else |
| 856 positive_test_filter_.push_back(filter_line); | 849 positive_test_filter_file_.push_back(filter_line); |
| 850 } | |
| 851 } | |
| 852 // Split --gtest_filter at '-', if there is one, to separate into | |
| 853 // positive filter and negative filter portions. | |
| 854 std::string filter = command_line->GetSwitchValueASCII(kGTestFilterFlag); | |
| 855 size_t dash_pos = filter.find('-'); | |
| 856 if (dash_pos == std::string::npos) { | |
| 857 for (std::string test_name : SplitString(filter, ":", base::TRIM_WHITESPACE, | |
|
Paweł Hajdan Jr.
2016/11/28 12:56:14
nit: Why do we need the loops for the positive fil
katthomas
2016/11/29 21:38:26
Oops, should have changed that back. Thanks for ca
| |
| 858 base::SPLIT_WANT_ALL)) { | |
| 859 positive_test_filter_gtest_.push_back(test_name); | |
| 857 } | 860 } |
| 858 } else { | 861 } else { |
| 859 // Split --gtest_filter at '-', if there is one, to separate into | 862 // Everything up to the dash. |
| 860 // positive filter and negative filter portions. | 863 for (std::string test_name : |
| 861 std::string filter = command_line->GetSwitchValueASCII(kGTestFilterFlag); | 864 SplitString(filter.substr(0, dash_pos), ":", base::TRIM_WHITESPACE, |
| 862 size_t dash_pos = filter.find('-'); | 865 base::SPLIT_WANT_ALL)) { |
| 863 if (dash_pos == std::string::npos) { | 866 positive_test_filter_gtest_.push_back(test_name); |
| 864 positive_test_filter_ = SplitString( | 867 } |
| 865 filter, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | |
| 866 } else { | |
| 867 // Everything up to the dash. | |
| 868 positive_test_filter_ = SplitString( | |
| 869 filter.substr(0, dash_pos), ":", base::TRIM_WHITESPACE, | |
| 870 base::SPLIT_WANT_ALL); | |
| 871 | 868 |
| 872 // Everything after the dash. | 869 // Everything after the dash. |
| 873 negative_test_filter_ = SplitString( | 870 for (std::string test_name : |
| 874 filter.substr(dash_pos + 1), ":", base::TRIM_WHITESPACE, | 871 SplitString(filter.substr(dash_pos + 1), ":", base::TRIM_WHITESPACE, |
| 875 base::SPLIT_WANT_ALL); | 872 base::SPLIT_WANT_ALL)) { |
| 873 negative_test_filter_.push_back(test_name); | |
| 876 } | 874 } |
| 877 } | 875 } |
| 878 | 876 |
| 879 if (!launcher_delegate_->GetTests(&tests_)) { | 877 if (!launcher_delegate_->GetTests(&tests_)) { |
| 880 LOG(ERROR) << "Failed to get list of tests."; | 878 LOG(ERROR) << "Failed to get list of tests."; |
| 881 return false; | 879 return false; |
| 882 } | 880 } |
| 883 | 881 |
| 884 if (!results_tracker_.Init(*command_line)) { | 882 if (!results_tracker_.Init(*command_line)) { |
| 885 LOG(ERROR) << "Failed to initialize test results tracker."; | 883 LOG(ERROR) << "Failed to initialize test results tracker."; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 945 #endif | 943 #endif |
| 946 | 944 |
| 947 #if defined(ARCH_CPU_64_BITS) | 945 #if defined(ARCH_CPU_64_BITS) |
| 948 results_tracker_.AddGlobalTag("CPU_64_BITS"); | 946 results_tracker_.AddGlobalTag("CPU_64_BITS"); |
| 949 #endif | 947 #endif |
| 950 | 948 |
| 951 return true; | 949 return true; |
| 952 } | 950 } |
| 953 | 951 |
| 954 void TestLauncher::RunTests() { | 952 void TestLauncher::RunTests() { |
| 953 // Compute the intersection of the gtest and filter file positive filters | |
|
Paweł Hajdan Jr.
2016/11/28 12:56:13
Could you explain more reasoning behind this?
It
Dirk Pranke
2016/11/29 02:07:15
I'm interpreting "Could you explain more" as "writ
katthomas
2016/11/29 21:38:26
Oh right, I didn't realize you could match pattern
| |
| 954 std::sort(positive_test_filter_file_.begin(), | |
| 955 positive_test_filter_file_.end()); | |
| 956 std::sort(positive_test_filter_gtest_.begin(), | |
| 957 positive_test_filter_gtest_.end()); | |
| 958 std::set_intersection( | |
| 959 positive_test_filter_file_.begin(), positive_test_filter_file_.end(), | |
| 960 positive_test_filter_gtest_.begin(), positive_test_filter_gtest_.end(), | |
| 961 std::back_inserter(positive_test_filter_)); | |
| 962 | |
| 955 std::vector<std::string> test_names; | 963 std::vector<std::string> test_names; |
| 956 for (size_t i = 0; i < tests_.size(); i++) { | 964 bool has_positive_filter = !positive_test_filter_file_.empty() || |
| 957 std::string test_name = FormatFullTestName( | 965 !positive_test_filter_gtest_.empty(); |
| 958 tests_[i].test_case_name, tests_[i].test_name); | 966 if (!has_positive_filter || !positive_test_filter_.empty() || |
| 967 !negative_test_filter_.empty()) { | |
| 968 for (size_t i = 0; i < tests_.size(); i++) { | |
| 969 std::string test_name = | |
| 970 FormatFullTestName(tests_[i].test_case_name, tests_[i].test_name); | |
| 959 | 971 |
| 960 results_tracker_.AddTest(test_name, tests_[i].file, tests_[i].line); | 972 results_tracker_.AddTest(test_name, tests_[i].file, tests_[i].line); |
| 961 | 973 |
| 962 const CommandLine* command_line = CommandLine::ForCurrentProcess(); | 974 const CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 963 if (test_name.find("DISABLED") != std::string::npos) { | 975 if (test_name.find("DISABLED") != std::string::npos) { |
| 964 results_tracker_.AddDisabledTest(test_name); | 976 results_tracker_.AddDisabledTest(test_name); |
| 965 | 977 |
| 966 // Skip disabled tests unless explicitly requested. | 978 // Skip disabled tests unless explicitly requested. |
| 967 if (!command_line->HasSwitch(kGTestRunDisabledTestsFlag)) | 979 if (!command_line->HasSwitch(kGTestRunDisabledTestsFlag)) |
| 968 continue; | 980 continue; |
| 969 } | |
| 970 | |
| 971 if (!launcher_delegate_->ShouldRunTest( | |
| 972 tests_[i].test_case_name, tests_[i].test_name)) { | |
| 973 continue; | |
| 974 } | |
| 975 | |
| 976 // Count tests in the binary, before we apply filter and sharding. | |
| 977 test_found_count_++; | |
| 978 | |
| 979 std::string test_name_no_disabled = TestNameWithoutDisabledPrefix( | |
| 980 test_name); | |
| 981 | |
| 982 // Skip the test that doesn't match the filter (if given). | |
| 983 if (!positive_test_filter_.empty()) { | |
| 984 bool found = false; | |
| 985 for (size_t k = 0; k < positive_test_filter_.size(); ++k) { | |
| 986 if (MatchPattern(test_name, positive_test_filter_[k]) || | |
| 987 MatchPattern(test_name_no_disabled, positive_test_filter_[k])) { | |
| 988 found = true; | |
| 989 break; | |
| 990 } | |
| 991 } | 981 } |
| 992 | 982 |
| 993 if (!found) | 983 if (!launcher_delegate_->ShouldRunTest(tests_[i].test_case_name, |
| 984 tests_[i].test_name)) { | |
| 994 continue; | 985 continue; |
| 995 } | |
| 996 if (!negative_test_filter_.empty()) { | |
| 997 bool excluded = false; | |
| 998 for (size_t k = 0; k < negative_test_filter_.size(); ++k) { | |
| 999 if (MatchPattern(test_name, negative_test_filter_[k]) || | |
| 1000 MatchPattern(test_name_no_disabled, negative_test_filter_[k])) { | |
| 1001 excluded = true; | |
| 1002 break; | |
| 1003 } | |
| 1004 } | 986 } |
| 1005 | 987 |
| 1006 if (excluded) | 988 // Count tests in the binary, before we apply filter and sharding. |
| 989 test_found_count_++; | |
| 990 | |
| 991 std::string test_name_no_disabled = | |
| 992 TestNameWithoutDisabledPrefix(test_name); | |
| 993 | |
| 994 // Skip the test that doesn't match the filter (if given). | |
| 995 if (!positive_test_filter_.empty()) { | |
| 996 bool found = false; | |
| 997 for (size_t k = 0; k < positive_test_filter_.size(); ++k) { | |
| 998 if (MatchPattern(test_name, positive_test_filter_[k]) || | |
| 999 MatchPattern(test_name_no_disabled, positive_test_filter_[k])) { | |
| 1000 found = true; | |
| 1001 break; | |
| 1002 } | |
| 1003 } | |
| 1004 | |
| 1005 if (!found) | |
| 1006 continue; | |
| 1007 } | |
| 1008 if (!negative_test_filter_.empty()) { | |
| 1009 bool excluded = false; | |
| 1010 for (size_t k = 0; k < negative_test_filter_.size(); ++k) { | |
| 1011 if (MatchPattern(test_name, negative_test_filter_[k]) || | |
| 1012 MatchPattern(test_name_no_disabled, negative_test_filter_[k])) { | |
| 1013 excluded = true; | |
| 1014 break; | |
| 1015 } | |
| 1016 } | |
| 1017 | |
| 1018 if (excluded) | |
| 1019 continue; | |
| 1020 } | |
| 1021 | |
| 1022 if (Hash(test_name) % total_shards_ != | |
| 1023 static_cast<uint32_t>(shard_index_)) | |
| 1007 continue; | 1024 continue; |
| 1025 | |
| 1026 test_names.push_back(test_name); | |
| 1008 } | 1027 } |
| 1009 | |
| 1010 if (Hash(test_name) % total_shards_ != static_cast<uint32_t>(shard_index_)) | |
| 1011 continue; | |
| 1012 | |
| 1013 test_names.push_back(test_name); | |
| 1014 } | 1028 } |
| 1015 | 1029 |
| 1016 // Save an early test summary in case the launcher crashes or gets killed. | 1030 // Save an early test summary in case the launcher crashes or gets killed. |
| 1017 MaybeSaveSummaryAsJSON({"EARLY_SUMMARY", kUnreliableResultsTag}); | 1031 MaybeSaveSummaryAsJSON({"EARLY_SUMMARY", kUnreliableResultsTag}); |
| 1018 | 1032 |
| 1019 test_started_count_ = launcher_delegate_->RunTests(this, test_names); | 1033 test_started_count_ = launcher_delegate_->RunTests(this, test_names); |
| 1020 | 1034 |
| 1021 if (test_started_count_ == 0) { | 1035 if (test_started_count_ == 0) { |
| 1022 fprintf(stdout, "0 tests run\n"); | 1036 fprintf(stdout, "0 tests run\n"); |
| 1023 fflush(stdout); | 1037 fflush(stdout); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1168 } | 1182 } |
| 1169 | 1183 |
| 1170 std::string snippet(full_output.substr(run_pos)); | 1184 std::string snippet(full_output.substr(run_pos)); |
| 1171 if (end_pos != std::string::npos) | 1185 if (end_pos != std::string::npos) |
| 1172 snippet = full_output.substr(run_pos, end_pos - run_pos); | 1186 snippet = full_output.substr(run_pos, end_pos - run_pos); |
| 1173 | 1187 |
| 1174 return snippet; | 1188 return snippet; |
| 1175 } | 1189 } |
| 1176 | 1190 |
| 1177 } // namespace base | 1191 } // namespace base |
| OLD | NEW |