blob: ee1d8390408366ebc9269bffcde83c5cddaaff6c [file] [log] [blame]
David Ghandehari9e5b5872016-07-28 09:50:04 -07001// 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
Andrew Top0d1858f2019-05-15 22:01:47 -07007#ifndef STARBOARD
8#include <signal.h>
9#endif
10
11#include <memory>
12
David Ghandehari9e5b5872016-07-28 09:50:04 -070013#include "base/at_exit.h"
14#include "base/base_paths.h"
15#include "base/base_switches.h"
Andrew Top0d1858f2019-05-15 22:01:47 -070016#include "base/bind.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070017#include "base/command_line.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070018#include "base/debug/debugger.h"
Andrew Top0d1858f2019-05-15 22:01:47 -070019#include "base/debug/profiler.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070020#include "base/debug/stack_trace.h"
Andrew Top0d1858f2019-05-15 22:01:47 -070021#include "base/feature_list.h"
22#include "base/files/file_path.h"
23#include "base/files/file_util.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070024#include "base/i18n/icu_util.h"
25#include "base/logging.h"
Andrew Top0d1858f2019-05-15 22:01:47 -070026#include "base/macros.h"
27#include "base/memory/ptr_util.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070028#include "base/path_service.h"
Andrew Top0d1858f2019-05-15 22:01:47 -070029#include "base/process/launch.h"
30#include "base/process/memory.h"
31#include "base/task/task_scheduler/task_scheduler.h"
32#include "base/test/gtest_xml_unittest_result_printer.h"
33#include "base/test/gtest_xml_util.h"
34#include "base/test/icu_test_util.h"
35#include "base/test/launcher/unit_test_launcher.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070036#include "base/test/multiprocess_test.h"
Andrew Top0d1858f2019-05-15 22:01:47 -070037#include "base/test/test_switches.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070038#include "base/test/test_timeouts.h"
Andrew Top0d1858f2019-05-15 22:01:47 -070039#include "base/time/time.h"
40#include "build/build_config.h"
41#include "testing/gmock/include/gmock/gmock.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070042#include "testing/gtest/include/gtest/gtest.h"
43#include "testing/multiprocess_func_list.h"
44
45#if defined(OS_MACOSX)
46#include "base/mac/scoped_nsautorelease_pool.h"
47#if defined(OS_IOS)
48#include "base/test/test_listener_ios.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070049#endif // OS_IOS
50#endif // OS_MACOSX
51
Andrew Top0d1858f2019-05-15 22:01:47 -070052#if !defined(OS_WIN)
53#include "base/i18n/rtl.h"
54#if !defined(OS_IOS)
55#include "base/strings/string_util.h"
56#include "third_party/icu/source/common/unicode/uloc.h"
57#endif
58#endif
59
60#if defined(OS_ANDROID)
David Ghandehari9e5b5872016-07-28 09:50:04 -070061#include "base/test/test_support_android.h"
62#endif
63
64#if defined(OS_IOS)
65#include "base/test/test_support_ios.h"
66#endif
67
Andrew Top0d1858f2019-05-15 22:01:47 -070068#if defined(OS_LINUX)
69#include "base/test/fontconfig_util_linux.h"
70#include "starboard/types.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070071#endif
72
Andrew Top0d1858f2019-05-15 22:01:47 -070073namespace base {
74
David Ghandehari9e5b5872016-07-28 09:50:04 -070075namespace {
76
Andrew Top0d1858f2019-05-15 22:01:47 -070077// Returns true if the test is marked as "MAYBE_".
78// When using different prefixes depending on platform, we use MAYBE_ and
79// preprocessor directives to replace MAYBE_ with the target prefix.
80bool IsMarkedMaybe(const testing::TestInfo& test) {
81 return strncmp(test.name(), "MAYBE_", 6) == 0;
82}
83
84class DisableMaybeTests : public testing::EmptyTestEventListener {
David Ghandehari9e5b5872016-07-28 09:50:04 -070085 public:
Andrew Top0d1858f2019-05-15 22:01:47 -070086 void OnTestStart(const testing::TestInfo& test_info) override {
87 ASSERT_FALSE(IsMarkedMaybe(test_info))
David Ghandehari9e5b5872016-07-28 09:50:04 -070088 << "Probably the OS #ifdefs don't include all of the necessary "
89 "platforms.\nPlease ensure that no tests have the MAYBE_ prefix "
90 "after the code is preprocessed.";
91 }
92};
93
Andrew Top0d1858f2019-05-15 22:01:47 -070094class ResetCommandLineBetweenTests : public testing::EmptyTestEventListener {
David Ghandehari9e5b5872016-07-28 09:50:04 -070095 public:
Andrew Top0d1858f2019-05-15 22:01:47 -070096 ResetCommandLineBetweenTests() : old_command_line_(CommandLine::NO_PROGRAM) {}
David Ghandehari9e5b5872016-07-28 09:50:04 -070097
Andrew Top0d1858f2019-05-15 22:01:47 -070098 void OnTestStart(const testing::TestInfo& test_info) override {
David Ghandehari9e5b5872016-07-28 09:50:04 -070099 old_command_line_ = *CommandLine::ForCurrentProcess();
100 }
101
Andrew Top0d1858f2019-05-15 22:01:47 -0700102 void OnTestEnd(const testing::TestInfo& test_info) override {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700103 *CommandLine::ForCurrentProcess() = old_command_line_;
104 }
105
106 private:
107 CommandLine old_command_line_;
108
Andrew Top0d1858f2019-05-15 22:01:47 -0700109 DISALLOW_COPY_AND_ASSIGN(ResetCommandLineBetweenTests);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700110};
111
Andrew Top0d1858f2019-05-15 22:01:47 -0700112class CheckForLeakedGlobals : public testing::EmptyTestEventListener {
113 public:
114 CheckForLeakedGlobals() = default;
115
116 // Check for leaks in individual tests.
117 void OnTestStart(const testing::TestInfo& test) override {
118 scheduler_set_before_test_ = TaskScheduler::GetInstance();
119 }
120 void OnTestEnd(const testing::TestInfo& test) override {
121 auto* task_scheduler = TaskScheduler::GetInstance();
122 DCHECK_EQ(scheduler_set_before_test_, task_scheduler)
123 << " in test " << test.test_case_name() << "." << test.name();
124 }
125
126 // Check for leaks in test cases (consisting of one or more tests).
127 void OnTestCaseStart(const testing::TestCase& test_case) override {
128 scheduler_set_before_case_ = TaskScheduler::GetInstance();
129 }
130 void OnTestCaseEnd(const testing::TestCase& test_case) override {
131 DCHECK_EQ(scheduler_set_before_case_, TaskScheduler::GetInstance())
132 << " in case " << test_case.name();
133 }
134
135 private:
136 TaskScheduler* scheduler_set_before_test_ = nullptr;
137 TaskScheduler* scheduler_set_before_case_ = nullptr;
138
139 DISALLOW_COPY_AND_ASSIGN(CheckForLeakedGlobals);
140};
141
142std::string GetProfileName() {
143 static const char kDefaultProfileName[] = "test-profile-{pid}";
144 CR_DEFINE_STATIC_LOCAL(std::string, profile_name, ());
145 if (profile_name.empty()) {
146 const base::CommandLine& command_line =
147 *base::CommandLine::ForCurrentProcess();
148 if (command_line.HasSwitch(switches::kProfilingFile))
149 profile_name = command_line.GetSwitchValueASCII(switches::kProfilingFile);
150 else
151 profile_name = std::string(kDefaultProfileName);
152 }
153 return profile_name;
154}
155
156void InitializeLogging() {
157#if defined(OS_ANDROID)
158 InitAndroidTestLogging();
159#else
160 FilePath exe;
161 PathService::Get(FILE_EXE, &exe);
162 FilePath log_filename = exe.ReplaceExtension(FILE_PATH_LITERAL("log"));
163 logging::LoggingSettings settings;
164 settings.logging_dest = logging::LOG_TO_ALL;
165 settings.log_file = log_filename.value().c_str();
166 settings.delete_old = logging::DELETE_OLD_LOG_FILE;
167 logging::InitLogging(settings);
168 // We want process and thread IDs because we may have multiple processes.
169 // Note: temporarily enabled timestamps in an effort to catch bug 6361.
170 logging::SetLogItems(true, true, true, true);
171#endif // !defined(OS_ANDROID)
172}
173
David Ghandehari9e5b5872016-07-28 09:50:04 -0700174} // namespace
175
Andrew Top0d1858f2019-05-15 22:01:47 -0700176#if !defined(STARBOARD)
177int RunUnitTestsUsingBaseTestSuite(int argc, char **argv) {
178 TestSuite test_suite(argc, argv);
179 return LaunchUnitTests(argc, argv,
180 Bind(&TestSuite::Run, Unretained(&test_suite)));
181}
182#endif
David Ghandehari9e5b5872016-07-28 09:50:04 -0700183
Andrew Top0d1858f2019-05-15 22:01:47 -0700184TestSuite::TestSuite(int argc, char** argv) {
185 PreInitialize();
186 InitializeFromCommandLine(argc, argv);
187 // Logging must be initialized before any thread has a chance to call logging
188 // functions.
189 InitializeLogging();
David Ghandehari9e5b5872016-07-28 09:50:04 -0700190}
191
Andrew Top0d1858f2019-05-15 22:01:47 -0700192#if defined(OS_WIN)
193TestSuite::TestSuite(int argc, wchar_t** argv) {
194 PreInitialize();
195 InitializeFromCommandLine(argc, argv);
196 // Logging must be initialized before any thread has a chance to call logging
197 // functions.
198 InitializeLogging();
David Ghandehari9e5b5872016-07-28 09:50:04 -0700199}
Andrew Top0d1858f2019-05-15 22:01:47 -0700200#endif // defined(OS_WIN)
David Ghandehari9e5b5872016-07-28 09:50:04 -0700201
202TestSuite::~TestSuite() {
203 if (initialized_command_line_)
204 CommandLine::Reset();
Andrew Topcab77702019-09-17 13:14:36 -0700205 logging::CloseLogFile();
David Ghandehari9e5b5872016-07-28 09:50:04 -0700206}
207
Andrew Top0d1858f2019-05-15 22:01:47 -0700208void TestSuite::InitializeFromCommandLine(int argc, char** argv) {
209 initialized_command_line_ = CommandLine::Init(argc, argv);
210 testing::InitGoogleTest(&argc, argv);
211 testing::InitGoogleMock(&argc, argv);
212
213#if defined(OS_IOS)
214 InitIOSRunHook(this, argc, argv);
215#endif
216}
217
218#if defined(OS_WIN)
219void TestSuite::InitializeFromCommandLine(int argc, wchar_t** argv) {
220 // Windows CommandLine::Init ignores argv anyway.
221 initialized_command_line_ = CommandLine::Init(argc, NULL);
222 testing::InitGoogleTest(&argc, argv);
223 testing::InitGoogleMock(&argc, argv);
224}
225#endif // defined(OS_WIN)
226
227void TestSuite::PreInitialize() {
228 DCHECK(!is_initialized_);
229
David Ghandehari9e5b5872016-07-28 09:50:04 -0700230#if defined(OS_WIN)
231 testing::GTEST_FLAG(catch_exceptions) = false;
232#endif
Andrew Top0d1858f2019-05-15 22:01:47 -0700233 EnableTerminationOnHeapCorruption();
234#if defined(OS_LINUX) && defined(USE_AURA)
David Ghandehari9e5b5872016-07-28 09:50:04 -0700235 // When calling native char conversion functions (e.g wrctomb) we need to
236 // have the locale set. In the absence of such a call the "C" locale is the
237 // default. In the gtk code (below) gtk_init() implicitly sets a locale.
238 setlocale(LC_ALL, "");
Andrew Top0d1858f2019-05-15 22:01:47 -0700239#endif // defined(OS_LINUX) && defined(USE_AURA)
David Ghandehari9e5b5872016-07-28 09:50:04 -0700240
Andrew Top0d1858f2019-05-15 22:01:47 -0700241// On Android, AtExitManager is created in
242// testing/android/native_test_wrapper.cc before main() is called.
243// For Cobalt, at_exit_manager some times need to be created earlier than the
244// start of test case.
245#if !defined(OS_ANDROID) && !defined(STARBOARD)
246 at_exit_manager_.reset(new AtExitManager);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700247#endif
248
249 // Don't add additional code to this function. Instead add it to
250 // Initialize(). See bug 6436.
251}
252
Andrew Top0d1858f2019-05-15 22:01:47 -0700253void TestSuite::AddTestLauncherResultPrinter() {
254 // Only add the custom printer if requested.
255 if (!CommandLine::ForCurrentProcess()->HasSwitch(
256 switches::kTestLauncherOutput)) {
257 return;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700258 }
259
Andrew Top0d1858f2019-05-15 22:01:47 -0700260 FilePath output_path(CommandLine::ForCurrentProcess()->GetSwitchValuePath(
261 switches::kTestLauncherOutput));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700262
Andrew Top0d1858f2019-05-15 22:01:47 -0700263 // Do not add the result printer if output path already exists. It's an
264 // indicator there is a process printing to that file, and we're likely
265 // its child. Do not clobber the results in that case.
266 if (PathExists(output_path)) {
267 LOG(WARNING) << "Test launcher output path " << output_path.AsUTF8Unsafe()
268 << " exists. Not adding test launcher result printer.";
269 return;
270 }
271
272#if !defined(STARBOARD)
273 printer_ = new XmlUnitTestResultPrinter;
274 CHECK(printer_->Initialize(output_path))
275 << "Output path is " << output_path.AsUTF8Unsafe()
276 << " and PathExists(output_path) is " << PathExists(output_path);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700277 testing::TestEventListeners& listeners =
278 testing::UnitTest::GetInstance()->listeners();
Andrew Top0d1858f2019-05-15 22:01:47 -0700279 listeners.Append(printer_);
280#endif
David Ghandehari9e5b5872016-07-28 09:50:04 -0700281}
282
283// Don't add additional code to this method. Instead add it to
284// Initialize(). See bug 6436.
285int TestSuite::Run() {
Andrew Top0d1858f2019-05-15 22:01:47 -0700286#if defined(OS_IOS)
287 RunTestsFromIOSApp();
288#endif
289
David Ghandehari9e5b5872016-07-28 09:50:04 -0700290#if defined(OS_MACOSX)
Andrew Top0d1858f2019-05-15 22:01:47 -0700291 mac::ScopedNSAutoreleasePool scoped_pool;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700292#endif
293
294 Initialize();
295 std::string client_func =
296 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
297 switches::kTestChildProcess);
298
299 // Check to see if we are being run as a client process.
300 if (!client_func.empty())
301 return multi_process_function_list::InvokeChildProcessTest(client_func);
302#if defined(OS_IOS)
Andrew Top0d1858f2019-05-15 22:01:47 -0700303 test_listener_ios::RegisterTestEndListener();
David Ghandehari9e5b5872016-07-28 09:50:04 -0700304#endif
Andrew Top0d1858f2019-05-15 22:01:47 -0700305
David Ghandehari9e5b5872016-07-28 09:50:04 -0700306 int result = RUN_ALL_TESTS();
307
David Ghandehari9e5b5872016-07-28 09:50:04 -0700308#if defined(OS_MACOSX)
309 // This MUST happen before Shutdown() since Shutdown() tears down
310 // objects (such as NotificationService::current()) that Cocoa
311 // objects use to remove themselves as observers.
312 scoped_pool.Recycle();
313#endif
314
315 Shutdown();
316
317 return result;
318}
319
Andrew Top0d1858f2019-05-15 22:01:47 -0700320void TestSuite::DisableCheckForLeakedGlobals() {
321 DCHECK(!is_initialized_);
322 check_for_leaked_globals_ = false;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700323}
324
Andrew Top0d1858f2019-05-15 22:01:47 -0700325void TestSuite::UnitTestAssertHandler(const char* file,
326 int line,
327 const base::StringPiece summary,
328 const base::StringPiece stack_trace) {
329#if defined(OS_ANDROID)
330 // Correlating test stdio with logcat can be difficult, so we emit this
331 // helpful little hint about what was running. Only do this for Android
332 // because other platforms don't separate out the relevant logs in the same
333 // way.
334 const ::testing::TestInfo* const test_info =
335 ::testing::UnitTest::GetInstance()->current_test_info();
336 if (test_info) {
337 LOG(ERROR) << "Currently running: " << test_info->test_case_name() << "."
338 << test_info->name();
339 fflush(stderr);
340 }
341#endif // defined(OS_ANDROID)
342
343#if !defined(STARBOARD)
344 // XmlUnitTestResultPrinter inherits gtest format, where assert has summary
345 // and message. In GTest, summary is just a logged text, and message is a
346 // logged text, concatenated with stack trace of assert.
347 // Concatenate summary and stack_trace here, to pass it as a message.
348 if (printer_) {
349 const std::string summary_str = summary.as_string();
350 const std::string stack_trace_str = summary_str + stack_trace.as_string();
351 printer_->OnAssert(file, line, summary_str, stack_trace_str);
352 }
353#endif
354
355#if defined(STARBOARD)
356 SbSystemRequestStop(1);
357#else
358 // The logging system actually prints the message before calling the assert
359 // handler. Just exit now to avoid printing too many stack traces.
360 _exit(1);
361#endif
362}
363
364#if defined(OS_WIN)
365namespace {
366
367// Disable optimizations to prevent function folding or other transformations
368// that will make the call stacks on failures more confusing.
369#pragma optimize("", off)
370// Handlers for invalid parameter, pure call, and abort. They generate a
371// breakpoint to ensure that we get a call stack on these failures.
372void InvalidParameter(const wchar_t* expression,
373 const wchar_t* function,
374 const wchar_t* file,
375 unsigned int line,
376 uintptr_t reserved) {
377 // CRT printed message is sufficient.
378 __debugbreak();
379 _exit(1);
380}
381
382void PureCall() {
383 fprintf(stderr, "Pure-virtual function call. Terminating.\n");
384 __debugbreak();
385 _exit(1);
386}
387
388void AbortHandler(int signal) {
389 // Print EOL after the CRT abort message.
390 fprintf(stderr, "\n");
391 __debugbreak();
392}
393#pragma optimize("", on)
394
395} // namespace
396#endif
397
David Ghandehari9e5b5872016-07-28 09:50:04 -0700398void TestSuite::SuppressErrorDialogs() {
399#if defined(OS_WIN)
400 UINT new_flags = SEM_FAILCRITICALERRORS |
401 SEM_NOGPFAULTERRORBOX |
402 SEM_NOOPENFILEERRORBOX;
403
404 // Preserve existing error mode, as discussed at
405 // http://blogs.msdn.com/oldnewthing/archive/2004/07/27/198410.aspx
406 UINT existing_flags = SetErrorMode(new_flags);
407 SetErrorMode(existing_flags | new_flags);
408
Andrew Top0d1858f2019-05-15 22:01:47 -0700409#if defined(_DEBUG)
David Ghandehari9e5b5872016-07-28 09:50:04 -0700410 // Suppress the "Debug Assertion Failed" dialog.
411 // TODO(hbono): remove this code when gtest has it.
412 // http://groups.google.com/d/topic/googletestframework/OjuwNlXy5ac/discussion
David Ghandehari9e5b5872016-07-28 09:50:04 -0700413 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
Andrew Top0d1858f2019-05-15 22:01:47 -0700414 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
415 _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
416 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
417#endif // defined(_DEBUG)
418
419 // See crbug.com/783040 for test code to trigger all of these failures.
420 _set_invalid_parameter_handler(InvalidParameter);
421 _set_purecall_handler(PureCall);
422 signal(SIGABRT, AbortHandler);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700423#endif // defined(OS_WIN)
424}
425
426void TestSuite::Initialize() {
Andrew Top0d1858f2019-05-15 22:01:47 -0700427 DCHECK(!is_initialized_);
428
429 const CommandLine* command_line = CommandLine::ForCurrentProcess();
430#if !defined(OS_IOS)
431 if (command_line->HasSwitch(switches::kWaitForDebugger)) {
432 debug::WaitForDebugger(60, true);
433 }
David Ghandehari9e5b5872016-07-28 09:50:04 -0700434#endif
Andrew Top0d1858f2019-05-15 22:01:47 -0700435 // Set up a FeatureList instance, so that code using that API will not hit a
436 // an error that it's not set. It will be cleared automatically.
437 // TestFeatureForBrowserTest1 and TestFeatureForBrowserTest2 used in
438 // ContentBrowserTestScopedFeatureListTest to ensure ScopedFeatureList keeps
439 // features from command line.
440 std::string enabled =
441 command_line->GetSwitchValueASCII(switches::kEnableFeatures);
442 std::string disabled =
443 command_line->GetSwitchValueASCII(switches::kDisableFeatures);
444 enabled += ",TestFeatureForBrowserTest1";
445 disabled += ",TestFeatureForBrowserTest2";
446#if !defined(STARBOARD)
447 scoped_feature_list_.InitFromCommandLine(enabled, disabled);
448#endif
449
450 // The enable-features and disable-features flags were just slurped into a
451 // FeatureList, so remove them from the command line. Tests should enable and
452 // disable features via the ScopedFeatureList API rather than command-line
453 // flags.
454 CommandLine new_command_line(command_line->GetProgram());
455 CommandLine::SwitchMap switches = command_line->GetSwitches();
456
457 switches.erase(switches::kEnableFeatures);
458 switches.erase(switches::kDisableFeatures);
459
460 for (const auto& iter : switches)
461 new_command_line.AppendSwitchNative(iter.first, iter.second);
462
463 *CommandLine::ForCurrentProcess() = new_command_line;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700464
465#if defined(OS_IOS)
466 InitIOSTestMessageLoop();
467#endif // OS_IOS
468
Andrew Top0d1858f2019-05-15 22:01:47 -0700469#if defined(OS_ANDROID)
470 InitAndroidTestMessageLoop();
David Ghandehari9e5b5872016-07-28 09:50:04 -0700471#endif // else defined(OS_ANDROID)
472
Andrew Top0d1858f2019-05-15 22:01:47 -0700473 CHECK(debug::EnableInProcessStackDumping());
David Ghandehari9e5b5872016-07-28 09:50:04 -0700474#if defined(OS_WIN)
Andrew Top0d1858f2019-05-15 22:01:47 -0700475 RouteStdioToConsole(true);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700476 // Make sure we run with high resolution timer to minimize differences
477 // between production code and test code.
Andrew Top0d1858f2019-05-15 22:01:47 -0700478 Time::EnableHighResolutionTimer(true);
David Ghandehari9e5b5872016-07-28 09:50:04 -0700479#endif // defined(OS_WIN)
480
481 // In some cases, we do not want to see standard error dialogs.
Andrew Top0d1858f2019-05-15 22:01:47 -0700482 if (!debug::BeingDebugged() &&
483 !command_line->HasSwitch("show-error-dialogs")) {
David Ghandehari9e5b5872016-07-28 09:50:04 -0700484 SuppressErrorDialogs();
Andrew Top0d1858f2019-05-15 22:01:47 -0700485 debug::SetSuppressDebugUI(true);
486 assert_handler_ = std::make_unique<logging::ScopedLogAssertHandler>(
487 base::Bind(&TestSuite::UnitTestAssertHandler, base::Unretained(this)));
David Ghandehari9e5b5872016-07-28 09:50:04 -0700488 }
489
Andrew Top0d1858f2019-05-15 22:01:47 -0700490 base::test::InitializeICUForTesting();
David Ghandehari9e5b5872016-07-28 09:50:04 -0700491
Andrew Top0d1858f2019-05-15 22:01:47 -0700492 // On the Mac OS X command line, the default locale is *_POSIX. In Chromium,
493 // the locale is set via an OS X locale API and is never *_POSIX.
494 // Some tests (such as those involving word break iterator) will behave
495 // differently and fail if we use *POSIX locale. Setting it to en_US here
496 // does not affect tests that explicitly overrides the locale for testing.
497 // This can be an issue on all platforms other than Windows.
498 // TODO(jshin): Should we set the locale via an OS X locale API here?
499#if !defined(OS_WIN)
500#if defined(OS_IOS)
501 i18n::SetICUDefaultLocale("en_US");
502#else
503 std::string default_locale(uloc_getDefault());
504 if (EndsWith(default_locale, "POSIX", CompareCase::INSENSITIVE_ASCII))
505 i18n::SetICUDefaultLocale("en_US");
506#endif
507#endif
508
509#if defined(OS_LINUX)
510 // TODO(thomasanderson): Call TearDownFontconfig() in Shutdown(). It would
511 // currently crash because of leaked FcFontSet's in font_fallback_linux.cc.
512 SetUpFontconfig();
513#endif
514
515 // Add TestEventListeners to enforce certain properties across tests.
516 testing::TestEventListeners& listeners =
517 testing::UnitTest::GetInstance()->listeners();
518 listeners.Append(new DisableMaybeTests);
519 listeners.Append(new ResetCommandLineBetweenTests);
520 if (check_for_leaked_globals_)
521 listeners.Append(new CheckForLeakedGlobals);
522
523 AddTestLauncherResultPrinter();
David Ghandehari9e5b5872016-07-28 09:50:04 -0700524
525 TestTimeouts::Initialize();
Andrew Top0d1858f2019-05-15 22:01:47 -0700526
527 trace_to_file_.BeginTracingFromCommandLineOptions();
528
529 base::debug::StartProfiling(GetProfileName());
530
531 is_initialized_ = true;
David Ghandehari9e5b5872016-07-28 09:50:04 -0700532}
533
534void TestSuite::Shutdown() {
Andrew Top0d1858f2019-05-15 22:01:47 -0700535 DCHECK(is_initialized_);
536 base::debug::StopProfiling();
David Ghandehari9e5b5872016-07-28 09:50:04 -0700537}
Andrew Top0d1858f2019-05-15 22:01:47 -0700538
539} // namespace base