// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/test/test_suite.h"

#include <signal.h>

#include <memory>

#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/debugger.h"
#include "base/debug/profiler.h"
#include "base/debug/stack_trace.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/i18n/icu_util.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/path_service.h"
#include "base/process/launch.h"
#include "base/process/memory.h"
#include "base/test/gtest_xml_unittest_result_printer.h"
#include "base/test/gtest_xml_util.h"
#include "base/test/icu_test_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 "build/build_config.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"
#endif  // OS_IOS
#endif  // OS_MACOSX

#if !defined(OS_WIN)
#include "base/i18n/rtl.h"
#if !defined(OS_IOS)
#include "base/strings/string_util.h"
#include "third_party/icu/source/common/unicode/uloc.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

namespace base {

namespace {

class MaybeTestDisabler : public testing::EmptyTestEventListener {
 public:
  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) {
  }

  void OnTestStart(const testing::TestInfo& test_info) override {
    old_command_line_ = *CommandLine::ForCurrentProcess();
  }

  void OnTestEnd(const testing::TestInfo& test_info) override {
    *CommandLine::ForCurrentProcess() = old_command_line_;
  }

 private:
  CommandLine old_command_line_;

  DISALLOW_COPY_AND_ASSIGN(TestClientInitializer);
};

std::string GetProfileName() {
  static const char kDefaultProfileName[] = "test-profile-{pid}";
  CR_DEFINE_STATIC_LOCAL(std::string, profile_name, ());
  if (profile_name.empty()) {
    const base::CommandLine& command_line =
        *base::CommandLine::ForCurrentProcess();
    if (command_line.HasSwitch(switches::kProfilingFile))
      profile_name = command_line.GetSwitchValueASCII(switches::kProfilingFile);
    else
      profile_name = std::string(kDefaultProfileName);
  }
  return profile_name;
}

void InitializeLogging() {
#if defined(OS_ANDROID)
  InitAndroidTestLogging();
#else
  FilePath exe;
  PathService::Get(FILE_EXE, &exe);
  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);
  // We want process and thread IDs because we may have multiple processes.
  // Note: temporarily enabled timestamps in an effort to catch bug 6361.
  logging::SetLogItems(true, true, true, true);
#endif  // !defined(OS_ANDROID)
}

}  // namespace

int RunUnitTestsUsingBaseTestSuite(int argc, char **argv) {
  TestSuite test_suite(argc, argv);
  return LaunchUnitTests(argc, argv,
                         Bind(&TestSuite::Run, Unretained(&test_suite)));
}

TestSuite::TestSuite(int argc, char** argv) : initialized_command_line_(false) {
  PreInitialize();
  InitializeFromCommandLine(argc, argv);
  // Logging must be initialized before any thread has a chance to call logging
  // functions.
  InitializeLogging();
}

#if defined(OS_WIN)
TestSuite::TestSuite(int argc, wchar_t** argv)
    : initialized_command_line_(false) {
  PreInitialize();
  InitializeFromCommandLine(argc, argv);
  // Logging must be initialized before any thread has a chance to call logging
  // functions.
  InitializeLogging();
}
#endif  // defined(OS_WIN)

TestSuite::~TestSuite() {
  if (initialized_command_line_)
    CommandLine::Reset();
}

void TestSuite::InitializeFromCommandLine(int argc, char** argv) {
  initialized_command_line_ = CommandLine::Init(argc, argv);
  testing::InitGoogleTest(&argc, argv);
  testing::InitGoogleMock(&argc, argv);

#if defined(OS_IOS)
  InitIOSRunHook(this, argc, argv);
#endif
}

#if defined(OS_WIN)
void TestSuite::InitializeFromCommandLine(int argc, wchar_t** argv) {
  // Windows CommandLine::Init ignores argv anyway.
  initialized_command_line_ = CommandLine::Init(argc, NULL);
  testing::InitGoogleTest(&argc, argv);
  testing::InitGoogleMock(&argc, argv);
}
#endif  // defined(OS_WIN)

void TestSuite::PreInitialize() {
#if defined(OS_WIN)
  testing::GTEST_FLAG(catch_exceptions) = false;
#endif
  EnableTerminationOnHeapCorruption();
#if defined(OS_LINUX) && defined(USE_AURA)
  // When calling native char conversion functions (e.g wrctomb) we need to
  // have the locale set. In the absence of such a call the "C" locale is the
  // default. In the gtk code (below) gtk_init() implicitly sets a locale.
  setlocale(LC_ALL, "");
#endif  // defined(OS_LINUX) && defined(USE_AURA)

  // On Android, AtExitManager is created in
  // testing/android/native_test_wrapper.cc before main() is called.
#if !defined(OS_ANDROID)
  at_exit_manager_.reset(new AtExitManager);
#endif

  // Don't add additional code to this function.  Instead add it to
  // Initialize().  See bug 6436.
}


// static
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);
}

void TestSuite::AddTestLauncherResultPrinter() {
  // Only add the custom printer if requested.
  if (!CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kTestLauncherOutput)) {
    return;
  }

  FilePath output_path(CommandLine::ForCurrentProcess()->GetSwitchValuePath(
      switches::kTestLauncherOutput));

  // Do not add the result printer if output path already exists. It's an
  // indicator there is a process printing to that file, and we're likely
  // its child. Do not clobber the results in that case.
  if (PathExists(output_path)) {
    LOG(WARNING) << "Test launcher output path " << output_path.AsUTF8Unsafe()
                 << " exists. Not adding test launcher result printer.";
    return;
  }

  printer_ = new XmlUnitTestResultPrinter;
  CHECK(printer_->Initialize(output_path));
  testing::TestEventListeners& listeners =
      testing::UnitTest::GetInstance()->listeners();
  listeners.Append(printer_);
}

// Don't add additional code to this method.  Instead add it to
// Initialize().  See bug 6436.
int TestSuite::Run() {
#if defined(OS_IOS)
  RunTestsFromIOSApp();
#endif

#if defined(OS_MACOSX)
  mac::ScopedNSAutoreleasePool scoped_pool;
#endif

  Initialize();
  std::string client_func =
      CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
          switches::kTestChildProcess);

  // Check to see if we are being run as a client process.
  if (!client_func.empty())
    return multi_process_function_list::InvokeChildProcessTest(client_func);
#if defined(OS_IOS)
  test_listener_ios::RegisterTestEndListener();
#endif

  int result = RUN_ALL_TESTS();

#if defined(OS_MACOSX)
  // This MUST happen before Shutdown() since Shutdown() tears down
  // objects (such as NotificationService::current()) that Cocoa
  // objects use to remove themselves as observers.
  scoped_pool.Recycle();
#endif

  Shutdown();

  return result;
}

void TestSuite::UnitTestAssertHandler(const char* file,
                                      int line,
                                      const base::StringPiece summary,
                                      const base::StringPiece stack_trace) {
#if defined(OS_ANDROID)
  // Correlating test stdio with logcat can be difficult, so we emit this
  // helpful little hint about what was running.  Only do this for Android
  // because other platforms don't separate out the relevant logs in the same
  // way.
  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  // defined(OS_ANDROID)

  // XmlUnitTestResultPrinter inherits gtest format, where assert has summary
  // and message. In GTest, summary is just a logged text, and message is a
  // logged text, concatenated with stack trace of assert.
  // Concatenate summary and stack_trace here, to pass it as a message.
  if (printer_) {
    const std::string summary_str = summary.as_string();
    const std::string stack_trace_str = summary_str + stack_trace.as_string();
    printer_->OnAssert(file, line, summary_str, stack_trace_str);
  }

  // The logging system actually prints the message before calling the assert
  // handler. Just exit now to avoid printing too many stack traces.
  _exit(1);
}

#if defined(OS_WIN)
namespace {

// Disable optimizations to prevent function folding or other transformations
// that will make the call stacks on failures more confusing.
#pragma optimize("", off)
// Handlers for invalid parameter, pure call, and abort. They generate a
// breakpoint to ensure that we get a call stack on these failures.
void InvalidParameter(const wchar_t* expression,
                      const wchar_t* function,
                      const wchar_t* file,
                      unsigned int line,
                      uintptr_t reserved) {
  // CRT printed message is sufficient.
  __debugbreak();
  _exit(1);
}

void PureCall() {
  fprintf(stderr, "Pure-virtual function call. Terminating.\n");
  __debugbreak();
  _exit(1);
}

void AbortHandler(int signal) {
  // Print EOL after the CRT abort message.
  fprintf(stderr, "\n");
  __debugbreak();
}
#pragma optimize("", on)

}  // namespace
#endif

void TestSuite::SuppressErrorDialogs() {
#if defined(OS_WIN)
  UINT new_flags = SEM_FAILCRITICALERRORS |
                   SEM_NOGPFAULTERRORBOX |
                   SEM_NOOPENFILEERRORBOX;

  // Preserve existing error mode, as discussed at
  // http://blogs.msdn.com/oldnewthing/archive/2004/07/27/198410.aspx
  UINT existing_flags = SetErrorMode(new_flags);
  SetErrorMode(existing_flags | new_flags);

#if defined(_DEBUG)
  // Suppress the "Debug Assertion Failed" dialog.
  // TODO(hbono): remove this code when gtest has it.
  // http://groups.google.com/d/topic/googletestframework/OjuwNlXy5ac/discussion
  _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
  _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
  _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
  _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
#endif  // defined(_DEBUG)

  // See crbug.com/783040 for test code to trigger all of these failures.
  _set_invalid_parameter_handler(InvalidParameter);
  _set_purecall_handler(PureCall);
  signal(SIGABRT, AbortHandler);
#endif  // defined(OS_WIN)
}

void TestSuite::Initialize() {
  const CommandLine* command_line = CommandLine::ForCurrentProcess();
#if !defined(OS_IOS)
  if (command_line->HasSwitch(switches::kWaitForDebugger)) {
    debug::WaitForDebugger(60, true);
  }
#endif
  // Set up a FeatureList instance, so that code using that API will not hit a
  // an error that it's not set. It will be cleared automatically.
  // TestFeatureForBrowserTest1 and TestFeatureForBrowserTest2 used in
  // ContentBrowserTestScopedFeatureListTest to ensure ScopedFeatureList keeps
  // features from command line.
  std::string enabled =
      command_line->GetSwitchValueASCII(switches::kEnableFeatures);
  std::string disabled =
      command_line->GetSwitchValueASCII(switches::kDisableFeatures);
  enabled += ",TestFeatureForBrowserTest1";
  disabled += ",TestFeatureForBrowserTest2";
  scoped_feature_list_.InitFromCommandLine(enabled, disabled);

  // The enable-features and disable-features flags were just slurped into a
  // FeatureList, so remove them from the command line. Tests should enable and
  // disable features via the ScopedFeatureList API rather than command-line
  // flags.
  CommandLine new_command_line(command_line->GetProgram());
  CommandLine::SwitchMap switches = command_line->GetSwitches();

  switches.erase(switches::kEnableFeatures);
  switches.erase(switches::kDisableFeatures);

  for (const auto& iter : switches)
    new_command_line.AppendSwitchNative(iter.first, iter.second);

  *CommandLine::ForCurrentProcess() = new_command_line;

#if defined(OS_IOS)
  InitIOSTestMessageLoop();
#endif  // OS_IOS

#if defined(OS_ANDROID)
  InitAndroidTestMessageLoop();
#endif  // else defined(OS_ANDROID)

  CHECK(debug::EnableInProcessStackDumping());
#if defined(OS_WIN)
  RouteStdioToConsole(true);
  // Make sure we run with high resolution timer to minimize differences
  // between production code and test code.
  Time::EnableHighResolutionTimer(true);
#endif  // defined(OS_WIN)

  // In some cases, we do not want to see standard error dialogs.
  if (!debug::BeingDebugged() &&
      !command_line->HasSwitch("show-error-dialogs")) {
    SuppressErrorDialogs();
    debug::SetSuppressDebugUI(true);
    assert_handler_ = std::make_unique<logging::ScopedLogAssertHandler>(
        base::Bind(&TestSuite::UnitTestAssertHandler, base::Unretained(this)));
  }

  base::test::InitializeICUForTesting();

  // On the Mac OS X command line, the default locale is *_POSIX. In Chromium,
  // the locale is set via an OS X locale API and is never *_POSIX.
  // Some tests (such as those involving word break iterator) will behave
  // differently and fail if we use *POSIX locale. Setting it to en_US here
  // does not affect tests that explicitly overrides the locale for testing.
  // This can be an issue on all platforms other than Windows.
  // TODO(jshin): Should we set the locale via an OS X locale API here?
#if !defined(OS_WIN)
#if defined(OS_IOS)
  i18n::SetICUDefaultLocale("en_US");
#else
  std::string default_locale(uloc_getDefault());
  if (EndsWith(default_locale, "POSIX", CompareCase::INSENSITIVE_ASCII))
    i18n::SetICUDefaultLocale("en_US");
#endif
#endif

  CatchMaybeTests();
  ResetCommandLine();
  AddTestLauncherResultPrinter();

  TestTimeouts::Initialize();

  trace_to_file_.BeginTracingFromCommandLineOptions();

  base::debug::StartProfiling(GetProfileName());
}

void TestSuite::Shutdown() {
  base::debug::StopProfiling();
}

}  // namespace base
