| 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 "chrome/test/out_of_proc_test_runner.h" |
| 6 |
| 5 #include <string> | 7 #include <string> |
| 6 #include <vector> | 8 #include <vector> |
| 7 | 9 |
| 8 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 9 #include "base/environment.h" | 11 #include "base/environment.h" |
| 10 #include "base/file_util.h" | 12 #include "base/file_util.h" |
| 11 #include "base/hash_tables.h" | 13 #include "base/hash_tables.h" |
| 12 #include "base/logging.h" | 14 #include "base/logging.h" |
| 13 #include "base/mac/scoped_nsautorelease_pool.h" | 15 #include "base/mac/scoped_nsautorelease_pool.h" |
| 14 #include "base/memory/linked_ptr.h" | 16 #include "base/memory/linked_ptr.h" |
| (...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 " Specifies a timeout (in milliseconds) after which a running test\n" | 533 " Specifies a timeout (in milliseconds) after which a running test\n" |
| 532 " will be forcefully terminated.\n" | 534 " will be forcefully terminated.\n" |
| 533 " --help\n" | 535 " --help\n" |
| 534 " Shows this message.\n" | 536 " Shows this message.\n" |
| 535 " --gtest_help\n" | 537 " --gtest_help\n" |
| 536 " Shows the gtest help message.\n"); | 538 " Shows the gtest help message.\n"); |
| 537 } | 539 } |
| 538 | 540 |
| 539 } // namespace | 541 } // namespace |
| 540 | 542 |
| 543 namespace test { |
| 544 |
| 545 // Note that we cannot use the Singleton or LazyInstance here because the |
| 546 // registration happens at linker-initialization, and we cannot rely on |
| 547 // AtExitManager being available yet. The life cycle of |
| 548 // |s_test_callback_registry| is from linker init through main (below) calling |
| 549 // CallTestCallbacksAndClear. |
| 550 typedef std::vector<RegisterTestCallback*> CallbackRegistry; |
| 551 CallbackRegistry* s_callback_registry = NULL; |
| 552 |
| 553 RegisterTestCallback::RegisterTestCallback() {} |
| 554 |
| 555 RegisterTestCallback::~RegisterTestCallback() {} |
| 556 |
| 557 void AddRegisterTestCallback(RegisterTestCallback* callback) { |
| 558 if (!s_callback_registry) |
| 559 s_callback_registry = new CallbackRegistry(); |
| 560 |
| 561 s_callback_registry->push_back(callback); |
| 562 } |
| 563 |
| 564 void CallRegisterTestCallbacksAndClear() { |
| 565 // |s_callback_registry| will only be non-NULL if tests are registered. |
| 566 if (!s_callback_registry) |
| 567 return; |
| 568 |
| 569 for (CallbackRegistry::const_iterator it = s_callback_registry->begin(); |
| 570 it != s_callback_registry->end(); ++it) { |
| 571 (*it)->RegisterTest(); |
| 572 delete *it; |
| 573 } |
| 574 s_callback_registry->clear(); |
| 575 delete s_callback_registry; |
| 576 s_callback_registry = NULL; |
| 577 } |
| 578 |
| 579 } // namespace test |
| 580 |
| 541 int main(int argc, char** argv) { | 581 int main(int argc, char** argv) { |
| 542 #if defined(OS_MACOSX) | 582 #if defined(OS_MACOSX) |
| 543 chrome_browser_application_mac::RegisterBrowserCrApp(); | 583 chrome_browser_application_mac::RegisterBrowserCrApp(); |
| 544 #endif | 584 #endif |
| 545 | 585 |
| 546 CommandLine::Init(argc, argv); | 586 CommandLine::Init(argc, argv); |
| 547 const CommandLine* command_line = CommandLine::ForCurrentProcess(); | 587 const CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 548 | 588 |
| 549 if (command_line->HasSwitch(kHelpFlag)) { | 589 if (command_line->HasSwitch(kHelpFlag)) { |
| 550 PrintUsage(); | 590 PrintUsage(); |
| 551 return 0; | 591 return 0; |
| 552 } | 592 } |
| 553 | 593 |
| 594 // The exit manager is in charge of calling the dtors of singleton objects. |
| 595 // On Windows, the call to ChromeMain() below will construct one for the |
| 596 // chrome.dll module, but that global is not shared with this module, so if |
| 597 // chrome.dll calls back out to this module and the called code uses a |
| 598 // singleton, we'll need this. On other platforms, ChromeMain() isn't called |
| 599 // at all below, so we instantiate a TestSuite which contains an exit manager |
| 600 // for any code after this point. Any callbacks for test registry are called |
| 601 // afterwards in case they also need an exit manager. |
| 602 ChromeTestSuite test_suite(argc, argv); |
| 603 test::CallRegisterTestCallbacksAndClear(); |
| 604 |
| 554 // TODO(pkasting): This "single_process vs. single-process" design is terrible | 605 // TODO(pkasting): This "single_process vs. single-process" design is terrible |
| 555 // UI. Instead, there should be some sort of signal flag on the command line, | 606 // UI. Instead, there should be some sort of signal flag on the command line, |
| 556 // with all subsequent arguments passed through to the underlying browser. | 607 // with all subsequent arguments passed through to the underlying browser. |
| 557 if (command_line->HasSwitch(kChildProcessFlag) || | 608 if (command_line->HasSwitch(kChildProcessFlag) || |
| 558 command_line->HasSwitch(kSingleProcessTestsFlag) || | 609 command_line->HasSwitch(kSingleProcessTestsFlag) || |
| 559 command_line->HasSwitch(kSingleProcessTestsAndChromeFlag) || | 610 command_line->HasSwitch(kSingleProcessTestsAndChromeFlag) || |
| 560 command_line->HasSwitch(kGTestListTestsFlag) || | 611 command_line->HasSwitch(kGTestListTestsFlag) || |
| 561 command_line->HasSwitch(kGTestHelpFlag)) { | 612 command_line->HasSwitch(kGTestHelpFlag)) { |
| 562 | 613 |
| 563 #if defined(OS_WIN) | 614 #if defined(OS_WIN) |
| 564 if (command_line->HasSwitch(kChildProcessFlag) || | 615 if (command_line->HasSwitch(kChildProcessFlag) || |
| 565 command_line->HasSwitch(kSingleProcessTestsFlag)) { | 616 command_line->HasSwitch(kSingleProcessTestsFlag)) { |
| 566 // This is the browser process, so setup the sandbox broker. | 617 // This is the browser process, so setup the sandbox broker. |
| 567 sandbox::BrokerServices* broker_services = | 618 sandbox::BrokerServices* broker_services = |
| 568 sandbox::SandboxFactory::GetBrokerServices(); | 619 sandbox::SandboxFactory::GetBrokerServices(); |
| 569 if (broker_services) { | 620 if (broker_services) { |
| 570 sandbox::InitBrokerServices(broker_services); | 621 sandbox::InitBrokerServices(broker_services); |
| 571 // Precreate the desktop and window station used by the renderers. | 622 // Precreate the desktop and window station used by the renderers. |
| 572 sandbox::TargetPolicy* policy = broker_services->CreatePolicy(); | 623 sandbox::TargetPolicy* policy = broker_services->CreatePolicy(); |
| 573 sandbox::ResultCode result = policy->CreateAlternateDesktop(true); | 624 sandbox::ResultCode result = policy->CreateAlternateDesktop(true); |
| 574 CHECK(sandbox::SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION != result); | 625 CHECK(sandbox::SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION != result); |
| 575 policy->Release(); | 626 policy->Release(); |
| 576 } | 627 } |
| 577 } | 628 } |
| 578 #endif | 629 #endif |
| 579 return ChromeTestSuite(argc, argv).Run(); | 630 return test_suite.Run(); |
| 580 } | 631 } |
| 581 | 632 |
| 582 // The exit manager is in charge of calling the dtors of singleton objects. | |
| 583 // On Windows, the call to ChromeMain() below will construct one for the | |
| 584 // chrome.dll module, but that global is not shared with this module, so if | |
| 585 // chrome.dll calls back out to this module and the called code uses a | |
| 586 // singleton, we'll need this. On other platforms, ChromeMain() isn't called | |
| 587 // at all below, so this is the lone exit manager for any code after this | |
| 588 // point. | |
| 589 // NOTE: We can't init this atop main() because ChromeTestSuite, as a subclass | |
| 590 // of TestSuite, creates one. So we wait until after the Run() call above to | |
| 591 // create the manager for the code path that _doesn't_ use ChromeTestSuite. | |
| 592 base::AtExitManager exit_manager; | |
| 593 | |
| 594 #if defined(OS_WIN) | 633 #if defined(OS_WIN) |
| 595 if (command_line->HasSwitch(switches::kProcessType)) { | 634 if (command_line->HasSwitch(switches::kProcessType)) { |
| 596 // This is a child process, call ChromeMain. | 635 // This is a child process, call ChromeMain. |
| 597 FilePath chrome_path(command_line->GetProgram().DirName()); | 636 FilePath chrome_path(command_line->GetProgram().DirName()); |
| 598 chrome_path = chrome_path.Append(chrome::kBrowserResourcesDll); | 637 chrome_path = chrome_path.Append(chrome::kBrowserResourcesDll); |
| 599 HMODULE dll = LoadLibrary(chrome_path.value().c_str()); | 638 HMODULE dll = LoadLibrary(chrome_path.value().c_str()); |
| 600 DLL_MAIN entry_point = | 639 DLL_MAIN entry_point = |
| 601 reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll, "ChromeMain")); | 640 reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll, "ChromeMain")); |
| 602 if (!entry_point) | 641 if (!entry_point) |
| 603 return -1; | 642 return -1; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 exit_code = 1; | 681 exit_code = 1; |
| 643 break; | 682 break; |
| 644 } | 683 } |
| 645 | 684 |
| 646 // Special value "-1" means "repeat indefinitely". | 685 // Special value "-1" means "repeat indefinitely". |
| 647 if (cycles != -1) | 686 if (cycles != -1) |
| 648 cycles--; | 687 cycles--; |
| 649 } | 688 } |
| 650 return exit_code; | 689 return exit_code; |
| 651 } | 690 } |
| OLD | NEW |