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