blob: d15e54bab0a7ea706f3ba46357a1cac339ad23ea [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// Copyright (c) 2011 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 "content/public/test/browser_test_base.h"
6
7#include "base/bind.h"
8#include "base/command_line.h"
9#include "base/debug/stack_trace.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010010#include "content/browser/renderer_host/render_process_host_impl.h"
11#include "content/public/browser/browser_thread.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000012#include "content/public/common/content_switches.h"
13#include "content/public/common/main_function_params.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010014#include "content/public/test/test_utils.h"
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010015#include "net/test/embedded_test_server/embedded_test_server.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000016
Ben Murdoch58e6fbe2013-07-26 10:20:38 +010017#if defined(OS_POSIX)
18#include "base/process/process_handle.h"
19#endif
20
Torne (Richard Coles)58218062012-11-14 11:43:16 +000021#if defined(OS_MACOSX)
22#include "base/mac/mac_util.h"
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010023#include "base/power_monitor/power_monitor.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000024#endif
25
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000026#if defined(OS_ANDROID)
27#include "base/threading/thread_restrictions.h"
28#include "content/public/browser/browser_main_runner.h"
29#include "content/public/browser/browser_thread.h"
30#endif
31
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010032namespace content {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000033namespace {
34
35#if defined(OS_POSIX)
36// On SIGTERM (sent by the runner on timeouts), dump a stack trace (to make
37// debugging easier) and also exit with a known error code (so that the test
38// framework considers this a failure -- http://crbug.com/57578).
39// Note: We only want to do this in the browser process, and not forked
40// processes. That might lead to hangs because of locks inside tcmalloc or the
41// OS. See http://crbug.com/141302.
42static int g_browser_process_pid;
43static void DumpStackTraceSignalHandler(int signal) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000044 if (g_browser_process_pid == base::GetCurrentProcId()) {
45 logging::RawLog(logging::LOG_ERROR,
46 "BrowserTestBase signal handler received SIGTERM. "
47 "Backtrace:\n");
Torne (Richard Coles)58218062012-11-14 11:43:16 +000048 base::debug::StackTrace().PrintBacktrace();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000049 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +000050 _exit(128 + signal);
51}
52#endif // defined(OS_POSIX)
53
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010054void RunTaskOnRendererThread(const base::Closure& task,
55 const base::Closure& quit_task) {
56 task.Run();
57 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit_task);
58}
59
Torne (Richard Coles)58218062012-11-14 11:43:16 +000060} // namespace
61
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010062extern int BrowserMain(const MainFunctionParams&);
Torne (Richard Coles)58218062012-11-14 11:43:16 +000063
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010064BrowserTestBase::BrowserTestBase()
65 : embedded_test_server_(
66 new net::test_server::EmbeddedTestServer(
67 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO))) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +000068#if defined(OS_MACOSX)
69 base::mac::SetOverrideAmIBundled(true);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010070 base::PowerMonitor::AllocateSystemIOPorts();
Torne (Richard Coles)58218062012-11-14 11:43:16 +000071#endif
72
73#if defined(OS_POSIX)
74 handle_sigterm_ = true;
75#endif
76}
77
78BrowserTestBase::~BrowserTestBase() {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000079#if defined(OS_ANDROID)
80 // RemoteTestServer can cause wait on the UI thread.
81 base::ThreadRestrictions::ScopedAllowWait allow_wait;
82 test_server_.reset(NULL);
83#endif
Torne (Richard Coles)58218062012-11-14 11:43:16 +000084}
85
86void BrowserTestBase::SetUp() {
87 CommandLine* command_line = CommandLine::ForCurrentProcess();
88
89 // The tests assume that file:// URIs can freely access other file:// URIs.
90 command_line->AppendSwitch(switches::kAllowFileAccessFromFiles);
91
92 command_line->AppendSwitch(switches::kDomAutomationController);
93
94 command_line->AppendSwitch(switches::kSkipGpuDataLoading);
95
96 MainFunctionParams params(*command_line);
97 params.ui_task =
98 new base::Closure(
99 base::Bind(&BrowserTestBase::ProxyRunTestOnMainThreadLoop, this));
100
101 SetUpInProcessBrowserTestFixture();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000102#if defined(OS_ANDROID)
103 BrowserMainRunner::Create()->Initialize(params);
104 // We are done running the test by now. During teardown we
105 // need to be able to perform IO.
106 base::ThreadRestrictions::SetIOAllowed(true);
107 BrowserThread::PostTask(
108 BrowserThread::IO, FROM_HERE,
109 base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed),
110 true));
111#else
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000112 BrowserMain(params);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000113#endif
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000114 TearDownInProcessBrowserTestFixture();
115}
116
117void BrowserTestBase::TearDown() {
118}
119
120void BrowserTestBase::ProxyRunTestOnMainThreadLoop() {
121#if defined(OS_POSIX)
122 if (handle_sigterm_) {
123 g_browser_process_pid = base::GetCurrentProcId();
124 signal(SIGTERM, DumpStackTraceSignalHandler);
125 }
126#endif // defined(OS_POSIX)
127 RunTestOnMainThreadLoop();
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100128 embedded_test_server_.reset();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000129}
130
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000131void BrowserTestBase::CreateTestServer(const base::FilePath& test_server_base) {
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000132 CHECK(!test_server_.get());
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100133 test_server_.reset(new net::SpawnedTestServer(
134 net::SpawnedTestServer::TYPE_HTTP,
135 net::SpawnedTestServer::kLocalhost,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000136 test_server_base));
137}
138
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100139void BrowserTestBase::PostTaskToInProcessRendererAndWait(
140 const base::Closure& task) {
141 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess));
142
143 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner;
144
145 base::MessageLoop* renderer_loop =
146 RenderProcessHostImpl::GetInProcessRendererThreadForTesting();
147 CHECK(renderer_loop);
148
149 renderer_loop->PostTask(
150 FROM_HERE,
151 base::Bind(&RunTaskOnRendererThread, task, runner->QuitClosure()));
152 runner->Run();
153}
154
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000155} // namespace content