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