• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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 "base/test/test_suite.h"
6 
7 #include <signal.h>
8 
9 #include <algorithm>
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 #include "base/allocator/partition_allocator/src/partition_alloc/partition_alloc_buildflags.h"
15 #include "base/allocator/partition_allocator/src/partition_alloc/tagging.h"
16 #include "base/at_exit.h"
17 #include "base/base_paths.h"
18 #include "base/base_switches.h"
19 #include "base/command_line.h"
20 #include "base/debug/asan_service.h"
21 #include "base/debug/debugger.h"
22 #include "base/debug/profiler.h"
23 #include "base/debug/stack_trace.h"
24 #include "base/feature_list.h"
25 #include "base/files/file_path.h"
26 #include "base/files/file_util.h"
27 #include "base/functional/bind.h"
28 #include "base/i18n/icu_util.h"
29 #include "base/i18n/rtl.h"
30 #include "base/logging.h"
31 #include "base/memory/ptr_util.h"
32 #include "base/memory/raw_ptr.h"
33 #include "base/metrics/statistics_recorder.h"
34 #include "base/no_destructor.h"
35 #include "base/path_service.h"
36 #include "base/process/launch.h"
37 #include "base/process/memory.h"
38 #include "base/process/process.h"
39 #include "base/process/process_handle.h"
40 #include "base/strings/string_piece.h"
41 #include "base/strings/utf_string_conversions.h"
42 #include "base/task/thread_pool/thread_pool_instance.h"
43 #include "base/test/gtest_xml_unittest_result_printer.h"
44 #include "base/test/gtest_xml_util.h"
45 #include "base/test/icu_test_util.h"
46 #include "base/test/launcher/unit_test_launcher.h"
47 #include "base/test/mock_entropy_provider.h"
48 #include "base/test/multiprocess_test.h"
49 #include "base/test/scoped_feature_list.h"
50 #include "base/test/scoped_run_loop_timeout.h"
51 #include "base/test/test_switches.h"
52 #include "base/test/test_timeouts.h"
53 #include "base/threading/platform_thread.h"
54 #include "base/time/time.h"
55 #include "base/tracing_buildflags.h"
56 #include "build/build_config.h"
57 #include "testing/gmock/include/gmock/gmock.h"
58 #include "testing/gtest/include/gtest/gtest.h"
59 #include "testing/multiprocess_func_list.h"
60 
61 #if BUILDFLAG(IS_APPLE)
62 #include "base/apple/scoped_nsautorelease_pool.h"
63 #endif  // BUILDFLAG(IS_APPLE)
64 
65 #if BUILDFLAG(IS_IOS)
66 #include "base/test/test_listener_ios.h"
67 #include "base/test/test_support_ios.h"
68 #else
69 #include "base/strings/string_util.h"
70 #include "third_party/icu/source/common/unicode/uloc.h"
71 #endif
72 
73 #if BUILDFLAG(IS_ANDROID)
74 #include "base/test/test_support_android.h"
75 #endif
76 
77 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
78 #include "third_party/test_fonts/fontconfig/fontconfig_util_linux.h"
79 #endif
80 
81 #if BUILDFLAG(IS_FUCHSIA)
82 #include "base/fuchsia/system_info.h"
83 #endif
84 
85 #if BUILDFLAG(IS_WIN)
86 #if defined(_DEBUG)
87 #include <crtdbg.h>
88 #endif  // _DEBUG
89 #include <windows.h>
90 
91 #include "base/debug/handle_hooks_win.h"
92 #endif  // BUILDFLAG(IS_WIN)
93 
94 #if BUILDFLAG(USE_PARTITION_ALLOC)
95 #include "base/allocator/partition_alloc_support.h"
96 #endif  // BUILDFLAG(USE_PARTITION_ALLOC)
97 
98 namespace base {
99 
100 namespace {
101 
102 // Returns true if the test is marked as "MAYBE_".
103 // When using different prefixes depending on platform, we use MAYBE_ and
104 // preprocessor directives to replace MAYBE_ with the target prefix.
IsMarkedMaybe(const testing::TestInfo & test)105 bool IsMarkedMaybe(const testing::TestInfo& test) {
106   return strncmp(test.name(), "MAYBE_", 6) == 0;
107 }
108 
109 class DisableMaybeTests : public testing::EmptyTestEventListener {
110  public:
OnTestStart(const testing::TestInfo & test_info)111   void OnTestStart(const testing::TestInfo& test_info) override {
112     ASSERT_FALSE(IsMarkedMaybe(test_info))
113         << "Probably the OS #ifdefs don't include all of the necessary "
114            "platforms.\nPlease ensure that no tests have the MAYBE_ prefix "
115            "after the code is preprocessed.";
116   }
117 };
118 
119 class ResetCommandLineBetweenTests : public testing::EmptyTestEventListener {
120  public:
ResetCommandLineBetweenTests()121   ResetCommandLineBetweenTests() : old_command_line_(CommandLine::NO_PROGRAM) {
122     // TODO(crbug.com/1123627): Remove this after A/B test is done.
123     // Workaround a test-specific race conditon with StatisticsRecorder lock
124     // initialization checking CommandLine by ensuring it's created here (when
125     // we start the test process), rather than in some arbitrary test. This
126     // prevents a race with OnTestEnd().
127     StatisticsRecorder::FindHistogram("Dummy");
128   }
129 
130   ResetCommandLineBetweenTests(const ResetCommandLineBetweenTests&) = delete;
131   ResetCommandLineBetweenTests& operator=(const ResetCommandLineBetweenTests&) =
132       delete;
133 
OnTestStart(const testing::TestInfo & test_info)134   void OnTestStart(const testing::TestInfo& test_info) override {
135     old_command_line_ = *CommandLine::ForCurrentProcess();
136   }
137 
OnTestEnd(const testing::TestInfo & test_info)138   void OnTestEnd(const testing::TestInfo& test_info) override {
139     *CommandLine::ForCurrentProcess() = old_command_line_;
140   }
141 
142  private:
143   CommandLine old_command_line_;
144 };
145 
146 // Initializes a base::test::ScopedFeatureList for each individual test, which
147 // involves a FeatureList and a FieldTrialList, such that unit test don't need
148 // to initialize them manually.
149 class FeatureListScopedToEachTest : public testing::EmptyTestEventListener {
150  public:
151   FeatureListScopedToEachTest() = default;
152   ~FeatureListScopedToEachTest() override = default;
153 
154   FeatureListScopedToEachTest(const FeatureListScopedToEachTest&) = delete;
155   FeatureListScopedToEachTest& operator=(const FeatureListScopedToEachTest&) =
156       delete;
157 
OnTestStart(const testing::TestInfo & test_info)158   void OnTestStart(const testing::TestInfo& test_info) override {
159     const CommandLine* command_line = CommandLine::ForCurrentProcess();
160 
161     // We set up a FeatureList via ScopedFeatureList::InitFromCommandLine().
162     // This ensures that code using that API will not hit an error that it's
163     // not set. It will be cleared by ~ScopedFeatureList().
164 
165     // TestFeatureForBrowserTest1 and TestFeatureForBrowserTest2 used in
166     // ContentBrowserTestScopedFeatureListTest to ensure ScopedFeatureList keeps
167     // features from command line.
168     std::string enabled =
169         command_line->GetSwitchValueASCII(switches::kEnableFeatures);
170     std::string disabled =
171         command_line->GetSwitchValueASCII(switches::kDisableFeatures);
172     enabled += ",TestFeatureForBrowserTest1";
173     disabled += ",TestFeatureForBrowserTest2";
174     scoped_feature_list_.InitFromCommandLine(enabled, disabled);
175 
176     // The enable-features and disable-features flags were just slurped into a
177     // FeatureList, so remove them from the command line. Tests should enable
178     // and disable features via the ScopedFeatureList API rather than
179     // command-line flags.
180     CommandLine new_command_line(command_line->GetProgram());
181     CommandLine::SwitchMap switches = command_line->GetSwitches();
182 
183     switches.erase(switches::kEnableFeatures);
184     switches.erase(switches::kDisableFeatures);
185 
186     for (const auto& iter : switches)
187       new_command_line.AppendSwitchNative(iter.first, iter.second);
188 
189     *CommandLine::ForCurrentProcess() = new_command_line;
190 
191     // TODO(https://crbug.com/1413674): Enable PartitionAlloc in unittests with
192     // ASAN.
193 #if BUILDFLAG(USE_PARTITION_ALLOC) && !defined(ADDRESS_SANITIZER)
194     allocator::PartitionAllocSupport::Get()->ReconfigureAfterFeatureListInit(
195         "",
196         /*configure_dangling_pointer_detector=*/true);
197 #endif
198   }
199 
OnTestEnd(const testing::TestInfo & test_info)200   void OnTestEnd(const testing::TestInfo& test_info) override {
201     scoped_feature_list_.Reset();
202   }
203 
204  private:
205   test::ScopedFeatureList scoped_feature_list_;
206 };
207 
208 class CheckForLeakedGlobals : public testing::EmptyTestEventListener {
209  public:
210   CheckForLeakedGlobals() = default;
211 
212   CheckForLeakedGlobals(const CheckForLeakedGlobals&) = delete;
213   CheckForLeakedGlobals& operator=(const CheckForLeakedGlobals&) = delete;
214 
215   // Check for leaks in individual tests.
OnTestStart(const testing::TestInfo & test)216   void OnTestStart(const testing::TestInfo& test) override {
217     feature_list_set_before_test_ = FeatureList::GetInstance();
218     thread_pool_set_before_test_ = ThreadPoolInstance::Get();
219   }
OnTestEnd(const testing::TestInfo & test)220   void OnTestEnd(const testing::TestInfo& test) override {
221     DCHECK_EQ(feature_list_set_before_test_, FeatureList::GetInstance())
222         << " in test " << test.test_case_name() << "." << test.name();
223     DCHECK_EQ(thread_pool_set_before_test_, ThreadPoolInstance::Get())
224         << " in test " << test.test_case_name() << "." << test.name();
225     feature_list_set_before_test_ = nullptr;
226     thread_pool_set_before_test_ = nullptr;
227   }
228 
229   // Check for leaks in test cases (consisting of one or more tests).
OnTestCaseStart(const testing::TestCase & test_case)230   void OnTestCaseStart(const testing::TestCase& test_case) override {
231     feature_list_set_before_case_ = FeatureList::GetInstance();
232     thread_pool_set_before_case_ = ThreadPoolInstance::Get();
233   }
OnTestCaseEnd(const testing::TestCase & test_case)234   void OnTestCaseEnd(const testing::TestCase& test_case) override {
235     DCHECK_EQ(feature_list_set_before_case_, FeatureList::GetInstance())
236         << " in case " << test_case.name();
237     DCHECK_EQ(thread_pool_set_before_case_, ThreadPoolInstance::Get())
238         << " in case " << test_case.name();
239     feature_list_set_before_case_ = nullptr;
240     thread_pool_set_before_case_ = nullptr;
241   }
242 
243  private:
244   raw_ptr<FeatureList, DanglingUntriaged> feature_list_set_before_test_ =
245       nullptr;
246   raw_ptr<FeatureList> feature_list_set_before_case_ = nullptr;
247   raw_ptr<ThreadPoolInstance> thread_pool_set_before_test_ = nullptr;
248   raw_ptr<ThreadPoolInstance> thread_pool_set_before_case_ = nullptr;
249 };
250 
251 // iOS: base::Process is not available.
252 // macOS: Tests may run at background priority locally (crbug.com/1358639#c6) or
253 // on bots (crbug.com/931721#c7).
254 #if !BUILDFLAG(IS_APPLE)
255 class CheckProcessPriority : public testing::EmptyTestEventListener {
256  public:
CheckProcessPriority()257   CheckProcessPriority() { CHECK(!IsProcessBackgrounded()); }
258 
259   CheckProcessPriority(const CheckProcessPriority&) = delete;
260   CheckProcessPriority& operator=(const CheckProcessPriority&) = delete;
261 
OnTestStart(const testing::TestInfo & test)262   void OnTestStart(const testing::TestInfo& test) override {
263     EXPECT_FALSE(IsProcessBackgrounded());
264   }
OnTestEnd(const testing::TestInfo & test)265   void OnTestEnd(const testing::TestInfo& test) override {
266     EXPECT_FALSE(IsProcessBackgrounded());
267   }
268 
269  private:
IsProcessBackgrounded() const270   bool IsProcessBackgrounded() const {
271     return Process::Current().GetPriority() == Process::Priority::kBestEffort;
272   }
273 };
274 #endif  // !BUILDFLAG(IS_APPLE)
275 
GetProfileName()276 const std::string& GetProfileName() {
277   static const NoDestructor<std::string> profile_name([]() {
278     const CommandLine& command_line = *CommandLine::ForCurrentProcess();
279     if (command_line.HasSwitch(switches::kProfilingFile))
280       return command_line.GetSwitchValueASCII(switches::kProfilingFile);
281     else
282       return std::string("test-profile-{pid}");
283   }());
284   return *profile_name;
285 }
286 
InitializeLogging()287 void InitializeLogging() {
288 #if BUILDFLAG(IS_FUCHSIA)
289   constexpr auto kLoggingDest = logging::LOG_TO_STDERR;
290 #else
291   constexpr auto kLoggingDest =
292       logging::LOG_TO_SYSTEM_DEBUG_LOG | logging::LOG_TO_STDERR;
293 #endif
294   CHECK(logging::InitLogging({.logging_dest = kLoggingDest}));
295 
296   // We want process and thread IDs because we may have multiple processes.
297 #if BUILDFLAG(IS_ANDROID)
298   // To view log output with IDs and timestamps use "adb logcat -v threadtime".
299   logging::SetLogItems(false, false, false, false);
300 #else
301   // We want process and thread IDs because we may have multiple processes.
302   logging::SetLogItems(true, true, false, false);
303 #endif  // !BUILDFLAG(IS_ANDROID)
304 }
305 
306 #if BUILDFLAG(IS_WIN)
307 // Handlers for invalid parameter, pure call, and abort. They generate a
308 // breakpoint to ensure that we get a call stack on these failures.
309 // These functions should be written to be unique in order to avoid confusing
310 // call stacks from /OPT:ICF function folding. Printing a unique message or
311 // returning a unique value will do this. Note that for best results they need
312 // to be unique from *all* functions in Chrome.
InvalidParameter(const wchar_t * expression,const wchar_t * function,const wchar_t * file,unsigned int line,uintptr_t reserved)313 void InvalidParameter(const wchar_t* expression,
314                       const wchar_t* function,
315                       const wchar_t* file,
316                       unsigned int line,
317                       uintptr_t reserved) {
318   // CRT printed message is sufficient.
319   __debugbreak();
320   _exit(1);
321 }
322 
PureCall()323 void PureCall() {
324   fprintf(stderr, "Pure-virtual function call. Terminating.\n");
325   __debugbreak();
326   _exit(1);
327 }
328 
AbortHandler(int signal)329 void AbortHandler(int signal) {
330   // Print EOL after the CRT abort message.
331   fprintf(stderr, "\n");
332   __debugbreak();
333 }
334 #endif
335 
336 }  // namespace
337 
RunUnitTestsUsingBaseTestSuite(int argc,char ** argv)338 int RunUnitTestsUsingBaseTestSuite(int argc, char** argv) {
339   TestSuite test_suite(argc, argv);
340   return LaunchUnitTests(argc, argv,
341                          BindOnce(&TestSuite::Run, Unretained(&test_suite)));
342 }
343 
TestSuite(int argc,char ** argv)344 TestSuite::TestSuite(int argc, char** argv) : argc_(argc), argv_(argv) {
345   PreInitialize();
346 }
347 
348 #if BUILDFLAG(IS_WIN)
TestSuite(int argc,wchar_t ** argv)349 TestSuite::TestSuite(int argc, wchar_t** argv) : argc_(argc) {
350   argv_as_strings_.reserve(argc);
351   argv_as_pointers_.reserve(argc + 1);
352   std::for_each(argv, argv + argc, [this](wchar_t* arg) {
353     argv_as_strings_.push_back(WideToUTF8(arg));
354     // Have to use .data() here to get a mutable pointer.
355     argv_as_pointers_.push_back(argv_as_strings_.back().data());
356   });
357   // `argv` is specified as containing `argc + 1` pointers, of which the last is
358   // null.
359   argv_as_pointers_.push_back(nullptr);
360   argv_ = argv_as_pointers_.data();
361   PreInitialize();
362 }
363 #endif  // BUILDFLAG(IS_WIN)
364 
~TestSuite()365 TestSuite::~TestSuite() {
366   if (initialized_command_line_)
367     CommandLine::Reset();
368 }
369 
370 // Don't add additional code to this method.  Instead add it to
371 // Initialize().  See bug 6436.
Run()372 int TestSuite::Run() {
373 #if BUILDFLAG(IS_APPLE)
374   apple::ScopedNSAutoreleasePool scoped_pool;
375 #endif
376 
377   std::string client_func =
378       CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
379           switches::kTestChildProcess);
380 
381 #if BUILDFLAG(IS_FUCHSIA)
382   // Cache the system info so individual tests do not need to worry about it.
383   // Some ProcessUtilTest cases, which use kTestChildProcess, do not pass any
384   // services, so skip this if that switch was present.
385   // This must be called before Initialize() because, for example,
386   // content::ContentTestSuite::Initialize() may use the cached values.
387   if (client_func.empty())
388     CHECK(FetchAndCacheSystemInfo());
389 #endif
390 
391   Initialize();
392 
393   // Check to see if we are being run as a client process.
394   if (!client_func.empty())
395     return multi_process_function_list::InvokeChildProcessTest(client_func);
396 
397 #if BUILDFLAG(IS_IOS)
398   test_listener_ios::RegisterTestEndListener();
399 #endif
400 
401 #if BUILDFLAG(IS_LINUX)
402   // There's no standard way to opt processes into MTE on Linux just yet,
403   // so this call explicitly opts this test into synchronous MTE mode, where
404   // pointer mismatches are detected immediately.
405   ::partition_alloc::ChangeMemoryTaggingModeForCurrentThread(
406       ::partition_alloc::TagViolationReportingMode::kSynchronous);
407 #elif BUILDFLAG(IS_ANDROID)
408     // On Android, the tests are opted into synchronous MTE mode by the
409     // memtagMode attribute in an AndroidManifest.xml file or via an `am compat`
410     // command, so and explicit call to ChangeMemoryTaggingModeForCurrentThread
411     // is not needed.
412 #endif
413 
414   int result = RunAllTests();
415 
416 #if BUILDFLAG(IS_APPLE)
417   // This MUST happen before Shutdown() since Shutdown() tears down
418   // objects (such as NotificationService::current()) that Cocoa
419   // objects use to remove themselves as observers.
420   scoped_pool.Recycle();
421 #endif
422 
423   Shutdown();
424 
425   return result;
426 }
427 
DisableCheckForThreadAndProcessPriority()428 void TestSuite::DisableCheckForThreadAndProcessPriority() {
429   DCHECK(!is_initialized_);
430   check_for_thread_and_process_priority_ = false;
431 }
432 
DisableCheckForLeakedGlobals()433 void TestSuite::DisableCheckForLeakedGlobals() {
434   DCHECK(!is_initialized_);
435   check_for_leaked_globals_ = false;
436 }
437 
UnitTestAssertHandler(const char * file,int line,const StringPiece summary,const StringPiece stack_trace)438 void TestSuite::UnitTestAssertHandler(const char* file,
439                                       int line,
440                                       const StringPiece summary,
441                                       const StringPiece stack_trace) {
442 #if BUILDFLAG(IS_ANDROID)
443   // Correlating test stdio with logcat can be difficult, so we emit this
444   // helpful little hint about what was running.  Only do this for Android
445   // because other platforms don't separate out the relevant logs in the same
446   // way.
447   const ::testing::TestInfo* const test_info =
448       ::testing::UnitTest::GetInstance()->current_test_info();
449   if (test_info) {
450     LOG(ERROR) << "Currently running: " << test_info->test_case_name() << "."
451                << test_info->name();
452     fflush(stderr);
453   }
454 #endif  // BUILDFLAG(IS_ANDROID)
455 
456   // XmlUnitTestResultPrinter inherits gtest format, where assert has summary
457   // and message. In GTest, summary is just a logged text, and message is a
458   // logged text, concatenated with stack trace of assert.
459   // Concatenate summary and stack_trace here, to pass it as a message.
460   if (printer_) {
461     const std::string summary_str(summary);
462     const std::string stack_trace_str = summary_str + std::string(stack_trace);
463     printer_->OnAssert(file, line, summary_str, stack_trace_str);
464   }
465 
466   // The logging system actually prints the message before calling the assert
467   // handler. Just exit now to avoid printing too many stack traces.
468   _exit(1);
469 }
470 
SuppressErrorDialogs()471 void TestSuite::SuppressErrorDialogs() {
472 #if BUILDFLAG(IS_WIN)
473   UINT new_flags =
474       SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX;
475 
476   // Preserve existing error mode, as discussed at
477   // http://blogs.msdn.com/oldnewthing/archive/2004/07/27/198410.aspx
478   UINT existing_flags = SetErrorMode(new_flags);
479   SetErrorMode(existing_flags | new_flags);
480 
481 #if defined(_DEBUG)
482   // Suppress the "Debug Assertion Failed" dialog.
483   // TODO(hbono): remove this code when gtest has it.
484   // http://groups.google.com/d/topic/googletestframework/OjuwNlXy5ac/discussion
485   _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
486   _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
487   _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
488   _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
489 #endif  // defined(_DEBUG)
490 
491   // See crbug.com/783040 for test code to trigger all of these failures.
492   _set_invalid_parameter_handler(InvalidParameter);
493   _set_purecall_handler(PureCall);
494   signal(SIGABRT, AbortHandler);
495 #endif  // BUILDFLAG(IS_WIN)
496 }
497 
Initialize()498 void TestSuite::Initialize() {
499   DCHECK(!is_initialized_);
500 
501   InitializeFromCommandLine(&argc_, argv_);
502 
503   // Logging must be initialized before any thread has a chance to call logging
504   // functions.
505   InitializeLogging();
506 
507   // The AsanService causes ASAN errors to emit additional information. It is
508   // helpful on its own. It is also required by ASAN BackupRefPtr when
509   // reconfiguring PartitionAlloc below.
510 #if defined(ADDRESS_SANITIZER)
511   base::debug::AsanService::GetInstance()->Initialize();
512 #endif
513 
514   // TODO(https://crbug.com/1400058): Enable BackupRefPtr in unittests on
515   // Android too. Same for ASAN.
516   // TODO(https://crbug.com/1413674): Enable PartitionAlloc in unittests with
517   // ASAN.
518 #if BUILDFLAG(USE_PARTITION_ALLOC) && !defined(ADDRESS_SANITIZER)
519   allocator::PartitionAllocSupport::Get()->ReconfigureForTests();
520 #endif  // BUILDFLAG(IS_WIN)
521 
522   test::ScopedRunLoopTimeout::SetAddGTestFailureOnTimeout();
523 
524   const CommandLine* command_line = CommandLine::ForCurrentProcess();
525 #if !BUILDFLAG(IS_IOS)
526   if (command_line->HasSwitch(switches::kWaitForDebugger)) {
527     debug::WaitForDebugger(60, true);
528   }
529 #endif
530 
531 #if BUILDFLAG(DCHECK_IS_CONFIGURABLE)
532   // Default the configurable DCHECK level to FATAL when running death tests'
533   // child process, so that they behave as expected.
534   // TODO(crbug.com/1057995): Remove this in favor of the codepath in
535   // FeatureList::SetInstance() when/if OnTestStart() TestEventListeners
536   // are fixed to be invoked in the child process as expected.
537   if (command_line->HasSwitch("gtest_internal_run_death_test"))
538     logging::LOGGING_DCHECK = logging::LOG_FATAL;
539 #endif  // BUILDFLAG(DCHECK_IS_CONFIGURABLE)
540 
541 #if BUILDFLAG(IS_IOS)
542   InitIOSTestMessageLoop();
543 #endif  // BUILDFLAG(IS_IOS)
544 
545 #if BUILDFLAG(IS_ANDROID)
546   InitAndroidTestMessageLoop();
547 #endif  // else BUILDFLAG(IS_ANDROID)
548 
549   CHECK(debug::EnableInProcessStackDumping());
550 #if BUILDFLAG(IS_WIN)
551   RouteStdioToConsole(true);
552   // Make sure we run with high resolution timer to minimize differences
553   // between production code and test code.
554   Time::EnableHighResolutionTimer(true);
555 #endif  // BUILDFLAG(IS_WIN)
556 
557   // In some cases, we do not want to see standard error dialogs.
558   if (!debug::BeingDebugged() &&
559       !command_line->HasSwitch("show-error-dialogs")) {
560     SuppressErrorDialogs();
561     debug::SetSuppressDebugUI(true);
562     assert_handler_ = std::make_unique<logging::ScopedLogAssertHandler>(
563         BindRepeating(&TestSuite::UnitTestAssertHandler, Unretained(this)));
564   }
565 
566   // Child processes generally do not need ICU.
567   if (!command_line->HasSwitch("test-child-process")) {
568     test::InitializeICUForTesting();
569 
570     // A number of tests only work if the locale is en_US. This can be an issue
571     // on all platforms. To fix this we force the default locale to en_US. This
572     // does not affect tests that explicitly overrides the locale for testing.
573     // TODO(jshin): Should we set the locale via an OS X locale API here?
574     i18n::SetICUDefaultLocale("en_US");
575   }
576 
577 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
578   test_fonts::SetUpFontconfig();
579 #endif
580 
581   // Add TestEventListeners to enforce certain properties across tests.
582   testing::TestEventListeners& listeners =
583       testing::UnitTest::GetInstance()->listeners();
584   listeners.Append(new DisableMaybeTests);
585   listeners.Append(new ResetCommandLineBetweenTests);
586   listeners.Append(new FeatureListScopedToEachTest);
587   if (check_for_leaked_globals_)
588     listeners.Append(new CheckForLeakedGlobals);
589   if (check_for_thread_and_process_priority_) {
590 #if !BUILDFLAG(IS_APPLE)
591     listeners.Append(new CheckProcessPriority);
592 #endif
593   }
594 
595   AddTestLauncherResultPrinter();
596 
597   TestTimeouts::Initialize();
598 
599 #if BUILDFLAG(ENABLE_BASE_TRACING)
600   trace_to_file_.BeginTracingFromCommandLineOptions();
601 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
602 
603   debug::StartProfiling(GetProfileName());
604 
605   debug::VerifyDebugger();
606 
607   is_initialized_ = true;
608 }
609 
InitializeFromCommandLine(int * argc,char ** argv)610 void TestSuite::InitializeFromCommandLine(int* argc, char** argv) {
611   // CommandLine::Init() is called earlier from PreInitialize().
612   testing::InitGoogleTest(argc, argv);
613   testing::InitGoogleMock(argc, argv);
614 
615 #if BUILDFLAG(IS_IOS)
616   InitIOSArgs(*argc, argv);
617 #endif
618 }
619 
RunAllTests()620 int TestSuite::RunAllTests() {
621   return RUN_ALL_TESTS();
622 }
623 
Shutdown()624 void TestSuite::Shutdown() {
625   DCHECK(is_initialized_);
626   debug::StopProfiling();
627 }
628 
PreInitialize()629 void TestSuite::PreInitialize() {
630   DCHECK(!is_initialized_);
631 
632 #if BUILDFLAG(IS_WIN)
633   base::debug::HandleHooks::PatchLoadedModules();
634 #endif  // BUILDFLAG(IS_WIN)
635 
636   // The default death_test_style of "fast" is a frequent source of subtle test
637   // flakiness. And on some platforms like macOS, use of system libraries after
638   // fork() but before exec() is unsafe. Using the threadsafe style by default
639   // alleviates these concerns.
640   //
641   // However, the threasafe style does not work reliably on Android, so that
642   // will keep the default of "fast". See https://crbug.com/815537,
643   // https://github.com/google/googletest/issues/1496, and
644   // https://github.com/google/googletest/issues/2093.
645   // TODO(danakj): Determine if all death tests should be skipped on Android
646   // (many already are, such as for DCHECK-death tests).
647 #if !BUILDFLAG(IS_ANDROID)
648   testing::GTEST_FLAG(death_test_style) = "threadsafe";
649 #endif
650 
651 #if BUILDFLAG(IS_WIN)
652   testing::GTEST_FLAG(catch_exceptions) = false;
653 #endif
654   EnableTerminationOnHeapCorruption();
655 #if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && defined(USE_AURA)
656   // When calling native char conversion functions (e.g wrctomb) we need to
657   // have the locale set. In the absence of such a call the "C" locale is the
658   // default. In the gtk code (below) gtk_init() implicitly sets a locale.
659   setlocale(LC_ALL, "");
660   // We still need number to string conversions to be locale insensitive.
661   setlocale(LC_NUMERIC, "C");
662 #endif  // (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && defined(USE_AURA)
663 
664   // On Android, AtExitManager is created in
665   // testing/android/native_test_wrapper.cc before main() is called.
666 #if !BUILDFLAG(IS_ANDROID)
667   at_exit_manager_ = std::make_unique<AtExitManager>();
668 #endif
669 
670   // This needs to be done during construction as some users of this class rely
671   // on the constructor to initialise the CommandLine.
672   initialized_command_line_ = CommandLine::Init(argc_, argv_);
673 
674   // Don't add additional code to this function.  Instead add it to
675   // Initialize().  See bug 6436.
676 }
677 
AddTestLauncherResultPrinter()678 void TestSuite::AddTestLauncherResultPrinter() {
679   // Only add the custom printer if requested.
680   if (!CommandLine::ForCurrentProcess()->HasSwitch(
681           switches::kTestLauncherOutput)) {
682     return;
683   }
684 
685   FilePath output_path(CommandLine::ForCurrentProcess()->GetSwitchValuePath(
686       switches::kTestLauncherOutput));
687 
688   // Do not add the result printer if output path already exists. It's an
689   // indicator there is a process printing to that file, and we're likely
690   // its child. Do not clobber the results in that case.
691   if (PathExists(output_path)) {
692     LOG(WARNING) << "Test launcher output path " << output_path.AsUTF8Unsafe()
693                  << " exists. Not adding test launcher result printer.";
694     return;
695   }
696 
697   printer_ = new XmlUnitTestResultPrinter;
698   CHECK(printer_->Initialize(output_path))
699       << "Output path is " << output_path.AsUTF8Unsafe()
700       << " and PathExists(output_path) is " << PathExists(output_path);
701   testing::TestEventListeners& listeners =
702       testing::UnitTest::GetInstance()->listeners();
703   listeners.Append(printer_);
704 }
705 
706 }  // namespace base
707