blob: af63adbce3bac8a3d4079ef3a90b619e33f16f95 [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"
[email protected]23cc9a12009-07-30 21:27:0111#include "base/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]cec4a272009-07-31 21:55:0317#include "chrome/browser/net/url_request_mock_util.h"
[email protected]d4515eb2009-01-30 00:40:4318#include "chrome/browser/profile.h"
19#include "chrome/browser/profile_manager.h"
[email protected]8bcdec92009-02-25 16:15:1820#include "chrome/browser/renderer_host/render_process_host.h"
[email protected]5c238752009-06-13 10:29:0721#include "chrome/browser/tab_contents/tab_contents.h"
[email protected]108c2a12009-06-05 22:18:0922#if defined(OS_WIN)
[email protected]d4515eb2009-01-30 00:40:4323#include "chrome/browser/views/frame/browser_view.h"
[email protected]108c2a12009-06-05 22:18:0924#endif
[email protected]d4515eb2009-01-30 00:40:4325#include "chrome/common/chrome_constants.h"
26#include "chrome/common/chrome_paths.h"
27#include "chrome/common/chrome_switches.h"
28#include "chrome/common/main_function_params.h"
[email protected]ad1f9bd2009-07-30 20:23:1529#include "chrome/common/notification_registrar.h"
30#include "chrome/common/notification_type.h"
[email protected]d4515eb2009-01-30 00:40:4331#include "chrome/test/testing_browser_process.h"
32#include "chrome/test/ui_test_utils.h"
[email protected]b59ff372009-07-15 22:04:3233#include "net/base/mock_host_resolver.h"
[email protected]d4515eb2009-01-30 00:40:4334#include "sandbox/src/dep.h"
35
36extern int BrowserMain(const MainFunctionParams&);
37
38const wchar_t kUnitTestShowWindows[] = L"show-windows";
39
[email protected]4ff446f2009-07-10 18:29:3940// Default delay for the time-out at which we stop the
41// inner-message loop the first time.
[email protected]b5f95102009-07-01 19:53:5942const int kInitialTimeoutInMS = 30000;
43
44// Delay for sub-sequent time-outs once the initial time-out happened.
45const int kSubsequentTimeoutInMS = 5000;
46
[email protected]8bcdec92009-02-25 16:15:1847InProcessBrowserTest::InProcessBrowserTest()
48 : browser_(NULL),
49 show_window_(false),
[email protected]56cdae32009-03-12 19:58:2050 dom_automation_enabled_(false),
51 single_process_(false),
[email protected]4ff446f2009-07-10 18:29:3952 original_single_process_(false),
53 initial_timeout_(kInitialTimeoutInMS) {
[email protected]d4515eb2009-01-30 00:40:4354}
55
56void InProcessBrowserTest::SetUp() {
[email protected]d4515eb2009-01-30 00:40:4357 // Cleanup the user data dir.
[email protected]23cc9a12009-07-30 21:27:0158 FilePath user_data_dir;
[email protected]d4515eb2009-01-30 00:40:4359 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
[email protected]23cc9a12009-07-30 21:27:0160 ASSERT_LT(10, static_cast<int>(user_data_dir.value().size())) <<
[email protected]d4515eb2009-01-30 00:40:4361 "The user data directory name passed into this test was too "
62 "short to delete safely. Please check the user-data-dir "
63 "argument and try again.";
[email protected]2c9bf9d72009-08-07 00:43:4964 if (ShouldDeleteProfile())
65 ASSERT_TRUE(file_util::DieFileDie(user_data_dir, true));
[email protected]d4515eb2009-01-30 00:40:4366
67 // The unit test suite creates a testingbrowser, but we want the real thing.
68 // Delete the current one. We'll install the testing one in TearDown.
69 delete g_browser_process;
70
71 // Don't delete the resources when BrowserMain returns. Many ui classes
72 // cache SkBitmaps in a static field so that if we delete the resource
73 // bundle we'll crash.
74 browser_shutdown::delete_resources_on_shutdown = false;
75
76 CommandLine* command_line = CommandLine::ForCurrentProcessMutable();
[email protected]56cdae32009-03-12 19:58:2077 original_command_line_.reset(new CommandLine(*command_line));
[email protected]d4515eb2009-01-30 00:40:4378
[email protected]9665fa62009-04-13 22:15:2979 SetUpCommandLine(command_line);
80
[email protected]108c2a12009-06-05 22:18:0981#if defined(OS_WIN)
[email protected]d4515eb2009-01-30 00:40:4382 // Hide windows on show.
[email protected]8bcdec92009-02-25 16:15:1883 if (!command_line->HasSwitch(kUnitTestShowWindows) && !show_window_)
[email protected]d4515eb2009-01-30 00:40:4384 BrowserView::SetShowState(SW_HIDE);
[email protected]108c2a12009-06-05 22:18:0985#endif
[email protected]d4515eb2009-01-30 00:40:4386
[email protected]8bcdec92009-02-25 16:15:1887 if (dom_automation_enabled_)
88 command_line->AppendSwitch(switches::kDomAutomationController);
89
[email protected]56cdae32009-03-12 19:58:2090 if (single_process_)
91 command_line->AppendSwitch(switches::kSingleProcess);
92
[email protected]cdbc1842009-08-26 02:56:5893 // Turn off tip loading for tests; see http://crbug.com/17725
94 command_line->AppendSwitch(switches::kDisableWebResources);
[email protected]0a519262009-07-13 18:14:0895
[email protected]23cc9a12009-07-30 21:27:0196 command_line->AppendSwitchWithValue(switches::kUserDataDir,
97 user_data_dir.ToWStringHack());
[email protected]d4515eb2009-01-30 00:40:4398
99 // For some reason the sandbox wasn't happy running in test mode. These
100 // tests aren't intended to test the sandbox, so we turn it off.
101 command_line->AppendSwitch(switches::kNoSandbox);
102
[email protected]e01aba812009-07-09 18:31:24103 // Don't show the first run ui.
104 command_line->AppendSwitch(switches::kNoFirstRun);
105
[email protected]8bcdec92009-02-25 16:15:18106 // Single-process mode is not set in BrowserMain so it needs to be processed
107 // explicitlty.
[email protected]56cdae32009-03-12 19:58:20108 original_single_process_ = RenderProcessHost::run_renderer_in_process();
[email protected]8bcdec92009-02-25 16:15:18109 if (command_line->HasSwitch(switches::kSingleProcess))
110 RenderProcessHost::set_run_renderer_in_process(true);
111
[email protected]7f74a4e2009-04-30 17:00:24112 // Explicitly set the path of the exe used for the renderer and plugin,
113 // otherwise they'll try to use unit_test.exe.
[email protected]6cea14d2009-09-10 18:19:18114 FilePath subprocess_path;
[email protected]7f74a4e2009-04-30 17:00:24115 PathService::Get(base::FILE_EXE, &subprocess_path);
[email protected]6cea14d2009-09-10 18:19:18116 subprocess_path = subprocess_path.DirName();
117 subprocess_path = subprocess_path.AppendASCII(WideToASCII(
118 chrome::kBrowserProcessExecutablePath));
[email protected]7f74a4e2009-04-30 17:00:24119 command_line->AppendSwitchWithValue(switches::kBrowserSubprocessPath,
[email protected]6cea14d2009-09-10 18:19:18120 subprocess_path.ToWStringHack());
[email protected]d4515eb2009-01-30 00:40:43121
[email protected]9c73efa2009-07-08 00:18:36122 // Enable warning level logging so that we can see when bad stuff happens.
123 command_line->AppendSwitch(switches::kEnableLogging);
124 command_line->AppendSwitchWithValue(switches::kLoggingLevel,
125 IntToWString(1)); // warning
126
[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]b59ff372009-07-15 22:04:32132 scoped_refptr<net::RuleBasedHostResolverProc> host_resolver_proc(
133 new net::RuleBasedHostResolverProc(NULL));
134 ConfigureHostResolverProc(host_resolver_proc);
135 net::ScopedDefaultHostResolverProc scoped_host_resolver_proc(
136 host_resolver_proc);
[email protected]d4515eb2009-01-30 00:40:43137 BrowserMain(params);
138}
139
140void InProcessBrowserTest::TearDown() {
141 // Reinstall testing browser process.
142 delete g_browser_process;
143 g_browser_process = new TestingBrowserProcess();
144
145 browser_shutdown::delete_resources_on_shutdown = true;
146
[email protected]108c2a12009-06-05 22:18:09147#if defined(WIN)
[email protected]d4515eb2009-01-30 00:40:43148 BrowserView::SetShowState(-1);
[email protected]108c2a12009-06-05 22:18:09149#endif
[email protected]56cdae32009-03-12 19:58:20150
151 *CommandLine::ForCurrentProcessMutable() = *original_command_line_;
152 RenderProcessHost::set_run_renderer_in_process(original_single_process_);
[email protected]d4515eb2009-01-30 00:40:43153}
154
[email protected]d4515eb2009-01-30 00:40:43155HTTPTestServer* InProcessBrowserTest::StartHTTPServer() {
156 // The HTTPServer must run on the IO thread.
157 DCHECK(!http_server_.get());
158 http_server_ = HTTPTestServer::CreateServer(
159 L"chrome/test/data",
160 g_browser_process->io_thread()->message_loop());
161 return http_server_.get();
162}
163
164// Creates a browser with a single tab (about:blank), waits for the tab to
165// finish loading and shows the browser.
166Browser* InProcessBrowserTest::CreateBrowser(Profile* profile) {
167 Browser* browser = Browser::Create(profile);
168
169 browser->AddTabWithURL(
[email protected]5a4940be2009-05-06 06:44:39170 GURL("about:blank"), GURL(), PageTransition::START_PAGE, true, -1, false,
171 NULL);
[email protected]f0a51fb52009-03-05 12:46:38172
[email protected]d4515eb2009-01-30 00:40:43173 // Wait for the page to finish loading.
174 ui_test_utils::WaitForNavigation(
[email protected]ce3fa3c2009-04-20 19:55:57175 &browser->GetSelectedTabContents()->controller());
[email protected]d4515eb2009-01-30 00:40:43176
177 browser->window()->Show();
178
179 return browser;
180}
181
182void InProcessBrowserTest::RunTestOnMainThreadLoop() {
183 // In the long term it would be great if we could use a TestingProfile
184 // here and only enable services you want tested, but that requires all
185 // consumers of Profile to handle NULL services.
186 FilePath user_data_dir;
187 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
188 ProfileManager* profile_manager = g_browser_process->profile_manager();
189 Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
190 if (!profile) {
191 // We should only be able to get here if the profile already exists and
192 // has been created.
193 NOTREACHED();
194 MessageLoopForUI::current()->Quit();
195 return;
196 }
197
[email protected]eca6a4f2009-06-25 17:29:09198
199 // Before we run the browser, we have to hack the path to the exe to match
200 // what it would be if Chrome was running, because it is used to fork renderer
201 // processes, on Linux at least (failure to do so will cause a browser_test to
202 // be run instead of a renderer).
203 FilePath chrome_path;
204 CHECK(PathService::Get(base::FILE_EXE, &chrome_path));
205 chrome_path = chrome_path.DirName();
206#if defined(OS_WIN)
207 chrome_path = chrome_path.Append(chrome::kBrowserProcessExecutablePath);
208#elif defined(OS_POSIX)
209 chrome_path = chrome_path.Append(
210 WideToASCII(chrome::kBrowserProcessExecutablePath));
211#endif
212 CHECK(PathService::Override(base::FILE_EXE, chrome_path));
213
[email protected]cec4a272009-07-31 21:55:03214 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
215 NewRunnableFunction(chrome_browser_net::SetUrlRequestMocksEnabled, true));
216
[email protected]d4515eb2009-01-30 00:40:43217 browser_ = CreateBrowser(profile);
218
[email protected]b5f95102009-07-01 19:53:59219 // Start the timeout timer to prevent hangs.
220 MessageLoopForUI::current()->PostDelayedTask(FROM_HERE,
221 NewRunnableMethod(this, &InProcessBrowserTest::TimedOut),
[email protected]4ff446f2009-07-10 18:29:39222 initial_timeout_);
[email protected]b5f95102009-07-01 19:53:59223
[email protected]d4515eb2009-01-30 00:40:43224 RunTestOnMainThread();
[email protected]17c4f3c2009-07-04 16:36:25225 CleanUpOnMainThread();
[email protected]d4515eb2009-01-30 00:40:43226
[email protected]cc661e52009-07-27 19:18:41227 // Close all browser windows. This might not happen immediately, since some
228 // may need to wait for beforeunload and unload handlers to fire in a tab.
229 // When all windows are closed, the last window will call Quit().
[email protected]e6152c22009-06-23 23:33:27230 BrowserList::const_iterator browser = BrowserList::begin();
231 for (; browser != BrowserList::end(); ++browser)
[email protected]cc661e52009-07-27 19:18:41232 (*browser)->CloseWindow();
[email protected]d4515eb2009-01-30 00:40:43233
234 // Stop the HTTP server.
235 http_server_ = NULL;
[email protected]d4515eb2009-01-30 00:40:43236}
[email protected]deb27ae2009-04-10 02:37:22237
[email protected]b59ff372009-07-15 22:04:32238void InProcessBrowserTest::ConfigureHostResolverProc(
239 net::RuleBasedHostResolverProc* host_resolver_proc) {
[email protected]2c3b06d2009-09-02 19:23:23240 // Something inside the browser does this lookup implicitly. Make it fail
241 // to avoid external dependency. It won't break the tests.
242 host_resolver_proc->AddSimulatedFailure("*.google.com");
[email protected]2bd6ca1c2009-08-27 16:42:20243
[email protected]deb27ae2009-04-10 02:37:22244 // See http://en.wikipedia.org/wiki/Web_Proxy_Autodiscovery_Protocol
245 // We don't want the test code to use it.
[email protected]b59ff372009-07-15 22:04:32246 host_resolver_proc->AddSimulatedFailure("wpad");
[email protected]deb27ae2009-04-10 02:37:22247}
[email protected]b5f95102009-07-01 19:53:59248
249void InProcessBrowserTest::TimedOut() {
250 DCHECK(MessageLoopForUI::current()->IsNested());
251
252 GTEST_NONFATAL_FAILURE_("Timed-out");
253
254 // Start the timeout timer to prevent hangs.
255 MessageLoopForUI::current()->PostDelayedTask(FROM_HERE,
256 NewRunnableMethod(this, &InProcessBrowserTest::TimedOut),
257 kSubsequentTimeoutInMS);
258
259 MessageLoopForUI::current()->Quit();
260}
[email protected]4ff446f2009-07-10 18:29:39261
262void InProcessBrowserTest::SetInitialTimeoutInMS(int timeout_value) {
263 DCHECK_GT(timeout_value, 0);
264 initial_timeout_ = timeout_value;
265}