// 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

#if defined(OS_LINUX)
#include "base/test/fontconfig_util_linux.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))
      << "Output path is " << output_path.AsUTF8Unsafe()
      << " and PathExists(output_path) is " << PathExists(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

#if defined(OS_LINUX)
  // TODO(thomasanderson): Call TearDownFontconfig() in Shutdown().  It would
  // currently crash because of leaked FcFontSet's in font_fallback_linux.cc.
  SetUpFontconfig();
#endif

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

  TestTimeouts::Initialize();

  trace_to_file_.BeginTracingFromCommandLineOptions();

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

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

}  // namespace base
