diff options
author | sky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-30 00:40:43 +0000 |
---|---|---|
committer | sky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-30 00:40:43 +0000 |
commit | d4515eb94ad33ac2ab9bfd1094c8e1edd1eefa1b (patch) | |
tree | add4a98df5bcdbb3ca0e1f4471c77f453d52a1f4 /chrome/test/in_process_browser_test.cc | |
parent | 0815731ac884b41853725e51e26b0697449747b4 (diff) | |
download | chromium_src-d4515eb94ad33ac2ab9bfd1094c8e1edd1eefa1b.zip chromium_src-d4515eb94ad33ac2ab9bfd1094c8e1edd1eefa1b.tar.gz chromium_src-d4515eb94ad33ac2ab9bfd1094c8e1edd1eefa1b.tar.bz2 |
Provides the ability to write a unit test that brings up a browser. As
a proof of concept I converted
FindInPageControllerTest.FindInPageFrames over to this.
See the description in InProcessBrowserTest for how it all works.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/19644
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8934 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/test/in_process_browser_test.cc')
-rw-r--r-- | chrome/test/in_process_browser_test.cc | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/chrome/test/in_process_browser_test.cc b/chrome/test/in_process_browser_test.cc new file mode 100644 index 0000000..581ddab --- /dev/null +++ b/chrome/test/in_process_browser_test.cc @@ -0,0 +1,179 @@ +// Copyright (c) 2006-2008 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 "chrome/test/in_process_browser_test.h" + +#include "base/command_line.h" +#include "base/file_util.h" +#include "base/path_service.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/browser_shutdown.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/profile_manager.h" +#include "chrome/browser/views/frame/browser_view.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/main_function_params.h" +#include "chrome/test/testing_browser_process.h" +#include "chrome/test/ui_test_utils.h" +#include "sandbox/src/sandbox_factory.h" +#include "sandbox/src/dep.h" + +extern int BrowserMain(const MainFunctionParams&); + +const wchar_t kUnitTestShowWindows[] = L"show-windows"; + +namespace { + +bool DieFileDie(const std::wstring& file, bool recurse) { + if (!file_util::PathExists(file)) + return true; + + // Sometimes Delete fails, so try a few more times. + for (int i = 0; i < 10; ++i) { + if (file_util::Delete(file, recurse)) + return true; + PlatformThread::Sleep(100); + } + return false; +} + +} // namespace + +InProcessBrowserTest::InProcessBrowserTest() : browser_(NULL) { +} + +void InProcessBrowserTest::SetUp() { + // Cleanup the user data dir. + std::wstring user_data_dir; + PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); + ASSERT_LT(10, static_cast<int>(user_data_dir.size())) << + "The user data directory name passed into this test was too " + "short to delete safely. Please check the user-data-dir " + "argument and try again."; + ASSERT_TRUE(DieFileDie(user_data_dir, true)); + + // The unit test suite creates a testingbrowser, but we want the real thing. + // Delete the current one. We'll install the testing one in TearDown. + delete g_browser_process; + + // Don't delete the resources when BrowserMain returns. Many ui classes + // cache SkBitmaps in a static field so that if we delete the resource + // bundle we'll crash. + browser_shutdown::delete_resources_on_shutdown = false; + + CommandLine* command_line = CommandLine::ForCurrentProcessMutable(); + + // Hide windows on show. + if (!command_line->HasSwitch(kUnitTestShowWindows)) + BrowserView::SetShowState(SW_HIDE); + + command_line->AppendSwitchWithValue(switches::kUserDataDir, user_data_dir); + + // For some reason the sandbox wasn't happy running in test mode. These + // tests aren't intended to test the sandbox, so we turn it off. + command_line->AppendSwitch(switches::kNoSandbox); + + // Explicitly set the path of the exe used for the renderer, otherwise it'll + // try to use unit_test.exe. + std::wstring renderer_path; + PathService::Get(base::FILE_EXE, &renderer_path); + file_util::TrimFilename(&renderer_path); + file_util::AppendToPath(&renderer_path, + chrome::kBrowserProcessExecutableName); + command_line->AppendSwitchWithValue(switches::kRendererPath, renderer_path); + + sandbox::SandboxInterfaceInfo sandbox_info = {0}; + SandboxInitWrapper sandbox_wrapper; + MainFunctionParams params(*command_line, sandbox_wrapper); + params.ui_task = + NewRunnableMethod(this, &InProcessBrowserTest::RunTestOnMainThreadLoop); + BrowserMain(params); +} + +void InProcessBrowserTest::TearDown() { + // Reinstall testing browser process. + delete g_browser_process; + g_browser_process = new TestingBrowserProcess(); + + browser_shutdown::delete_resources_on_shutdown = true; + + BrowserView::SetShowState(-1); +} + +void InProcessBrowserTest::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + if (type == NOTIFY_BROWSER_CLOSED) { + DCHECK(Source<Browser>(source).ptr() == browser_); + browser_ = NULL; + } else { + NOTREACHED(); + } +} + +HTTPTestServer* InProcessBrowserTest::StartHTTPServer() { + // The HTTPServer must run on the IO thread. + DCHECK(!http_server_.get()); + http_server_ = HTTPTestServer::CreateServer( + L"chrome/test/data", + g_browser_process->io_thread()->message_loop()); + return http_server_.get(); +} + +// Creates a browser with a single tab (about:blank), waits for the tab to +// finish loading and shows the browser. +Browser* InProcessBrowserTest::CreateBrowser(Profile* profile) { + Browser* browser = Browser::Create(profile); + + browser->AddTabWithURL( + GURL("about:blank"), GURL(), PageTransition::START_PAGE, true, NULL); + + // Wait for the page to finish loading. + ui_test_utils::WaitForNavigation( + browser->GetSelectedTabContents()->controller()); + + browser->window()->Show(); + + return browser; +} + +void InProcessBrowserTest::RunTestOnMainThreadLoop() { + // In the long term it would be great if we could use a TestingProfile + // here and only enable services you want tested, but that requires all + // consumers of Profile to handle NULL services. + FilePath user_data_dir; + PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); + ProfileManager* profile_manager = g_browser_process->profile_manager(); + Profile* profile = profile_manager->GetDefaultProfile(user_data_dir); + if (!profile) { + // We should only be able to get here if the profile already exists and + // has been created. + NOTREACHED(); + MessageLoopForUI::current()->Quit(); + return; + } + + profile->InitExtensions(); + + browser_ = CreateBrowser(profile); + + registrar_.Add(this, NOTIFY_BROWSER_CLOSED, Source<Browser>(browser_)); + + RunTestOnMainThread(); + + if (browser_) + browser_->CloseAllTabs(); + + // Remove all registered notifications, otherwise by the time the + // destructor is run the NotificationService is dead. + registrar_.RemoveAll(); + + // Stop the HTTP server. + http_server_ = NULL; + + MessageLoopForUI::current()->Quit(); +} |