OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |