blob: 8aaf586a6d15a4bd526418def59de4cc65d865ab [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]e01aba812009-07-09 18:31:24110 // Don't show the first run ui.
111 command_line->AppendSwitch(switches::kNoFirstRun);
112
[email protected]8bcdec92009-02-25 16:15:18113 // Single-process mode is not set in BrowserMain so it needs to be processed
114 // explicitlty.
[email protected]56cdae32009-03-12 19:58:20115 original_single_process_ = RenderProcessHost::run_renderer_in_process();
[email protected]8bcdec92009-02-25 16:15:18116 if (command_line->HasSwitch(switches::kSingleProcess))
117 RenderProcessHost::set_run_renderer_in_process(true);
118
[email protected]7f74a4e2009-04-30 17:00:24119 // Explicitly set the path of the exe used for the renderer and plugin,
120 // otherwise they'll try to use unit_test.exe.
121 std::wstring subprocess_path;
122 PathService::Get(base::FILE_EXE, &subprocess_path);
123 FilePath fp_subprocess_path = FilePath::FromWStringHack(subprocess_path);
124 subprocess_path = fp_subprocess_path.DirName().ToWStringHack();
125 file_util::AppendToPath(&subprocess_path,
[email protected]075a7252009-04-23 18:07:51126 chrome::kBrowserProcessExecutablePath);
[email protected]7f74a4e2009-04-30 17:00:24127 command_line->AppendSwitchWithValue(switches::kBrowserSubprocessPath,
128 subprocess_path);
[email protected]d4515eb2009-01-30 00:40:43129
[email protected]9c73efa2009-07-08 00:18:36130 // Enable warning level logging so that we can see when bad stuff happens.
131 command_line->AppendSwitch(switches::kEnableLogging);
132 command_line->AppendSwitchWithValue(switches::kLoggingLevel,
133 IntToWString(1)); // warning
134
[email protected]d4515eb2009-01-30 00:40:43135 SandboxInitWrapper sandbox_wrapper;
[email protected]7c321082009-02-09 15:35:47136 MainFunctionParams params(*command_line, sandbox_wrapper, NULL);
[email protected]d4515eb2009-01-30 00:40:43137 params.ui_task =
138 NewRunnableMethod(this, &InProcessBrowserTest::RunTestOnMainThreadLoop);
[email protected]13324ed2009-04-03 05:14:19139
[email protected]13324ed2009-04-03 05:14:19140 scoped_refptr<net::RuleBasedHostMapper> host_mapper(
141 new net::RuleBasedHostMapper());
[email protected]deb27ae2009-04-10 02:37:22142 ConfigureHostMapper(host_mapper.get());
[email protected]7844fc52009-04-07 08:58:48143 net::ScopedHostMapper scoped_host_mapper(host_mapper.get());
[email protected]d4515eb2009-01-30 00:40:43144 BrowserMain(params);
145}
146
147void InProcessBrowserTest::TearDown() {
148 // Reinstall testing browser process.
149 delete g_browser_process;
150 g_browser_process = new TestingBrowserProcess();
151
152 browser_shutdown::delete_resources_on_shutdown = true;
153
[email protected]108c2a12009-06-05 22:18:09154#if defined(WIN)
[email protected]d4515eb2009-01-30 00:40:43155 BrowserView::SetShowState(-1);
[email protected]108c2a12009-06-05 22:18:09156#endif
[email protected]56cdae32009-03-12 19:58:20157
158 *CommandLine::ForCurrentProcessMutable() = *original_command_line_;
159 RenderProcessHost::set_run_renderer_in_process(original_single_process_);
[email protected]d4515eb2009-01-30 00:40:43160}
161
[email protected]d4515eb2009-01-30 00:40:43162HTTPTestServer* InProcessBrowserTest::StartHTTPServer() {
163 // The HTTPServer must run on the IO thread.
164 DCHECK(!http_server_.get());
165 http_server_ = HTTPTestServer::CreateServer(
166 L"chrome/test/data",
167 g_browser_process->io_thread()->message_loop());
168 return http_server_.get();
169}
170
171// Creates a browser with a single tab (about:blank), waits for the tab to
172// finish loading and shows the browser.
173Browser* InProcessBrowserTest::CreateBrowser(Profile* profile) {
174 Browser* browser = Browser::Create(profile);
175
176 browser->AddTabWithURL(
[email protected]5a4940be2009-05-06 06:44:39177 GURL("about:blank"), GURL(), PageTransition::START_PAGE, true, -1, false,
178 NULL);
[email protected]f0a51fb52009-03-05 12:46:38179
[email protected]d4515eb2009-01-30 00:40:43180 // Wait for the page to finish loading.
181 ui_test_utils::WaitForNavigation(
[email protected]ce3fa3c2009-04-20 19:55:57182 &browser->GetSelectedTabContents()->controller());
[email protected]d4515eb2009-01-30 00:40:43183
184 browser->window()->Show();
185
186 return browser;
187}
188
189void InProcessBrowserTest::RunTestOnMainThreadLoop() {
190 // In the long term it would be great if we could use a TestingProfile
191 // here and only enable services you want tested, but that requires all
192 // consumers of Profile to handle NULL services.
193 FilePath user_data_dir;
194 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
195 ProfileManager* profile_manager = g_browser_process->profile_manager();
196 Profile* profile = profile_manager->GetDefaultProfile(user_data_dir);
197 if (!profile) {
198 // We should only be able to get here if the profile already exists and
199 // has been created.
200 NOTREACHED();
201 MessageLoopForUI::current()->Quit();
202 return;
203 }
204
[email protected]eca6a4f2009-06-25 17:29:09205
206 // Before we run the browser, we have to hack the path to the exe to match
207 // what it would be if Chrome was running, because it is used to fork renderer
208 // processes, on Linux at least (failure to do so will cause a browser_test to
209 // be run instead of a renderer).
210 FilePath chrome_path;
211 CHECK(PathService::Get(base::FILE_EXE, &chrome_path));
212 chrome_path = chrome_path.DirName();
213#if defined(OS_WIN)
214 chrome_path = chrome_path.Append(chrome::kBrowserProcessExecutablePath);
215#elif defined(OS_POSIX)
216 chrome_path = chrome_path.Append(
217 WideToASCII(chrome::kBrowserProcessExecutablePath));
218#endif
219 CHECK(PathService::Override(base::FILE_EXE, chrome_path));
220
[email protected]d4515eb2009-01-30 00:40:43221 browser_ = CreateBrowser(profile);
222
[email protected]b5f95102009-07-01 19:53:59223 // Start the timeout timer to prevent hangs.
224 MessageLoopForUI::current()->PostDelayedTask(FROM_HERE,
225 NewRunnableMethod(this, &InProcessBrowserTest::TimedOut),
226 kInitialTimeoutInMS);
227
[email protected]d4515eb2009-01-30 00:40:43228 RunTestOnMainThread();
[email protected]17c4f3c2009-07-04 16:36:25229 CleanUpOnMainThread();
[email protected]d4515eb2009-01-30 00:40:43230
[email protected]e6152c22009-06-23 23:33:27231 BrowserList::const_iterator browser = BrowserList::begin();
232 for (; browser != BrowserList::end(); ++browser)
[email protected]b6e38ef2009-06-16 00:43:23233 (*browser)->CloseAllTabs();
[email protected]d4515eb2009-01-30 00:40:43234
235 // Stop the HTTP server.
236 http_server_ = NULL;
237
238 MessageLoopForUI::current()->Quit();
239}
[email protected]deb27ae2009-04-10 02:37:22240
241void InProcessBrowserTest::ConfigureHostMapper(
242 net::RuleBasedHostMapper* host_mapper) {
243 host_mapper->AllowDirectLookup("*.google.com");
244 // See http://en.wikipedia.org/wiki/Web_Proxy_Autodiscovery_Protocol
245 // We don't want the test code to use it.
246 host_mapper->AddSimulatedFailure("wpad");
247}
[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}