browser_test_base.cc revision 58e6fbe4ee35d65e14b626c557d37565bf8ad179
1// 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" 10#include "content/browser/renderer_host/render_process_host_impl.h" 11#include "content/public/browser/browser_thread.h" 12#include "content/public/common/content_switches.h" 13#include "content/public/common/main_function_params.h" 14#include "content/public/test/test_utils.h" 15#include "net/test/embedded_test_server/embedded_test_server.h" 16 17#if defined(OS_POSIX) 18#include "base/process/process_handle.h" 19#endif 20 21#if defined(OS_MACOSX) 22#include "base/mac/mac_util.h" 23#include "base/power_monitor/power_monitor.h" 24#endif 25 26#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 32namespace content { 33namespace { 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) { 44 if (g_browser_process_pid == base::GetCurrentProcId()) { 45 logging::RawLog(logging::LOG_ERROR, 46 "BrowserTestBase signal handler received SIGTERM. " 47 "Backtrace:\n"); 48 base::debug::StackTrace().PrintBacktrace(); 49 } 50 _exit(128 + signal); 51} 52#endif // defined(OS_POSIX) 53 54void 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 60} // namespace 61 62extern int BrowserMain(const MainFunctionParams&); 63 64BrowserTestBase::BrowserTestBase() 65 : embedded_test_server_( 66 new net::test_server::EmbeddedTestServer( 67 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO))) { 68#if defined(OS_MACOSX) 69 base::mac::SetOverrideAmIBundled(true); 70 base::PowerMonitor::AllocateSystemIOPorts(); 71#endif 72 73#if defined(OS_POSIX) 74 handle_sigterm_ = true; 75#endif 76} 77 78BrowserTestBase::~BrowserTestBase() { 79#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 84} 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(); 102#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 112 BrowserMain(params); 113#endif 114 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(); 128 embedded_test_server_.reset(); 129} 130 131void BrowserTestBase::CreateTestServer(const base::FilePath& test_server_base) { 132 CHECK(!test_server_.get()); 133 test_server_.reset(new net::SpawnedTestServer( 134 net::SpawnedTestServer::TYPE_HTTP, 135 net::SpawnedTestServer::kLocalhost, 136 test_server_base)); 137} 138 139void 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 155} // namespace content 156