Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: base/test/launcher/test_launcher.cc

Issue 117113003: GTTF: add an option to pass test filter using a file (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/test/launcher/test_launcher.h ('k') | base/test/test_switches.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #if defined(OS_POSIX) 7 #if defined(OS_POSIX)
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #endif 9 #endif
10 10
11 #include "base/at_exit.h" 11 #include "base/at_exit.h"
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/environment.h" 14 #include "base/environment.h"
15 #include "base/file_util.h" 15 #include "base/file_util.h"
16 #include "base/files/file_path.h" 16 #include "base/files/file_path.h"
17 #include "base/format_macros.h" 17 #include "base/format_macros.h"
18 #include "base/lazy_instance.h" 18 #include "base/lazy_instance.h"
19 #include "base/logging.h" 19 #include "base/logging.h"
20 #include "base/memory/scoped_ptr.h" 20 #include "base/memory/scoped_ptr.h"
21 #include "base/message_loop/message_loop.h" 21 #include "base/message_loop/message_loop.h"
22 #include "base/process/kill.h" 22 #include "base/process/kill.h"
23 #include "base/process/launch.h" 23 #include "base/process/launch.h"
24 #include "base/strings/string_number_conversions.h" 24 #include "base/strings/string_number_conversions.h"
25 #include "base/strings/string_split.h"
26 #include "base/strings/string_util.h"
25 #include "base/strings/stringprintf.h" 27 #include "base/strings/stringprintf.h"
26 #include "base/strings/utf_string_conversions.h" 28 #include "base/strings/utf_string_conversions.h"
27 #include "base/test/launcher/test_results_tracker.h" 29 #include "base/test/launcher/test_results_tracker.h"
28 #include "base/test/sequenced_worker_pool_owner.h" 30 #include "base/test/sequenced_worker_pool_owner.h"
29 #include "base/test/test_switches.h" 31 #include "base/test/test_switches.h"
30 #include "base/test/test_timeouts.h" 32 #include "base/test/test_timeouts.h"
31 #include "base/threading/thread_checker.h" 33 #include "base/threading/thread_checker.h"
32 #include "base/time/time.h" 34 #include "base/time/time.h"
33 #include "testing/gtest/include/gtest/gtest.h" 35 #include "testing/gtest/include/gtest/gtest.h"
34 36
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 // Returns true if bot mode has been requested, i.e. defaults optimized 183 // Returns true if bot mode has been requested, i.e. defaults optimized
182 // for continuous integration bots. This way developers don't have to remember 184 // for continuous integration bots. This way developers don't have to remember
183 // special command-line flags. 185 // special command-line flags.
184 bool BotModeEnabled() { 186 bool BotModeEnabled() {
185 scoped_ptr<Environment> env(Environment::Create()); 187 scoped_ptr<Environment> env(Environment::Create());
186 return CommandLine::ForCurrentProcess()->HasSwitch( 188 return CommandLine::ForCurrentProcess()->HasSwitch(
187 switches::kTestLauncherBotMode) || 189 switches::kTestLauncherBotMode) ||
188 env->HasVar("CHROMIUM_TEST_LAUNCHER_BOT_MODE"); 190 env->HasVar("CHROMIUM_TEST_LAUNCHER_BOT_MODE");
189 } 191 }
190 192
191 // For a basic pattern matching for gtest_filter options. (Copied from
192 // gtest.cc, see the comment below and http://crbug.com/44497)
193 bool PatternMatchesString(const char* pattern, const char* str) {
194 switch (*pattern) {
195 case '\0':
196 case ':': // Either ':' or '\0' marks the end of the pattern.
197 return *str == '\0';
198 case '?': // Matches any single character.
199 return *str != '\0' && PatternMatchesString(pattern + 1, str + 1);
200 case '*': // Matches any string (possibly empty) of characters.
201 return (*str != '\0' && PatternMatchesString(pattern, str + 1)) ||
202 PatternMatchesString(pattern + 1, str);
203 default: // Non-special character. Matches itself.
204 return *pattern == *str &&
205 PatternMatchesString(pattern + 1, str + 1);
206 }
207 }
208
209 // TODO(phajdan.jr): Avoid duplicating gtest code. (http://crbug.com/44497)
210 // For basic pattern matching for gtest_filter options. (Copied from
211 // gtest.cc)
212 bool MatchesFilter(const std::string& name, const std::string& filter) {
213 const char *cur_pattern = filter.c_str();
214 for (;;) {
215 if (PatternMatchesString(cur_pattern, name.c_str())) {
216 return true;
217 }
218
219 // Finds the next pattern in the filter.
220 cur_pattern = strchr(cur_pattern, ':');
221
222 // Returns if no more pattern can be found.
223 if (cur_pattern == NULL) {
224 return false;
225 }
226
227 // Skips the pattern separater (the ':' character).
228 cur_pattern++;
229 }
230 }
231
232 void RunCallback( 193 void RunCallback(
233 const TestLauncher::LaunchChildGTestProcessCallback& callback, 194 const TestLauncher::LaunchChildGTestProcessCallback& callback,
234 int exit_code, 195 int exit_code,
235 const TimeDelta& elapsed_time, 196 const TimeDelta& elapsed_time,
236 bool was_timeout, 197 bool was_timeout,
237 const std::string& output) { 198 const std::string& output) {
238 callback.Run(exit_code, elapsed_time, was_timeout, output); 199 callback.Run(exit_code, elapsed_time, was_timeout, output);
239 } 200 }
240 201
241 void DoLaunchChildTestProcess( 202 void DoLaunchChildTestProcess(
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 return false; 636 return false;
676 } 637 }
677 638
678 parallel_jobs_ = jobs; 639 parallel_jobs_ = jobs;
679 } 640 }
680 fprintf(stdout, "Using %" PRIuS " parallel jobs.\n", parallel_jobs_); 641 fprintf(stdout, "Using %" PRIuS " parallel jobs.\n", parallel_jobs_);
681 fflush(stdout); 642 fflush(stdout);
682 worker_pool_owner_.reset( 643 worker_pool_owner_.reset(
683 new SequencedWorkerPoolOwner(parallel_jobs_, "test_launcher")); 644 new SequencedWorkerPoolOwner(parallel_jobs_, "test_launcher"));
684 645
685 // Split --gtest_filter at '-', if there is one, to separate into 646 if (command_line->HasSwitch(switches::kTestLauncherFilterFile) &&
686 // positive filter and negative filter portions. 647 command_line->HasSwitch(kGTestFilterFlag)) {
687 std::string filter = command_line->GetSwitchValueASCII(kGTestFilterFlag); 648 LOG(ERROR) << "Only one of --test-launcher-filter-file and --gtest_filter "
688 positive_test_filter_ = filter; 649 << "at a time is allowed.";
689 size_t dash_pos = filter.find('-'); 650 return false;
690 if (dash_pos != std::string::npos) { 651 }
691 // Everything up to the dash.
692 positive_test_filter_ = filter.substr(0, dash_pos);
693 652
694 // Everything after the dash. 653 if (command_line->HasSwitch(switches::kTestLauncherFilterFile)) {
695 negative_test_filter_ = filter.substr(dash_pos + 1); 654 std::string filter;
655 if (!ReadFileToString(
656 command_line->GetSwitchValuePath(switches::kTestLauncherFilterFile),
657 &filter)) {
658 LOG(ERROR) << "Failed to read the filter file.";
659 return false;
660 }
661
662 std::vector<std::string> filter_lines;
663 SplitString(filter, '\n', &filter_lines);
664 for (size_t i = 0; i < filter_lines.size(); i++) {
665 if (filter_lines[i].empty())
666 continue;
667
668 if (filter_lines[i][0] == '-')
669 negative_test_filter_.push_back(filter_lines[i].substr(1));
670 else
671 positive_test_filter_.push_back(filter_lines[i]);
672 }
673 } else {
674 // Split --gtest_filter at '-', if there is one, to separate into
sky 2013/12/18 17:19:59 I thought you could you multiple - patterns?
Paweł Hajdan Jr. 2013/12/18 17:50:30 You can. It's --gtest_filter=Test.Positive1:Test.P
sky 2013/12/18 21:48:42 I was thinking more of: Test.Positive1:Test.Positi
675 // positive filter and negative filter portions.
676 std::string filter = command_line->GetSwitchValueASCII(kGTestFilterFlag);
677 size_t dash_pos = filter.find('-');
678 if (dash_pos == std::string::npos) {
679 SplitString(filter, ':', &positive_test_filter_);
680 } else {
681 // Everything up to the dash.
682 SplitString(filter.substr(0, dash_pos), ':', &positive_test_filter_);
683
684 // Everything after the dash.
685 SplitString(filter.substr(dash_pos + 1), ':', &negative_test_filter_);
686 }
696 } 687 }
697 688
698 if (!results_tracker_.Init(*command_line)) { 689 if (!results_tracker_.Init(*command_line)) {
699 LOG(ERROR) << "Failed to initialize test results tracker."; 690 LOG(ERROR) << "Failed to initialize test results tracker.";
700 return 1; 691 return 1;
701 } 692 }
702 693
703 return true; 694 return true;
704 } 695 }
705 696
(...skipping 15 matching lines...) Expand all
721 // Skip disabled tests. 712 // Skip disabled tests.
722 const CommandLine* command_line = CommandLine::ForCurrentProcess(); 713 const CommandLine* command_line = CommandLine::ForCurrentProcess();
723 if (test_name.find("DISABLED") != std::string::npos && 714 if (test_name.find("DISABLED") != std::string::npos &&
724 !command_line->HasSwitch(kGTestRunDisabledTestsFlag)) { 715 !command_line->HasSwitch(kGTestRunDisabledTestsFlag)) {
725 continue; 716 continue;
726 } 717 }
727 718
728 std::string filtering_test_name = 719 std::string filtering_test_name =
729 launcher_delegate_->GetTestNameForFiltering(test_case, test_info); 720 launcher_delegate_->GetTestNameForFiltering(test_case, test_info);
730 721
731 // Skip the test that doesn't match the filter string (if given). 722 // Skip the test that doesn't match the filter (if given).
732 if ((!positive_test_filter_.empty() && 723 if (!positive_test_filter_.empty()) {
733 !MatchesFilter(filtering_test_name, positive_test_filter_)) || 724 bool found = false;
734 MatchesFilter(filtering_test_name, negative_test_filter_)) { 725 for (size_t k = 0; k < positive_test_filter_.size(); ++k) {
726 if (MatchPattern(filtering_test_name, positive_test_filter_[k])) {
727 found = true;
728 break;
729 }
730 }
731
732 if (!found)
733 continue;
734 }
735 bool excluded = false;
736 for (size_t k = 0; k < negative_test_filter_.size(); ++k) {
737 if (MatchPattern(filtering_test_name, negative_test_filter_[k])) {
738 excluded = true;
739 break;
740 }
741 }
742 if (excluded)
735 continue; 743 continue;
736 }
737 744
738 if (!launcher_delegate_->ShouldRunTest(test_case, test_info)) 745 if (!launcher_delegate_->ShouldRunTest(test_case, test_info))
739 continue; 746 continue;
740 747
741 if (num_runnable_tests++ % total_shards_ != shard_index_) 748 if (num_runnable_tests++ % total_shards_ != shard_index_)
742 continue; 749 continue;
743 750
744 test_names.push_back(test_name); 751 test_names.push_back(test_name);
745 } 752 }
746 } 753 }
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 1011
1005 g_live_processes.Get().erase(process_handle); 1012 g_live_processes.Get().erase(process_handle);
1006 } 1013 }
1007 1014
1008 base::CloseProcessHandle(process_handle); 1015 base::CloseProcessHandle(process_handle);
1009 1016
1010 return exit_code; 1017 return exit_code;
1011 } 1018 }
1012 1019
1013 } // namespace base 1020 } // namespace base
OLDNEW
« no previous file with comments | « base/test/launcher/test_launcher.h ('k') | base/test/test_switches.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698