blob: e698e27dde9dd12b96dfeb538f29940699786546 [file] [log] [blame]
[email protected]d4515eb2009-01-30 00:40:431// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/test/in_process_browser_test.h"
6
7#include "base/command_line.h"
[email protected]d8412052009-04-21 22:01:018#include "base/file_path.h"
[email protected]d4515eb2009-01-30 00:40:439#include "base/file_util.h"
10#include "base/path_service.h"
11#include "chrome/browser/browser.h"
[email protected]b6e38ef2009-06-16 00:43:2312#include "chrome/browser/browser_list.h"
[email protected]d4515eb2009-01-30 00:40:4313#include "chrome/browser/browser_process.h"
14#include "chrome/browser/browser_shutdown.h"
[email protected]108c2a12009-06-05 22:18:0915#include "chrome/browser/browser_window.h"
[email protected]d4515eb2009-01-30 00:40:4316#include "chrome/browser/profile.h"
17#include "chrome/browser/profile_manager.h"
[email protected]8bcdec92009-02-25 16:15:1818#include "chrome/browser/renderer_host/render_process_host.h"
[email protected]5c238752009-06-13 10:29:0719#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]108c2a12009-06-05 22:18:0920#if defined(OS_WIN)
[email protected]d4515eb2009-01-30 00:40:4321#include "chrome/browser/views/frame/browser_view.h"
[email protected]108c2a12009-06-05 22:18:0922#endif
[email protected]d4515eb2009-01-30 00:40:4323#include "chrome/common/chrome_constants.h"
24#include "chrome/common/chrome_paths.h"
25#include "chrome/common/chrome_switches.h"
26#include "chrome/common/main_function_params.h"
27#include "chrome/test/testing_browser_process.h"
28#include "chrome/test/ui_test_utils.h"
[email protected]13324ed2009-04-03 05:14:1929#include "net/base/host_resolver_unittest.h"
[email protected]d4515eb2009-01-30 00:40:4330#include "sandbox/src/dep.h"
31
32extern int BrowserMain(const MainFunctionParams&);
33
34const wchar_t kUnitTestShowWindows[] = L"show-windows";
35
[email protected]b5f95102009-07-01 19:53:5936// Delay for the time-out at which we stop the inner-message loop the first
37// time.
38const int kInitialTimeoutInMS = 30000;
39
40// Delay for sub-sequent time-outs once the initial time-out happened.
41const int kSubsequentTimeoutInMS = 5000;
42
[email protected]d4515eb2009-01-30 00:40:4343namespace {
44
45bool DieFileDie(const std::wstring& file, bool recurse) {
46 if (!file_util::PathExists(file))
47 return true;
48
49 // Sometimes Delete fails, so try a few more times.
50 for (int i = 0; i < 10; ++i) {
51 if (file_util::Delete(file, recurse))
52 return true;
53 PlatformThread::Sleep(100);
54 }
55 return false;
56}
57
58} // namespace
59
[email protected]8bcdec92009-02-25 16:15:1860InProcessBrowserTest::InProcessBrowserTest()
61 : browser_(NULL),
62 show_window_(false),
[email protected]56cdae32009-03-12 19:58:2063 dom_automation_enabled_(false),
64 single_process_(false),
65 original_single_process_(false) {
[email protected]d4515eb2009-01-30 00:40:4366}
67
68void InProcessBrowserTest::SetUp() {
69 // Cleanup the user data dir.
70 std::wstring user_data_dir;
71 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
72 ASSERT_LT(10, static_cast<int>(user_data_dir.size())) <<
73 "The user data directory name passed into this test was too "
74 "short to delete safely. Please check the user-data-dir "
75 "argument and try again.";
76 ASSERT_TRUE(DieFileDie(user_data_dir, true));
77
78 // The unit test suite creates a testingbrowser, but we want the real thing.
79 // Delete the current one. We'll install the testing one in TearDown.
80 delete g_browser_process;
81
82 // Don't delete the resources when BrowserMain returns. Many ui classes
83 // cache SkBitmaps in a static field so that if we delete the resource
84 // bundle we'll crash.
85 browser_shutdown::delete_resources_on_shutdown = false;
86
87 CommandLine* command_line = CommandLine::ForCurrentProcessMutable();
[email protected]56cdae32009-03-12 19:58:2088 original_command_line_.reset(new CommandLine(*command_line));
[email protected]d4515eb2009-01-30 00:40:4389
[email protected]9665fa62009-04-13 22:15:2990 SetUpCommandLine(command_line);
91
[email protected]108c2a12009-06-05 22:18:0992#if defined(OS_WIN)
[email protected]d4515eb2009-01-30 00:40:4393 // Hide windows on show.
[email protected]8bcdec92009-02-25 16:15:1894 if (!command_line->HasSwitch(kUnitTestShowWindows) && !show_window_)
[email protected]d4515eb2009-01-30 00:40:4395 BrowserView::SetShowState(SW_HIDE);
[email protected]108c2a12009-06-05 22:18:0996#endif
[email protected]d4515eb2009-01-30 00:40:4397
[email protected]8bcdec92009-02-25 16:15:1898 if (dom_automation_enabled_)
99 command_line->AppendSwitch(switches::kDomAutomationController);
100
[email protected]56cdae32009-03-12 19:58:20101 if (single_process_)
102 command_line->AppendSwitch(switches::kSingleProcess);
103
[email protected]d4515eb2009-01-30 00:40:43104 command_line->AppendSwitchWithValue(switches::kUserDataDir, user_data_dir);
105
106 // For some reason the sandbox wasn't happy running in test mode. These
107 // tests aren't intended to test the sandbox, so we turn it off.
108 command_line->AppendSwitch(switches::kNoSandbox);
109
[email protected]8bcdec92009-02-25 16:15:18110 // Single-process mode is not set in BrowserMain so it needs to be processed
111 // explicitlty.
[email protected]56cdae32009-03-12 19:58:20112 original_single_process_ = RenderProcessHost::run_renderer_in_process();
[email protected]8bcdec92009-02-25 16:15:18113 if (command_line->HasSwitch(switches::kSingleProcess))
114 RenderProcessHost::set_run_renderer_in_process(true);
115
[email protected]7f74a4e2009-04-30 17:00:24116 // Explicitly set the path of the exe used for the renderer and plugin,
117 // otherwise they'll try to use unit_test.exe.
118 std::wstring subprocess_path;
119 PathService::Get(base::FILE_EXE, &subprocess_path);
120 FilePath fp_subprocess_path = FilePath::FromWStringHack(subprocess_path);
121 subprocess_path = fp_subprocess_path.DirName().ToWStringHack();
122 file_util::AppendToPath(&subprocess_path,
[email protected]075a7252009-04-23 18:07:51123 chrome::kBrowserProcessExecutablePath);
[email protected]7f74a4e2009-04-30 17:00:24124 command_line->AppendSwitchWithValue(switches::kBrowserSubprocessPath,
125 subprocess_path);
[email protected]d4515eb2009-01-30 00:40:43126
[email protected]d4515eb2009-01-30 00:40:43127 SandboxInitWrapper sandbox_wrapper;
[email protected]7c321082009-02-09 15:35:47128 MainFunctionParams params(*command_line, sandbox_wrapper, NULL);
[email protected]d4515eb2009-01-30 00:40:43129 params.ui_task =
130 NewRunnableMethod(this, &InProcessBrowserTest::RunTestOnMainThreadLoop);
[email protected]13324ed2009-04-03 05:14:19131
[email protected]13324ed2009-04-03 05:14:19132 scoped_refptr<net::RuleBasedHostMapper> host_mapper(
133 new net::RuleBasedHostMapper());
[email protected]deb27ae2009-04-10 02:37:22134 ConfigureHostMapper(host_mapper.get());
[email protected]7844fc52009-04-07 08:58:48135 net::ScopedHostMapper scoped_host_mapper(host_mapper.get());
[email protected]d4515eb2009-01-30 00:40:43136 BrowserMain(params);
137}
138
139void InProcessBrowserTest::TearDown() {
140 // Reinstall testing browser process.
141 delete g_browser_process;
142 g_browser_process = new TestingBrowserProcess();
143
144 browser_shutdown::delete_resources_on_shutdown = true;
145
[email protected]108c2a12009-06-05 22:18:09146#if defined(WIN)
[email protected]d4515eb2009-01-30 00:40:43147 BrowserView::SetShowState(-1);
[email protected]108c2a12009-06-05 22:18:09148#endif
[email protected]56cdae32009-03-12 19:58:20149
150 *CommandLine::ForCurrentProcessMutable() = *original_command_line_;
151 RenderProcessHost::set_run_renderer_in_process(original_single_process_);
[email protected]d4515eb2009-01-30 00:40:43152}
153
[email protected]d4515eb2009-01-30 00:40:43154HTTPTestServer* InProcessBrowserTest::StartHTTPServer() {
155 // The HTTPServer must run on the IO thread.
156 DCHECK(!http_server_.get());
157 http_server_ = HTTPTestServer::CreateServer(
158 L"chrome/test/data",
159 g_browser_process->io_thread()->message_loop());
160 return http_server_.get();
161}
162
163// Creates a browser with a single tab (about:blank), waits for the tab to
164// finish loading and shows the browser.
165Browser* InProcessBrowserTest::CreateBrowser(Profile* profile) {
166 Browser* browser = Browser::Create(profile);
167
168 browser->AddTabWithURL(
[email protected]5a4940be2009-05-06 06:44:39169 GURL("about:blank"), GURL(), PageTransition::START_PAGE, true, -1, false,
170 NULL);
[email protected]f0a51fb52009-03-05 12:46:38171
[email protected]d4515eb2009-01-30 00:40:43172 // Wait for the page to finish loading.
173 ui_test_utils::WaitForNavigation(
[email protected]ce3fa3c2009-04-20 19:55:57174 &browser->GetSelectedTabContents()->controller());
[email protected]d4515eb2009-01-30 00:40:43175
176 browser->window()->Show();
177
178 return browser;
179}
180
181void InProcessBrowserTest::RunTestOnMainThreadLoop() {
182 // In the long term it would be great if we could use a TestingProfile
183 // here and only enable services you want tested, but that requires all
184 // consumers of Profile to handle NULL services.
185 FilePath user_data_dir;
186 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
187 ProfileManager* profile_manager = g_browser_process->profile_manager();
188 Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
189 if (!profile) {
190 // We should only be able to get here if the profile already exists and
191 // has been created.
192 NOTREACHED();
193 MessageLoopForUI::current()->Quit();
194 return;
195 }
196
[email protected]eca6a4f2009-06-25 17:29:09197
198 // Before we run the browser, we have to hack the path to the exe to match
199 // what it would be if Chrome was running, because it is used to fork renderer
200 // processes, on Linux at least (failure to do so will cause a browser_test to
201 // be run instead of a renderer).
202 FilePath chrome_path;
203 CHECK(PathService::Get(base::FILE_EXE, &chrome_path));
204 chrome_path = chrome_path.DirName();
205#if defined(OS_WIN)
206 chrome_path = chrome_path.Append(chrome::kBrowserProcessExecutablePath);
207#elif defined(OS_POSIX)
208 chrome_path = chrome_path.Append(
209 WideToASCII(chrome::kBrowserProcessExecutablePath));
210#endif
211 CHECK(PathService::Override(base::FILE_EXE, chrome_path));
212
[email protected]d4515eb2009-01-30 00:40:43213 browser_ = CreateBrowser(profile);
214
[email protected]b5f95102009-07-01 19:53:59215 // Start the timeout timer to prevent hangs.
216 MessageLoopForUI::current()->PostDelayedTask(FROM_HERE,
217 NewRunnableMethod(this, &InProcessBrowserTest::TimedOut),
218 kInitialTimeoutInMS);
219
[email protected]d4515eb2009-01-30 00:40:43220 RunTestOnMainThread();
221
[email protected]e6152c22009-06-23 23:33:27222 BrowserList::const_iterator browser = BrowserList::begin();
223 for (; browser != BrowserList::end(); ++browser)
[email protected]b6e38ef2009-06-16 00:43:23224 (*browser)->CloseAllTabs();
[email protected]d4515eb2009-01-30 00:40:43225
226 // Stop the HTTP server.
227 http_server_ = NULL;
228
229 MessageLoopForUI::current()->Quit();
230}
[email protected]deb27ae2009-04-10 02:37:22231
232void InProcessBrowserTest::ConfigureHostMapper(
233 net::RuleBasedHostMapper* host_mapper) {
234 host_mapper->AllowDirectLookup("*.google.com");
235 // See http://en.wikipedia.org/wiki/Web_Proxy_Autodiscovery_Protocol
236 // We don't want the test code to use it.
237 host_mapper->AddSimulatedFailure("wpad");
238}
[email protected]b5f95102009-07-01 19:53:59239
240void InProcessBrowserTest::TimedOut() {
241 DCHECK(MessageLoopForUI::current()->IsNested());
242
243 GTEST_NONFATAL_FAILURE_("Timed-out");
244
245 // Start the timeout timer to prevent hangs.
246 MessageLoopForUI::current()->PostDelayedTask(FROM_HERE,
247 NewRunnableMethod(this, &InProcessBrowserTest::TimedOut),
248 kSubsequentTimeoutInMS);
249
250 MessageLoopForUI::current()->Quit();
251}