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