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