browser_test_base.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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 "base/process_util.h" 11#include "content/browser/renderer_host/render_process_host_impl.h" 12#include "content/public/browser/browser_thread.h" 13#include "content/public/common/content_switches.h" 14#include "content/public/common/main_function_params.h" 15#include "content/public/test/test_utils.h" 16#include "net/test/embedded_test_server/embedded_test_server.h" 17 18#if defined(OS_MACOSX) 19#include "base/mac/mac_util.h" 20#include "base/power_monitor/power_monitor.h" 21#endif 22 23#if defined(OS_ANDROID) 24#include "base/threading/thread_restrictions.h" 25#include "content/public/browser/browser_main_runner.h" 26#include "content/public/browser/browser_thread.h" 27#endif 28 29namespace content { 30namespace { 31 32#if defined(OS_POSIX) 33// On SIGTERM (sent by the runner on timeouts), dump a stack trace (to make 34// debugging easier) and also exit with a known error code (so that the test 35// framework considers this a failure -- http://crbug.com/57578). 36// Note: We only want to do this in the browser process, and not forked 37// processes. That might lead to hangs because of locks inside tcmalloc or the 38// OS. See http://crbug.com/141302. 39static int g_browser_process_pid; 40static void DumpStackTraceSignalHandler(int signal) { 41 if (g_browser_process_pid == base::GetCurrentProcId()) { 42 logging::RawLog(logging::LOG_ERROR, 43 "BrowserTestBase signal handler received SIGTERM. " 44 "Backtrace:\n"); 45 base::debug::StackTrace().PrintBacktrace(); 46 } 47 _exit(128 + signal); 48} 49#endif // defined(OS_POSIX) 50 51void RunTaskOnRendererThread(const base::Closure& task, 52 const base::Closure& quit_task) { 53 task.Run(); 54 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit_task); 55} 56 57} // namespace 58 59extern int BrowserMain(const MainFunctionParams&); 60 61BrowserTestBase::BrowserTestBase() 62 : embedded_test_server_( 63 new net::test_server::EmbeddedTestServer( 64 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO))) { 65#if defined(OS_MACOSX) 66 base::mac::SetOverrideAmIBundled(true); 67 base::PowerMonitor::AllocateSystemIOPorts(); 68#endif 69 70#if defined(OS_POSIX) 71 handle_sigterm_ = true; 72#endif 73} 74 75BrowserTestBase::~BrowserTestBase() { 76#if defined(OS_ANDROID) 77 // RemoteTestServer can cause wait on the UI thread. 78 base::ThreadRestrictions::ScopedAllowWait allow_wait; 79 test_server_.reset(NULL); 80#endif 81} 82 83void BrowserTestBase::SetUp() { 84 CommandLine* command_line = CommandLine::ForCurrentProcess(); 85 86 // The tests assume that file:// URIs can freely access other file:// URIs. 87 command_line->AppendSwitch(switches::kAllowFileAccessFromFiles); 88 89 command_line->AppendSwitch(switches::kDomAutomationController); 90 91 command_line->AppendSwitch(switches::kSkipGpuDataLoading); 92 93 MainFunctionParams params(*command_line); 94 params.ui_task = 95 new base::Closure( 96 base::Bind(&BrowserTestBase::ProxyRunTestOnMainThreadLoop, this)); 97 98 SetUpInProcessBrowserTestFixture(); 99#if defined(OS_ANDROID) 100 BrowserMainRunner::Create()->Initialize(params); 101 // We are done running the test by now. During teardown we 102 // need to be able to perform IO. 103 base::ThreadRestrictions::SetIOAllowed(true); 104 BrowserThread::PostTask( 105 BrowserThread::IO, FROM_HERE, 106 base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed), 107 true)); 108#else 109 BrowserMain(params); 110#endif 111 TearDownInProcessBrowserTestFixture(); 112} 113 114void BrowserTestBase::TearDown() { 115} 116 117void BrowserTestBase::ProxyRunTestOnMainThreadLoop() { 118#if defined(OS_POSIX) 119 if (handle_sigterm_) { 120 g_browser_process_pid = base::GetCurrentProcId(); 121 signal(SIGTERM, DumpStackTraceSignalHandler); 122 } 123#endif // defined(OS_POSIX) 124 RunTestOnMainThreadLoop(); 125 embedded_test_server_.reset(); 126} 127 128void BrowserTestBase::CreateTestServer(const base::FilePath& test_server_base) { 129 CHECK(!test_server_.get()); 130 test_server_.reset(new net::SpawnedTestServer( 131 net::SpawnedTestServer::TYPE_HTTP, 132 net::SpawnedTestServer::kLocalhost, 133 test_server_base)); 134} 135 136void BrowserTestBase::PostTaskToInProcessRendererAndWait( 137 const base::Closure& task) { 138 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)); 139 140 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner; 141 142 base::MessageLoop* renderer_loop = 143 RenderProcessHostImpl::GetInProcessRendererThreadForTesting(); 144 CHECK(renderer_loop); 145 146 renderer_loop->PostTask( 147 FROM_HERE, 148 base::Bind(&RunTaskOnRendererThread, task, runner->QuitClosure())); 149 runner->Run(); 150} 151 152} // namespace content 153