diff options
27 files changed, 427 insertions, 122 deletions
diff --git a/chrome/browser/extensions/permissions_updater_unittest.cc b/chrome/browser/extensions/permissions_updater_unittest.cc index 4910dc3..207183f 100644 --- a/chrome/browser/extensions/permissions_updater_unittest.cc +++ b/chrome/browser/extensions/permissions_updater_unittest.cc @@ -6,6 +6,7 @@ #include "base/json/json_file_value_serializer.h" #include "base/memory/ref_counted.h" #include "base/path_service.h" +#include "base/run_loop.h" #include "base/values.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service_unittest.h" @@ -15,7 +16,6 @@ #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/permissions/permission_set.h" #include "chrome/test/base/testing_profile.h" -#include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_service.h" @@ -47,7 +47,8 @@ class PermissionsUpdaterListener : public content::NotificationObserver { return; waiting_ = true; - ui_test_utils::RunMessageLoop(); + base::RunLoop run_loop; + run_loop.Run(); } bool received_notification() const { return received_notification_; } diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index 59286c4..cecb6c9 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc @@ -48,6 +48,7 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/url_constants.h" +#include "content/public/test/browser_test_utils.h" #include "content/public/test/test_navigation_observer.h" #include "grit/generated_resources.h" #include "net/base/mock_host_resolver.h" @@ -1017,9 +1018,9 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest { content::NotificationService::AllSources(), NULL, 1); base::RunLoop run_loop; observer.WaitForObservation( - base::Bind(&ui_test_utils::RunThisRunLoop, + base::Bind(&content::RunThisRunLoop, base::Unretained(&run_loop)), - ui_test_utils::GetQuitTaskForRunLoop(&run_loop)); + content::GetQuitTaskForRunLoop(&run_loop)); } } diff --git a/chrome/browser/renderer_host/plugin_info_message_filter_unittest.cc b/chrome/browser/renderer_host/plugin_info_message_filter_unittest.cc index f7a31b3..34a5576 100644 --- a/chrome/browser/renderer_host/plugin_info_message_filter_unittest.cc +++ b/chrome/browser/renderer_host/plugin_info_message_filter_unittest.cc @@ -8,9 +8,9 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/message_loop.h" +#include "base/run_loop.h" #include "base/utf_string_conversions.h" #include "chrome/common/render_messages.h" -#include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/plugin_service.h" #include "content/public/browser/plugin_service_filter.h" #include "content/public/test/test_browser_thread.h" @@ -91,7 +91,8 @@ class PluginInfoMessageFilterTest : public ::testing::Test { PluginService::GetInstance()->GetPlugins( base::Bind(&PluginInfoMessageFilterTest::PluginsLoaded, base::Unretained(this))); - ui_test_utils::RunMessageLoop(); + base::RunLoop run_loop; + run_loop.Run(); } protected: diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 59fca7b..9f9eee2 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -487,7 +487,6 @@ ], 'defines': [ 'HAS_OUT_OF_PROC_TEST_RUNNER', - 'BROWSER_TESTS_HEADER_OVERRIDE="chrome/test/base/in_process_browser_test.h"', ], 'sources': [ 'browser/browser_focus_uitest.cc', @@ -2640,7 +2639,6 @@ ], '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', @@ -3441,7 +3439,6 @@ ], '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', @@ -3591,7 +3588,6 @@ ], 'defines': [ 'HAS_OUT_OF_PROC_TEST_RUNNER', - 'BROWSER_TESTS_HEADER_OVERRIDE="chrome/test/base/in_process_browser_test.h"', ], 'sources': [ 'app/chrome_dll.rc', @@ -3888,7 +3884,6 @@ # TODO(phajdan.jr): Only temporary, to make transition easier. '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', @@ -4039,7 +4034,6 @@ ], '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', diff --git a/chrome/test/base/chrome_test_launcher.cc b/chrome/test/base/chrome_test_launcher.cc index 8ca9974..bc11da9 100644 --- a/chrome/test/base/chrome_test_launcher.cc +++ b/chrome/test/base/chrome_test_launcher.cc @@ -6,6 +6,7 @@ #include "base/command_line.h" #include "base/logging.h" +#include "base/run_loop.h" #include "base/scoped_temp_dir.h" #include "base/test/test_file_util.h" #include "chrome/app/chrome_main_delegate.h" @@ -13,6 +14,7 @@ #include "chrome/common/chrome_constants.h" #include "chrome/test/base/chrome_test_suite.h" #include "content/public/app/content_main.h" +#include "content/public/browser/browser_thread.h" #if defined(OS_MACOSX) #include "chrome/browser/chrome_browser_application_mac.h" @@ -23,6 +25,10 @@ #include "sandbox/win/src/sandbox_types.h" #endif // defined(OS_WIN) +#if defined(TOOLKIT_VIEWS) +#include "ui/views/focus/accelerator_handler.h" +#endif + class ChromeTestLauncherDelegate : public test_launcher::TestLauncherDelegate { public: ChromeTestLauncherDelegate() { @@ -106,9 +112,29 @@ class ChromeTestLauncherDelegate : public test_launcher::TestLauncherDelegate { return true; } + virtual void PreRunMessageLoop(base::RunLoop* run_loop) OVERRIDE { +#if !defined(USE_AURA) && defined(TOOLKIT_VIEWS) + DCHECK(!handler_.get()); + if (content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { + handler_.reset(new views::AcceleratorHandler); + run_loop->set_dispatcher(handler_.get()); + } +#endif + } + + virtual void PostRunMessageLoop() { +#if !defined(USE_AURA) && defined(TOOLKIT_VIEWS) + handler_.reset(); +#endif + } + private: ScopedTempDir temp_dir_; +#if !defined(USE_AURA) && defined(TOOLKIT_VIEWS) + scoped_ptr<views::AcceleratorHandler> handler_; +#endif + DISALLOW_COPY_AND_ASSIGN(ChromeTestLauncherDelegate); }; diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index 129ecc1..4bd8b2e6 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc @@ -53,6 +53,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/render_process_host.h" +#include "content/public/test/browser_test_utils.h" #include "content/public/test/mock_resource_context.h" #include "net/cookies/cookie_monster.h" #include "net/url_request/url_request_context.h" @@ -396,8 +397,7 @@ void TestingProfile::BlockUntilBookmarkModelLoaded() { if (GetBookmarkModel()->IsLoaded()) return; base::RunLoop run_loop; - BookmarkLoadObserver observer( - ui_test_utils::GetQuitTaskForRunLoop(&run_loop)); + BookmarkLoadObserver observer(content::GetQuitTaskForRunLoop(&run_loop)); GetBookmarkModel()->AddObserver(&observer); run_loop.Run(); GetBookmarkModel()->RemoveObserver(&observer); diff --git a/chrome/test/base/ui_test_utils.cc b/chrome/test/base/ui_test_utils.cc index cc38fa7..089e6ac 100644 --- a/chrome/test/base/ui_test_utils.cc +++ b/chrome/test/base/ui_test_utils.cc @@ -63,6 +63,7 @@ #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_view.h" #include "content/public/common/geoposition.h" +#include "content/public/test/browser_test_utils.h" #include "content/public/test/test_navigation_observer.h" #include "googleurl/src/gurl.h" #include "net/base/net_util.h" @@ -73,10 +74,6 @@ #include "ui/gfx/size.h" #include "ui/ui_controls/ui_controls.h" -#if defined(TOOLKIT_VIEWS) -#include "ui/views/focus/accelerator_handler.h" -#endif - #if defined(USE_AURA) #include "ash/shell.h" #include "ui/aura/root_window.h" @@ -94,17 +91,6 @@ using content::WebContents; static const int kDefaultWsPort = 8880; -// Number of times to repost a Quit task so that the MessageLoop finishes up -// pending tasks and tasks posted by those pending tasks without risking the -// potential hang behavior of MessageLoop::QuitWhenIdle. -// The criteria for choosing this number: it should be high enough to make the -// quit act like QuitWhenIdle, while taking into account that any page which is -// animating may be rendering another frame for each quit deferral. For an -// animating page, the potential delay to quitting the RunLoop would be -// kNumQuitDeferrals * frame_render_time. Some perf tests run slow, such as -// 200ms/frame. -static const int kNumQuitDeferrals = 10; - namespace ui_test_utils { namespace { @@ -291,35 +277,7 @@ void RunAllPendingMessageAndSendQuit(content::BrowserThread::ID thread_id, void RunMessageLoop() { base::RunLoop run_loop; - RunThisRunLoop(&run_loop); -} - -void RunThisRunLoop(base::RunLoop* run_loop) { - MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); -#if !defined(USE_AURA) && defined(TOOLKIT_VIEWS) - scoped_ptr<views::AcceleratorHandler> handler; - if (content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { - handler.reset(new views::AcceleratorHandler); - run_loop->set_dispatcher(handler.get()); - } -#endif - run_loop->Run(); -} - -// TODO(jbates) move this to a new test_utils.cc in content/test/ -static void DeferredQuitRunLoop(const base::Closure& quit_task, - int num_quit_deferrals) { - if (num_quit_deferrals <= 0) { - quit_task.Run(); - } else { - MessageLoop::current()->PostTask(FROM_HERE, - base::Bind(&DeferredQuitRunLoop, quit_task, num_quit_deferrals - 1)); - } -} - -base::Closure GetQuitTaskForRunLoop(base::RunLoop* run_loop) { - return base::Bind(&DeferredQuitRunLoop, run_loop->QuitClosure(), - kNumQuitDeferrals); + content::RunThisRunLoop(&run_loop); } void RunAllPendingInMessageLoop() { @@ -343,7 +301,7 @@ void RunAllPendingInMessageLoop(content::BrowserThread::ID thread_id) { content::BrowserThread::PostTask(thread_id, FROM_HERE, base::Bind(&RunAllPendingMessageAndSendQuit, current_thread_id, run_loop.QuitClosure())); - ui_test_utils::RunThisRunLoop(&run_loop); + content::RunThisRunLoop(&run_loop); } bool GetCurrentTabTitle(const Browser* browser, string16* title) { @@ -364,8 +322,8 @@ void WaitForNavigations(NavigationController* controller, number_of_navigations); base::RunLoop run_loop; observer.WaitForObservation( - base::Bind(&ui_test_utils::RunThisRunLoop, base::Unretained(&run_loop)), - ui_test_utils::GetQuitTaskForRunLoop(&run_loop)); + base::Bind(&content::RunThisRunLoop, base::Unretained(&run_loop)), + content::GetQuitTaskForRunLoop(&run_loop)); } void WaitForNewTab(Browser* browser) { @@ -412,8 +370,8 @@ void NavigateToURL(chrome::NavigateParams* params) { chrome::Navigate(params); base::RunLoop run_loop; observer.WaitForObservation( - base::Bind(&ui_test_utils::RunThisRunLoop, base::Unretained(&run_loop)), - ui_test_utils::GetQuitTaskForRunLoop(&run_loop)); + base::Bind(&content::RunThisRunLoop, base::Unretained(&run_loop)), + content::GetQuitTaskForRunLoop(&run_loop)); } void NavigateToURL(Browser* browser, const GURL& url) { @@ -486,8 +444,8 @@ static void NavigateToURLWithDispositionBlockUntilNavigationsComplete( if (disposition == CURRENT_TAB) { base::RunLoop run_loop; same_tab_observer.WaitForObservation( - base::Bind(&ui_test_utils::RunThisRunLoop, base::Unretained(&run_loop)), - ui_test_utils::GetQuitTaskForRunLoop(&run_loop)); + base::Bind(&content::RunThisRunLoop, base::Unretained(&run_loop)), + content::GetQuitTaskForRunLoop(&run_loop)); return; } else if (web_contents) { NavigationController* controller = &web_contents->GetController(); @@ -738,9 +696,9 @@ void WaitForBookmarkModelToLoad(BookmarkModel* model) { if (model->IsLoaded()) return; base::RunLoop run_loop; - BookmarkLoadObserver observer(GetQuitTaskForRunLoop(&run_loop)); + BookmarkLoadObserver observer(content::GetQuitTaskForRunLoop(&run_loop)); model->AddObserver(&observer); - RunThisRunLoop(&run_loop); + content::RunThisRunLoop(&run_loop); model->RemoveObserver(&observer); ASSERT_TRUE(model->IsLoaded()); } @@ -864,7 +822,7 @@ MessageLoopRunner::~MessageLoopRunner() { } void MessageLoopRunner::Run() { - ui_test_utils::RunThisRunLoop(&run_loop_); + content::RunThisRunLoop(&run_loop_); } base::Closure MessageLoopRunner::QuitClosure() { @@ -872,7 +830,7 @@ base::Closure MessageLoopRunner::QuitClosure() { } void MessageLoopRunner::Quit() { - ui_test_utils::GetQuitTaskForRunLoop(&run_loop_).Run(); + content::GetQuitTaskForRunLoop(&run_loop_).Run(); } TestWebSocketServer::TestWebSocketServer() diff --git a/chrome/test/base/ui_test_utils.h b/chrome/test/base/ui_test_utils.h index 015e570..56339ec 100644 --- a/chrome/test/base/ui_test_utils.h +++ b/chrome/test/base/ui_test_utils.h @@ -95,13 +95,6 @@ enum BrowserTestWaitFlags { // process browser tests that need to block until a condition is met. void RunMessageLoop(); -// Variant of RunMessageLoop that takes RunLoop. -void RunThisRunLoop(base::RunLoop* run_loop); - -// Get task to quit the given RunLoop. It allows a few generations of pending -// tasks to run as opposed to run_loop->QuitClosure(). -base::Closure GetQuitTaskForRunLoop(base::RunLoop* run_loop); - // Turns on nestable tasks, runs all pending tasks in the message loop, // then resets nestable tasks to what they were originally. Prefer this // over MessageLoop::RunAllPending for in process browser tests to run diff --git a/chrome/test/gpu/test_support_gpu.gypi b/chrome/test/gpu/test_support_gpu.gypi index 1648a06..075ec20 100644 --- a/chrome/test/gpu/test_support_gpu.gypi +++ b/chrome/test/gpu/test_support_gpu.gypi @@ -26,7 +26,6 @@ ], 'defines': [ 'HAS_OUT_OF_PROC_TEST_RUNNER', - 'BROWSER_TESTS_HEADER_OVERRIDE="chrome/test/base/in_process_browser_test.h"', ], 'include_dirs': [ '<(src_dir)', diff --git a/chrome/test/perf/rendering/throughput_tests.cc b/chrome/test/perf/rendering/throughput_tests.cc index c488999a..4720ee0 100644 --- a/chrome/test/perf/rendering/throughput_tests.cc +++ b/chrome/test/perf/rendering/throughput_tests.cc @@ -28,6 +28,7 @@ #include "chrome/test/perf/perf_test.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_switches.h" +#include "content/public/test/browser_test_utils.h" #include "content/test/gpu/gpu_test_config.h" #include "googleurl/src/gurl.h" #include "net/base/mock_host_resolver.h" @@ -201,7 +202,7 @@ class ThroughputTest : public BrowserPerfTest { MessageLoop::current()->PostDelayedTask( FROM_HERE, run_loop.QuitClosure(), base::TimeDelta::FromMilliseconds(ms)); - ui_test_utils::RunThisRunLoop(&run_loop); + content::RunThisRunLoop(&run_loop); } // Take snapshot of the current tab, encode it as PNG, and save to a SkBitmap. diff --git a/content/content_tests.gypi b/content/content_tests.gypi index c0672bb..a8bce63 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi @@ -27,6 +27,7 @@ 'sources': [ 'public/test/accessibility_test_utils_win.h', 'public/test/browser_test.h', + 'public/test/browser_test_utils.h', 'public/test/content_test_suite_base.h', 'public/test/js_injection_ready_observer.h', 'public/test/mock_download_item.h', @@ -74,6 +75,7 @@ 'test/accessibility_test_utils_win.cc', 'test/browser_test_base.cc', 'test/browser_test_base.h', + 'test/browser_test_utils.cc', 'test/content_test_suite.cc', 'test/content_test_suite.h', 'test/content_test_suite_base.cc', @@ -521,6 +523,7 @@ 'content_plugin', 'content_renderer', 'content_shell_lib', + 'content_shell_pak', 'test_support_content', '../base/base.gyp:test_support_base', '../ipc/ipc.gyp:test_support_ipc', @@ -543,8 +546,10 @@ 'sources': [ 'test/content_browser_test.h', 'test/content_browser_test.cc', + 'test/content_browser_test_utils.cc', + 'test/content_browser_test_utils.h', + 'test/content_browser_test_test.cc', 'test/content_test_launcher.cc', - 'renderer/pepper/pepper_file_chooser_host_browsertest.cc', ], 'conditions': [ ['OS=="win"', { @@ -584,6 +589,11 @@ '../base/allocator/allocator.gyp:allocator', ], }], + ['OS=="mac"', { + 'dependencies': [ + 'content_shell', # Needed for Content Shell.app's Helper. + ], + }], ], }, ], diff --git a/content/public/test/browser_test.h b/content/public/test/browser_test.h index ba82be13..8fe49b6 100644 --- a/content/public/test/browser_test.h +++ b/content/public/test/browser_test.h @@ -13,13 +13,6 @@ // 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 - #include "base/compiler_specific.h" #define IN_PROC_BROWSER_TEST_(test_case_name, test_name, parent_class,\ diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h new file mode 100644 index 0000000..849842b --- /dev/null +++ b/content/public/test/browser_test_utils.h @@ -0,0 +1,33 @@ +// Copyright (c) 2012 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_PUBLIC_TEST_BROWSER_TEST_UTILS_H_ +#define CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_ + +#include "base/callback_forward.h" +#include "googleurl/src/gurl.h" + +namespace base { +class RunLoop; +} + +// A collections of functions designed for use with content_browsertests and +// browser_tests. +// TO BE CLEAR: any function here must work against both binaries. If it only +// works with browser_tests, it should be in chrome\test\base\ui_test_utils.h. +// If it only works with content_browsertests, it should be in +// content\test\content_browser_test_utils.h. + +namespace content { + +// Variant of RunMessageLoop that takes RunLoop. +void RunThisRunLoop(base::RunLoop* run_loop); + +// Get task to quit the given RunLoop. It allows a few generations of pending +// tasks to run as opposed to run_loop->QuitClosure(). +base::Closure GetQuitTaskForRunLoop(base::RunLoop* run_loop); + +} // namespace content + +#endif // CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_ diff --git a/content/public/test/test_launcher.h b/content/public/test/test_launcher.h index c44a455..1f7cdac 100644 --- a/content/public/test/test_launcher.h +++ b/content/public/test/test_launcher.h @@ -10,6 +10,10 @@ class CommandLine; +namespace base { +class RunLoop; +} + namespace test_launcher { extern const char kEmptyTestName[]; @@ -30,6 +34,8 @@ class TestLauncherDelegate { virtual bool Run(int argc, char** argv, int* return_code) = 0; virtual int RunTestSuite(int argc, char** argv) = 0; virtual bool AdjustChildProcessCommandLine(CommandLine* command_line) = 0; + virtual void PreRunMessageLoop(base::RunLoop* run_loop) {} + virtual void PostRunMessageLoop() {} protected: virtual ~TestLauncherDelegate(); @@ -39,6 +45,8 @@ int LaunchTests(TestLauncherDelegate* launcher_delegate, int argc, char** argv) WARN_UNUSED_RESULT; +TestLauncherDelegate* GetCurrentTestLauncherDelegate(); + } // namespace test_launcher #endif // CONTENT_PUBLIC_TEST_TEST_LAUNCHER_H_ diff --git a/content/shell/shell.h b/content/shell/shell.h index 918b6ff..39dfbec 100644 --- a/content/shell/shell.h +++ b/content/shell/shell.h @@ -64,6 +64,9 @@ class Shell : public WebContentsDelegate, // Returns the Shell object corresponding to the given RenderViewHost. static Shell* FromRenderViewHost(RenderViewHost* rvh); + // Returns the currently open windows. + static std::vector<Shell*>& windows() { return windows_; } + // Closes all windows and returns. This runs a message loop. static void CloseAllWindows(); diff --git a/content/shell/shell_browser_main_parts.cc b/content/shell/shell_browser_main_parts.cc index 0d8ca89..0d35fca 100644 --- a/content/shell/shell_browser_main_parts.cc +++ b/content/shell/shell_browser_main_parts.cc @@ -11,6 +11,7 @@ #include "base/threading/thread.h" #include "base/threading/thread_restrictions.h" #include "content/public/common/content_switches.h" +#include "content/public/common/main_function_params.h" #include "content/shell/shell.h" #include "content/shell/shell_browser_context.h" #include "content/shell/shell_devtools_delegate.h" @@ -37,6 +38,8 @@ static GURL GetStartupURL() { ShellBrowserMainParts::ShellBrowserMainParts( const content::MainFunctionParams& parameters) : BrowserMainParts(), + parameters_(parameters), + run_message_loop_(true), devtools_delegate_(NULL) { } @@ -88,6 +91,16 @@ void ShellBrowserMainParts::PreMainMessageLoopRun() { MSG_ROUTING_NONE, NULL); } + + if (parameters_.ui_task) { + parameters_.ui_task->Run(); + delete parameters_.ui_task; + run_message_loop_ = false; + } +} + +bool ShellBrowserMainParts::MainMessageLoopRun(int* result_code) { + return !run_message_loop_; } void ShellBrowserMainParts::PostMainMessageLoopRun() { diff --git a/content/shell/shell_browser_main_parts.h b/content/shell/shell_browser_main_parts.h index 8f86599..7c6abf1 100644 --- a/content/shell/shell_browser_main_parts.h +++ b/content/shell/shell_browser_main_parts.h @@ -21,14 +21,15 @@ struct MainFunctionParams; class ShellBrowserMainParts : public BrowserMainParts { public: - explicit ShellBrowserMainParts(const content::MainFunctionParams& parameters); + explicit ShellBrowserMainParts(const MainFunctionParams& parameters); virtual ~ShellBrowserMainParts(); - // content::BrowserMainParts overrides. + // BrowserMainParts overrides. virtual void PreEarlyInitialization() OVERRIDE; virtual void PreMainMessageLoopStart() OVERRIDE; virtual void PostMainMessageLoopStart() OVERRIDE; virtual void PreMainMessageLoopRun() OVERRIDE; + virtual bool MainMessageLoopRun(int* result_code) OVERRIDE; virtual void PostMainMessageLoopRun() OVERRIDE; ShellDevToolsDelegate* devtools_delegate() { return devtools_delegate_; } @@ -38,6 +39,10 @@ class ShellBrowserMainParts : public BrowserMainParts { private: scoped_ptr<ShellBrowserContext> browser_context_; + // For running content_browsertests. + const MainFunctionParams& parameters_; + bool run_message_loop_; + ShellDevToolsDelegate* devtools_delegate_; DISALLOW_COPY_AND_ASSIGN(ShellBrowserMainParts); diff --git a/content/test/browser_test_utils.cc b/content/test/browser_test_utils.cc new file mode 100644 index 0000000..c82e61a --- /dev/null +++ b/content/test/browser_test_utils.cc @@ -0,0 +1,59 @@ +// Copyright (c) 2012 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/public/test/browser_test_utils.h" + +#include "base/bind.h" +#include "base/message_loop.h" +#include "base/run_loop.h" +#include "content/public/test/test_launcher.h" + +namespace { + +// Number of times to repost a Quit task so that the MessageLoop finishes up +// pending tasks and tasks posted by those pending tasks without risking the +// potential hang behavior of MessageLoop::QuitWhenIdle. +// The criteria for choosing this number: it should be high enough to make the +// quit act like QuitWhenIdle, while taking into account that any page which is +// animating may be rendering another frame for each quit deferral. For an +// animating page, the potential delay to quitting the RunLoop would be +// kNumQuitDeferrals * frame_render_time. Some perf tests run slow, such as +// 200ms/frame. +static const int kNumQuitDeferrals = 10; + +static void DeferredQuitRunLoop(const base::Closure& quit_task, + int num_quit_deferrals) { + if (num_quit_deferrals <= 0) { + quit_task.Run(); + } else { + MessageLoop::current()->PostTask(FROM_HERE, + base::Bind(&DeferredQuitRunLoop, quit_task, num_quit_deferrals - 1)); + } +} + +} + +namespace content { + +void RunThisRunLoop(base::RunLoop* run_loop) { + MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); + + test_launcher::TestLauncherDelegate* delegate = + test_launcher::GetCurrentTestLauncherDelegate(); + // TODO(jam): the null check shouldn't be needed, since this code should only + // be called from browser_tests. Unfortunately some unittests are calling this + // code. + if (delegate) + delegate->PreRunMessageLoop(run_loop); + run_loop->Run(); + if (delegate) + delegate->PostRunMessageLoop(); +} + +base::Closure GetQuitTaskForRunLoop(base::RunLoop* run_loop) { + return base::Bind(&DeferredQuitRunLoop, run_loop->QuitClosure(), + kNumQuitDeferrals); +} + +} // namespace content diff --git a/content/test/content_browser_test.cc b/content/test/content_browser_test.cc index b1dddd0..9eb5c63 100644 --- a/content/test/content_browser_test.cc +++ b/content/test/content_browser_test.cc @@ -4,8 +4,13 @@ #include "content/test/content_browser_test.h" +#include "base/command_line.h" #include "base/debug/stack_trace.h" +#include "base/file_path.h" +#include "base/logging.h" #include "base/message_loop.h" +#include "base/path_service.h" +#include "content/public/common/content_switches.h" #include "content/shell/shell.h" #include "content/shell/shell_main_delegate.h" #include "content/test/test_content_client.h" @@ -15,16 +20,37 @@ #endif ContentBrowserTest::ContentBrowserTest() { +#if defined(OS_MACOSX) + // See comment in InProcessBrowserTest::InProcessBrowserTest(). + FilePath content_shell_path; + CHECK(PathService::Get(base::FILE_EXE, &content_shell_path)); + content_shell_path = content_shell_path.DirName(); + content_shell_path = content_shell_path.Append( + FILE_PATH_LITERAL("Content Shell.app/Contents/MacOS/Content Shell")); + CHECK(PathService::Override(base::FILE_EXE, content_shell_path)); +#endif } ContentBrowserTest::~ContentBrowserTest() { } void ContentBrowserTest::SetUp() { - DCHECK(!content::GetContentClient()); shell_main_delegate_.reset(new ShellMainDelegate); shell_main_delegate_->PreSandboxStartup(); +#if defined(OS_MACOSX) + // See InProcessBrowserTest::PrepareTestCommandLine(). + CommandLine* command_line = CommandLine::ForCurrentProcess(); + FilePath subprocess_path; + PathService::Get(base::FILE_EXE, &subprocess_path); + subprocess_path = subprocess_path.DirName().DirName(); + DCHECK_EQ(subprocess_path.BaseName().value(), "Contents"); + subprocess_path = subprocess_path.Append( + "Frameworks/Content Shell Helper.app/Contents/MacOS/Content Shell Helper"); + command_line->AppendSwitchPath(switches::kBrowserSubprocessPath, + subprocess_path); +#endif + BrowserTestBase::SetUp(); } @@ -45,6 +71,9 @@ static void DumpStackTraceSignalHandler(int signal) { #endif // defined(OS_POSIX) void ContentBrowserTest::RunTestOnMainThreadLoop() { + CHECK_EQ(content::Shell::windows().size(), 1u); + shell_ = content::Shell::windows()[0]; + #if defined(OS_POSIX) signal(SIGTERM, DumpStackTraceSignalHandler); #endif // defined(OS_POSIX) @@ -71,9 +100,4 @@ void ContentBrowserTest::RunTestOnMainThreadLoop() { #if defined(OS_MACOSX) pool.Recycle(); #endif - - MessageLoopForUI::current()->Quit(); -#if defined(OS_MACOSX) - pool.Recycle(); -#endif } diff --git a/content/test/content_browser_test.h b/content/test/content_browser_test.h index d00077b..44bf42d 100644 --- a/content/test/content_browser_test.h +++ b/content/test/content_browser_test.h @@ -6,10 +6,15 @@ #define CONTENT_TEST_CONTENT_BROWSER_TEST_H_ #include "base/memory/scoped_ptr.h" +#include "content/public/test/browser_test.h" #include "content/test/browser_test_base.h" class ShellMainDelegate; +namespace content { +class Shell; +} + class ContentBrowserTest : public BrowserTestBase { protected: ContentBrowserTest(); @@ -22,8 +27,13 @@ class ContentBrowserTest : public BrowserTestBase { // BrowserTestBase: virtual void RunTestOnMainThreadLoop() OVERRIDE; + // Returns the window for the test. + content::Shell* shell() const { return shell_; } + private: scoped_ptr<ShellMainDelegate> shell_main_delegate_; + + content::Shell* shell_; }; #endif // CONTENT_TEST_CONTENT_BROWSER_TEST_H_ diff --git a/content/test/content_browser_test_test.cc b/content/test/content_browser_test_test.cc new file mode 100644 index 0000000..552a03c --- /dev/null +++ b/content/test/content_browser_test_test.cc @@ -0,0 +1,19 @@ +// 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 "content/test/content_browser_test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace content { + +IN_PROC_BROWSER_TEST_F(ContentBrowserTest, Basic) { + GURL url = GetTestUrl(("."), "simple_page.html"); + NavigateToURL(shell(), url); + + // TODO(jam): move TitleWatcher in a followup change to check title. +} + +} // namespace content diff --git a/content/test/content_browser_test_utils.cc b/content/test/content_browser_test_utils.cc new file mode 100644 index 0000000..0794328 --- /dev/null +++ b/content/test/content_browser_test_utils.cc @@ -0,0 +1,48 @@ +// Copyright (c) 2012 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_utils.h" + +#include "base/bind.h" +#include "base/file_path.h" +#include "base/path_service.h" +#include "base/run_loop.h" +#include "content/public/browser/navigation_controller.h" +#include "content/public/browser/notification_source.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/content_paths.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/test_navigation_observer.h" +#include "content/shell/shell.h" +#include "net/base/net_util.h" + +namespace content { + +FilePath GetTestFilePath(const char* dir, const char* file) { + FilePath path; + PathService::Get(DIR_TEST_DATA, &path); + return path.Append( + FilePath().AppendASCII(dir).Append(FilePath().AppendASCII(file))); +} + +GURL GetTestUrl(const char* dir, const char* file) { + return net::FilePathToFileURL(GetTestFilePath(dir, file)); +} + +void NavigateToURL(Shell* window, const GURL& url) { + NavigationController* controller = &window->web_contents()->GetController(); + TestNavigationObserver same_tab_observer( + Source<NavigationController>(controller), + NULL, + 1); + + window->LoadURL(url); + + base::RunLoop run_loop; + same_tab_observer.WaitForObservation( + base::Bind(&RunThisRunLoop, base::Unretained(&run_loop)), + GetQuitTaskForRunLoop(&run_loop)); +} + +} // namespace content diff --git a/content/test/content_browser_test_utils.h b/content/test/content_browser_test_utils.h new file mode 100644 index 0000000..5957d11 --- /dev/null +++ b/content/test/content_browser_test_utils.h @@ -0,0 +1,38 @@ +// Copyright (c) 2012 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_UTILS_H_ +#define CONTENT_TEST_CONTENT_BROWSER_TEST_UTILS_H_ + +#include "googleurl/src/gurl.h" + +class FilePath; + +// A collections of functions designed for use with content_browsertests. +// Note: if a function here also works with browser_tests, it should be in +// content\public\test\browser_test_utils.h + +namespace content { + +class Shell; + +// Generate the file path for testing a particular test. +// The file for the tests is all located in +// content/test/data/dir/<file> +// The returned path is FilePath format. +FilePath GetTestFilePath(const char* dir, const char* file); + +// Generate the URL for testing a particular test. +// HTML for the tests is all located in +// test_root_directory/dir/<file> +// The returned path is GURL format. +GURL GetTestUrl(const char* dir, const char* file); + +// Navigates the selected tab of |window| to |url|, blocking until the +// navigation finishes. +void NavigateToURL(Shell* window, const GURL& url); + +} // namespace content + +#endif // CONTENT_TEST_CONTENT_BROWSER_TEST_UTILS_H_ diff --git a/content/test/content_test_launcher.cc b/content/test/content_test_launcher.cc index 2194cde..58f8e04 100644 --- a/content/test/content_test_launcher.cc +++ b/content/test/content_test_launcher.cc @@ -12,13 +12,81 @@ #include "base/test/test_suite.h" #include "content/public/app/content_main.h" #include "content/public/common/content_switches.h" +#include "content/public/test/content_test_suite_base.h" +#include "content/shell/shell_content_browser_client.h" +#include "content/shell/shell_content_client.h" #include "content/shell/shell_main_delegate.h" +#include "testing/gtest/include/gtest/gtest.h" #if defined(OS_WIN) #include "content/public/app/startup_helper_win.h" #include "sandbox/win/src/sandbox_types.h" +#include "ui/base/win/scoped_ole_initializer.h" #endif // defined(OS_WIN) +namespace content { + +class ContentShellTestSuiteInitializer + : public testing::EmptyTestEventListener { + public: + ContentShellTestSuiteInitializer() { + } + + virtual void OnTestStart(const testing::TestInfo& test_info) OVERRIDE { + DCHECK(!GetContentClient()); + content_client_.reset(new ShellContentClient); + browser_content_client_.reset(new ShellContentBrowserClient()); + content_client_->set_browser_for_testing(browser_content_client_.get()); + SetContentClient(content_client_.get()); + } + + virtual void OnTestEnd(const testing::TestInfo& test_info) OVERRIDE { + DCHECK_EQ(content_client_.get(), GetContentClient()); + browser_content_client_.reset(); + content_client_.reset(); + SetContentClient(NULL); + } + + private: + scoped_ptr<ShellContentClient> content_client_; + scoped_ptr<ShellContentBrowserClient> browser_content_client_; + + DISALLOW_COPY_AND_ASSIGN(ContentShellTestSuiteInitializer); +}; + +class ContentBrowserTestSuite : public ContentTestSuiteBase { + public: + ContentBrowserTestSuite(int argc, char** argv) + : ContentTestSuiteBase(argc, argv) { + } + virtual ~ContentBrowserTestSuite() { + } + + protected: + virtual void Initialize() OVERRIDE { + ContentTestSuiteBase::Initialize(); + + testing::TestEventListeners& listeners = + testing::UnitTest::GetInstance()->listeners(); + listeners.Append(new ContentShellTestSuiteInitializer); + } + virtual void Shutdown() OVERRIDE { + base::TestSuite::Shutdown(); + } + + virtual ContentClient* CreateClientForInitialization() OVERRIDE { + return new ShellContentClient(); + } + +#if defined(OS_WIN) + ui::ScopedOleInitializer ole_initializer_; +#endif + + DISALLOW_COPY_AND_ASSIGN(ContentBrowserTestSuite); +}; + +} // namespace content + class ContentTestLauncherDelegate : public test_launcher::TestLauncherDelegate { public: ContentTestLauncherDelegate() { @@ -31,31 +99,33 @@ class ContentTestLauncherDelegate : public test_launcher::TestLauncherDelegate { } virtual bool Run(int argc, char** argv, int* return_code) OVERRIDE { -#if defined(OS_WIN) +#if defined(OS_WIN) || defined(OS_LINUX) CommandLine* command_line = CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(switches::kProcessType)) { + ShellMainDelegate delegate; +#if defined(OS_WIN) sandbox::SandboxInterfaceInfo sandbox_info = {0}; content::InitializeSandboxInfo(&sandbox_info); - ShellMainDelegate delegate; *return_code = content::ContentMain(GetModuleHandle(NULL), &sandbox_info, &delegate); +#elif defined(OS_LINUX) + *return_code = content::ContentMain(argc, + const_cast<const char**>(argv), + &delegate); +#endif // defined(OS_WIN) return true; } -#endif // defined(OS_WIN) +#endif // defined(OS_WIN) || defined(OS_LINUX) return false; } virtual int RunTestSuite(int argc, char** argv) OVERRIDE { - return base::TestSuite(argc, argv).Run(); + return content::ContentBrowserTestSuite(argc, argv).Run(); } virtual bool AdjustChildProcessCommandLine( CommandLine* command_line) OVERRIDE { - FilePath file_exe; - if (!PathService::Get(base::FILE_EXE, &file_exe)) - return false; - command_line->AppendSwitchPath(switches::kBrowserSubprocessPath, file_exe); return true; } diff --git a/content/test/data/simple_page.html b/content/test/data/simple_page.html new file mode 100644 index 0000000..7283ba2 --- /dev/null +++ b/content/test/data/simple_page.html @@ -0,0 +1,6 @@ +<html> +<head><title>Simple Page</title></head> +<body> +Basic html test. +</body> +</html> diff --git a/content/test/test_launcher.cc b/content/test/test_launcher.cc index e8e347b..47ce759 100644 --- a/content/test/test_launcher.cc +++ b/content/test/test_launcher.cc @@ -41,6 +41,10 @@ namespace test_launcher { +namespace { +TestLauncherDelegate* g_launcher_delegate; +} + // The environment variable name for the total number of test shards. const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; // The environment variable name for the test shard index. @@ -573,6 +577,8 @@ TestLauncherDelegate::~TestLauncherDelegate() { int LaunchTests(TestLauncherDelegate* launcher_delegate, int argc, char** argv) { + DCHECK(!g_launcher_delegate); + g_launcher_delegate = launcher_delegate; launcher_delegate->EarlyInitialize(); CommandLine::Init(argc, argv); @@ -664,4 +670,8 @@ int LaunchTests(TestLauncherDelegate* launcher_delegate, return exit_code; } +TestLauncherDelegate* GetCurrentTestLauncherDelegate() { + return g_launcher_delegate; +} + } // namespace test_launcher diff --git a/content/test/test_navigation_observer.cc b/content/test/test_navigation_observer.cc index 2342c63..3cdd359 100644 --- a/content/test/test_navigation_observer.cc +++ b/content/test/test_navigation_observer.cc @@ -10,26 +10,12 @@ #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/render_view_host_observer.h" +#include "content/public/test/browser_test_utils.h" #include "content/public/test/js_injection_ready_observer.h" #include "testing/gtest/include/gtest/gtest.h" namespace content { -namespace { - -// Allow some pending tasks up to |num_deferrals| generations to complete. -void DeferredQuitRunLoop(const base::Closure& quit_task, - int num_quit_deferrals) { - if (num_quit_deferrals <= 0) { - quit_task.Run(); - } else { - MessageLoop::current()->PostTask(FROM_HERE, - base::Bind(&DeferredQuitRunLoop, quit_task, num_quit_deferrals - 1)); - } -} - -} // namespace - // This class observes |render_view_host| and calls OnJsInjectionReady() of // |js_injection_ready_observer| when the time is right to inject JavaScript // into the page. @@ -101,13 +87,9 @@ void TestNavigationObserver::WaitForObservation( void TestNavigationObserver::Wait() { base::RunLoop run_loop; - // Number of times to repost Quit task to allow pending tasks to complete. See - // kNumQuitDeferrals in ui_test_utils.cc for explanation. - const int num_quit_deferrals = 10; WaitForObservation( base::Bind(&base::RunLoop::Run, base::Unretained(&run_loop)), - base::Bind(&DeferredQuitRunLoop, run_loop.QuitClosure(), - num_quit_deferrals)); + content::GetQuitTaskForRunLoop(&run_loop)); } TestNavigationObserver::TestNavigationObserver( |