diff options
-rw-r--r-- | build/all.gyp | 6 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 54 | ||||
-rw-r--r-- | chrome/test/base/chrome_test_launcher.cc | 132 | ||||
-rw-r--r-- | chrome/test/base/in_process_browser_test.cc | 24 | ||||
-rw-r--r-- | chrome/test/base/in_process_browser_test.h | 106 | ||||
-rw-r--r-- | chrome/test/base/test_launcher_utils.cc | 25 | ||||
-rw-r--r-- | chrome/test/base/test_launcher_utils.h | 6 | ||||
-rw-r--r-- | content/content_tests.gypi | 47 | ||||
-rw-r--r-- | content/test/browser_test.h | 83 | ||||
-rw-r--r-- | content/test/browser_test_base.cc | 47 | ||||
-rw-r--r-- | content/test/browser_test_base.h | 54 | ||||
-rw-r--r-- | content/test/content_browser_test.cc | 72 | ||||
-rw-r--r-- | content/test/content_browser_test.h | 35 | ||||
-rw-r--r-- | content/test/content_test_launcher.cc | 54 | ||||
-rw-r--r-- | content/test/test_launcher.cc (renamed from chrome/test/base/out_of_proc_test_runner.cc) | 180 | ||||
-rw-r--r-- | content/test/test_launcher.h | 44 |
16 files changed, 700 insertions, 269 deletions
diff --git a/build/all.gyp b/build/all.gyp index 6572e65..6e4ef8c 100644 --- a/build/all.gyp +++ b/build/all.gyp @@ -161,6 +161,7 @@ '../chrome/chrome.gyp:sync_unit_tests', '../chrome/chrome.gyp:ui_tests', '../chrome/chrome.gyp:unit_tests', + '../content/content.gyp:content_browsertests', '../content/content.gyp:content_unittests', '../crypto/crypto.gyp:crypto_unittests', '../ui/ui.gyp:gfx_unittests', @@ -219,6 +220,7 @@ '../chrome/chrome.gyp:sync_unit_tests', '../chrome/chrome.gyp:ui_tests', '../chrome/chrome.gyp:unit_tests', + '../content/content.gyp:content_browsertests', '../content/content.gyp:content_unittests', '../crypto/crypto.gyp:crypto_unittests', '../ui/ui.gyp:gfx_unittests', @@ -333,6 +335,7 @@ '../chrome/chrome.gyp:sync_unit_tests', '../chrome/chrome.gyp:ui_tests', '../chrome/chrome.gyp:unit_tests', + '../content/content.gyp:content_browsertests', '../content/content.gyp:content_unittests', '../ui/ui.gyp:gfx_unittests', '../gpu/gpu.gyp:gpu_unittests', @@ -359,6 +362,7 @@ '../chrome/chrome.gyp:sync_unit_tests', '../chrome/chrome.gyp:ui_tests', '../chrome/chrome.gyp:unit_tests', + '../content/content.gyp:content_browsertests', '../content/content.gyp:content_unittests', '../ui/ui.gyp:gfx_unittests', '../gpu/gpu.gyp:gpu_unittests', @@ -435,6 +439,7 @@ '../chrome/chrome.gyp:sync_unit_tests', '../chrome/chrome.gyp:ui_tests', '../chrome/chrome.gyp:unit_tests', + '../content/content.gyp:content_browsertests', '../content/content.gyp:content_unittests', # mini_installer_tests depends on mini_installer. This should be # defined in installer.gyp. @@ -572,6 +577,7 @@ '../chrome/chrome.gyp:sync_integration_tests', '../chrome/chrome.gyp:ui_tests', '../chrome/chrome.gyp:unit_tests', + '../content/content.gyp:content_browsertests', '../content/content.gyp:content_unittests', '../crypto/crypto.gyp:crypto_unittests', '../dbus/dbus.gyp:dbus_unittests', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index accdde8..691e8c6 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -484,7 +484,10 @@ 'include_dirs': [ '..', ], - 'defines': [ 'HAS_OUT_OF_PROC_TEST_RUNNER' ], + 'defines': [ + 'HAS_OUT_OF_PROC_TEST_RUNNER', + 'BROWSER_TESTS_HEADER_OVERRIDE="chrome/test/base/in_process_browser_test.h"', + ], 'sources': [ 'browser/accessibility/accessibility_mac_uitest.mm', 'browser/autofill/autofill_browsertest.cc', @@ -508,9 +511,11 @@ 'browser/ui/views/ssl_client_certificate_selector_browsertest.cc', 'browser/ui/views/tabs/tab_dragging_test.cc', 'browser/ui/webui/workers_ui_browsertest.cc', - 'test/base/out_of_proc_test_runner.cc', + 'test/base/chrome_test_launcher.cc', 'test/base/view_event_test_base.cc', 'test/base/view_event_test_base.h', + '../content/test/test_launcher.cc', + '../content/test/test_launcher.h', ], 'conditions': [ ['toolkit_uses_gtk == 1', { @@ -2192,7 +2197,10 @@ 'include_dirs': [ '..', ], - 'defines': [ 'HAS_OUT_OF_PROC_TEST_RUNNER' ], + 'defines': [ + 'HAS_OUT_OF_PROC_TEST_RUNNER', + 'BROWSER_TESTS_HEADER_OVERRIDE="chrome/test/base/in_process_browser_test.h"', + ], 'sources': [ 'app/breakpad_mac_stubs.mm', 'app/chrome_command_ids.h', @@ -2455,7 +2463,7 @@ 'test/base/in_process_browser_test_browsertest.cc', 'test/base/render_view_test.cc', 'test/base/render_view_test.h', - 'test/base/out_of_proc_test_runner.cc', + 'test/base/chrome_test_launcher.cc', 'test/data/webui/assertions.js', 'test/data/webui/async_gen-inl.h', 'test/data/webui/async_gen.js', @@ -2485,6 +2493,8 @@ '../content/renderer/render_widget_browsertest.cc', '../content/renderer/render_widget_browsertest.h', '../content/renderer/v8_value_converter_browsertest.cc', + '../content/test/test_launcher.cc', + '../content/test/test_launcher.h', ], 'conditions': [ ['chromeos==0', { @@ -2725,11 +2735,16 @@ 'include_dirs': [ '..', ], - 'defines': [ 'HAS_OUT_OF_PROC_TEST_RUNNER' ], + 'defines': [ + 'HAS_OUT_OF_PROC_TEST_RUNNER', + 'BROWSER_TESTS_HEADER_OVERRIDE="chrome/test/base/in_process_browser_test.h"', + ], 'sources': [ 'app/chrome_dll.rc', 'browser/safe_browsing/safe_browsing_test.cc', - 'test/base/out_of_proc_test_runner.cc', + 'test/base/chrome_test_launcher.cc', + '../content/test/test_launcher.cc', + '../content/test/test_launcher.h', ], 'conditions': [ ['safe_browsing==0', { @@ -3113,7 +3128,10 @@ '<(protoc_out_dir)', ], # TODO(phajdan.jr): Only temporary, to make transition easier. - 'defines': [ 'HAS_OUT_OF_PROC_TEST_RUNNER' ], + 'defines': [ + 'HAS_OUT_OF_PROC_TEST_RUNNER', + 'BROWSER_TESTS_HEADER_OVERRIDE="chrome/test/base/in_process_browser_test.h"', + ], 'sources': [ 'app/chrome_command_ids.h', 'app/chrome_dll.rc', @@ -3122,7 +3140,7 @@ 'browser/password_manager/password_form_data.cc', 'browser/sessions/session_backend.cc', 'browser/sync/glue/session_model_associator.cc', - 'test/base/out_of_proc_test_runner.cc', + 'test/base/chrome_test_launcher.cc', 'test/data/resource.rc', 'browser/sync/test/integration/apps_helper.cc', 'browser/sync/test/integration/apps_helper.h', @@ -3179,6 +3197,8 @@ 'browser/sync/test/integration/two_client_typed_urls_sync_test.cc', 'browser/sync/test/integration/typed_urls_helper.cc', 'browser/sync/test/integration/typed_urls_helper.h', + '../content/test/test_launcher.cc', + '../content/test/test_launcher.h', ], 'conditions': [ ['toolkit_uses_gtk == 1', { @@ -3261,7 +3281,10 @@ '<(INTERMEDIATE_DIR)', '<(protoc_out_dir)', ], - 'defines': [ 'HAS_OUT_OF_PROC_TEST_RUNNER' ], + 'defines': [ + 'HAS_OUT_OF_PROC_TEST_RUNNER', + 'BROWSER_TESTS_HEADER_OVERRIDE="chrome/test/base/in_process_browser_test.h"', + ], 'sources': [ 'app/chrome_command_ids.h', 'app/chrome_dll.rc', @@ -3296,8 +3319,10 @@ 'browser/sync/test/integration/sync_test.h', 'browser/sync/test/integration/typed_urls_helper.cc', 'browser/sync/test/integration/typed_urls_helper.h', - 'test/base/out_of_proc_test_runner.cc', + 'test/base/chrome_test_launcher.cc', 'test/data/resource.rc', + '../content/test/test_launcher.cc', + '../content/test/test_launcher.h', ], 'conditions': [ ['toolkit_uses_gtk == 1', { @@ -3393,12 +3418,17 @@ '..', '<(test_list_out_dir)', ], - 'defines': [ 'HAS_OUT_OF_PROC_TEST_RUNNER' ], + 'defines': [ + 'HAS_OUT_OF_PROC_TEST_RUNNER', + 'BROWSER_TESTS_HEADER_OVERRIDE="chrome/test/base/in_process_browser_test.h"', + ], 'sources': [ 'browser/gpu_pixel_browsertest.cc', 'browser/gpu_crash_browsertest.cc', - 'test/base/out_of_proc_test_runner.cc', + 'test/base/chrome_test_launcher.cc', 'test/gpu/webgl_conformance_tests.cc', + '../content/test/test_launcher.cc', + '../content/test/test_launcher.h', '<(test_list_out_dir)/webgl_conformance_test_list_autogen.h', ], # hard_dependency is necessary for this target because it has actions diff --git a/chrome/test/base/chrome_test_launcher.cc b/chrome/test/base/chrome_test_launcher.cc new file mode 100644 index 0000000..57eb5b1 --- /dev/null +++ b/chrome/test/base/chrome_test_launcher.cc @@ -0,0 +1,132 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/test/test_launcher.h" + +#include "base/command_line.h" +#include "base/logging.h" +#include "base/scoped_temp_dir.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/test/base/chrome_test_suite.h" + +#if defined(OS_MACOSX) +#include "chrome/browser/chrome_browser_application_mac.h" +#endif // defined(OS_MACOSX) + +#if defined(OS_WIN) +#include "base/base_switches.h" +#include "content/common/sandbox_policy.h" +#include "sandbox/src/dep.h" +#include "sandbox/src/sandbox_factory.h" +#include "sandbox/src/sandbox_types.h" + +// The entry point signature of chrome.dll. +typedef int (*DLL_MAIN)(HINSTANCE, sandbox::SandboxInterfaceInfo*, wchar_t*); +#endif // defined(OS_WIN) + +class ChromeTestLauncherDelegate : public test_launcher::TestLauncherDelegate { + public: + ChromeTestLauncherDelegate() { + } + + virtual ~ChromeTestLauncherDelegate() { + } + + virtual void EarlyInitialize() OVERRIDE { +#if defined(OS_MACOSX) + chrome_browser_application_mac::RegisterBrowserCrApp(); +#endif + } + + virtual bool Run(int argc, char** argv, int* return_code) OVERRIDE { + CommandLine* command_line = CommandLine::ForCurrentProcess(); + + // TODO(pkasting): This "single_process vs. single-process" design is + // terrible UI. Instead, there should be some sort of signal flag on the + // command line, with all subsequent arguments passed through to the + // underlying browser. + if (command_line->HasSwitch(test_launcher::kSingleProcessTestsFlag) || + command_line->HasSwitch( + test_launcher::kSingleProcessTestsAndChromeFlag) || + command_line->HasSwitch(test_launcher::kGTestListTestsFlag) || + command_line->HasSwitch(test_launcher::kGTestHelpFlag)) { +#if defined(OS_WIN) + if (command_line->HasSwitch(test_launcher::kSingleProcessTestsFlag)) { + // This is the browser process, so setup the sandbox broker. + sandbox::BrokerServices* broker_services = + sandbox::SandboxFactory::GetBrokerServices(); + if (broker_services) { + sandbox::InitBrokerServices(broker_services); + // Precreate the desktop and window station used by the renderers. + sandbox::TargetPolicy* policy = broker_services->CreatePolicy(); + sandbox::ResultCode result = policy->CreateAlternateDesktop(true); + CHECK(sandbox::SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION != result); + policy->Release(); + } + } +#endif + *return_code = ChromeTestSuite(argc, argv).Run(); + return true; + } + +#if defined(OS_WIN) + if (command_line->HasSwitch(switches::kProcessType)) { + // This is a child process, call ChromeMain. + FilePath chrome_path(command_line->GetProgram().DirName()); + chrome_path = chrome_path.Append(chrome::kBrowserResourcesDll); + HMODULE dll = LoadLibrary(chrome_path.value().c_str()); + DLL_MAIN entry_point = + reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll, "ChromeMain")); + if (!entry_point) + return false; + + // Initialize the sandbox services. + sandbox::SandboxInterfaceInfo sandbox_info = {0}; + sandbox_info.target_services = + sandbox::SandboxFactory::GetTargetServices(); + *return_code = + entry_point(GetModuleHandle(NULL), &sandbox_info, GetCommandLineW()); + return true; + } +#endif // defined(OS_WIN) + return false; + } + + virtual bool AdjustChildProcessCommandLine( + CommandLine* command_line) OVERRIDE { + CommandLine new_command_line(command_line->GetProgram()); + CommandLine::SwitchMap switches = command_line->GetSwitches(); + + // Strip out user-data-dir if present. We will add it back in again later. + switches.erase(switches::kUserDataDir); + + for (CommandLine::SwitchMap::const_iterator iter = switches.begin(); + iter != switches.end(); ++iter) { + new_command_line.AppendSwitchNative((*iter).first, (*iter).second); + } + + // Create a new user data dir and pass it to the child. + ScopedTempDir temp_dir; + if (!temp_dir.CreateUniqueTempDir() || !temp_dir.IsValid()) { + LOG(ERROR) << "Error creating temp profile directory"; + return false; + } + new_command_line.AppendSwitchPath(switches::kUserDataDir, temp_dir.path()); + + // file:// access for ChromeOS. + new_command_line.AppendSwitch(switches::kAllowFileAccess); + + *command_line = new_command_line; + return true; + } + + private: + DISALLOW_COPY_AND_ASSIGN(ChromeTestLauncherDelegate); +}; + +int main(int argc, char** argv) { + ChromeTestLauncherDelegate launcher_delegate; + return test_launcher::LaunchTests(&launcher_delegate, argc, argv); +} diff --git a/chrome/test/base/in_process_browser_test.cc b/chrome/test/base/in_process_browser_test.cc index 43b105c..6d19499 100644 --- a/chrome/test/base/in_process_browser_test.cc +++ b/chrome/test/base/in_process_browser_test.cc @@ -33,23 +33,14 @@ #include "content/browser/renderer_host/render_process_host.h" #include "content/browser/tab_contents/tab_contents.h" #include "content/common/content_notification_types.h" -#include "content/common/main_function_params.h" #include "content/renderer/mock_content_renderer_client.h" #include "net/base/mock_host_resolver.h" #include "net/test/test_server.h" -#include "sandbox/src/dep.h" - -#if defined(OS_MACOSX) -#include "base/mac/mac_util.h" -#include "base/system_monitor/system_monitor.h" -#endif #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/audio_handler.h" #endif -extern int BrowserMain(const MainFunctionParams&); - // Passed as value of kTestType. static const char kBrowserTestType[] = "browser"; @@ -58,11 +49,6 @@ InProcessBrowserTest::InProcessBrowserTest() show_window_(false), dom_automation_enabled_(false), tab_closeable_state_watcher_enabled_(false) { -#if defined(OS_MACOSX) - base::mac::SetOverrideAmIBundled(true); - base::SystemMonitor::AllocateSystemIOPorts(); -#endif - // Before we run the browser, we have to hack the path to the exe to match // what it would be if Chrome was running, because it is used to fork renderer // processes, on Linux at least (failure to do so will cause a browser_test to @@ -132,14 +118,7 @@ void InProcessBrowserTest::SetUp() { net::ScopedDefaultHostResolverProc scoped_host_resolver_proc( host_resolver_.get()); - SandboxInitWrapper sandbox_wrapper; - MainFunctionParams params(*command_line, sandbox_wrapper, NULL); - params.ui_task = - NewRunnableMethod(this, &InProcessBrowserTest::RunTestOnMainThreadLoop); - - SetUpInProcessBrowserTestFixture(); - BrowserMain(params); - TearDownInProcessBrowserTestFixture(); + BrowserTestBase::SetUp(); } void InProcessBrowserTest::PrepareTestCommandLine(CommandLine* command_line) { @@ -199,6 +178,7 @@ bool InProcessBrowserTest::CreateUserDataDirectory() { void InProcessBrowserTest::TearDown() { DCHECK(!g_browser_process); + BrowserTestBase::TearDown(); } void InProcessBrowserTest::AddTabAtIndexToBrowser( diff --git a/chrome/test/base/in_process_browser_test.h b/chrome/test/base/in_process_browser_test.h index 3623d8d..af8860d 100644 --- a/chrome/test/base/in_process_browser_test.h +++ b/chrome/test/base/in_process_browser_test.h @@ -11,6 +11,8 @@ #include "base/memory/scoped_ptr.h" #include "base/scoped_temp_dir.h" #include "content/common/page_transition_types.h" +#include "content/test/browser_test.h" +#include "content/test/browser_test_base.h" #include "net/test/test_server.h" #include "testing/gtest/include/gtest/gtest.h" @@ -70,22 +72,17 @@ class RuleBasedHostResolverProc; // InProcessBrowserTest disables the sandbox when running. // // See ui_test_utils for a handful of methods designed for use with this class. -class InProcessBrowserTest : public testing::Test { +class InProcessBrowserTest : public BrowserTestBase { public: InProcessBrowserTest(); virtual ~InProcessBrowserTest(); - // We do this so we can be used in a Task. - void AddRef() {} - void Release() {} - static bool ImplementsThreadSafeReferenceCounting() { return false; } - // Configures everything for an in process browser test, then invokes // BrowserMain. BrowserMain ends up invoking RunTestOnMainThreadLoop. - virtual void SetUp(); + virtual void SetUp() OVERRIDE; // Restores state configured in SetUp. - virtual void TearDown(); + virtual void TearDown() OVERRIDE; protected: // Returns the browser created by CreateBrowser. @@ -107,9 +104,6 @@ class InProcessBrowserTest : public testing::Test { // RunTestOnMainThread(). virtual void SetUpOnMainThread() {} - // Override this rather than TestBody. - virtual void RunTestOnMainThread() = 0; - // Initializes the contents of the user data directory. Called by SetUp() // after creating the user data directory, but before any browser is launched. // If a test wishes to set up some initial non-empty state in the user data @@ -117,19 +111,6 @@ class InProcessBrowserTest : public testing::Test { // successful. virtual bool SetUpUserDataDirectory() WARN_UNUSED_RESULT; - // We need these special methods because InProcessBrowserTest::SetUp is the - // bottom of the stack that winds up calling your test method, so it is not - // always an option to do what you want by overriding it and calling the - // superclass version. - // - // Override this for things you would normally override SetUp for. It will be - // called before your individual test fixture method is run, but after most - // of the overhead initialization has occured. - virtual void SetUpInProcessBrowserTestFixture() {} - - // Override this for things you would normally override TearDown for. - virtual void TearDownInProcessBrowserTestFixture() {} - // Override this to add command line flags specific to your test. virtual void SetUpCommandLine(CommandLine* command_line) {} @@ -137,6 +118,9 @@ class InProcessBrowserTest : public testing::Test { // main thread before the browser is torn down. virtual void CleanUpOnMainThread() {} + // BrowserTestBase: + virtual void RunTestOnMainThreadLoop() OVERRIDE; + // Returns the testing server. Guaranteed to be non-NULL. net::TestServer* test_server() { return test_server_.get(); } @@ -176,11 +160,6 @@ class InProcessBrowserTest : public testing::Test { // if successful. virtual bool CreateUserDataDirectory() WARN_UNUSED_RESULT; - // This is invoked from main after browser_init/browser_main have completed. - // This prepares for the test by creating a new browser, runs the test - // (RunTestOnMainThread), quits the browsers and returns. - void RunTestOnMainThreadLoop(); - // Quits all open browsers and waits until there are no more browsers. void QuitBrowsers(); @@ -218,75 +197,6 @@ class InProcessBrowserTest : public testing::Test { #if defined(OS_CHROMEOS) chromeos::ScopedStubCrosEnabler stub_cros_enabler_; #endif // defined(OS_CHROMEOS) - - DISALLOW_COPY_AND_ASSIGN(InProcessBrowserTest); }; -// We only want to use InProcessBrowserTest in test targets which properly -// isolate each test case by running each test in a separate process. -// This way if a test hangs the test launcher can reliably terminate it. -// -// InProcessBrowserTest cannot be run more than once in the same address space -// anyway - otherwise the second test crashes. -#if defined(HAS_OUT_OF_PROC_TEST_RUNNER) - -#define IN_PROC_BROWSER_TEST_(test_case_name, test_name, parent_class,\ - parent_id)\ -class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ - public:\ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ - protected:\ - virtual void RunTestOnMainThread();\ - private:\ - virtual void TestBody() {}\ - static ::testing::TestInfo* const test_info_;\ - GTEST_DISALLOW_COPY_AND_ASSIGN_(\ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ -};\ -\ -::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ - ::test_info_ =\ - ::testing::internal::MakeAndRegisterTestInfo(\ - #test_case_name, #test_name, "", "", \ - (parent_id), \ - parent_class::SetUpTestCase, \ - parent_class::TearDownTestCase, \ - new ::testing::internal::TestFactoryImpl<\ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ -void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::RunTestOnMainThread() - -#define IN_PROC_BROWSER_TEST_F(test_fixture, test_name)\ - IN_PROC_BROWSER_TEST_(test_fixture, test_name, test_fixture,\ - ::testing::internal::GetTypeId<test_fixture>()) - -#define IN_PROC_BROWSER_TEST_P(test_case_name, test_name) \ - class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ - : public test_case_name { \ - public: \ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ - protected: \ - virtual void RunTestOnMainThread(); \ - private: \ - virtual void TestBody() {} \ - static int AddToRegistry() { \ - ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ - GetTestCasePatternHolder<test_case_name>(\ - #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ - #test_case_name, \ - #test_name, \ - new ::testing::internal::TestMetaFactory< \ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ - return 0; \ - } \ - static int gtest_registering_dummy_; \ - GTEST_DISALLOW_COPY_AND_ASSIGN_(\ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ - }; \ - int GTEST_TEST_CLASS_NAME_(test_case_name, \ - test_name)::gtest_registering_dummy_ = \ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ - void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::RunTestOnMainThread() - -#endif // defined(HAS_OUT_OF_PROC_TEST_RUNNER) - #endif // CHROME_TEST_BASE_IN_PROCESS_BROWSER_TEST_H_ diff --git a/chrome/test/base/test_launcher_utils.cc b/chrome/test/base/test_launcher_utils.cc index 039f30c..4dfe1f7 100644 --- a/chrome/test/base/test_launcher_utils.cc +++ b/chrome/test/base/test_launcher_utils.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/test/base/test_launcher_utils.h" + #include "base/command_line.h" #include "base/environment.h" #include "base/logging.h" @@ -10,18 +12,8 @@ #include "base/string_number_conversions.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" -#include "chrome/test/base/test_launcher_utils.h" #include "ui/gfx/gl/gl_switches.h" -namespace { - -// A multiplier for slow tests. We generally avoid multiplying -// test timeouts by any constants. Here it is used as last resort -// to implement the SLOW_ test prefix. -static const int kSlowTestTimeoutMultiplier = 5; - -} // namespace - namespace test_launcher_utils { void PrepareBrowserCommandLineForTests(CommandLine* command_line) { @@ -94,17 +86,4 @@ bool OverrideGLImplementation(CommandLine* command_line, return true; } -int GetTestTerminationTimeout(const std::string& test_name, - int default_timeout_ms) { - int timeout_ms = default_timeout_ms; - - // Make it possible for selected tests to request a longer timeout. - // Generally tests should really avoid doing too much, and splitting - // a test instead of using SLOW prefix is strongly preferred. - if (test_name.find("SLOW_") != std::string::npos) - timeout_ms *= kSlowTestTimeoutMultiplier; - - return timeout_ms; -} - } // namespace test_launcher_utils diff --git a/chrome/test/base/test_launcher_utils.h b/chrome/test/base/test_launcher_utils.h index 3c1a219..95a69cf 100644 --- a/chrome/test/base/test_launcher_utils.h +++ b/chrome/test/base/test_launcher_utils.h @@ -29,12 +29,6 @@ bool OverrideGLImplementation( CommandLine* command_line, const std::string& implementation_name) WARN_UNUSED_RESULT; -// Returns test termination tiemout based on test name -// and a default timeout. Makes it possible to override -// the default timeout using command-line or test prefix. -int GetTestTerminationTimeout(const std::string& test_name, - int default_timeout_ms); - } // namespace test_launcher_utils #endif // CHROME_TEST_BASE_TEST_LAUNCHER_UTILS_H_ diff --git a/content/content_tests.gypi b/content/content_tests.gypi index 998c9078..052d6c0 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi @@ -52,6 +52,9 @@ 'gpu/gpu_idirect3d9_mock_win.cc', 'gpu/gpu_idirect3d9_mock_win.h', 'renderer/mock_content_renderer_client.cc', + 'test/browser_test.h', + 'test/browser_test_base.cc', + 'test/browser_test_base.h', 'test/content_test_suite.cc', 'test/content_test_suite.h', 'test/test_browser_context.cc', @@ -202,6 +205,50 @@ }], ], }, + { + 'target_name': 'content_browsertests', + 'type': 'executable', + 'dependencies': [ + 'content_browser', + 'content_gpu', + 'content_plugin', + 'content_renderer', + 'test_support_content', + '../base/base.gyp:test_support_base', + '../net/net.gyp:net_test_support', + '../testing/gtest.gyp:gtest', + ], + 'include_dirs': [ + '..', + ], + 'defines': [ + 'HAS_OUT_OF_PROC_TEST_RUNNER', + ], + 'sources': [ + 'test/content_browser_test.h', + 'test/content_browser_test.cc', + 'test/content_test_launcher.cc', + 'test/test_launcher.cc', + 'test/test_launcher.h', + ], + 'conditions': [ + ['OS=="win"', { + 'dependencies': [ + '../sandbox/sandbox.gyp:sandbox', + ], + 'link_settings': { + 'libraries': [ + '-lcomctl32.lib', + ], + }, + }], + ['OS=="win" and win_use_allocator_shim==1', { + 'dependencies': [ + '../base/allocator/allocator.gyp:allocator', + ], + }], + ], + }, ], 'conditions': [ ['target_arch=="arm"', { diff --git a/content/test/browser_test.h b/content/test/browser_test.h new file mode 100644 index 0000000..5c0d9ca --- /dev/null +++ b/content/test/browser_test.h @@ -0,0 +1,83 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_TEST_BROWSER_TEST_H_ +#define CONTENT_TEST_BROWSER_TEST_H_ +#pragma once + +// We only want to use InProcessBrowserTest in test targets which properly +// isolate each test case by running each test in a separate process. +// This way if a test hangs the test launcher can reliably terminate it. +// +// InProcessBrowserTest cannot be run more than once in the same address space +// anyway - otherwise the second test crashes. +#if defined(HAS_OUT_OF_PROC_TEST_RUNNER) + +#if defined(BROWSER_TESTS_HEADER_OVERRIDE) +#include BROWSER_TESTS_HEADER_OVERRIDE +#else +#include "content/test/content_browser_test.h" +typedef ContentBrowserTest InProcessBrowserTest; +#endif + +#define IN_PROC_BROWSER_TEST_(test_case_name, test_name, parent_class,\ + parent_id)\ +class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ + public:\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ + protected:\ + virtual void RunTestOnMainThread();\ + private:\ + virtual void TestBody() {}\ + static ::testing::TestInfo* const test_info_;\ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ +};\ +\ +::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ + ::test_info_ =\ + ::testing::internal::MakeAndRegisterTestInfo(\ + #test_case_name, #test_name, "", "", \ + (parent_id), \ + parent_class::SetUpTestCase, \ + parent_class::TearDownTestCase, \ + new ::testing::internal::TestFactoryImpl<\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ +void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::RunTestOnMainThread() + +#define IN_PROC_BROWSER_TEST_F(test_fixture, test_name)\ + IN_PROC_BROWSER_TEST_(test_fixture, test_name, test_fixture,\ + ::testing::internal::GetTypeId<test_fixture>()) + +#define IN_PROC_BROWSER_TEST_P(test_case_name, test_name) \ + class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + : public test_case_name { \ + public: \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ + protected: \ + virtual void RunTestOnMainThread(); \ + private: \ + virtual void TestBody() {} \ + static int AddToRegistry() { \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder<test_case_name>(\ + #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ + #test_case_name, \ + #test_name, \ + new ::testing::internal::TestMetaFactory< \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ + return 0; \ + } \ + static int gtest_registering_dummy_; \ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ + }; \ + int GTEST_TEST_CLASS_NAME_(test_case_name, \ + test_name)::gtest_registering_dummy_ = \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ + void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::RunTestOnMainThread() + +#endif // defined(HAS_OUT_OF_PROC_TEST_RUNNER) + +#endif // CONTENT_TEST_BROWSER_TEST_H_
\ No newline at end of file diff --git a/content/test/browser_test_base.cc b/content/test/browser_test_base.cc new file mode 100644 index 0000000..9a63db0 --- /dev/null +++ b/content/test/browser_test_base.cc @@ -0,0 +1,47 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/test/browser_test_base.h" + +#include "base/command_line.h" +#include "base/task.h" +#include "content/common/main_function_params.h" +#include "sandbox/src/dep.h" + +#if defined(OS_MACOSX) +#include "base/mac/mac_util.h" +#include "base/system_monitor/system_monitor.h" +#endif + +extern int BrowserMain(const MainFunctionParams&); + +BrowserTestBase::BrowserTestBase() { +#if defined(OS_MACOSX) + base::mac::SetOverrideAmIBundled(true); + base::SystemMonitor::AllocateSystemIOPorts(); +#endif +} + +BrowserTestBase::~BrowserTestBase() { +} + +void BrowserTestBase::SetUp() { + SandboxInitWrapper sandbox_wrapper; + MainFunctionParams params(*CommandLine::ForCurrentProcess(), + sandbox_wrapper, + NULL); + params.ui_task = + NewRunnableMethod(this, &BrowserTestBase::ProxyRunTestOnMainThreadLoop); + + SetUpInProcessBrowserTestFixture(); + BrowserMain(params); + TearDownInProcessBrowserTestFixture(); +} + +void BrowserTestBase::TearDown() { +} + +void BrowserTestBase::ProxyRunTestOnMainThreadLoop() { + RunTestOnMainThreadLoop(); +}
\ No newline at end of file diff --git a/content/test/browser_test_base.h b/content/test/browser_test_base.h new file mode 100644 index 0000000..3174eaf --- /dev/null +++ b/content/test/browser_test_base.h @@ -0,0 +1,54 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_TEST_BROWSER_TEST_BASE_H_ +#define CONTENT_TEST_BROWSER_TEST_BASE_H_ +#pragma once + +#include "base/compiler_specific.h" +#include "testing/gtest/include/gtest/gtest.h" + +class BrowserTestBase : public testing::Test { + public: + BrowserTestBase(); + virtual ~BrowserTestBase(); + + // We do this so we can be used in a Task. + void AddRef() {} + void Release() {} + static bool ImplementsThreadSafeReferenceCounting() { return false; } + + // Configures everything for an in process browser test, then invokes + // BrowserMain. BrowserMain ends up invoking RunTestOnMainThreadLoop. + virtual void SetUp() OVERRIDE; + + // Restores state configured in SetUp. + virtual void TearDown() OVERRIDE; + + protected: + // We need these special methods because SetUp is the bottom of the stack + // that winds up calling your test method, so it is not always an option + // to do what you want by overriding it and calling the superclass version. + // + // Override this for things you would normally override SetUp for. It will be + // called before your individual test fixture method is run, but after most + // of the overhead initialization has occured. + virtual void SetUpInProcessBrowserTestFixture() {} + + // Override this for things you would normally override TearDown for. + virtual void TearDownInProcessBrowserTestFixture() {} + + // Override this rather than TestBody. + virtual void RunTestOnMainThread() = 0; + + // This is invoked from main after browser_init/browser_main have completed. + // This prepares for the test by creating a new browser, runs the test + // (RunTestOnMainThread), quits the browsers and returns. + virtual void RunTestOnMainThreadLoop() = 0; + + private: + void ProxyRunTestOnMainThreadLoop(); +}; + +#endif // CONTENT_TEST_BROWSER_TEST_BASE_H_ diff --git a/content/test/content_browser_test.cc b/content/test/content_browser_test.cc new file mode 100644 index 0000000..48cf18d --- /dev/null +++ b/content/test/content_browser_test.cc @@ -0,0 +1,72 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/test/content_browser_test.h" + +#include "base/debug/stack_trace.h" +#include "base/mac/scoped_nsautorelease_pool.h" +#include "base/message_loop.h" +#include "content/test/test_content_client.h" + +ContentBrowserTest::ContentBrowserTest() { +} + +ContentBrowserTest::~ContentBrowserTest() { +} + +void ContentBrowserTest::SetUp() { + DCHECK(!content::GetContentClient()); + content_client_.reset(new TestContentClient); + content::SetContentClient(content_client_.get()); + + content_browser_client_.reset(new content::MockContentBrowserClient()); + content_client_->set_browser(content_browser_client_.get()); + + BrowserTestBase::SetUp(); +} + +void ContentBrowserTest::TearDown() { + BrowserTestBase::TearDown(); + + DCHECK_EQ(content_client_.get(), content::GetContentClient()); + content::SetContentClient(NULL); + content_client_.reset(); + + content_browser_client_.reset(); +} + +#if defined(OS_POSIX) +// On SIGTERM (sent by the runner on timeouts), dump a stack trace (to make +// debugging easier) and also exit with a known error code (so that the test +// framework considers this a failure -- http://crbug.com/57578). +static void DumpStackTraceSignalHandler(int signal) { + base::debug::StackTrace().PrintBacktrace(); + _exit(128 + signal); +} +#endif // defined(OS_POSIX) + +void ContentBrowserTest::RunTestOnMainThreadLoop() { +#if defined(OS_POSIX) + signal(SIGTERM, DumpStackTraceSignalHandler); +#endif // defined(OS_POSIX) + + // On Mac, without the following autorelease pool, code which is directly + // executed (as opposed to executed inside a message loop) would autorelease + // objects into a higher-level pool. This pool is not recycled in-sync with + // the message loops' pools and causes problems with code relying on + // deallocation via an autorelease pool (such as browser window closure and + // browser shutdown). To avoid this, the following pool is recycled after each + // time code is directly executed. + base::mac::ScopedNSAutoreleasePool pool; + + // Pump startup related events. + MessageLoopForUI::current()->RunAllPending(); + pool.Recycle(); + + RunTestOnMainThread(); + pool.Recycle(); + + MessageLoopForUI::current()->Quit(); + pool.Recycle(); +}
\ No newline at end of file diff --git a/content/test/content_browser_test.h b/content/test/content_browser_test.h new file mode 100644 index 0000000..03af28a --- /dev/null +++ b/content/test/content_browser_test.h @@ -0,0 +1,35 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_TEST_CONTENT_BROWSER_TEST_H_ +#define CONTENT_TEST_CONTENT_BROWSER_TEST_H_ +#pragma once + +#include "base/memory/scoped_ptr.h" +#include "content/browser/mock_content_browser_client.h" +#include "content/test/browser_test_base.h" + +namespace content { +class ContentBrowserClient; +class ContentClient; +} + +class ContentBrowserTest : public BrowserTestBase { + protected: + ContentBrowserTest(); + virtual ~ContentBrowserTest(); + + // testing::Test: + virtual void SetUp() OVERRIDE; + virtual void TearDown() OVERRIDE; + + // BrowserTestBase: + virtual void RunTestOnMainThreadLoop() OVERRIDE; + + private: + scoped_ptr<content::ContentClient> content_client_; + scoped_ptr<content::ContentBrowserClient> content_browser_client_; +}; + +#endif // CONTENT_TEST_CONTENT_BROWSER_TEST_H_
\ No newline at end of file diff --git a/content/test/content_test_launcher.cc b/content/test/content_test_launcher.cc new file mode 100644 index 0000000..7bef177 --- /dev/null +++ b/content/test/content_test_launcher.cc @@ -0,0 +1,54 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/test/test_launcher.h" + +#include "base/command_line.h" +#include "base/logging.h" +#include "base/scoped_temp_dir.h" +#include "content/test/content_test_suite.h" + +class ContentTestLauncherDelegate : public test_launcher::TestLauncherDelegate { + public: + ContentTestLauncherDelegate() { + } + + virtual ~ContentTestLauncherDelegate() { + } + + virtual void EarlyInitialize() OVERRIDE { + } + + virtual bool Run(int argc, char** argv, int* return_code) OVERRIDE { + CommandLine* command_line = CommandLine::ForCurrentProcess(); + + // TODO(pkasting): This "single_process vs. single-process" design is + // terrible UI. Instead, there should be some sort of signal flag on the + // command line, with all subsequent arguments passed through to the + // underlying browser. + if (command_line->HasSwitch(test_launcher::kSingleProcessTestsFlag) || + command_line->HasSwitch( + test_launcher::kSingleProcessTestsAndChromeFlag) || + command_line->HasSwitch(test_launcher::kGTestListTestsFlag) || + command_line->HasSwitch(test_launcher::kGTestHelpFlag)) { + *return_code = ContentTestSuite(argc, argv).Run(); + return true; + } + + return false; + } + + virtual bool AdjustChildProcessCommandLine( + CommandLine* command_line) OVERRIDE { + return true; + } + + private: + DISALLOW_COPY_AND_ASSIGN(ContentTestLauncherDelegate); +}; + +int main(int argc, char** argv) { + ContentTestLauncherDelegate launcher_delegate; + return test_launcher::LaunchTests(&launcher_delegate, argc, argv); +}
\ No newline at end of file diff --git a/chrome/test/base/out_of_proc_test_runner.cc b/content/test/test_launcher.cc index 0b865d2..6395b3b 100644 --- a/chrome/test/base/out_of_proc_test_runner.cc +++ b/content/test/test_launcher.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "content/test/test_launcher.h" + #include <string> #include <vector> @@ -21,48 +23,14 @@ #include "base/test/test_timeouts.h" #include "base/time.h" #include "base/utf_string_conversions.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/test/base/chrome_test_suite.h" -#include "chrome/test/base/in_process_browser_test.h" -#include "chrome/test/base/test_launcher_utils.h" +#include "content/test/browser_test.h" #include "net/base/escape.h" #include "testing/gtest/include/gtest/gtest.h" -#if defined(OS_WIN) -#include "base/base_switches.h" -#include "chrome/common/chrome_constants.h" -#include "content/common/sandbox_policy.h" -#include "sandbox/src/dep.h" -#include "sandbox/src/sandbox_factory.h" -#include "sandbox/src/sandbox_types.h" -#endif // defined(OS_WIN) - -#if defined(OS_MACOSX) -#include "chrome/browser/chrome_browser_application_mac.h" -#endif // defined(OS_MACOSX) - -#if defined(OS_WIN) -// The entry point signature of chrome.dll. -typedef int (*DLL_MAIN)(HINSTANCE, sandbox::SandboxInterfaceInfo*, wchar_t*); -#endif // defined(OS_WIN) +namespace test_launcher { namespace { -const char kGTestFilterFlag[] = "gtest_filter"; -const char kGTestHelpFlag[] = "gtest_help"; -const char kGTestListTestsFlag[] = "gtest_list_tests"; -const char kGTestRepeatFlag[] = "gtest_repeat"; -const char kGTestRunDisabledTestsFlag[] = "gtest_also_run_disabled_tests"; -const char kGTestOutputFlag[] = "gtest_output"; - -const char kSingleProcessTestsFlag[] = "single_process"; -const char kSingleProcessTestsAndChromeFlag[] = "single-process"; -// The following is kept for historical reasons (so people that are used to -// using it don't get surprised). -const char kChildProcessFlag[] = "child"; - -const char kHelpFlag[] = "help"; - // The environment variable name for the total number of test shards. static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; // The environment variable name for the test shard index. @@ -303,9 +271,29 @@ bool MatchesFilter(const std::string& name, const std::string& filter) { } } +// A multiplier for slow tests. We generally avoid multiplying +// test timeouts by any constants. Here it is used as last resort +// to implement the SLOW_ test prefix. +static const int kSlowTestTimeoutMultiplier = 5; + +int GetTestTerminationTimeout(const std::string& test_name, + int default_timeout_ms) { + int timeout_ms = default_timeout_ms; + + // Make it possible for selected tests to request a longer timeout. + // Generally tests should really avoid doing too much, and splitting + // a test instead of using SLOW prefix is strongly preferred. + if (test_name.find("SLOW_") != std::string::npos) + timeout_ms *= kSlowTestTimeoutMultiplier; + + return timeout_ms; +} + // Runs test specified by |test_name| in a child process, // and returns the exit code. -int RunTest(const std::string& test_name, int default_timeout_ms) { +int RunTest(TestLauncherDelegate* launcher_delegate, + const std::string& test_name, + int default_timeout_ms) { // Some of the below method calls will leak objects if there is no // autorelease pool in place. base::mac::ScopedNSAutoreleasePool pool; @@ -324,9 +312,6 @@ int RunTest(const std::string& test_name, int default_timeout_ms) { // has been shut down and will actually crash). switches.erase(kGTestRepeatFlag); - // Strip out user-data-dir if present. We will add it back in again later. - switches.erase(switches::kUserDataDir); - for (CommandLine::SwitchMap::const_iterator iter = switches.begin(); iter != switches.end(); ++iter) { new_cmd_line.AppendSwitchNative((*iter).first, (*iter).second); @@ -336,22 +321,14 @@ int RunTest(const std::string& test_name, int default_timeout_ms) { // tests unless this flag was specified to the browser test executable. new_cmd_line.AppendSwitch("gtest_also_run_disabled_tests"); new_cmd_line.AppendSwitchASCII("gtest_filter", test_name); - new_cmd_line.AppendSwitch(kChildProcessFlag); + new_cmd_line.AppendSwitch(kSingleProcessTestsFlag); // Do not let the child ignore failures. We need to propagate the // failure status back to the parent. new_cmd_line.AppendSwitch(base::TestSuite::kStrictFailureHandling); - // Create a new user data dir and pass it to the child. - ScopedTempDir temp_dir; - if (!temp_dir.CreateUniqueTempDir() || !temp_dir.IsValid()) { - LOG(ERROR) << "Error creating temp profile directory"; - return false; - } - new_cmd_line.AppendSwitchPath(switches::kUserDataDir, temp_dir.path()); - - // file:// access for ChromeOS. - new_cmd_line.AppendSwitch(switches::kAllowFileAccess); + if (!launcher_delegate->AdjustChildProcessCommandLine(&new_cmd_line)) + return -1; const char* browser_wrapper = getenv("BROWSER_WRAPPER"); if (browser_wrapper) { @@ -376,11 +353,10 @@ int RunTest(const std::string& test_name, int default_timeout_ms) { #endif if (!base::LaunchProcess(new_cmd_line, options, &process_handle)) - return false; + return -1; - int timeout_ms = - test_launcher_utils::GetTestTerminationTimeout(test_name, - default_timeout_ms); + int timeout_ms = GetTestTerminationTimeout(test_name, + default_timeout_ms); int exit_code = 0; if (!base::WaitForExitCodeWithTimeout(process_handle, &exit_code, @@ -409,7 +385,10 @@ int RunTest(const std::string& test_name, int default_timeout_ms) { return exit_code; } -bool RunTests(bool should_shard, int total_shards, int shard_index) { +bool RunTests(TestLauncherDelegate* launcher_delegate, + bool should_shard, + int total_shards, + int shard_index) { const CommandLine* command_line = CommandLine::ForCurrentProcess(); DCHECK(!command_line->HasSwitch(kGTestListTestsFlag)); @@ -480,7 +459,9 @@ bool RunTests(bool should_shard, int total_shards, int shard_index) { base::Time start_time = base::Time::Now(); ++test_run_count; - int exit_code = RunTest(test_name, TestTimeouts::action_max_timeout_ms()); + int exit_code = RunTest(launcher_delegate, + test_name, + TestTimeouts::action_max_timeout_ms()); if (exit_code == 0) { // Test passed. printer.OnTestEnd(test_info->name(), test_case->name(), true, false, @@ -538,10 +519,28 @@ void PrintUsage() { } // namespace -int main(int argc, char** argv) { -#if defined(OS_MACOSX) - chrome_browser_application_mac::RegisterBrowserCrApp(); -#endif +const char kGTestFilterFlag[] = "gtest_filter"; +const char kGTestHelpFlag[] = "gtest_help"; +const char kGTestListTestsFlag[] = "gtest_list_tests"; +const char kGTestRepeatFlag[] = "gtest_repeat"; +const char kGTestRunDisabledTestsFlag[] = "gtest_also_run_disabled_tests"; +const char kGTestOutputFlag[] = "gtest_output"; + +const char kSingleProcessTestsFlag[] = "single_process"; +const char kSingleProcessTestsAndChromeFlag[] = "single-process"; +// The following is kept for historical reasons (so people that are used to +// using it don't get surprised). +const char kChildProcessFlag[] = "child"; + +const char kHelpFlag[] = "help"; + +TestLauncherDelegate::~TestLauncherDelegate() { +} + +int LaunchTests(TestLauncherDelegate* launcher_delegate, + int argc, + char** argv) { + launcher_delegate->EarlyInitialize(); CommandLine::Init(argc, argv); const CommandLine* command_line = CommandLine::ForCurrentProcess(); @@ -551,51 +550,9 @@ int main(int argc, char** argv) { return 0; } - // TODO(pkasting): This "single_process vs. single-process" design is terrible - // UI. Instead, there should be some sort of signal flag on the command line, - // with all subsequent arguments passed through to the underlying browser. - if (command_line->HasSwitch(kChildProcessFlag) || - command_line->HasSwitch(kSingleProcessTestsFlag) || - command_line->HasSwitch(kSingleProcessTestsAndChromeFlag) || - command_line->HasSwitch(kGTestListTestsFlag) || - command_line->HasSwitch(kGTestHelpFlag)) { - -#if defined(OS_WIN) - if (command_line->HasSwitch(kChildProcessFlag) || - command_line->HasSwitch(kSingleProcessTestsFlag)) { - // This is the browser process, so setup the sandbox broker. - sandbox::BrokerServices* broker_services = - sandbox::SandboxFactory::GetBrokerServices(); - if (broker_services) { - sandbox::InitBrokerServices(broker_services); - // Precreate the desktop and window station used by the renderers. - sandbox::TargetPolicy* policy = broker_services->CreatePolicy(); - sandbox::ResultCode result = policy->CreateAlternateDesktop(true); - CHECK(sandbox::SBOX_ERROR_FAILED_TO_SWITCH_BACK_WINSTATION != result); - policy->Release(); - } - } -#endif - return ChromeTestSuite(argc, argv).Run(); - } - -#if defined(OS_WIN) - if (command_line->HasSwitch(switches::kProcessType)) { - // This is a child process, call ChromeMain. - FilePath chrome_path(command_line->GetProgram().DirName()); - chrome_path = chrome_path.Append(chrome::kBrowserResourcesDll); - HMODULE dll = LoadLibrary(chrome_path.value().c_str()); - DLL_MAIN entry_point = - reinterpret_cast<DLL_MAIN>(::GetProcAddress(dll, "ChromeMain")); - if (!entry_point) - return -1; - - // Initialize the sandbox services. - sandbox::SandboxInterfaceInfo sandbox_info = {0}; - sandbox_info.target_services = sandbox::SandboxFactory::GetTargetServices(); - return entry_point(GetModuleHandle(NULL), &sandbox_info, GetCommandLineW()); - } -#endif + int return_code = 0; + if (launcher_delegate->Run(argc, argv, &return_code)) + return return_code; int32 total_shards; int32 shard_index; @@ -617,7 +574,9 @@ int main(int argc, char** argv) { // from disk may be slow on a busy bot, and can easily exceed the default // timeout causing flaky test failures. Use an empty test that only starts // and closes a browser with a long timeout to avoid those problems. - RunTest(kEmptyTestName, TestTimeouts::large_test_timeout_ms()); + RunTest(launcher_delegate, + kEmptyTestName, + TestTimeouts::large_test_timeout_ms()); int cycles = 1; if (command_line->HasSwitch(kGTestRepeatFlag)) { @@ -627,7 +586,10 @@ int main(int argc, char** argv) { int exit_code = 0; while (cycles != 0) { - if (!RunTests(should_shard, total_shards, shard_index)) { + if (!RunTests(launcher_delegate, + should_shard, + total_shards, + shard_index)) { exit_code = 1; break; } @@ -638,3 +600,5 @@ int main(int argc, char** argv) { } return exit_code; } + +} // namespcae test_launcher
\ No newline at end of file diff --git a/content/test/test_launcher.h b/content/test/test_launcher.h new file mode 100644 index 0000000..f695116 --- /dev/null +++ b/content/test/test_launcher.h @@ -0,0 +1,44 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_TEST_TEST_LAUNCHER_H_ +#define CONTENT_TEST_TEST_LAUNCHER_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/compiler_specific.h" + +class CommandLine; + +namespace test_launcher { + +extern const char kGTestFilterFlag[]; +extern const char kGTestHelpFlag[]; +extern const char kGTestListTestsFlag[]; +extern const char kGTestRepeatFlag[]; +extern const char kGTestRunDisabledTestsFlag[]; +extern const char kGTestOutputFlag[]; + +extern const char kSingleProcessTestsFlag[]; +extern const char kSingleProcessTestsAndChromeFlag[]; + +extern const char kHelpFlag[]; + +class TestLauncherDelegate { + public: + virtual void EarlyInitialize() = 0; + virtual bool Run(int argc, char** argv, int* return_code) = 0; + virtual bool AdjustChildProcessCommandLine(CommandLine* command_line) = 0; + + protected: + virtual ~TestLauncherDelegate(); +}; + +int LaunchTests(TestLauncherDelegate* launcher_delegate, + int argc, + char** argv) WARN_UNUSED_RESULT; + +} // namespace test_launcher + +#endif // CONTENT_TEST_TEST_LAUNCHER_H_
\ No newline at end of file |