blob: 3f4ce3909bbfd2d25f8f48ff59ccf1cabba16333 [file] [log] [blame]
[email protected]c4ff4952010-01-08 19:12:471// Copyright (c) 2010 The Chromium Authors. All rights reserved.
[email protected]d4515eb2009-01-30 00:40:432// 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"
[email protected]fb895c62009-10-09 18:20:3011#include "base/test/test_file_util.h"
[email protected]d4515eb2009-01-30 00:40:4312#include "chrome/browser/browser.h"
[email protected]b6e38ef2009-06-16 00:43:2313#include "chrome/browser/browser_list.h"
[email protected]d4515eb2009-01-30 00:40:4314#include "chrome/browser/browser_process.h"
15#include "chrome/browser/browser_shutdown.h"
[email protected]108c2a12009-06-05 22:18:0916#include "chrome/browser/browser_window.h"
[email protected]6fad2632009-11-02 05:59:3717#include "chrome/browser/chrome_thread.h"
[email protected]c4ff4952010-01-08 19:12:4718#include "chrome/browser/intranet_redirect_detector.h"
[email protected]0ac83682010-01-22 17:46:2719#include "chrome/browser/io_thread.h"
[email protected]cec4a272009-07-31 21:55:0320#include "chrome/browser/net/url_request_mock_util.h"
[email protected]d4515eb2009-01-30 00:40:4321#include "chrome/browser/profile.h"
22#include "chrome/browser/profile_manager.h"
[email protected]8bcdec92009-02-25 16:15:1823#include "chrome/browser/renderer_host/render_process_host.h"
[email protected]5c238752009-06-13 10:29:0724#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]108c2a12009-06-05 22:18:0925#if defined(OS_WIN)
[email protected]d4515eb2009-01-30 00:40:4326#include "chrome/browser/views/frame/browser_view.h"
[email protected]108c2a12009-06-05 22:18:0927#endif
[email protected]d4515eb2009-01-30 00:40:4328#include "chrome/common/chrome_constants.h"
29#include "chrome/common/chrome_paths.h"
30#include "chrome/common/chrome_switches.h"
31#include "chrome/common/main_function_params.h"
[email protected]ad1f9bd2009-07-30 20:23:1532#include "chrome/common/notification_registrar.h"
33#include "chrome/common/notification_type.h"
[email protected]e0d481582009-09-15 21:06:2534#include "chrome/common/url_constants.h"
[email protected]d4515eb2009-01-30 00:40:4335#include "chrome/test/testing_browser_process.h"
36#include "chrome/test/ui_test_utils.h"
[email protected]c4ff4952010-01-08 19:12:4737#include "net/base/mock_host_resolver.h"
[email protected]d4515eb2009-01-30 00:40:4338#include "sandbox/src/dep.h"
39
[email protected]8ecd3aad2009-11-04 08:32:2240#if defined(OS_LINUX)
41#include "base/singleton.h"
42#include "chrome/browser/renderer_host/render_sandbox_host_linux.h"
43#include "chrome/browser/zygote_host_linux.h"
44
45namespace {
46
47// A helper class to do Linux-only initialization only once per process.
48class LinuxHostInit {
49 public:
50 LinuxHostInit() {
[email protected]576a4ca2009-11-05 01:41:0951 RenderSandboxHostLinux* shost = Singleton<RenderSandboxHostLinux>::get();
[email protected]8ecd3aad2009-11-04 08:32:2252 shost->Init("");
[email protected]576a4ca2009-11-05 01:41:0953 ZygoteHost* zhost = Singleton<ZygoteHost>::get();
[email protected]8ecd3aad2009-11-04 08:32:2254 zhost->Init("");
55 }
56 ~LinuxHostInit() {}
57};
58
59} // namespace
60#endif
61
[email protected]d4515eb2009-01-30 00:40:4362extern int BrowserMain(const MainFunctionParams&);
63
64const wchar_t kUnitTestShowWindows[] = L"show-windows";
65
[email protected]ddf8a4b02010-03-22 23:08:3066// Passed as value of kTestType.
67static const char kBrowserTestType[] = "browser";
68
[email protected]4ff446f2009-07-10 18:29:3969// Default delay for the time-out at which we stop the
70// inner-message loop the first time.
[email protected]b5f95102009-07-01 19:53:5971const int kInitialTimeoutInMS = 30000;
72
73// Delay for sub-sequent time-outs once the initial time-out happened.
74const int kSubsequentTimeoutInMS = 5000;
75
[email protected]8bcdec92009-02-25 16:15:1876InProcessBrowserTest::InProcessBrowserTest()
77 : browser_(NULL),
78 show_window_(false),
[email protected]56cdae32009-03-12 19:58:2079 dom_automation_enabled_(false),
80 single_process_(false),
[email protected]4ff446f2009-07-10 18:29:3981 original_single_process_(false),
82 initial_timeout_(kInitialTimeoutInMS) {
[email protected]d4515eb2009-01-30 00:40:4383}
84
[email protected]c4ff4952010-01-08 19:12:4785InProcessBrowserTest::~InProcessBrowserTest() {
86}
87
[email protected]d4515eb2009-01-30 00:40:4388void InProcessBrowserTest::SetUp() {
89 // Cleanup the user data dir.
[email protected]23cc9a12009-07-30 21:27:0190 FilePath user_data_dir;
[email protected]d4515eb2009-01-30 00:40:4391 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
[email protected]23cc9a12009-07-30 21:27:0192 ASSERT_LT(10, static_cast<int>(user_data_dir.value().size())) <<
[email protected]d4515eb2009-01-30 00:40:4393 "The user data directory name passed into this test was too "
94 "short to delete safely. Please check the user-data-dir "
95 "argument and try again.";
[email protected]2c9bf9d72009-08-07 00:43:4996 if (ShouldDeleteProfile())
97 ASSERT_TRUE(file_util::DieFileDie(user_data_dir, true));
[email protected]d4515eb2009-01-30 00:40:4398
99 // The unit test suite creates a testingbrowser, but we want the real thing.
100 // Delete the current one. We'll install the testing one in TearDown.
101 delete g_browser_process;
102
103 // Don't delete the resources when BrowserMain returns. Many ui classes
104 // cache SkBitmaps in a static field so that if we delete the resource
105 // bundle we'll crash.
106 browser_shutdown::delete_resources_on_shutdown = false;
107
108 CommandLine* command_line = CommandLine::ForCurrentProcessMutable();
[email protected]56cdae32009-03-12 19:58:20109 original_command_line_.reset(new CommandLine(*command_line));
[email protected]d4515eb2009-01-30 00:40:43110
[email protected]9665fa62009-04-13 22:15:29111 SetUpCommandLine(command_line);
112
[email protected]108c2a12009-06-05 22:18:09113#if defined(OS_WIN)
[email protected]d4515eb2009-01-30 00:40:43114 // Hide windows on show.
[email protected]8bcdec92009-02-25 16:15:18115 if (!command_line->HasSwitch(kUnitTestShowWindows) && !show_window_)
[email protected]d4515eb2009-01-30 00:40:43116 BrowserView::SetShowState(SW_HIDE);
[email protected]108c2a12009-06-05 22:18:09117#endif
[email protected]d4515eb2009-01-30 00:40:43118
[email protected]8bcdec92009-02-25 16:15:18119 if (dom_automation_enabled_)
120 command_line->AppendSwitch(switches::kDomAutomationController);
121
[email protected]56cdae32009-03-12 19:58:20122 if (single_process_)
123 command_line->AppendSwitch(switches::kSingleProcess);
124
[email protected]cdbc1842009-08-26 02:56:58125 // Turn off tip loading for tests; see http://crbug.com/17725
126 command_line->AppendSwitch(switches::kDisableWebResources);
[email protected]0a519262009-07-13 18:14:08127
[email protected]23cc9a12009-07-30 21:27:01128 command_line->AppendSwitchWithValue(switches::kUserDataDir,
129 user_data_dir.ToWStringHack());
[email protected]d4515eb2009-01-30 00:40:43130
131 // For some reason the sandbox wasn't happy running in test mode. These
132 // tests aren't intended to test the sandbox, so we turn it off.
133 command_line->AppendSwitch(switches::kNoSandbox);
134
[email protected]e01aba812009-07-09 18:31:24135 // Don't show the first run ui.
136 command_line->AppendSwitch(switches::kNoFirstRun);
137
[email protected]ddf8a4b02010-03-22 23:08:30138 // This is a Browser test.
139 command_line->AppendSwitchWithValue(switches::kTestType,
140 ASCIIToWide(kBrowserTestType));
141
[email protected]8bcdec92009-02-25 16:15:18142 // Single-process mode is not set in BrowserMain so it needs to be processed
143 // explicitlty.
[email protected]56cdae32009-03-12 19:58:20144 original_single_process_ = RenderProcessHost::run_renderer_in_process();
[email protected]8bcdec92009-02-25 16:15:18145 if (command_line->HasSwitch(switches::kSingleProcess))
146 RenderProcessHost::set_run_renderer_in_process(true);
147
[email protected]7f74a4e2009-04-30 17:00:24148 // Explicitly set the path of the exe used for the renderer and plugin,
149 // otherwise they'll try to use unit_test.exe.
[email protected]6cea14d2009-09-10 18:19:18150 FilePath subprocess_path;
[email protected]7f74a4e2009-04-30 17:00:24151 PathService::Get(base::FILE_EXE, &subprocess_path);
[email protected]6cea14d2009-09-10 18:19:18152 subprocess_path = subprocess_path.DirName();
153 subprocess_path = subprocess_path.AppendASCII(WideToASCII(
154 chrome::kBrowserProcessExecutablePath));
[email protected]7f74a4e2009-04-30 17:00:24155 command_line->AppendSwitchWithValue(switches::kBrowserSubprocessPath,
[email protected]6cea14d2009-09-10 18:19:18156 subprocess_path.ToWStringHack());
[email protected]d4515eb2009-01-30 00:40:43157
[email protected]9c73efa2009-07-08 00:18:36158 // Enable warning level logging so that we can see when bad stuff happens.
159 command_line->AppendSwitch(switches::kEnableLogging);
160 command_line->AppendSwitchWithValue(switches::kLoggingLevel,
161 IntToWString(1)); // warning
162
[email protected]d4515eb2009-01-30 00:40:43163 SandboxInitWrapper sandbox_wrapper;
[email protected]7c321082009-02-09 15:35:47164 MainFunctionParams params(*command_line, sandbox_wrapper, NULL);
[email protected]d4515eb2009-01-30 00:40:43165 params.ui_task =
166 NewRunnableMethod(this, &InProcessBrowserTest::RunTestOnMainThreadLoop);
[email protected]13324ed2009-04-03 05:14:19167
[email protected]c4ff4952010-01-08 19:12:47168 host_resolver_ = new net::RuleBasedHostResolverProc(
169 new IntranetRedirectHostResolverProc(NULL));
[email protected]c7ad50f2009-09-11 06:28:15170
171 // Something inside the browser does this lookup implicitly. Make it fail
172 // to avoid external dependency. It won't break the tests.
173 host_resolver_->AddSimulatedFailure("*.google.com");
174
175 // See http://en.wikipedia.org/wiki/Web_Proxy_Autodiscovery_Protocol
176 // We don't want the test code to use it.
177 host_resolver_->AddSimulatedFailure("wpad");
178
[email protected]b59ff372009-07-15 22:04:32179 net::ScopedDefaultHostResolverProc scoped_host_resolver_proc(
[email protected]c7ad50f2009-09-11 06:28:15180 host_resolver_.get());
[email protected]5c5de8c2009-09-23 17:11:26181
182 SetUpInProcessBrowserTestFixture();
[email protected]60a782e2010-02-24 22:41:35183
184 // Before we run the browser, we have to hack the path to the exe to match
185 // what it would be if Chrome was running, because it is used to fork renderer
186 // processes, on Linux at least (failure to do so will cause a browser_test to
187 // be run instead of a renderer).
188 FilePath chrome_path;
189 CHECK(PathService::Get(base::FILE_EXE, &chrome_path));
190 chrome_path = chrome_path.DirName();
191#if defined(OS_WIN)
192 chrome_path = chrome_path.Append(chrome::kBrowserProcessExecutablePath);
193#elif defined(OS_POSIX)
194 chrome_path = chrome_path.Append(
195 WideToASCII(chrome::kBrowserProcessExecutablePath));
196#endif
197 CHECK(PathService::Override(base::FILE_EXE, chrome_path));
198
199#if defined(OS_LINUX)
200 // Initialize the RenderSandbox and Zygote hosts. Apparently they get used
201 // for InProcessBrowserTest, and this is not the normal browser startup path.
202 Singleton<LinuxHostInit>::get();
203#endif
204
[email protected]d4515eb2009-01-30 00:40:43205 BrowserMain(params);
[email protected]5c5de8c2009-09-23 17:11:26206 TearDownInProcessBrowserTestFixture();
[email protected]d4515eb2009-01-30 00:40:43207}
208
209void InProcessBrowserTest::TearDown() {
210 // Reinstall testing browser process.
211 delete g_browser_process;
212 g_browser_process = new TestingBrowserProcess();
213
214 browser_shutdown::delete_resources_on_shutdown = true;
215
[email protected]108c2a12009-06-05 22:18:09216#if defined(WIN)
[email protected]d4515eb2009-01-30 00:40:43217 BrowserView::SetShowState(-1);
[email protected]108c2a12009-06-05 22:18:09218#endif
[email protected]56cdae32009-03-12 19:58:20219
220 *CommandLine::ForCurrentProcessMutable() = *original_command_line_;
221 RenderProcessHost::set_run_renderer_in_process(original_single_process_);
[email protected]d4515eb2009-01-30 00:40:43222}
223
[email protected]d4515eb2009-01-30 00:40:43224HTTPTestServer* InProcessBrowserTest::StartHTTPServer() {
225 // The HTTPServer must run on the IO thread.
226 DCHECK(!http_server_.get());
227 http_server_ = HTTPTestServer::CreateServer(
228 L"chrome/test/data",
229 g_browser_process->io_thread()->message_loop());
230 return http_server_.get();
231}
232
233// Creates a browser with a single tab (about:blank), waits for the tab to
234// finish loading and shows the browser.
235Browser* InProcessBrowserTest::CreateBrowser(Profile* profile) {
236 Browser* browser = Browser::Create(profile);
237
[email protected]e0d481582009-09-15 21:06:25238 browser->AddTabWithURL(GURL(chrome::kAboutBlankURL), GURL(),
239 PageTransition::START_PAGE, true, -1, false, NULL);
[email protected]f0a51fb52009-03-05 12:46:38240
[email protected]d4515eb2009-01-30 00:40:43241 // Wait for the page to finish loading.
242 ui_test_utils::WaitForNavigation(
[email protected]ce3fa3c2009-04-20 19:55:57243 &browser->GetSelectedTabContents()->controller());
[email protected]d4515eb2009-01-30 00:40:43244
245 browser->window()->Show();
246
247 return browser;
248}
249
250void InProcessBrowserTest::RunTestOnMainThreadLoop() {
251 // In the long term it would be great if we could use a TestingProfile
252 // here and only enable services you want tested, but that requires all
253 // consumers of Profile to handle NULL services.
[email protected]ddf8a4b02010-03-22 23:08:30254 Profile* profile = ProfileManager::GetDefaultProfile();
[email protected]d4515eb2009-01-30 00:40:43255 if (!profile) {
256 // We should only be able to get here if the profile already exists and
257 // has been created.
258 NOTREACHED();
259 MessageLoopForUI::current()->Quit();
260 return;
261 }
262
[email protected]6fad2632009-11-02 05:59:37263 ChromeThread::PostTask(
264 ChromeThread::IO, FROM_HERE,
[email protected]cec4a272009-07-31 21:55:03265 NewRunnableFunction(chrome_browser_net::SetUrlRequestMocksEnabled, true));
266
[email protected]d4515eb2009-01-30 00:40:43267 browser_ = CreateBrowser(profile);
268
[email protected]b5f95102009-07-01 19:53:59269 // Start the timeout timer to prevent hangs.
270 MessageLoopForUI::current()->PostDelayedTask(FROM_HERE,
271 NewRunnableMethod(this, &InProcessBrowserTest::TimedOut),
[email protected]4ff446f2009-07-10 18:29:39272 initial_timeout_);
[email protected]b5f95102009-07-01 19:53:59273
[email protected]d4515eb2009-01-30 00:40:43274 RunTestOnMainThread();
[email protected]17c4f3c2009-07-04 16:36:25275 CleanUpOnMainThread();
[email protected]d4515eb2009-01-30 00:40:43276
[email protected]cc661e52009-07-27 19:18:41277 // Close all browser windows. This might not happen immediately, since some
278 // may need to wait for beforeunload and unload handlers to fire in a tab.
279 // When all windows are closed, the last window will call Quit().
[email protected]0e28ef02009-11-23 17:46:53280#if defined(OS_MACOSX)
281 // When the browser window closes, Cocoa will generate an inner-loop that
282 // processes the RenderProcessHost delete task, so allow task nesting.
283 bool old_state = MessageLoopForUI::current()->NestableTasksAllowed();
284 MessageLoopForUI::current()->SetNestableTasksAllowed(true);
285#endif
[email protected]e6152c22009-06-23 23:33:27286 BrowserList::const_iterator browser = BrowserList::begin();
287 for (; browser != BrowserList::end(); ++browser)
[email protected]cc661e52009-07-27 19:18:41288 (*browser)->CloseWindow();
[email protected]0e28ef02009-11-23 17:46:53289#if defined(OS_MACOSX)
290 MessageLoopForUI::current()->SetNestableTasksAllowed(old_state);
291#endif
[email protected]d4515eb2009-01-30 00:40:43292
293 // Stop the HTTP server.
294 http_server_ = NULL;
[email protected]d4515eb2009-01-30 00:40:43295}
[email protected]deb27ae2009-04-10 02:37:22296
[email protected]b5f95102009-07-01 19:53:59297void InProcessBrowserTest::TimedOut() {
298 DCHECK(MessageLoopForUI::current()->IsNested());
299
[email protected]94ab2ad2009-10-15 18:18:51300 std::string error_message = "Test timed out. Each test runs for a max of ";
301 error_message += IntToString(kInitialTimeoutInMS);
302 error_message += " ms (kInitialTimeoutInMS).";
303
304 GTEST_NONFATAL_FAILURE_(error_message.c_str());
[email protected]b5f95102009-07-01 19:53:59305
306 // Start the timeout timer to prevent hangs.
307 MessageLoopForUI::current()->PostDelayedTask(FROM_HERE,
308 NewRunnableMethod(this, &InProcessBrowserTest::TimedOut),
309 kSubsequentTimeoutInMS);
310
311 MessageLoopForUI::current()->Quit();
312}
[email protected]4ff446f2009-07-10 18:29:39313
314void InProcessBrowserTest::SetInitialTimeoutInMS(int timeout_value) {
315 DCHECK_GT(timeout_value, 0);
316 initial_timeout_ = timeout_value;
317}