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

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

Issue 59623015: GTTF: Flip test launcher defaults (developer mode is now default) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase 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/launcher/unit_test_launcher.cc » ('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
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 bool UnsetEnvironmentVariableIfExists(const std::string& name) { 171 bool UnsetEnvironmentVariableIfExists(const std::string& name) {
172 scoped_ptr<Environment> env(Environment::Create()); 172 scoped_ptr<Environment> env(Environment::Create());
173 std::string str_val; 173 std::string str_val;
174 174
175 if (!env->GetVar(name.c_str(), &str_val)) 175 if (!env->GetVar(name.c_str(), &str_val))
176 return true; 176 return true;
177 177
178 return env->UnSetVar(name.c_str()); 178 return env->UnSetVar(name.c_str());
179 } 179 }
180 180
181 // 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
183 // special command-line flags.
184 bool BotModeEnabled() {
185 scoped_ptr<Environment> env(Environment::Create());
186 return CommandLine::ForCurrentProcess()->HasSwitch(
187 switches::kTestLauncherBotMode) ||
188 env->HasVar("CHROMIUM_TEST_LAUNCHER_BOT_MODE");
189 }
190
181 // For a basic pattern matching for gtest_filter options. (Copied from 191 // For a basic pattern matching for gtest_filter options. (Copied from
182 // gtest.cc, see the comment below and http://crbug.com/44497) 192 // gtest.cc, see the comment below and http://crbug.com/44497)
183 bool PatternMatchesString(const char* pattern, const char* str) { 193 bool PatternMatchesString(const char* pattern, const char* str) {
184 switch (*pattern) { 194 switch (*pattern) {
185 case '\0': 195 case '\0':
186 case ':': // Either ':' or '\0' marks the end of the pattern. 196 case ':': // Either ':' or '\0' marks the end of the pattern.
187 return *str == '\0'; 197 return *str == '\0';
188 case '?': // Matches any single character. 198 case '?': // Matches any single character.
189 return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); 199 return *str != '\0' && PatternMatchesString(pattern + 1, str + 1);
190 case '*': // Matches any string (possibly empty) of characters. 200 case '*': // Matches any string (possibly empty) of characters.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 int exit_code, 234 int exit_code,
225 const TimeDelta& elapsed_time, 235 const TimeDelta& elapsed_time,
226 bool was_timeout, 236 bool was_timeout,
227 const std::string& output) { 237 const std::string& output) {
228 callback.Run(exit_code, elapsed_time, was_timeout, output); 238 callback.Run(exit_code, elapsed_time, was_timeout, output);
229 } 239 }
230 240
231 void DoLaunchChildTestProcess( 241 void DoLaunchChildTestProcess(
232 const CommandLine& command_line, 242 const CommandLine& command_line,
233 base::TimeDelta timeout, 243 base::TimeDelta timeout,
244 bool redirect_stdio,
234 scoped_refptr<MessageLoopProxy> message_loop_proxy, 245 scoped_refptr<MessageLoopProxy> message_loop_proxy,
235 const TestLauncher::LaunchChildGTestProcessCallback& callback) { 246 const TestLauncher::LaunchChildGTestProcessCallback& callback) {
236 TimeTicks start_time = TimeTicks::Now(); 247 TimeTicks start_time = TimeTicks::Now();
237 248
238 // Redirect child process output to a file. 249 // Redirect child process output to a file.
239 base::FilePath output_file; 250 base::FilePath output_file;
240 CHECK(file_util::CreateTemporaryFile(&output_file)); 251 CHECK(file_util::CreateTemporaryFile(&output_file));
241 252
242 LaunchOptions options; 253 LaunchOptions options;
243 #if defined(OS_WIN) 254 #if defined(OS_WIN)
244 win::ScopedHandle handle; 255 win::ScopedHandle handle;
245 256
246 if (!CommandLine::ForCurrentProcess()->HasSwitch( 257 if (redirect_stdio) {
247 switches::kTestLauncherDeveloperMode)) {
248 // Make the file handle inheritable by the child. 258 // Make the file handle inheritable by the child.
249 SECURITY_ATTRIBUTES sa_attr; 259 SECURITY_ATTRIBUTES sa_attr;
250 sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES); 260 sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
251 sa_attr.lpSecurityDescriptor = NULL; 261 sa_attr.lpSecurityDescriptor = NULL;
252 sa_attr.bInheritHandle = TRUE; 262 sa_attr.bInheritHandle = TRUE;
253 263
254 handle.Set(CreateFile(output_file.value().c_str(), 264 handle.Set(CreateFile(output_file.value().c_str(),
255 GENERIC_WRITE, 265 GENERIC_WRITE,
256 FILE_SHARE_READ | FILE_SHARE_DELETE, 266 FILE_SHARE_READ | FILE_SHARE_DELETE,
257 &sa_attr, 267 &sa_attr,
258 OPEN_EXISTING, 268 OPEN_EXISTING,
259 FILE_ATTRIBUTE_TEMPORARY, 269 FILE_ATTRIBUTE_TEMPORARY,
260 NULL)); 270 NULL));
261 CHECK(handle.IsValid()); 271 CHECK(handle.IsValid());
262 options.inherit_handles = true; 272 options.inherit_handles = true;
263 options.stdin_handle = INVALID_HANDLE_VALUE; 273 options.stdin_handle = INVALID_HANDLE_VALUE;
264 options.stdout_handle = handle.Get(); 274 options.stdout_handle = handle.Get();
265 options.stderr_handle = handle.Get(); 275 options.stderr_handle = handle.Get();
266 } 276 }
267 #elif defined(OS_POSIX) 277 #elif defined(OS_POSIX)
268 options.new_process_group = true; 278 options.new_process_group = true;
269 279
270 base::FileHandleMappingVector fds_mapping; 280 base::FileHandleMappingVector fds_mapping;
271 file_util::ScopedFD output_file_fd_closer; 281 file_util::ScopedFD output_file_fd_closer;
272 282
273 if (!CommandLine::ForCurrentProcess()->HasSwitch( 283 if (redirect_stdio) {
274 switches::kTestLauncherDeveloperMode)) {
275 int output_file_fd = open(output_file.value().c_str(), O_RDWR); 284 int output_file_fd = open(output_file.value().c_str(), O_RDWR);
276 CHECK_GE(output_file_fd, 0); 285 CHECK_GE(output_file_fd, 0);
277 286
278 output_file_fd_closer.reset(&output_file_fd); 287 output_file_fd_closer.reset(&output_file_fd);
279 288
280 fds_mapping.push_back(std::make_pair(output_file_fd, STDOUT_FILENO)); 289 fds_mapping.push_back(std::make_pair(output_file_fd, STDOUT_FILENO));
281 fds_mapping.push_back(std::make_pair(output_file_fd, STDERR_FILENO)); 290 fds_mapping.push_back(std::make_pair(output_file_fd, STDERR_FILENO));
282 options.fds_to_remap = &fds_mapping; 291 options.fds_to_remap = &fds_mapping;
283 } 292 }
284 #endif 293 #endif
285 294
286 bool was_timeout = false; 295 bool was_timeout = false;
287 int exit_code = LaunchChildTestProcessWithOptions( 296 int exit_code = LaunchChildTestProcessWithOptions(
288 command_line, options, timeout, &was_timeout); 297 command_line, options, timeout, &was_timeout);
289 298
290 if (!CommandLine::ForCurrentProcess()->HasSwitch( 299 if (redirect_stdio) {
291 switches::kTestLauncherDeveloperMode)) {
292 #if defined(OS_WIN) 300 #if defined(OS_WIN)
293 FlushFileBuffers(handle.Get()); 301 FlushFileBuffers(handle.Get());
294 handle.Close(); 302 handle.Close();
295 #elif defined(OS_POSIX) 303 #elif defined(OS_POSIX)
296 output_file_fd_closer.reset(); 304 output_file_fd_closer.reset();
297 #endif 305 #endif
298 } 306 }
299 307
300 std::string output_file_contents; 308 std::string output_file_contents;
301 CHECK(base::ReadFileToString(output_file, &output_file_contents)); 309 CHECK(base::ReadFileToString(output_file, &output_file_contents));
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 size_t parallel_jobs) 341 size_t parallel_jobs)
334 : launcher_delegate_(launcher_delegate), 342 : launcher_delegate_(launcher_delegate),
335 total_shards_(1), 343 total_shards_(1),
336 shard_index_(0), 344 shard_index_(0),
337 cycles_(1), 345 cycles_(1),
338 test_started_count_(0), 346 test_started_count_(0),
339 test_finished_count_(0), 347 test_finished_count_(0),
340 test_success_count_(0), 348 test_success_count_(0),
341 test_broken_count_(0), 349 test_broken_count_(0),
342 retry_count_(0), 350 retry_count_(0),
343 retry_limit_(3), 351 retry_limit_(0),
344 run_result_(true), 352 run_result_(true),
345 watchdog_timer_(FROM_HERE, 353 watchdog_timer_(FROM_HERE,
346 TimeDelta::FromSeconds(kOutputTimeoutSeconds), 354 TimeDelta::FromSeconds(kOutputTimeoutSeconds),
347 this, 355 this,
348 &TestLauncher::OnOutputTimeout) { 356 &TestLauncher::OnOutputTimeout),
349 if (CommandLine::ForCurrentProcess()->HasSwitch( 357 parallel_jobs_(parallel_jobs) {
350 switches::kTestLauncherDeveloperMode)) { 358 if (BotModeEnabled()) {
351 parallel_jobs = 1;
352 retry_limit_ = 0;
353 fprintf(stdout, 359 fprintf(stdout,
354 "Forcing serial test execution in developer mode.\n" 360 "Enabling defaults optimized for continuous integration bots.\n");
355 "Disabling test retries in developer mode.\n");
356 fflush(stdout); 361 fflush(stdout);
362
363 // Enable test retries by default for bots. This can be still overridden
364 // from command line using --test-launcher-retry-limit flag.
365 retry_limit_ = 3;
366 } else {
367 // Default to serial test execution if not running on a bot. This makes it
368 // possible to disable stdio redirection and can still be overridden with
369 // --test-launcher-jobs flag.
370 parallel_jobs_ = 1;
357 } 371 }
358 worker_pool_owner_.reset(
359 new SequencedWorkerPoolOwner(parallel_jobs, "test_launcher"));
360 } 372 }
361 373
362 TestLauncher::~TestLauncher() { 374 TestLauncher::~TestLauncher() {
363 worker_pool_owner_->pool()->Shutdown(); 375 if (worker_pool_owner_)
376 worker_pool_owner_->pool()->Shutdown();
364 } 377 }
365 378
366 bool TestLauncher::Run(int argc, char** argv) { 379 bool TestLauncher::Run(int argc, char** argv) {
367 if (!Init()) 380 if (!Init())
368 return false; 381 return false;
369 382
370 #if defined(OS_POSIX) 383 #if defined(OS_POSIX)
371 CHECK_EQ(0, pipe(g_shutdown_pipe)); 384 CHECK_EQ(0, pipe(g_shutdown_pipe));
372 385
373 struct sigaction action; 386 struct sigaction action;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 const CommandLine& command_line, 424 const CommandLine& command_line,
412 const std::string& wrapper, 425 const std::string& wrapper,
413 base::TimeDelta timeout, 426 base::TimeDelta timeout,
414 const LaunchChildGTestProcessCallback& callback) { 427 const LaunchChildGTestProcessCallback& callback) {
415 DCHECK(thread_checker_.CalledOnValidThread()); 428 DCHECK(thread_checker_.CalledOnValidThread());
416 429
417 // Record the exact command line used to launch the child. 430 // Record the exact command line used to launch the child.
418 CommandLine new_command_line( 431 CommandLine new_command_line(
419 PrepareCommandLineForGTest(command_line, wrapper)); 432 PrepareCommandLineForGTest(command_line, wrapper));
420 433
434 // When running in parallel mode we need to redirect stdio to avoid mixed-up
435 // output. We also always redirect on the bots to get the test output into
436 // JSON summary.
437 bool redirect_stdio = (parallel_jobs_ > 1) || BotModeEnabled();
438
421 worker_pool_owner_->pool()->PostWorkerTask( 439 worker_pool_owner_->pool()->PostWorkerTask(
422 FROM_HERE, 440 FROM_HERE,
423 Bind(&DoLaunchChildTestProcess, 441 Bind(&DoLaunchChildTestProcess,
424 new_command_line, 442 new_command_line,
425 timeout, 443 timeout,
444 redirect_stdio,
426 MessageLoopProxy::current(), 445 MessageLoopProxy::current(),
427 Bind(&TestLauncher::OnLaunchTestProcessFinished, 446 Bind(&TestLauncher::OnLaunchTestProcessFinished,
428 Unretained(this), 447 Unretained(this),
429 callback))); 448 callback)));
430 } 449 }
431 450
432 void TestLauncher::OnTestFinished(const TestResult& result) { 451 void TestLauncher::OnTestFinished(const TestResult& result) {
433 ++test_finished_count_; 452 ++test_finished_count_;
434 453
435 bool print_snippet = false; 454 bool print_snippet = false;
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 if (!StringToInt(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 665 if (!StringToInt(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
647 switches::kTestLauncherRetryLimit), &retry_limit) || 666 switches::kTestLauncherRetryLimit), &retry_limit) ||
648 retry_limit < 0) { 667 retry_limit < 0) {
649 LOG(ERROR) << "Invalid value for " << switches::kTestLauncherRetryLimit; 668 LOG(ERROR) << "Invalid value for " << switches::kTestLauncherRetryLimit;
650 return false; 669 return false;
651 } 670 }
652 671
653 retry_limit_ = retry_limit; 672 retry_limit_ = retry_limit;
654 } 673 }
655 674
675 if (CommandLine::ForCurrentProcess()->HasSwitch(
676 switches::kTestLauncherJobs)) {
677 int jobs = -1;
678 if (!StringToInt(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
679 switches::kTestLauncherJobs), &jobs) ||
680 jobs < 0) {
681 LOG(ERROR) << "Invalid value for " << switches::kTestLauncherJobs;
682 return false;
683 }
684
685 parallel_jobs_ = jobs;
686 }
687 fprintf(stdout, "Using %" PRIuS " parallel jobs.\n", parallel_jobs_);
688 fflush(stdout);
689 worker_pool_owner_.reset(
690 new SequencedWorkerPoolOwner(parallel_jobs_, "test_launcher"));
691
656 // Split --gtest_filter at '-', if there is one, to separate into 692 // Split --gtest_filter at '-', if there is one, to separate into
657 // positive filter and negative filter portions. 693 // positive filter and negative filter portions.
658 std::string filter = command_line->GetSwitchValueASCII(kGTestFilterFlag); 694 std::string filter = command_line->GetSwitchValueASCII(kGTestFilterFlag);
659 positive_test_filter_ = filter; 695 positive_test_filter_ = filter;
660 size_t dash_pos = filter.find('-'); 696 size_t dash_pos = filter.find('-');
661 if (dash_pos != std::string::npos) { 697 if (dash_pos != std::string::npos) {
662 // Everything up to the dash. 698 // Everything up to the dash.
663 positive_test_filter_ = filter.substr(0, dash_pos); 699 positive_test_filter_ = filter.substr(0, dash_pos);
664 700
665 // Everything after the dash. 701 // Everything after the dash.
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 987
952 g_live_processes.Get().erase(process_handle); 988 g_live_processes.Get().erase(process_handle);
953 } 989 }
954 990
955 base::CloseProcessHandle(process_handle); 991 base::CloseProcessHandle(process_handle);
956 992
957 return exit_code; 993 return exit_code;
958 } 994 }
959 995
960 } // namespace base 996 } // namespace base
OLDNEW
« no previous file with comments | « base/test/launcher/test_launcher.h ('k') | base/test/launcher/unit_test_launcher.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698