browser_test_base.cc revision c2db58bd994c04d98e4ee2cd7565b71548655fe3
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#include "ui/compositor/compositor_switches.h" 17#include "ui/gl/gl_implementation.h" 18#include "ui/gl/gl_switches.h" 19 20#if defined(OS_POSIX) 21#include "base/process/process_handle.h" 22#endif 23 24#if defined(OS_MACOSX) 25#include "base/mac/mac_util.h" 26#include "base/power_monitor/power_monitor_device_source.h" 27#endif 28 29#if defined(OS_ANDROID) 30#include "base/threading/thread_restrictions.h" 31#include "content/public/browser/browser_main_runner.h" 32#include "content/public/browser/browser_thread.h" 33#endif 34 35#if defined(OS_CHROMEOS) 36#include "base/chromeos/chromeos_version.h" 37#endif 38 39namespace content { 40namespace { 41 42#if defined(OS_POSIX) 43// On SIGTERM (sent by the runner on timeouts), dump a stack trace (to make 44// debugging easier) and also exit with a known error code (so that the test 45// framework considers this a failure -- http://crbug.com/57578). 46// Note: We only want to do this in the browser process, and not forked 47// processes. That might lead to hangs because of locks inside tcmalloc or the 48// OS. See http://crbug.com/141302. 49static int g_browser_process_pid; 50static void DumpStackTraceSignalHandler(int signal) { 51 if (g_browser_process_pid == base::GetCurrentProcId()) { 52 logging::RawLog(logging::LOG_ERROR, 53 "BrowserTestBase signal handler received SIGTERM. " 54 "Backtrace:\n"); 55 base::debug::StackTrace().PrintBacktrace(); 56 } 57 _exit(128 + signal); 58} 59#endif // defined(OS_POSIX) 60 61void RunTaskOnRendererThread(const base::Closure& task, 62 const base::Closure& quit_task) { 63 task.Run(); 64 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit_task); 65} 66 67} // namespace 68 69extern int BrowserMain(const MainFunctionParams&); 70 71BrowserTestBase::BrowserTestBase() 72 : embedded_test_server_( 73 new net::test_server::EmbeddedTestServer( 74 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO))), 75 allow_test_contexts_(true), 76 allow_osmesa_(true) { 77#if defined(OS_MACOSX) 78 base::mac::SetOverrideAmIBundled(true); 79 base::PowerMonitorDeviceSource::AllocateSystemIOPorts(); 80#endif 81 82#if defined(OS_POSIX) 83 handle_sigterm_ = true; 84#endif 85} 86 87BrowserTestBase::~BrowserTestBase() { 88#if defined(OS_ANDROID) 89 // RemoteTestServer can cause wait on the UI thread. 90 base::ThreadRestrictions::ScopedAllowWait allow_wait; 91 test_server_.reset(NULL); 92#endif 93} 94 95void BrowserTestBase::SetUp() { 96 CommandLine* command_line = CommandLine::ForCurrentProcess(); 97 98 // The tests assume that file:// URIs can freely access other file:// URIs. 99 command_line->AppendSwitch(switches::kAllowFileAccessFromFiles); 100 101 command_line->AppendSwitch(switches::kDomAutomationController); 102 103 command_line->AppendSwitch(switches::kSkipGpuDataLoading); 104 105 MainFunctionParams params(*command_line); 106 params.ui_task = 107 new base::Closure( 108 base::Bind(&BrowserTestBase::ProxyRunTestOnMainThreadLoop, this)); 109 110#if defined(USE_AURA) 111 // Use test contexts for browser tests unless they override and force us to 112 // use a real context. 113 if (allow_test_contexts_) 114 command_line->AppendSwitch(switches::kTestCompositor); 115#endif 116 117 // When using real GL contexts, we usually use OSMesa as this works on all 118 // bots. The command line can override this behaviour to use a real GPU. 119 if (command_line->HasSwitch(switches::kUseGpuInTests)) 120 allow_osmesa_ = false; 121 122 // Some bots pass this flag when they want to use a real GPU. 123 if (command_line->HasSwitch("enable-gpu")) 124 allow_osmesa_ = false; 125 126#if defined(OS_MACOSX) 127 // On Mac we always use a real GPU. 128 allow_osmesa_ = false; 129#endif 130 131#if defined(OS_ANDROID) 132 // On Android we always use a real GPU. 133 allow_osmesa_ = false; 134#endif 135 136#if defined(OS_CHROMEOS) 137 // If the test is running on the chromeos envrionment (such as 138 // device or vm bots), the compositor will use real GL contexts, and 139 // we should use real GL bindings with it. 140 if (base::chromeos::IsRunningOnChromeOS()) 141 allow_osmesa_ = false; 142#endif 143 144 if (command_line->HasSwitch(switches::kUseGL)) { 145 NOTREACHED() << 146 "kUseGL should not be used with tests. Try kUseGpuInTests instead."; 147 } 148 149 if (allow_osmesa_) { 150 command_line->AppendSwitchASCII( 151 switches::kUseGL, gfx::kGLImplementationOSMesaName); 152 } 153 154 SetUpInProcessBrowserTestFixture(); 155#if defined(OS_ANDROID) 156 BrowserMainRunner::Create()->Initialize(params); 157 // We are done running the test by now. During teardown we 158 // need to be able to perform IO. 159 base::ThreadRestrictions::SetIOAllowed(true); 160 BrowserThread::PostTask( 161 BrowserThread::IO, FROM_HERE, 162 base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed), 163 true)); 164#else 165 BrowserMain(params); 166#endif 167 TearDownInProcessBrowserTestFixture(); 168} 169 170void BrowserTestBase::TearDown() { 171} 172 173void BrowserTestBase::ProxyRunTestOnMainThreadLoop() { 174#if defined(OS_POSIX) 175 if (handle_sigterm_) { 176 g_browser_process_pid = base::GetCurrentProcId(); 177 signal(SIGTERM, DumpStackTraceSignalHandler); 178 } 179#endif // defined(OS_POSIX) 180 RunTestOnMainThreadLoop(); 181 embedded_test_server_.reset(); 182} 183 184void BrowserTestBase::CreateTestServer(const base::FilePath& test_server_base) { 185 CHECK(!test_server_.get()); 186 test_server_.reset(new net::SpawnedTestServer( 187 net::SpawnedTestServer::TYPE_HTTP, 188 net::SpawnedTestServer::kLocalhost, 189 test_server_base)); 190} 191 192void BrowserTestBase::PostTaskToInProcessRendererAndWait( 193 const base::Closure& task) { 194 CHECK(CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)); 195 196 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner; 197 198 base::MessageLoop* renderer_loop = 199 RenderProcessHostImpl::GetInProcessRendererThreadForTesting(); 200 CHECK(renderer_loop); 201 202 renderer_loop->PostTask( 203 FROM_HERE, 204 base::Bind(&RunTaskOnRendererThread, task, runner->QuitClosure())); 205 runner->Run(); 206} 207 208} // namespace content 209