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

Side by Side Diff: content/test/out_of_proc_test_runner.cc

Issue 8036044: Add (not yet working) content_browsertests target. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years, 2 months 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 | « content/content_tests.gypi ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 <string> 5 #include <string>
6 #include <vector> 6 #include <vector>
7 7
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/environment.h" 9 #include "base/environment.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/hash_tables.h" 11 #include "base/hash_tables.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/mac/scoped_nsautorelease_pool.h" 13 #include "base/mac/scoped_nsautorelease_pool.h"
14 #include "base/memory/linked_ptr.h" 14 #include "base/memory/linked_ptr.h"
15 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
16 #include "base/process_util.h" 16 #include "base/process_util.h"
17 #include "base/scoped_temp_dir.h" 17 #include "base/scoped_temp_dir.h"
18 #include "base/string_number_conversions.h" 18 #include "base/string_number_conversions.h"
19 #include "base/string_util.h" 19 #include "base/string_util.h"
20 #include "base/test/test_suite.h" 20 #include "base/test/test_suite.h"
21 #include "base/test/test_timeouts.h" 21 #include "base/test/test_timeouts.h"
22 #include "base/time.h" 22 #include "base/time.h"
23 #include "base/utf_string_conversions.h" 23 #include "base/utf_string_conversions.h"
24 #include "chrome/common/chrome_switches.h" 24 #include "content/test/browser_test.h"
sky 2011/09/27 15:31:52 Are these classes landing separately?
25 #include "chrome/test/base/chrome_test_suite.h" 25 #include "content/test/browser_test_suite.h"
26 #include "chrome/test/base/in_process_browser_test.h"
27 #include "chrome/test/base/test_launcher_utils.h"
28 #include "net/base/escape.h" 26 #include "net/base/escape.h"
29 #include "testing/gtest/include/gtest/gtest.h" 27 #include "testing/gtest/include/gtest/gtest.h"
30 28
31 #if defined(OS_WIN) 29 #if defined(OS_WIN)
32 #include "base/base_switches.h" 30 #include "base/base_switches.h"
33 #include "chrome/common/chrome_constants.h"
34 #include "content/common/sandbox_policy.h" 31 #include "content/common/sandbox_policy.h"
35 #include "sandbox/src/dep.h" 32 #include "sandbox/src/dep.h"
36 #include "sandbox/src/sandbox_factory.h" 33 #include "sandbox/src/sandbox_factory.h"
37 #include "sandbox/src/sandbox_types.h" 34 #include "sandbox/src/sandbox_types.h"
38 #endif // defined(OS_WIN) 35 #endif // defined(OS_WIN)
39 36
37 #if defined(BROWSER_TESTS_USE_CHROME)
38 #include "chrome/common/chrome_switches.h"
39 #include "chrome/common/chrome_constants.h"
40
40 #if defined(OS_MACOSX) 41 #if defined(OS_MACOSX)
41 #include "chrome/browser/chrome_browser_application_mac.h" 42 #include "chrome/browser/chrome_browser_application_mac.h"
42 #endif // defined(OS_MACOSX) 43 #endif // defined(OS_MACOSX)
43 44
45 #endif // defined(BROWSER_TESTS_USE_CHROME)
46
44 #if defined(OS_WIN) 47 #if defined(OS_WIN)
45 // The entry point signature of chrome.dll. 48 // The entry point signature of chrome.dll.
46 typedef int (*DLL_MAIN)(HINSTANCE, sandbox::SandboxInterfaceInfo*, wchar_t*); 49 typedef int (*DLL_MAIN)(HINSTANCE, sandbox::SandboxInterfaceInfo*, wchar_t*);
47 #endif // defined(OS_WIN) 50 #endif // defined(OS_WIN)
48 51
49 namespace { 52 namespace {
50 53
51 const char kGTestFilterFlag[] = "gtest_filter"; 54 const char kGTestFilterFlag[] = "gtest_filter";
52 const char kGTestHelpFlag[] = "gtest_help"; 55 const char kGTestHelpFlag[] = "gtest_help";
53 const char kGTestListTestsFlag[] = "gtest_list_tests"; 56 const char kGTestListTestsFlag[] = "gtest_list_tests";
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 // Returns if no more pattern can be found. 299 // Returns if no more pattern can be found.
297 if (cur_pattern == NULL) { 300 if (cur_pattern == NULL) {
298 return false; 301 return false;
299 } 302 }
300 303
301 // Skips the pattern separater (the ':' character). 304 // Skips the pattern separater (the ':' character).
302 cur_pattern++; 305 cur_pattern++;
303 } 306 }
304 } 307 }
305 308
309 namespace {
310
311 // A multiplier for slow tests. We generally avoid multiplying
312 // test timeouts by any constants. Here it is used as last resort
313 // to implement the SLOW_ test prefix.
314 static const int kSlowTestTimeoutMultiplier = 5;
315
316 } // namespace
317
318 int GetTestTerminationTimeout(const std::string& test_name,
319 int default_timeout_ms) {
320 int timeout_ms = default_timeout_ms;
321
322 // Make it possible for selected tests to request a longer timeout.
323 // Generally tests should really avoid doing too much, and splitting
324 // a test instead of using SLOW prefix is strongly preferred.
325 if (test_name.find("SLOW_") != std::string::npos)
326 timeout_ms *= kSlowTestTimeoutMultiplier;
327
328 return timeout_ms;
329 }
330
306 // Runs test specified by |test_name| in a child process, 331 // Runs test specified by |test_name| in a child process,
307 // and returns the exit code. 332 // and returns the exit code.
308 int RunTest(const std::string& test_name, int default_timeout_ms) { 333 int RunTest(const std::string& test_name, int default_timeout_ms) {
309 // Some of the below method calls will leak objects if there is no 334 // Some of the below method calls will leak objects if there is no
310 // autorelease pool in place. 335 // autorelease pool in place.
311 base::mac::ScopedNSAutoreleasePool pool; 336 base::mac::ScopedNSAutoreleasePool pool;
312 337
313 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); 338 const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
314 CommandLine new_cmd_line(cmd_line->GetProgram()); 339 CommandLine new_cmd_line(cmd_line->GetProgram());
315 CommandLine::SwitchMap switches = cmd_line->GetSwitches(); 340 CommandLine::SwitchMap switches = cmd_line->GetSwitches();
316 341
317 // Strip out gtest_output flag because otherwise we would overwrite results 342 // Strip out gtest_output flag because otherwise we would overwrite results
318 // of the previous test. We will generate the final output file later 343 // of the previous test. We will generate the final output file later
319 // in RunTests(). 344 // in RunTests().
320 switches.erase(kGTestOutputFlag); 345 switches.erase(kGTestOutputFlag);
321 346
322 // Strip out gtest_repeat flag because we can only run one test in the child 347 // Strip out gtest_repeat flag because we can only run one test in the child
323 // process (restarting the browser in the same process is illegal after it 348 // process (restarting the browser in the same process is illegal after it
324 // has been shut down and will actually crash). 349 // has been shut down and will actually crash).
325 switches.erase(kGTestRepeatFlag); 350 switches.erase(kGTestRepeatFlag);
326 351
352 #if defined(BROWSER_TESTS_USE_CHROME)
327 // Strip out user-data-dir if present. We will add it back in again later. 353 // Strip out user-data-dir if present. We will add it back in again later.
328 switches.erase(switches::kUserDataDir); 354 switches.erase(switches::kUserDataDir);
355 #endif // defined(BROWSER_TESTS_USE_CHROME)
329 356
330 for (CommandLine::SwitchMap::const_iterator iter = switches.begin(); 357 for (CommandLine::SwitchMap::const_iterator iter = switches.begin();
331 iter != switches.end(); ++iter) { 358 iter != switches.end(); ++iter) {
332 new_cmd_line.AppendSwitchNative((*iter).first, (*iter).second); 359 new_cmd_line.AppendSwitchNative((*iter).first, (*iter).second);
333 } 360 }
334 361
335 // Always enable disabled tests. This method is not called with disabled 362 // Always enable disabled tests. This method is not called with disabled
336 // tests unless this flag was specified to the browser test executable. 363 // tests unless this flag was specified to the browser test executable.
337 new_cmd_line.AppendSwitch("gtest_also_run_disabled_tests"); 364 new_cmd_line.AppendSwitch("gtest_also_run_disabled_tests");
338 new_cmd_line.AppendSwitchASCII("gtest_filter", test_name); 365 new_cmd_line.AppendSwitchASCII("gtest_filter", test_name);
339 new_cmd_line.AppendSwitch(kChildProcessFlag); 366 new_cmd_line.AppendSwitch(kChildProcessFlag);
340 367
341 // Do not let the child ignore failures. We need to propagate the 368 // Do not let the child ignore failures. We need to propagate the
342 // failure status back to the parent. 369 // failure status back to the parent.
343 new_cmd_line.AppendSwitch(base::TestSuite::kStrictFailureHandling); 370 new_cmd_line.AppendSwitch(base::TestSuite::kStrictFailureHandling);
344 371
372 #if defined(BROWSER_TESTS_USE_CHROME)
345 // Create a new user data dir and pass it to the child. 373 // Create a new user data dir and pass it to the child.
346 ScopedTempDir temp_dir; 374 ScopedTempDir temp_dir;
347 if (!temp_dir.CreateUniqueTempDir() || !temp_dir.IsValid()) { 375 if (!temp_dir.CreateUniqueTempDir() || !temp_dir.IsValid()) {
348 LOG(ERROR) << "Error creating temp profile directory"; 376 LOG(ERROR) << "Error creating temp profile directory";
349 return false; 377 return false;
350 } 378 }
351 new_cmd_line.AppendSwitchPath(switches::kUserDataDir, temp_dir.path()); 379 new_cmd_line.AppendSwitchPath(switches::kUserDataDir, temp_dir.path());
352 380
353 // file:// access for ChromeOS. 381 // file:// access for ChromeOS.
354 new_cmd_line.AppendSwitch(switches::kAllowFileAccess); 382 new_cmd_line.AppendSwitch(switches::kAllowFileAccess);
383 #endif // defined(BROWSER_TESTS_USE_CHROME)
355 384
356 const char* browser_wrapper = getenv("BROWSER_WRAPPER"); 385 const char* browser_wrapper = getenv("BROWSER_WRAPPER");
357 if (browser_wrapper) { 386 if (browser_wrapper) {
358 #if defined(OS_WIN) 387 #if defined(OS_WIN)
359 new_cmd_line.PrependWrapper(ASCIIToWide(browser_wrapper)); 388 new_cmd_line.PrependWrapper(ASCIIToWide(browser_wrapper));
360 #elif defined(OS_POSIX) 389 #elif defined(OS_POSIX)
361 new_cmd_line.PrependWrapper(browser_wrapper); 390 new_cmd_line.PrependWrapper(browser_wrapper);
362 #endif 391 #endif
363 VLOG(1) << "BROWSER_WRAPPER was set, prefixing command_line with " 392 VLOG(1) << "BROWSER_WRAPPER was set, prefixing command_line with "
364 << browser_wrapper; 393 << browser_wrapper;
365 } 394 }
366 395
367 base::ProcessHandle process_handle; 396 base::ProcessHandle process_handle;
368 base::LaunchOptions options; 397 base::LaunchOptions options;
369 398
370 #if defined(OS_POSIX) 399 #if defined(OS_POSIX)
371 // On POSIX, we launch the test in a new process group with pgid equal to 400 // On POSIX, we launch the test in a new process group with pgid equal to
372 // its pid. Any child processes that the test may create will inherit the 401 // its pid. Any child processes that the test may create will inherit the
373 // same pgid. This way, if the test is abruptly terminated, we can clean up 402 // same pgid. This way, if the test is abruptly terminated, we can clean up
374 // any orphaned child processes it may have left behind. 403 // any orphaned child processes it may have left behind.
375 options.new_process_group = true; 404 options.new_process_group = true;
376 #endif 405 #endif
377 406
378 if (!base::LaunchProcess(new_cmd_line, options, &process_handle)) 407 if (!base::LaunchProcess(new_cmd_line, options, &process_handle))
379 return false; 408 return false;
380 409
381 int timeout_ms = 410 int timeout_ms = GetTestTerminationTimeout(test_name,
382 test_launcher_utils::GetTestTerminationTimeout(test_name, 411 default_timeout_ms);
383 default_timeout_ms);
384 412
385 int exit_code = 0; 413 int exit_code = 0;
386 if (!base::WaitForExitCodeWithTimeout(process_handle, &exit_code, 414 if (!base::WaitForExitCodeWithTimeout(process_handle, &exit_code,
387 timeout_ms)) { 415 timeout_ms)) {
388 LOG(ERROR) << "Test timeout (" << timeout_ms 416 LOG(ERROR) << "Test timeout (" << timeout_ms
389 << " ms) exceeded for " << test_name; 417 << " ms) exceeded for " << test_name;
390 418
391 exit_code = -1; // Set a non-zero exit code to signal a failure. 419 exit_code = -1; // Set a non-zero exit code to signal a failure.
392 420
393 // Ensure that the process terminates. 421 // Ensure that the process terminates.
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 if (broker_services) { 597 if (broker_services) {
570 sandbox::InitBrokerServices(broker_services); 598 sandbox::InitBrokerServices(broker_services);
571 // Precreate the desktop and window station used by the renderers. 599 // Precreate the desktop and window station used by the renderers.
572 sandbox::TargetPolicy* policy = broker_services->CreatePolicy(); 600 sandbox::TargetPolicy* policy = broker_services->CreatePolicy();
573 sandbox::ResultCode result = policy->CreateAlternateDesktop(true); 601 sandbox::ResultCode result = policy->CreateAlternateDesktop(true);
574 CHECK(sandbox::SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION != result); 602 CHECK(sandbox::SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION != result);
575 policy->Release(); 603 policy->Release();
576 } 604 }
577 } 605 }
578 #endif 606 #endif
579 return ChromeTestSuite(argc, argv).Run(); 607 return BrowserTestSuite(argc, argv).Run();
580 } 608 }
581 609
582 #if defined(OS_WIN) 610 #if defined(OS_WIN) && defined(BROWSER_TESTS_USE_CHROME)
583 if (command_line->HasSwitch(switches::kProcessType)) { 611 if (command_line->HasSwitch(switches::kProcessType)) {
584 // This is a child process, call ChromeMain. 612 // This is a child process, call ChromeMain.
585 FilePath chrome_path(command_line->GetProgram().DirName()); 613 FilePath chrome_path(command_line->GetProgram().DirName());
586 chrome_path = chrome_path.Append(chrome::kBrowserResourcesDll); 614 chrome_path = chrome_path.Append(chrome::kBrowserResourcesDll);
587 HMODULE dll = LoadLibrary(chrome_path.value().c_str()); 615 HMODULE dll = LoadLibrary(chrome_path.value().c_str());
588 DLL_MAIN entry_point = 616 DLL_MAIN entry_point =
589 reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll, "ChromeMain")); 617 reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll, "ChromeMain"));
590 if (!entry_point) 618 if (!entry_point)
591 return -1; 619 return -1;
592 620
593 // Initialize the sandbox services. 621 // Initialize the sandbox services.
594 sandbox::SandboxInterfaceInfo sandbox_info = {0}; 622 sandbox::SandboxInterfaceInfo sandbox_info = {0};
595 sandbox_info.target_services = sandbox::SandboxFactory::GetTargetServices(); 623 sandbox_info.target_services = sandbox::SandboxFactory::GetTargetServices();
596 return entry_point(GetModuleHandle(NULL), &sandbox_info, GetCommandLineW()); 624 return entry_point(GetModuleHandle(NULL), &sandbox_info, GetCommandLineW());
597 } 625 }
598 #endif 626 #endif // defined(OS_WIN) && defined(BROWSER_TESTS_USE_CHROME)
599 627
600 int32 total_shards; 628 int32 total_shards;
601 int32 shard_index; 629 int32 shard_index;
602 bool should_shard = ShouldShard(&total_shards, &shard_index); 630 bool should_shard = ShouldShard(&total_shards, &shard_index);
603 631
604 fprintf(stdout, 632 fprintf(stdout,
605 "Starting tests...\n" 633 "Starting tests...\n"
606 "IMPORTANT DEBUGGING NOTE: each test is run inside its own process.\n" 634 "IMPORTANT DEBUGGING NOTE: each test is run inside its own process.\n"
607 "For debugging a test inside a debugger, use the\n" 635 "For debugging a test inside a debugger, use the\n"
608 "--gtest_filter=<your_test_name> flag along with either\n" 636 "--gtest_filter=<your_test_name> flag along with either\n"
(...skipping 22 matching lines...) Expand all
631 exit_code = 1; 659 exit_code = 1;
632 break; 660 break;
633 } 661 }
634 662
635 // Special value "-1" means "repeat indefinitely". 663 // Special value "-1" means "repeat indefinitely".
636 if (cycles != -1) 664 if (cycles != -1)
637 cycles--; 665 cycles--;
638 } 666 }
639 return exit_code; 667 return exit_code;
640 } 668 }
OLDNEW
« no previous file with comments | « content/content_tests.gypi ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698