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 <fcntl.h>
8 #include <stddef.h>
9
10 #include <iostream>
11 #include <memory>
12 #include <utility>
13 #include <vector>
14
15 #include "base/base_switches.h"
16 #include "base/bind.h"
17 #include "base/command_line.h"
18 #include "base/debug/stack_trace.h"
19 #include "base/feature_list.h"
20 #include "base/files/file_path.h"
21 #include "base/files/scoped_file.h"
22 #include "base/i18n/icu_util.h"
23 #include "base/location.h"
24 #include "base/macros.h"
25 #include "base/rand_util.h"
26 #include "base/run_loop.h"
27 #include "base/single_thread_task_runner.h"
28 #include "base/strings/string_number_conversions.h"
29 #include "base/strings/string_util.h"
30 #include "base/system/sys_info.h"
31 #include "base/task/current_thread.h"
32 #include "base/task/thread_pool/thread_pool_instance.h"
33 #include "base/test/bind.h"
34 #include "base/test/scoped_run_loop_timeout.h"
35 #include "base/test/test_timeouts.h"
36 #include "base/threading/thread_restrictions.h"
37 #include "base/threading/thread_task_runner_handle.h"
38 #include "build/build_config.h"
39 #include "build/chromeos_buildflags.h"
40 #include "content/browser/browser_main_loop.h"
41 #include "content/browser/browser_thread_impl.h"
42 #include "content/browser/network_service_instance_impl.h"
43 #include "content/browser/renderer_host/render_process_host_impl.h"
44 #include "content/browser/scheduler/browser_task_executor.h"
45 #include "content/browser/startup_data_impl.h"
46 #include "content/browser/startup_helper.h"
47 #include "content/browser/storage_partition_impl.h"
48 #include "content/browser/tracing/memory_instrumentation_util.h"
49 #include "content/browser/tracing/tracing_controller_impl.h"
50 #include "content/public/app/content_main.h"
51 #include "content/public/browser/browser_task_traits.h"
52 #include "content/public/browser/browser_thread.h"
53 #include "content/public/browser/network_service_instance.h"
54 #include "content/public/browser/web_contents.h"
55 #include "content/public/common/content_client.h"
56 #include "content/public/common/content_switches.h"
57 #include "content/public/common/main_function_params.h"
58 #include "content/public/common/network_service_util.h"
59 #include "content/public/test/browser_test_utils.h"
60 #include "content/public/test/no_renderer_crashes_assertion.h"
61 #include "content/public/test/test_launcher.h"
62 #include "content/public/test/test_utils.h"
63 #include "content/test/content_browser_consistency_checker.h"
64 #include "gpu/command_buffer/service/gpu_switches.h"
65 #include "gpu/config/gpu_switches.h"
66 #include "media/base/media_switches.h"
67 #include "mojo/public/cpp/bindings/remote.h"
68 #include "mojo/public/cpp/bindings/sync_call_restrictions.h"
69 #include "mojo/public/cpp/platform/named_platform_channel.h"
70 #include "mojo/public/cpp/platform/platform_channel.h"
71 #include "net/dns/mock_host_resolver.h"
72 #include "net/test/embedded_test_server/embedded_test_server.h"
73 #include "services/network/public/cpp/features.h"
74 #include "services/network/public/mojom/network_service_test.mojom.h"
75 #include "services/tracing/public/cpp/trace_startup.h"
76 #include "ui/base/ui_base_features.h"
77 #include "ui/compositor/compositor_switches.h"
78 #include "ui/display/display_switches.h"
79 #include "ui/gl/gl_implementation.h"
80 #include "ui/gl/gl_switches.h"
81
82 #if defined(OS_LINUX) || defined(OS_CHROMEOS)
83 #include "ui/platform_window/common/platform_window_defaults.h" // nogncheck
84 #endif
85
86 #if defined(OS_ANDROID)
87 #include "base/android/task_scheduler/post_task_android.h"
88 #include "components/discardable_memory/service/discardable_shared_memory_manager.h" // nogncheck
89 #include "content/app/content_main_runner_impl.h"
90 #include "content/app/mojo/mojo_init.h"
91 #include "content/app/service_manager_environment.h"
92 #include "content/public/app/content_main_delegate.h"
93 #include "content/public/common/content_paths.h"
94 #include "testing/android/native_test/native_browser_test_support.h"
95 #include "ui/base/ui_base_paths.h"
96
97 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
98 #include "gin/v8_initializer.h" // nogncheck
99 #endif
100 #endif
101
102 #if defined(OS_MAC)
103 #include "content/browser/sandbox_parameters_mac.h"
104 #include "net/test/test_data_directory.h"
105 #include "ui/events/test/event_generator.h"
106 #include "ui/views/test/event_generator_delegate_mac.h"
107 #endif
108
109 #if defined(OS_FREEBSD) || defined(OS_DRAGONFLY)
110 #include <sys/signal.h>
111 #endif
112
113 #if defined(OS_POSIX)
114 #include "base/process/process_handle.h"
115 #endif
116
117 #if defined(USE_AURA)
118 #include "content/browser/compositor/image_transport_factory.h"
119 #include "ui/aura/test/event_generator_delegate_aura.h" // nogncheck
120 #endif
121
122 #if BUILDFLAG(IS_LACROS)
123 #include "base/files/file_path.h"
124 #include "base/files/scoped_file.h"
125 #include "chromeos/lacros/lacros_chrome_service_impl.h"
126 #include "mojo/public/cpp/platform/named_platform_channel.h"
127 #include "mojo/public/cpp/platform/platform_channel.h"
128 #include "mojo/public/cpp/platform/socket_utils_posix.h"
129 #endif
130
131 namespace content {
132 namespace {
133
134 // Whether an instance of BrowserTestBase has already been created in this
135 // process. Browser tests should each be run in a new process.
136 bool g_instance_already_created = false;
137
138 #if defined(OS_POSIX)
139 // On SIGSEGV or SIGTERM (sent by the runner on timeouts), dump a stack trace
140 // (to make debugging easier) and also exit with a known error code (so that
141 // the test framework considers this a failure -- http://crbug.com/57578).
142 // Note: We only want to do this in the browser process, and not forked
143 // processes. That might lead to hangs because of locks inside tcmalloc or the
144 // OS. See http://crbug.com/141302.
145 int g_browser_process_pid;
146
DumpStackTraceSignalHandler(int signal)147 void DumpStackTraceSignalHandler(int signal) {
148 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
149 switches::kDisableInProcessStackTraces) &&
150 g_browser_process_pid == base::GetCurrentProcId()) {
151 std::string message("BrowserTestBase received signal: ");
152 message += strsignal(signal);
153 message += ". Backtrace:\n";
154 logging::RawLog(logging::LOG_ERROR, message.c_str());
155 auto stack_trace = base::debug::StackTrace();
156 stack_trace.OutputToStream(&std::cerr);
157 #if defined(OS_ANDROID)
158 // Also output the trace to logcat on Android.
159 stack_trace.Print();
160 #endif
161 }
162 _exit(128 + signal);
163 }
164 #endif // defined(OS_POSIX)
165
RunTaskOnRendererThread(base::OnceClosure task,base::OnceClosure quit_task)166 void RunTaskOnRendererThread(base::OnceClosure task,
167 base::OnceClosure quit_task) {
168 std::move(task).Run();
169 GetUIThreadTaskRunner({})->PostTask(FROM_HERE, std::move(quit_task));
170 }
171
TraceStopTracingComplete(base::OnceClosure quit,const base::FilePath & file_path)172 void TraceStopTracingComplete(base::OnceClosure quit,
173 const base::FilePath& file_path) {
174 LOG(ERROR) << "Tracing written to: " << file_path.value();
175 std::move(quit).Run();
176 }
177
178 // See SetInitialWebContents comment for more information.
179 class InitialNavigationObserver : public WebContentsObserver {
180 public:
InitialNavigationObserver(WebContents * web_contents,base::OnceClosure callback)181 InitialNavigationObserver(WebContents* web_contents,
182 base::OnceClosure callback)
183 : WebContentsObserver(web_contents), callback_(std::move(callback)) {}
184 // WebContentsObserver implementation:
DidStartNavigation(NavigationHandle * navigation_handle)185 void DidStartNavigation(NavigationHandle* navigation_handle) override {
186 if (callback_)
187 std::move(callback_).Run();
188 }
189
190 private:
191 base::OnceClosure callback_;
192
193 DISALLOW_COPY_AND_ASSIGN(InitialNavigationObserver);
194 };
195
196 } // namespace
197
BrowserTestBase()198 BrowserTestBase::BrowserTestBase() {
199 #if defined(USE_OZONE) && defined(USE_X11)
200 // In case of the USE_OZONE + USE_X11 build, the OzonePlatform can either be
201 // enabled or disabled. However, tests may override the FeatureList that will
202 // result in unknown state for the UseOzonePlatform feature. Thus, the
203 // features::IsUsingOzonePlatform has static const initializer that won't be
204 // changed despite FeatureList being overridden. However, it requires to call
205 // this method at least once so that the value is set correctly. This place
206 // looks the most appropriate as tests haven't started to add own FeatureList
207 // yet and we still have the original value set by base::TestSuite.
208 ignore_result(features::IsUsingOzonePlatform());
209 #endif
210
211 CHECK(!g_instance_already_created)
212 << "Each browser test should be run in a new process. If you are adding "
213 "a new browser test suite that runs on Android, please add it to "
214 "//build/android/pylib/gtest/gtest_test_instance.py.";
215 g_instance_already_created = true;
216 #if defined(OS_LINUX) || defined(OS_CHROMEOS)
217 ui::test::EnableTestConfigForPlatformWindows();
218 #endif
219
220 #if defined(OS_POSIX)
221 handle_sigterm_ = true;
222 #endif
223
224 // This is called through base::TestSuite initially. It'll also be called
225 // inside BrowserMain, so tell the code to ignore the check that it's being
226 // called more than once
227 base::i18n::AllowMultipleInitializeCallsForTesting();
228
229 embedded_test_server_ = std::make_unique<net::EmbeddedTestServer>();
230
231 #if defined(USE_AURA)
232 ui::test::EventGeneratorDelegate::SetFactoryFunction(
233 base::BindRepeating(&aura::test::EventGeneratorDelegateAura::Create));
234 #elif defined(OS_MAC)
235 ui::test::EventGeneratorDelegate::SetFactoryFunction(
236 base::BindRepeating(&views::test::CreateEventGeneratorDelegateMac));
237 #endif
238 }
239
~BrowserTestBase()240 BrowserTestBase::~BrowserTestBase() {
241 CHECK(set_up_called_ || IsSkipped())
242 << "SetUp was not called. This probably means that the "
243 "developer has overridden the method and not called "
244 "the superclass version. In this case, the test "
245 "does not run and reports a false positive result.";
246 }
247
SetUp()248 void BrowserTestBase::SetUp() {
249 set_up_called_ = true;
250
251 if (!UseProductionQuotaSettings()) {
252 // By default use hardcoded quota settings to have a consistent testing
253 // environment.
254 const int kQuota = 5 * 1024 * 1024;
255 quota_settings_ =
256 std::make_unique<storage::QuotaSettings>(kQuota * 5, kQuota, 0, 0);
257 StoragePartitionImpl::SetDefaultQuotaSettingsForTesting(
258 quota_settings_.get());
259 }
260
261 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
262
263 if (!command_line->HasSwitch(switches::kUseFakeDeviceForMediaStream))
264 command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
265
266 // Features that depend on external factors (e.g. memory pressure monitor) can
267 // disable themselves based on the switch below (to ensure that browser tests
268 // behave deterministically / do not flakily change behavior based on external
269 // factors).
270 command_line->AppendSwitch(switches::kBrowserTest);
271
272 // Override the child process connection timeout since tests can exceed that
273 // when sharded.
274 command_line->AppendSwitchASCII(
275 switches::kIPCConnectionTimeout,
276 base::NumberToString(TestTimeouts::action_max_timeout().InSeconds()));
277
278 command_line->AppendSwitch(switches::kDomAutomationController);
279
280 // It is sometimes useful when looking at browser test failures to know which
281 // GPU blacklisting decisions were made.
282 command_line->AppendSwitch(switches::kLogGpuControlListDecisions);
283
284 // Make sure software compositing tests don't attempt to force hardware
285 // compositing.
286 if (use_software_compositing_) {
287 command_line->AppendSwitch(switches::kDisableGpu);
288 command_line->RemoveSwitch(switches::kDisableSoftwareCompositingFallback);
289 }
290
291 // The layout of windows on screen is unpredictable during tests, so disable
292 // occlusion when running browser tests.
293 command_line->AppendSwitch(
294 switches::kDisableBackgroundingOccludedWindowsForTesting);
295
296 if (enable_pixel_output_) {
297 DCHECK(!command_line->HasSwitch(switches::kForceDeviceScaleFactor))
298 << "--force-device-scale-factor flag already present. Tests using "
299 << "EnablePixelOutput should specify a forced device scale factor by "
300 << "passing it as an argument to EnblePixelOutput.";
301 DCHECK(force_device_scale_factor_);
302
303 // We do this before setting enable_pixel_output_ from the switch below so
304 // that the device scale factor is forced only when enabled from test code.
305 command_line->AppendSwitchASCII(
306 switches::kForceDeviceScaleFactor,
307 base::StringPrintf("%f", force_device_scale_factor_));
308 }
309
310 #if defined(USE_AURA)
311 // Most tests do not need pixel output, so we don't produce any. The command
312 // line can override this behaviour to allow for visual debugging.
313 if (command_line->HasSwitch(switches::kEnablePixelOutputInTests))
314 enable_pixel_output_ = true;
315
316 if (command_line->HasSwitch(switches::kDisableGLDrawingForTests)) {
317 NOTREACHED() << "kDisableGLDrawingForTests should not be used as it"
318 "is chosen by tests. Use kEnablePixelOutputInTests "
319 "to enable pixel output.";
320 }
321
322 // Don't enable pixel output for browser tests unless they override and force
323 // us to, or it's requested on the command line.
324 if (!enable_pixel_output_ && !use_software_compositing_)
325 command_line->AppendSwitch(switches::kDisableGLDrawingForTests);
326 #endif
327
328 bool use_software_gl = true;
329
330 // We usually use software GL as this works on all bots. The command
331 // line can override this behaviour to use hardware GL.
332 if (command_line->HasSwitch(switches::kUseGpuInTests))
333 use_software_gl = false;
334
335 // Some bots pass this flag when they want to use hardware GL.
336 if (command_line->HasSwitch("enable-gpu"))
337 use_software_gl = false;
338
339 #if defined(OS_MAC)
340 // On Mac we always use hardware GL.
341 use_software_gl = false;
342
343 // Expand the network service sandbox to allow reading the test TLS
344 // certificates.
345 SetNetworkTestCertsDirectoryForTesting(net::GetTestCertsDirectory());
346 #endif
347
348 #if defined(OS_ANDROID)
349 // On Android we always use hardware GL.
350 use_software_gl = false;
351 #endif
352
353 #if defined(OS_CHROMEOS)
354 // If the test is running on the chromeos envrionment (such as
355 // device or vm bots), we use hardware GL.
356 if (base::SysInfo::IsRunningOnChromeOS())
357 use_software_gl = false;
358 #endif
359
360 #if BUILDFLAG(IS_LACROS)
361 // If the test is running on the lacros environment, a file descriptor needs
362 // to be obtained and used to launch lacros-chrome so that a mojo connection
363 // between lacros-chrome and ash-chrome can be established.
364 // For more details, please see:
365 // //chrome/browser/chromeos/crosapi/test_mojo_connection_manager.h.
366 {
367 // TODO(crbug.com/1127581): Switch to use |kLacrosMojoSocketForTesting| in
368 // //chromeos/constants/chromeos_switches.h.
369 // Please refer to the CL comments for why it can't be done now:
370 // http://crrev.com/c/2402580/2/content/public/test/browser_test_base.cc
371 std::string socket_path =
372 command_line->GetSwitchValueASCII("lacros-mojo-socket-for-testing");
373 if (socket_path.empty()) {
374 chromeos::LacrosChromeServiceImpl::Get()->DisableCrosapiForTests();
375 } else {
376 auto channel = mojo::NamedPlatformChannel::ConnectToServer(socket_path);
377 base::ScopedFD socket_fd = channel.TakePlatformHandle().TakeFD();
378
379 // Mark the channel as blocking.
380 int flags = fcntl(socket_fd.get(), F_GETFL);
381 PCHECK(flags != -1);
382 fcntl(socket_fd.get(), F_SETFL, flags & ~O_NONBLOCK);
383
384 uint8_t buf[32];
385 std::vector<base::ScopedFD> descriptors;
386 auto size = mojo::SocketRecvmsg(socket_fd.get(), buf, sizeof(buf),
387 &descriptors, true /*block*/);
388 if (size < 0)
389 PLOG(ERROR) << "Error receiving message from the socket";
390 ASSERT_EQ(1, size);
391 EXPECT_EQ(0u, buf[0]);
392 ASSERT_EQ(1u, descriptors.size());
393 // It's OK to release the FD because lacros-chrome's code will consume it.
394 command_line->AppendSwitchASCII(
395 mojo::PlatformChannel::kHandleSwitch,
396 base::NumberToString(descriptors[0].release()));
397 }
398 }
399 #endif
400
401 if (use_software_gl && !use_software_compositing_)
402 command_line->AppendSwitch(switches::kOverrideUseSoftwareGLForTests);
403
404 // Use an sRGB color profile to ensure that the machine's color profile does
405 // not affect the results.
406 command_line->AppendSwitchASCII(switches::kForceDisplayColorProfile, "srgb");
407
408 if (!allow_network_access_to_host_resolutions_)
409 test_host_resolver_ = std::make_unique<TestHostResolver>();
410
411 ContentBrowserConsistencyChecker scoped_enable_consistency_checks;
412
413 SetUpInProcessBrowserTestFixture();
414
415 // Should not use CommandLine to modify features. Please use ScopedFeatureList
416 // instead.
417 DCHECK(!command_line->HasSwitch(switches::kEnableFeatures));
418 DCHECK(!command_line->HasSwitch(switches::kDisableFeatures));
419
420 // At this point, copy features to the command line, since BrowserMain will
421 // wipe out the current feature list.
422 std::string enabled_features;
423 std::string disabled_features;
424 if (base::FeatureList::GetInstance()) {
425 base::FeatureList::GetInstance()->GetFeatureOverrides(&enabled_features,
426 &disabled_features);
427 }
428
429 #if defined(USE_X11) && defined(USE_OZONE)
430 // Append OzonePlatform to the enabled features so that the CommandLine
431 // instance has correct values, and other processes if any (GPU, for example),
432 // also use correct path. features::IsUsingOzonePlatform() has static const
433 // initializer, which means the value of the features::IsUsingOzonePlatform()
434 // doesn't change even if tests override the FeatureList. Thus, it's correct
435 // to call it now as it is set way earlier than tests override the features.
436 //
437 // TODO(https://crbug.com/1096425): remove this as soon as use_x11 goes away.
438 if (features::IsUsingOzonePlatform())
439 enabled_features += ",UseOzonePlatform";
440 #endif
441
442 if (!enabled_features.empty()) {
443 command_line->AppendSwitchASCII(switches::kEnableFeatures,
444 enabled_features);
445 }
446 if (!disabled_features.empty()) {
447 command_line->AppendSwitchASCII(switches::kDisableFeatures,
448 disabled_features);
449 }
450
451 // Always disable the unsandbox GPU process for DX12 Info collection to avoid
452 // interference. This GPU process is launched 120 seconds after chrome starts.
453 command_line->AppendSwitch(switches::kDisableGpuProcessForDX12InfoCollection);
454
455 // The current global field trial list contains any trials that were activated
456 // prior to main browser startup. That global field trial list is about to be
457 // destroyed below, and will be recreated during the browser_tests browser
458 // process startup code. Pass the currently active trials to the subsequent
459 // list via the command line.
460 std::string field_trial_states;
461 base::FieldTrialList::AllStatesToString(&field_trial_states, false);
462 if (!field_trial_states.empty()) {
463 // Please use ScopedFeatureList to modify feature and field trials at the
464 // same time.
465 DCHECK(!command_line->HasSwitch(switches::kForceFieldTrials));
466 command_line->AppendSwitchASCII(switches::kForceFieldTrials,
467 field_trial_states);
468 }
469
470 // Need to wipe feature list clean, since BrowserMain calls
471 // FeatureList::SetInstance, which expects no instance to exist.
472 base::FeatureList::ClearInstanceForTesting();
473
474 auto created_main_parts_closure =
475 std::make_unique<CreatedMainPartsClosure>(base::BindOnce(
476 &BrowserTestBase::CreatedBrowserMainParts, base::Unretained(this)));
477
478 #if defined(OS_ANDROID)
479 // For all other platforms, we call ContentMain for browser tests which goes
480 // through the normal browser initialization paths. For Android, we must set
481 // things up manually. A meager re-implementation of ContentMainRunnerImpl
482 // follows.
483
484 base::i18n::AllowMultipleInitializeCallsForTesting();
485 base::i18n::InitializeICU();
486
487 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
488 gin::V8Initializer::LoadV8Snapshot();
489 #endif
490
491 ContentMainDelegate* delegate = GetContentMainDelegateForTesting();
492 // The delegate should have been set by JNI_OnLoad for the test target.
493 DCHECK(delegate);
494
495 bool startup_error = delegate->BasicStartupComplete(/*exit_code=*/nullptr);
496 DCHECK(!startup_error);
497
498 InitializeMojo();
499
500 // We can only setup startup tracing after mojo is initialized above.
501 tracing::EnableStartupTracingIfNeeded();
502
503 {
504 SetBrowserClientForTesting(delegate->CreateContentBrowserClient());
505 if (command_line->HasSwitch(switches::kSingleProcess))
506 SetRendererClientForTesting(delegate->CreateContentRendererClient());
507
508 content::RegisterPathProvider();
509 ui::RegisterPathProvider();
510
511 delegate->PreSandboxStartup();
512
513 DCHECK(!field_trial_list_);
514 if (delegate->ShouldCreateFeatureList()) {
515 field_trial_list_ = SetUpFieldTrialsAndFeatureList();
516 delegate->PostFieldTrialInitialization();
517 }
518
519 base::ThreadPoolInstance::Create("Browser");
520
521 delegate->PreCreateMainMessageLoop();
522 BrowserTaskExecutor::Create();
523 delegate->PostEarlyInitialization(/*is_running_tests=*/true);
524
525 StartBrowserThreadPool();
526 BrowserTaskExecutor::PostFeatureListSetup();
527 tracing::InitTracingPostThreadPoolStartAndFeatureList();
528 InitializeBrowserMemoryInstrumentationClient();
529 }
530
531 blink::TrialTokenValidator::SetOriginTrialPolicyGetter(
532 base::BindRepeating([]() -> blink::OriginTrialPolicy* {
533 ContentClient* client = GetContentClientForTesting();
534 return client ? client->GetOriginTrialPolicy() : nullptr;
535 }));
536
537 // All FeatureList overrides should have been registered prior to browser test
538 // SetUp().
539 base::FeatureList::ScopedDisallowOverrides disallow_feature_overrides(
540 "FeatureList overrides must happen in the test constructor, before "
541 "BrowserTestBase::SetUp() has run.");
542
543 auto discardable_shared_memory_manager =
544 std::make_unique<discardable_memory::DiscardableSharedMemoryManager>();
545 auto service_manager_env = std::make_unique<ServiceManagerEnvironment>(
546 BrowserTaskExecutor::CreateIOThread());
547 std::unique_ptr<StartupDataImpl> startup_data =
548 service_manager_env->CreateBrowserStartupData();
549
550 // ContentMain would normally call RunProcess() on the delegate and fallback
551 // to BrowserMain() if it did not run it (or equivalent) itself. On Android,
552 // RunProcess() will return 0 so we don't have to fallback to BrowserMain().
553 {
554 // This loop will wait until Java completes async initializion and the test
555 // is ready to run. We must allow nestable tasks so that tasks posted to the
556 // UI thread run as well. The loop is created before RunProcess() so that
557 // the StartupTaskRunner tasks will be nested inside this loop and able to
558 // run.
559 base::RunLoop loop{base::RunLoop::Type::kNestableTasksAllowed};
560
561 auto ui_task = std::make_unique<base::OnceClosure>(
562 base::BindOnce(&BrowserTestBase::WaitUntilJavaIsReady,
563 base::Unretained(this), loop.QuitClosure()));
564
565 // The MainFunctionParams must out-live all the startup tasks running.
566 MainFunctionParams params(*command_line);
567 params.ui_task = ui_task.release();
568 params.created_main_parts_closure = created_main_parts_closure.release();
569 params.startup_data = startup_data.get();
570 // Passing "" as the process type to indicate the browser process.
571 int exit_code = delegate->RunProcess("", params);
572 DCHECK_EQ(exit_code, 0);
573
574 // Waits for Java to finish initialization, then we can run the test.
575 loop.Run();
576
577 // The BrowserMainLoop startup tasks will call DisallowUnresponsiveTasks().
578 // So when we run the ProxyRunTestOnMainThreadLoop() we no longer can block,
579 // but tests should be allowed to. So we undo that blocking inside here.
580 base::ScopedAllowUnresponsiveTasksForTesting allow_unresponsive;
581 // Runs the test now that the Java setup is complete. This must be called
582 // directly from the same call stack as RUN_ALL_TESTS(), it may not be
583 // inside a posted task, or it would prevent NonNestable tasks from running
584 // inside tests.
585 ProxyRunTestOnMainThreadLoop();
586 }
587
588 {
589 base::ScopedAllowBaseSyncPrimitivesForTesting allow_wait;
590 // Shutting these down will block the thread.
591 ShutDownNetworkService();
592 service_manager_env.reset();
593 discardable_shared_memory_manager.reset();
594 }
595
596 base::PostTaskAndroid::SignalNativeSchedulerShutdownForTesting();
597 BrowserTaskExecutor::Shutdown();
598
599 // Normally the BrowserMainLoop does this during shutdown but on Android we
600 // don't go through shutdown, so this doesn't happen there. We do need it
601 // for the test harness to be able to delete temp dirs.
602 base::ThreadRestrictions::SetIOAllowed(true);
603 #else // defined(OS_ANDROID)
604 auto ui_task = std::make_unique<base::OnceClosure>(base::BindOnce(
605 &BrowserTestBase::ProxyRunTestOnMainThreadLoop, base::Unretained(this)));
606 GetContentMainParams()->ui_task = ui_task.release();
607 GetContentMainParams()->created_main_parts_closure =
608 created_main_parts_closure.release();
609 EXPECT_EQ(expected_exit_code_, ContentMain(*GetContentMainParams()));
610 #endif // defined(OS_ANDROID)
611 TearDownInProcessBrowserTestFixture();
612 }
613
TearDown()614 void BrowserTestBase::TearDown() {
615 #if defined(USE_AURA) || defined(OS_MAC)
616 ui::test::EventGeneratorDelegate::SetFactoryFunction(
617 ui::test::EventGeneratorDelegate::FactoryFunction());
618 #endif
619
620 StoragePartitionImpl::SetDefaultQuotaSettingsForTesting(nullptr);
621 }
622
UseProductionQuotaSettings()623 bool BrowserTestBase::UseProductionQuotaSettings() {
624 return false;
625 }
626
SimulateNetworkServiceCrash()627 void BrowserTestBase::SimulateNetworkServiceCrash() {
628 CHECK(!IsInProcessNetworkService())
629 << "Can't crash the network service if it's running in-process!";
630 mojo::Remote<network::mojom::NetworkServiceTest> network_service_test;
631 content::GetNetworkService()->BindTestInterface(
632 network_service_test.BindNewPipeAndPassReceiver());
633
634 base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
635 network_service_test.set_disconnect_handler(run_loop.QuitClosure());
636
637 network_service_test->SimulateCrash();
638 run_loop.Run();
639
640 // Make sure the cached mojo::Remote<NetworkService> receives error
641 // notification.
642 FlushNetworkServiceInstanceForTesting();
643
644 // Need to re-initialize the network process.
645 initialized_network_process_ = false;
646 InitializeNetworkProcess();
647 }
648
649 #if defined(OS_ANDROID)
WaitUntilJavaIsReady(base::OnceClosure quit_closure)650 void BrowserTestBase::WaitUntilJavaIsReady(base::OnceClosure quit_closure) {
651 if (testing::android::JavaAsyncStartupTasksCompleteForBrowserTests()) {
652 std::move(quit_closure).Run();
653 return;
654 }
655
656 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
657 FROM_HERE,
658 base::BindOnce(&BrowserTestBase::WaitUntilJavaIsReady,
659 base::Unretained(this), std::move(quit_closure)),
660 base::TimeDelta::FromMilliseconds(100));
661 return;
662 }
663 #endif
664
665 namespace {
666
GetDefaultTraceFilename()667 std::string GetDefaultTraceFilename() {
668 std::string test_suite_name = ::testing::UnitTest::GetInstance()
669 ->current_test_info()
670 ->test_suite_name();
671 std::string test_name =
672 ::testing::UnitTest::GetInstance()->current_test_info()->name();
673 // Parameterised tests might have slashes in their full name — replace them
674 // before using it as a file name to avoid trying to write to an incorrect
675 // location.
676 base::ReplaceChars(test_suite_name, "/", "_", &test_suite_name);
677 base::ReplaceChars(test_name, "/", "_", &test_name);
678 // Add random number to the trace file to distinguish traces from different
679 // test runs.
680 // We don't use timestamp here to avoid collisions with parallel runs of the
681 // same test.
682 std::string random_seed = base::NumberToString(base::RandInt(1e7, 1e8 - 1));
683 std::string status = ::testing::UnitTest::GetInstance()
684 ->current_test_info()
685 ->result()
686 ->Passed()
687 ? "OK"
688 : "FAIL";
689 return "trace_test_" + test_suite_name + "_" + test_name + "_" + random_seed +
690 "_" + status + ".json";
691 }
692
693 } // namespace
694
ProxyRunTestOnMainThreadLoop()695 void BrowserTestBase::ProxyRunTestOnMainThreadLoop() {
696 #if !defined(OS_ANDROID)
697 // All FeatureList overrides should have been registered prior to browser test
698 // SetUp(). Note that on Android, this scoper lives in SetUp() above.
699 base::FeatureList::ScopedDisallowOverrides disallow_feature_overrides(
700 "FeatureList overrides must happen in the test constructor, before "
701 "BrowserTestBase::SetUp() has run.");
702 #endif
703
704 // Install a RunLoop timeout if none is present but do not override tests that
705 // set a ScopedLoopRunTimeout from their fixture's constructor (which
706 // happens as part of setting up the test factory in gtest while
707 // ProxyRunTestOnMainThreadLoop() happens later as part of SetUp()).
708 base::Optional<base::test::ScopedRunLoopTimeout> scoped_run_timeout;
709 if (!base::test::ScopedRunLoopTimeout::ExistsForCurrentThread()) {
710 // TODO(https://crbug.com/918724): determine whether the timeout can be
711 // reduced from action_max_timeout() to action_timeout().
712 scoped_run_timeout.emplace(FROM_HERE, TestTimeouts::action_max_timeout());
713 }
714
715 #if defined(OS_POSIX)
716 g_browser_process_pid = base::GetCurrentProcId();
717 signal(SIGSEGV, DumpStackTraceSignalHandler);
718
719 if (handle_sigterm_)
720 signal(SIGTERM, DumpStackTraceSignalHandler);
721 #endif // defined(OS_POSIX)
722
723 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
724 switches::kEnableTracing)) {
725 base::trace_event::TraceConfig trace_config(
726 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
727 switches::kEnableTracing),
728 base::trace_event::RECORD_CONTINUOUSLY);
729 TracingController::GetInstance()->StartTracing(
730 trace_config,
731 TracingController::StartTracingDoneCallback());
732 }
733
734 {
735 // This can be called from a posted task. Allow nested tasks here, because
736 // otherwise the test body will have to do it in order to use RunLoop for
737 // waiting.
738 base::CurrentThread::ScopedNestableTaskAllower allow;
739
740 #if !defined(OS_ANDROID)
741 // Fail the test if a renderer crashes while the test is running.
742 //
743 // This cannot be enabled on Android, because of renderer kills triggered
744 // aggressively by the OS itself.
745 no_renderer_crashes_assertion_ =
746 std::make_unique<NoRendererCrashesAssertion>();
747 #endif
748
749 PreRunTestOnMainThread();
750 std::unique_ptr<InitialNavigationObserver> initial_navigation_observer;
751 if (initial_web_contents_) {
752 // Some tests may add host_resolver() rules in their SetUpOnMainThread
753 // method and navigate inside of it. This is a best effort to catch that
754 // and sync the host_resolver() rules to the network process in that case,
755 // to avoid navigations silently failing. This won't catch all cases, i.e.
756 // if the test creates a new window or tab and navigates that.
757 initial_navigation_observer = std::make_unique<InitialNavigationObserver>(
758 initial_web_contents_,
759 base::BindOnce(&BrowserTestBase::InitializeNetworkProcess,
760 base::Unretained(this)));
761 }
762 initial_web_contents_ = nullptr;
763 SetUpOnMainThread();
764 initial_navigation_observer.reset();
765
766 // Tests would have added their host_resolver() rules by now, so copy them
767 // to the network process if it's in use.
768 InitializeNetworkProcess();
769
770 bool old_io_allowed_value = false;
771 old_io_allowed_value = base::ThreadRestrictions::SetIOAllowed(false);
772 RunTestOnMainThread();
773 base::ThreadRestrictions::SetIOAllowed(old_io_allowed_value);
774 TearDownOnMainThread();
775 }
776
777 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
778 switches::kEnableTracing)) {
779 base::FilePath trace_file =
780 base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
781 switches::kEnableTracingOutput);
782 // If |trace_file| ends in a directory separator or is empty use a generated
783 // name in that directory (empty means current directory).
784 if (trace_file.empty() || trace_file.EndsWithSeparator())
785 trace_file = trace_file.AppendASCII(GetDefaultTraceFilename());
786
787 // Wait for tracing to collect results from the renderers.
788 base::RunLoop run_loop;
789 TracingController::GetInstance()->StopTracing(
790 TracingControllerImpl::CreateFileEndpoint(
791 trace_file, base::BindOnce(&TraceStopTracingComplete,
792 run_loop.QuitClosure(), trace_file)));
793 run_loop.Run();
794 }
795
796 PostRunTestOnMainThread();
797 }
798
SetAllowNetworkAccessToHostResolutions()799 void BrowserTestBase::SetAllowNetworkAccessToHostResolutions() {
800 const char kManualTestPrefix[] = "MANUAL_";
801 // Must be called before Setup() to take effect. This mode can only be
802 // used in manual tests to prevent flakiness in tryjobs due to the
803 // dependency on network access.
804 CHECK(!set_up_called_);
805 CHECK(base::StartsWith(
806 testing::UnitTest::GetInstance()->current_test_info()->name(),
807 kManualTestPrefix, base::CompareCase::SENSITIVE));
808 allow_network_access_to_host_resolutions_ = true;
809 }
810
CreateTestServer(const base::FilePath & test_server_base)811 void BrowserTestBase::CreateTestServer(const base::FilePath& test_server_base) {
812 embedded_test_server()->AddDefaultHandlers(test_server_base);
813 }
814
PostTaskToInProcessRendererAndWait(base::OnceClosure task)815 void BrowserTestBase::PostTaskToInProcessRendererAndWait(
816 base::OnceClosure task) {
817 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
818 switches::kSingleProcess));
819
820 scoped_refptr<base::SingleThreadTaskRunner> renderer_task_runner =
821 RenderProcessHostImpl::GetInProcessRendererThreadTaskRunnerForTesting();
822 CHECK(renderer_task_runner);
823
824 base::RunLoop run_loop;
825 renderer_task_runner->PostTask(
826 FROM_HERE, base::BindOnce(&RunTaskOnRendererThread, std::move(task),
827 run_loop.QuitClosure()));
828 run_loop.Run();
829 }
830
EnablePixelOutput(float force_device_scale_factor)831 void BrowserTestBase::EnablePixelOutput(float force_device_scale_factor) {
832 enable_pixel_output_ = true;
833 force_device_scale_factor_ = force_device_scale_factor;
834 }
835
UseSoftwareCompositing()836 void BrowserTestBase::UseSoftwareCompositing() {
837 use_software_compositing_ = true;
838 }
839
UsingSoftwareGL() const840 bool BrowserTestBase::UsingSoftwareGL() const {
841 base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
842 return cmd->GetSwitchValueASCII(switches::kUseGL) ==
843 gl::GetGLImplementationName(gl::GetSoftwareGLImplementation());
844 }
845
SetInitialWebContents(WebContents * web_contents)846 void BrowserTestBase::SetInitialWebContents(WebContents* web_contents) {
847 DCHECK(!initial_web_contents_);
848 initial_web_contents_ = web_contents;
849 }
850
InitializeNetworkProcess()851 void BrowserTestBase::InitializeNetworkProcess() {
852 if (initialized_network_process_)
853 return;
854
855 initialized_network_process_ = true;
856
857 // Test host resolver may not be initiatized if host resolutions are allowed
858 // to reach the network.
859 if (host_resolver()) {
860 host_resolver()->DisableModifications();
861 }
862
863 // Send the host resolver rules to the network service if it's in use. No need
864 // to do this if it's running in the browser process though.
865 if (!IsOutOfProcessNetworkService()) {
866 return;
867 }
868
869 mojo::Remote<network::mojom::NetworkServiceTest> network_service_test;
870 content::GetNetworkService()->BindTestInterface(
871 network_service_test.BindNewPipeAndPassReceiver());
872
873 // Do not set up host resolver rules if we allow the test to access
874 // the network.
875 if (allow_network_access_to_host_resolutions_) {
876 mojo::ScopedAllowSyncCallForTesting allow_sync_call;
877 network_service_test->SetAllowNetworkAccessToHostResolutions();
878 return;
879 }
880
881 std::vector<network::mojom::RulePtr> mojo_rules;
882
883 if (host_resolver()) {
884 net::RuleBasedHostResolverProc::RuleList rules =
885 host_resolver()->GetRules();
886 for (const auto& rule : rules) {
887 // For now, this covers all the rules used in content's tests.
888 // TODO(jam: expand this when we try to make browser_tests and
889 // components_browsertests work.
890 if (rule.resolver_type ==
891 net::RuleBasedHostResolverProc::Rule::kResolverTypeFail ||
892 rule.resolver_type ==
893 net::RuleBasedHostResolverProc::Rule::kResolverTypeFailTimeout) {
894 // The host "wpad" is added automatically in TestHostResolver, so we
895 // don't need to send it to NetworkServiceTest.
896 if (rule.host_pattern != "wpad") {
897 network::mojom::RulePtr mojo_rule = network::mojom::Rule::New();
898 mojo_rule->resolver_type =
899 (rule.resolver_type ==
900 net::RuleBasedHostResolverProc::Rule::kResolverTypeFail)
901 ? network::mojom::ResolverType::kResolverTypeFail
902 : network::mojom::ResolverType::kResolverTypeFailTimeout;
903 mojo_rule->host_pattern = rule.host_pattern;
904 mojo_rules.push_back(std::move(mojo_rule));
905 }
906 continue;
907 }
908
909 if ((rule.resolver_type !=
910 net::RuleBasedHostResolverProc::Rule::kResolverTypeSystem &&
911 rule.resolver_type !=
912 net::RuleBasedHostResolverProc::Rule::kResolverTypeIPLiteral) ||
913 rule.address_family !=
914 net::AddressFamily::ADDRESS_FAMILY_UNSPECIFIED ||
915 !!rule.latency_ms) {
916 continue;
917 }
918 network::mojom::RulePtr mojo_rule = network::mojom::Rule::New();
919 if (rule.resolver_type ==
920 net::RuleBasedHostResolverProc::Rule::kResolverTypeSystem) {
921 mojo_rule->resolver_type =
922 rule.replacement.empty()
923 ? network::mojom::ResolverType::kResolverTypeDirectLookup
924 : network::mojom::ResolverType::kResolverTypeSystem;
925 } else {
926 mojo_rule->resolver_type =
927 network::mojom::ResolverType::kResolverTypeIPLiteral;
928 }
929 mojo_rule->host_pattern = rule.host_pattern;
930 mojo_rule->replacement = rule.replacement;
931 mojo_rule->host_resolver_flags = rule.host_resolver_flags;
932 mojo_rule->canonical_name = rule.canonical_name;
933 mojo_rules.push_back(std::move(mojo_rule));
934 }
935 }
936
937 if (mojo_rules.empty()) {
938 return;
939 }
940
941 // Send the DNS rules to network service process. Android needs the RunLoop
942 // to dispatch a Java callback that makes network process to enter native
943 // code.
944 base::RunLoop loop{base::RunLoop::Type::kNestableTasksAllowed};
945 network_service_test->AddRules(std::move(mojo_rules), loop.QuitClosure());
946 loop.Run();
947 }
948
949 } // namespace content
950