From 3c2a17334b2d458a614af4727b88087379412d96 Mon Sep 17 00:00:00 2001 From: gunsch Date: Thu, 11 Sep 2014 19:04:53 -0700 Subject: [PATCH] Chromecast: end-to-end browser test based on content::BrowserTest. R=lcwu@chromium.org,byungchul@chromium.org,phajdan.jr@chromium.org BUG=409163 Review URL: https://codereview.chromium.org/518773003 Cr-Commit-Position: refs/heads/master@{#294523} --- chromecast/chromecast.gyp | 52 ++++++++++++-- .../net/network_change_notifier_factory_cast.cc | 16 +---- chromecast/shell/browser/cast_browser_context.cc | 4 ++ .../shell/browser/cast_browser_main_parts.cc | 9 ++- chromecast/shell/browser/cast_browser_main_parts.h | 7 +- .../shell/browser/cast_content_browser_client.cc | 5 ++ chromecast/shell/browser/test/DEPS | 3 + chromecast/shell/browser/test/OWNERS | 4 ++ .../shell/browser/test/chromecast_browser_test.cc | 79 ++++++++++++++++++++++ .../shell/browser/test/chromecast_browser_test.h | 56 +++++++++++++++ .../browser/test/chromecast_browser_test_runner.cc | 68 +++++++++++++++++++ .../browser/test/chromecast_shell_browser_test.cc | 36 ++++++++++ 12 files changed, 313 insertions(+), 26 deletions(-) create mode 100644 chromecast/shell/browser/test/DEPS create mode 100644 chromecast/shell/browser/test/OWNERS create mode 100644 chromecast/shell/browser/test/chromecast_browser_test.cc create mode 100644 chromecast/shell/browser/test/chromecast_browser_test.h create mode 100644 chromecast/shell/browser/test/chromecast_browser_test_runner.cc create mode 100644 chromecast/shell/browser/test/chromecast_shell_browser_test.cc diff --git a/chromecast/chromecast.gyp b/chromecast/chromecast.gyp index ee3520358bf3..644273e5dc45 100644 --- a/chromecast/chromecast.gyp +++ b/chromecast/chromecast.gyp @@ -394,19 +394,18 @@ ], # end of targets }, { # OS != "android" 'targets': [ - # This target includes all dependencies that cannot be built on Android. + # This target contains all of the primary code of |cast_shell|, except + # for |main|. This allows end-to-end tests using |cast_shell|. + # This also includes all targets that cannot be built on Android. { - 'target_name': 'cast_shell', - 'type': 'executable', + 'target_name': 'cast_shell_core', + 'type': '<(component)', 'dependencies': [ 'cast_net', 'cast_shell_common', 'media/media.gyp:cast_media', '../ui/aura/aura.gyp:aura_test_support', ], - 'sources': [ - 'shell/app/cast_main.cc', - ], 'conditions': [ ['chromecast_branding=="Chrome"', { 'dependencies': [ @@ -419,6 +418,47 @@ }], ], }, + { + 'target_name': 'cast_shell', + 'type': 'executable', + 'dependencies': [ + 'cast_shell_core', + ], + 'sources': [ + 'shell/app/cast_main.cc', + ], + }, + { + 'target_name': 'cast_shell_browser_test', + 'type': '<(gtest_target_type)', + 'dependencies': [ + 'cast_shell_test_support', + '../testing/gtest.gyp:gtest', + ], + 'defines': [ + 'HAS_OUT_OF_PROC_TEST_RUNNER', + ], + 'sources': [ + 'shell/browser/test/chromecast_shell_browser_test.cc', + ], + }, + { + 'target_name': 'cast_shell_test_support', + 'type': '<(component)', + 'defines': [ + 'HAS_OUT_OF_PROC_TEST_RUNNER', + ], + 'dependencies': [ + 'cast_shell_core', + '../content/content_shell_and_tests.gyp:content_browser_test_support', + '../testing/gtest.gyp:gtest', + ], + 'sources': [ + 'shell/browser/test/chromecast_browser_test.cc', + 'shell/browser/test/chromecast_browser_test.h', + 'shell/browser/test/chromecast_browser_test_runner.cc', + ], + }, ], # end of targets }], ], # end of conditions diff --git a/chromecast/net/network_change_notifier_factory_cast.cc b/chromecast/net/network_change_notifier_factory_cast.cc index 1c41171119f4..c446b1e5768d 100644 --- a/chromecast/net/network_change_notifier_factory_cast.cc +++ b/chromecast/net/network_change_notifier_factory_cast.cc @@ -4,28 +4,16 @@ #include "chromecast/net/network_change_notifier_factory_cast.h" -#include "base/lazy_instance.h" #include "chromecast/net/network_change_notifier_cast.h" namespace chromecast { -namespace { - -base::LazyInstance g_network_change_notifier_cast = - LAZY_INSTANCE_INITIALIZER; - -} // namespace - net::NetworkChangeNotifier* NetworkChangeNotifierFactoryCast::CreateInstance() { - return g_network_change_notifier_cast.Pointer(); + // Caller assumes ownership. + return new NetworkChangeNotifierCast(); } NetworkChangeNotifierFactoryCast::~NetworkChangeNotifierFactoryCast() { } -// static -NetworkChangeNotifierCast* NetworkChangeNotifierFactoryCast::GetInstance() { - return g_network_change_notifier_cast.Pointer(); -} - } // namespace chromecast diff --git a/chromecast/shell/browser/cast_browser_context.cc b/chromecast/shell/browser/cast_browser_context.cc index f1a5c201ba28..b9fa05e0e64f 100644 --- a/chromecast/shell/browser/cast_browser_context.cc +++ b/chromecast/shell/browser/cast_browser_context.cc @@ -52,6 +52,10 @@ CastBrowserContext::CastBrowserContext( } CastBrowserContext::~CastBrowserContext() { + content::BrowserThread::DeleteSoon( + content::BrowserThread::IO, + FROM_HERE, + resource_context_.release()); } void CastBrowserContext::InitWhileIOAllowed() { diff --git a/chromecast/shell/browser/cast_browser_main_parts.cc b/chromecast/shell/browser/cast_browser_main_parts.cc index 24e134277b47..c7f19028f08f 100644 --- a/chromecast/shell/browser/cast_browser_main_parts.cc +++ b/chromecast/shell/browser/cast_browser_main_parts.cc @@ -56,6 +56,7 @@ CastBrowserMainParts::CastBrowserMainParts( URLRequestContextFactory* url_request_context_factory) : BrowserMainParts(), cast_browser_process_(new CastBrowserProcess()), + parameters_(parameters), url_request_context_factory_(url_request_context_factory) { CommandLine* command_line = CommandLine::ForCurrentProcess(); AddDefaultCommandLineSwitches(command_line); @@ -104,7 +105,13 @@ void CastBrowserMainParts::PreMainMessageLoopRun() { } bool CastBrowserMainParts::MainMessageLoopRun(int* result_code) { - base::MessageLoopForUI::current()->Run(); + // If parameters_.ui_task is not NULL, we are running browser tests. In this + // case, the browser's main message loop will not run. + if (parameters_.ui_task) { + parameters_.ui_task->Run(); + } else { + base::MessageLoopForUI::current()->Run(); + } return true; } diff --git a/chromecast/shell/browser/cast_browser_main_parts.h b/chromecast/shell/browser/cast_browser_main_parts.h index e620eb24ac93..8e2671a8ae43 100644 --- a/chromecast/shell/browser/cast_browser_main_parts.h +++ b/chromecast/shell/browser/cast_browser_main_parts.h @@ -9,10 +9,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "content/public/browser/browser_main_parts.h" - -namespace content { -struct MainFunctionParams; -} +#include "content/public/common/main_function_params.h" namespace chromecast { namespace shell { @@ -36,7 +33,7 @@ class CastBrowserMainParts : public content::BrowserMainParts { private: scoped_ptr cast_browser_process_; - + const content::MainFunctionParams parameters_; // For running browser tests. URLRequestContextFactory* const url_request_context_factory_; DISALLOW_COPY_AND_ASSIGN(CastBrowserMainParts); diff --git a/chromecast/shell/browser/cast_content_browser_client.cc b/chromecast/shell/browser/cast_content_browser_client.cc index 919b19007df0..af3993b3b27e 100644 --- a/chromecast/shell/browser/cast_content_browser_client.cc +++ b/chromecast/shell/browser/cast_content_browser_client.cc @@ -14,6 +14,7 @@ #include "chromecast/shell/browser/cast_browser_process.h" #include "chromecast/shell/browser/geolocation/cast_access_token_store.h" #include "chromecast/shell/browser/url_request_context_factory.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/certificate_request_result_type.h" #include "content/public/browser/file_descriptor_info.h" #include "content/public/browser/render_process_host.h" @@ -30,6 +31,10 @@ CastContentBrowserClient::CastContentBrowserClient() } CastContentBrowserClient::~CastContentBrowserClient() { + content::BrowserThread::DeleteSoon( + content::BrowserThread::IO, + FROM_HERE, + url_request_context_factory_.release()); } content::BrowserMainParts* CastContentBrowserClient::CreateBrowserMainParts( diff --git a/chromecast/shell/browser/test/DEPS b/chromecast/shell/browser/test/DEPS new file mode 100644 index 000000000000..b969a40c3030 --- /dev/null +++ b/chromecast/shell/browser/test/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+content/public/test", +] diff --git a/chromecast/shell/browser/test/OWNERS b/chromecast/shell/browser/test/OWNERS new file mode 100644 index 000000000000..23be33d4fc28 --- /dev/null +++ b/chromecast/shell/browser/test/OWNERS @@ -0,0 +1,4 @@ +# content/public/test OWNERS for review of Chromecast browser test code +jcivelli@chromium.org +phajdan.jr@chromium.org +sky@chromium.org diff --git a/chromecast/shell/browser/test/chromecast_browser_test.cc b/chromecast/shell/browser/test/chromecast_browser_test.cc new file mode 100644 index 000000000000..bb1ab5d47fb8 --- /dev/null +++ b/chromecast/shell/browser/test/chromecast_browser_test.cc @@ -0,0 +1,79 @@ +// Copyright 2014 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 "chromecast/shell/browser/test/chromecast_browser_test.h" + +#include "base/command_line.h" +#include "base/logging.h" +#include "base/message_loop/message_loop.h" +#include "chromecast/shell/browser/cast_browser_context.h" +#include "chromecast/shell/browser/cast_browser_process.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/web_contents.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/test_navigation_observer.h" + +namespace chromecast { +namespace shell { + +ChromecastBrowserTest::ChromecastBrowserTest() + : setup_called_(false) { +} + +ChromecastBrowserTest::~ChromecastBrowserTest() { + CHECK(setup_called_) << "Overridden SetUp() did not call parent " + << "implementation, so test not run."; +} + +void ChromecastBrowserTest::SetUp() { + SetUpCommandLine(CommandLine::ForCurrentProcess()); + setup_called_ = true; + BrowserTestBase::SetUp(); +} + +void ChromecastBrowserTest::RunTestOnMainThreadLoop() { + // Pump startup related events. + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + base::RunLoop().RunUntilIdle(); + + SetUpOnMainThread(); + + RunTestOnMainThread(); + + TearDownOnMainThread(); + + for (content::RenderProcessHost::iterator i( + content::RenderProcessHost::AllHostsIterator()); + !i.IsAtEnd(); i.Advance()) { + i.GetCurrentValue()->FastShutdownIfPossible(); + } + + web_contents_.reset(); +} + +void ChromecastBrowserTest::NavigateToURL(content::WebContents* window, + const GURL& url) { + content::WaitForLoadStop(window); + content::TestNavigationObserver same_tab_observer(window, 1); + content::NavigationController::LoadURLParams params(url); + params.transition_type = content::PageTransitionFromInt( + content::PAGE_TRANSITION_TYPED | + content::PAGE_TRANSITION_FROM_ADDRESS_BAR); + window->GetController().LoadURLWithParams(params); + same_tab_observer.Wait(); +} + +content::WebContents* ChromecastBrowserTest::CreateBrowser() { + content::WebContents::CreateParams create_params( + CastBrowserProcess::GetInstance()->browser_context(), + NULL); + create_params.routing_id = MSG_ROUTING_NONE; + create_params.initial_size = gfx::Size(1280, 720); + web_contents_.reset(content::WebContents::Create(create_params)); + return web_contents_.get(); +} + +} // namespace shell +} // namespace chromecast diff --git a/chromecast/shell/browser/test/chromecast_browser_test.h b/chromecast/shell/browser/test/chromecast_browser_test.h new file mode 100644 index 000000000000..da031e790150 --- /dev/null +++ b/chromecast/shell/browser/test/chromecast_browser_test.h @@ -0,0 +1,56 @@ +// Copyright 2014 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 CHROMECAST_SHELL_BROWSER_TEST_CHROMECAST_BROWSER_TEST_H_ +#define CHROMECAST_SHELL_BROWSER_TEST_CHROMECAST_BROWSER_TEST_H_ + +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_base.h" + +namespace content { +class WebContents; +} + +namespace chromecast { +namespace shell { + +// This test allows for running an entire browser-process lifecycle per unit +// test, using Chromecast's cast_shell. This starts up the shell, runs a test +// case, then shuts down the entire shell. +// Note that this process takes 7-10 seconds per test case on Chromecast, so +// fewer test cases with more assertions are preferable. +class ChromecastBrowserTest : public content::BrowserTestBase { + protected: + ChromecastBrowserTest(); + virtual ~ChromecastBrowserTest(); + + // testing::Test implementation: + virtual void SetUp() OVERRIDE; + + // BrowserTestBase implementation: + virtual void RunTestOnMainThreadLoop() OVERRIDE; + + protected: + void NavigateToURL(content::WebContents* window, const GURL& gurl); + + // Creates a new window and loads about:blank. + content::WebContents* CreateBrowser(); + + // Returns the window for the test. + content::WebContents* web_contents() const { return web_contents_.get(); } + + private: + scoped_ptr web_contents_; + + bool setup_called_; + + DISALLOW_COPY_AND_ASSIGN(ChromecastBrowserTest); +}; + +} // namespace shell +} // namespace chromecast + +#endif // CHROMECAST_SHELL_BROWSER_TEST_CHROMECAST_BROWSER_TEST_H_ diff --git a/chromecast/shell/browser/test/chromecast_browser_test_runner.cc b/chromecast/shell/browser/test/chromecast_browser_test_runner.cc new file mode 100644 index 000000000000..baad23450739 --- /dev/null +++ b/chromecast/shell/browser/test/chromecast_browser_test_runner.cc @@ -0,0 +1,68 @@ +// Copyright 2014 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 "base/command_line.h" +#include "base/macros.h" +#include "base/sys_info.h" +#include "chromecast/shell/app/cast_main_delegate.h" +#include "content/public/common/content_switches.h" +#include "content/public/test/content_test_suite_base.h" +#include "content/public/test/test_launcher.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromecast { +namespace shell { + +namespace { + +const char kTestTypeBrowser[] = "browser"; + +class BrowserTestSuite : public content::ContentTestSuiteBase { + public: + BrowserTestSuite(int argc, char** argv) + : content::ContentTestSuiteBase(argc, argv) { + } + virtual ~BrowserTestSuite() { + } + + private: + DISALLOW_COPY_AND_ASSIGN(BrowserTestSuite); +}; + +class ChromecastTestLauncherDelegate : public content::TestLauncherDelegate { + public: + ChromecastTestLauncherDelegate() {} + virtual ~ChromecastTestLauncherDelegate() {} + + virtual int RunTestSuite(int argc, char** argv) OVERRIDE { + return BrowserTestSuite(argc, argv).Run(); + } + + virtual bool AdjustChildProcessCommandLine( + base::CommandLine* command_line, + const base::FilePath& temp_data_dir) OVERRIDE { + // TODO(gunsch): handle temp_data_dir + command_line->AppendSwitchASCII(switches::kTestType, kTestTypeBrowser); + return true; + } + + protected: + virtual content::ContentMainDelegate* CreateContentMainDelegate() OVERRIDE { + return new CastMainDelegate(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(ChromecastTestLauncherDelegate); +}; + +} // namespace + +} // namespace shell +} // namespace chromecast + +int main(int argc, char** argv) { + int default_jobs = std::max(1, base::SysInfo::NumberOfProcessors() / 2); + chromecast::shell::ChromecastTestLauncherDelegate launcher_delegate; + return LaunchTests(&launcher_delegate, default_jobs, argc, argv); +} diff --git a/chromecast/shell/browser/test/chromecast_shell_browser_test.cc b/chromecast/shell/browser/test/chromecast_shell_browser_test.cc new file mode 100644 index 000000000000..3016dcd0c27c --- /dev/null +++ b/chromecast/shell/browser/test/chromecast_shell_browser_test.cc @@ -0,0 +1,36 @@ +// Copyright 2014 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 "base/macros.h" +#include "chromecast/shell/browser/test/chromecast_browser_test.h" +#include "url/gurl.h" +#include "url/url_constants.h" + +namespace chromecast { +namespace shell { + +class ChromecastShellBrowserTest : public ChromecastBrowserTest { + public: + ChromecastShellBrowserTest() : url_(url::kAboutBlankURL) {} + + virtual void SetUpOnMainThread() OVERRIDE { + CreateBrowser(); + NavigateToURL(web_contents(), url_); + } + + private: + const GURL url_; + + DISALLOW_COPY_AND_ASSIGN(ChromecastShellBrowserTest); +}; + +IN_PROC_BROWSER_TEST_F(ChromecastShellBrowserTest, EmptyTest) { + // Run an entire browser lifecycle to ensure nothing breaks. + // TODO(gunsch): Remove this test case once there are actual assertions to + // test in a ChromecastBrowserTest instance. + EXPECT_TRUE(true); +} + +} // namespace shell +} // namespace chromecast -- 2.11.4.GIT