This source file includes following definitions.
- OnTestStart
- OnTestStart
- OnTestEnd
- RunUnitTestsUsingBaseTestSuite
- PreInitialize
- IsMarkedMaybe
- CatchMaybeTests
- ResetCommandLine
- AddTestLauncherResultPrinter
- Run
- UnitTestAssertHandler
- SuppressErrorDialogs
- Initialize
- Shutdown
#include "base/test/test_suite.h"
#include "base/at_exit.h"
#include "base/base_paths.h"
#include "base/base_switches.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/debug/debug_on_start_win.h"
#include "base/debug/debugger.h"
#include "base/debug/stack_trace.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/i18n/icu_util.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/process/memory.h"
#include "base/test/gtest_xml_util.h"
#include "base/test/launcher/unit_test_launcher.h"
#include "base/test/multiprocess_test.h"
#include "base/test/test_switches.h"
#include "base/test/test_timeouts.h"
#include "base/time/time.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"
#if defined(OS_MACOSX)
#include "base/mac/scoped_nsautorelease_pool.h"
#if defined(OS_IOS)
#include "base/test/test_listener_ios.h"
#else
#include "base/test/mock_chrome_application_mac.h"
#endif
#endif
#if defined(OS_ANDROID)
#include "base/test/test_support_android.h"
#endif
#if defined(OS_IOS)
#include "base/test/test_support_ios.h"
#endif
#if defined(TOOLKIT_GTK)
#include <gtk/gtk.h>
#endif
namespace {
class MaybeTestDisabler : public testing::EmptyTestEventListener {
public:
virtual void OnTestStart(const testing::TestInfo& test_info) OVERRIDE {
ASSERT_FALSE(TestSuite::IsMarkedMaybe(test_info))
<< "Probably the OS #ifdefs don't include all of the necessary "
"platforms.\nPlease ensure that no tests have the MAYBE_ prefix "
"after the code is preprocessed.";
}
};
class TestClientInitializer : public testing::EmptyTestEventListener {
public:
TestClientInitializer()
: old_command_line_(CommandLine::NO_PROGRAM) {
}
virtual void OnTestStart(const testing::TestInfo& test_info) OVERRIDE {
old_command_line_ = *CommandLine::ForCurrentProcess();
}
virtual void OnTestEnd(const testing::TestInfo& test_info) OVERRIDE {
*CommandLine::ForCurrentProcess() = old_command_line_;
}
private:
CommandLine old_command_line_;
DISALLOW_COPY_AND_ASSIGN(TestClientInitializer);
};
}
namespace base {
int RunUnitTestsUsingBaseTestSuite(int argc, char **argv) {
TestSuite test_suite(argc, argv);
return base::LaunchUnitTests(
argc, argv, Bind(&TestSuite::Run, Unretained(&test_suite)));
}
}
TestSuite::TestSuite(int argc, char** argv) : initialized_command_line_(false) {
PreInitialize(argc, argv, true);
}
TestSuite::TestSuite(int argc, char** argv, bool create_at_exit_manager)
: initialized_command_line_(false) {
PreInitialize(argc, argv, create_at_exit_manager);
}
TestSuite::~TestSuite() {
if (initialized_command_line_)
CommandLine::Reset();
}
void TestSuite::PreInitialize(int argc, char** argv,
bool create_at_exit_manager) {
#if defined(OS_WIN)
testing::GTEST_FLAG(catch_exceptions) = false;
base::TimeTicks::SetNowIsHighResNowIfSupported();
#endif
base::EnableTerminationOnHeapCorruption();
initialized_command_line_ = CommandLine::Init(argc, argv);
testing::InitGoogleTest(&argc, argv);
testing::InitGoogleMock(&argc, argv);
#if defined(OS_LINUX) && defined(USE_AURA)
setlocale(LC_ALL, "");
#elif defined(TOOLKIT_GTK)
gtk_init_check(&argc, &argv);
#endif
#if !defined(OS_ANDROID)
if (create_at_exit_manager)
at_exit_manager_.reset(new base::AtExitManager);
#endif
#if defined(OS_IOS)
InitIOSRunHook(this, argc, argv);
#endif
}
bool TestSuite::IsMarkedMaybe(const testing::TestInfo& test) {
return strncmp(test.name(), "MAYBE_", 6) == 0;
}
void TestSuite::CatchMaybeTests() {
testing::TestEventListeners& listeners =
testing::UnitTest::GetInstance()->listeners();
listeners.Append(new MaybeTestDisabler);
}
void TestSuite::ResetCommandLine() {
testing::TestEventListeners& listeners =
testing::UnitTest::GetInstance()->listeners();
listeners.Append(new TestClientInitializer);
}
#if !defined(OS_IOS)
void TestSuite::AddTestLauncherResultPrinter() {
if (!CommandLine::ForCurrentProcess()->HasSwitch(
switches::kTestLauncherOutput)) {
return;
}
FilePath output_path(CommandLine::ForCurrentProcess()->GetSwitchValuePath(
switches::kTestLauncherOutput));
if (PathExists(output_path)) {
LOG(WARNING) << "Test launcher output path " << output_path.AsUTF8Unsafe()
<< " exists. Not adding test launcher result printer.";
return;
}
XmlUnitTestResultPrinter* printer = new XmlUnitTestResultPrinter;
CHECK(printer->Initialize(output_path));
testing::TestEventListeners& listeners =
testing::UnitTest::GetInstance()->listeners();
listeners.Append(printer);
}
#endif
int TestSuite::Run() {
#if defined(OS_IOS)
RunTestsFromIOSApp();
#endif
#if defined(OS_MACOSX)
base::mac::ScopedNSAutoreleasePool scoped_pool;
#endif
Initialize();
std::string client_func =
CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kTestChildProcess);
if (!client_func.empty())
return multi_process_function_list::InvokeChildProcessTest(client_func);
#if defined(OS_IOS)
base::test_listener_ios::RegisterTestEndListener();
#endif
int result = RUN_ALL_TESTS();
#if defined(OS_MACOSX)
scoped_pool.Recycle();
#endif
Shutdown();
return result;
}
void TestSuite::UnitTestAssertHandler(const std::string& str) {
#if defined(OS_ANDROID)
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
if (test_info) {
LOG(ERROR) << "Currently running: " << test_info->test_case_name() << "."
<< test_info->name();
fflush(stderr);
}
#endif
_exit(1);
}
void TestSuite::SuppressErrorDialogs() {
#if defined(OS_WIN)
UINT new_flags = SEM_FAILCRITICALERRORS |
SEM_NOGPFAULTERRORBOX |
SEM_NOOPENFILEERRORBOX;
UINT existing_flags = SetErrorMode(new_flags);
SetErrorMode(existing_flags | new_flags);
#if defined(_DEBUG) && defined(_HAS_EXCEPTIONS) && (_HAS_EXCEPTIONS == 1)
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
#endif
#endif
}
void TestSuite::Initialize() {
#if defined(OS_MACOSX) && !defined(OS_IOS)
mock_cr_app::RegisterMockCrApp();
#endif
#if defined(OS_IOS)
InitIOSTestMessageLoop();
#endif
#if defined(OS_ANDROID)
InitAndroidTest();
#else
base::FilePath exe;
PathService::Get(base::FILE_EXE, &exe);
base::FilePath log_filename = exe.ReplaceExtension(FILE_PATH_LITERAL("log"));
logging::LoggingSettings settings;
settings.logging_dest = logging::LOG_TO_ALL;
settings.log_file = log_filename.value().c_str();
settings.delete_old = logging::DELETE_OLD_LOG_FILE;
logging::InitLogging(settings);
logging::SetLogItems(true, true, true, true);
#endif
CHECK(base::debug::EnableInProcessStackDumping());
#if defined(OS_WIN)
base::Time::EnableHighResolutionTimer(true);
#endif
if (!base::debug::BeingDebugged() &&
!CommandLine::ForCurrentProcess()->HasSwitch("show-error-dialogs")) {
SuppressErrorDialogs();
base::debug::SetSuppressDebugUI(true);
logging::SetLogAssertHandler(UnitTestAssertHandler);
}
base::i18n::InitializeICU();
CatchMaybeTests();
ResetCommandLine();
#if !defined(OS_IOS)
AddTestLauncherResultPrinter();
#endif
TestTimeouts::Initialize();
}
void TestSuite::Shutdown() {
}