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

// This test validates that the ProcessSingleton class properly makes sure
// that there is only one main browser process.
//
// It is currently compiled and run on Windows and Posix(non-Mac) platforms.
// Mac uses system services and ProcessSingletonMac is a noop.  (Maybe it still
// makes sense to test that the system services are giving the behavior we
// want?)

#include <stddef.h>

#include <memory>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/path_service.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "base/process/process_iterator.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/single_thread_task_runner_forward.h"
#include "base/test/test_timeouts.h"
#include "base/threading/thread.h"
#include "build/build_config.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_result_codes.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/test_launcher_utils.h"
#include "content/public/test/browser_test.h"
#include "testing/gmock/include/gmock/gmock.h"

using ::testing::AnyOf;
using ::testing::Eq;

namespace {

// This is for the code that is to be ran in multiple threads at once,
// to stress a race condition on first process start.
// We use the thread safe ref counted base class so that we can use the
// base::Bind to run the StartChrome methods in many threads.
class ChromeStarter : public base::RefCountedThreadSafe<ChromeStarter> {
 public:
  ChromeStarter(base::TimeDelta timeout,
                const base::FilePath& user_data_dir,
                const base::CommandLine& initial_command_line_for_relaunch)
      : ready_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                     base::WaitableEvent::InitialState::NOT_SIGNALED),
        done_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                    base::WaitableEvent::InitialState::NOT_SIGNALED),
        process_terminated_(false),
        timeout_(timeout),
        user_data_dir_(user_data_dir),
        initial_command_line_for_relaunch_(initial_command_line_for_relaunch) {}

  ChromeStarter(const ChromeStarter&) = delete;
  ChromeStarter& operator=(const ChromeStarter&) = delete;

  // We must reset some data members since we reuse the same ChromeStarter
  // object and start/stop it a few times. We must start fresh! :-)
  void Reset() {
    ready_event_.Reset();
    done_event_.Reset();
    if (process_.IsValid())
      process_.Close();
    process_terminated_ = false;
  }

  void StartChrome(base::WaitableEvent* start_event, bool first_run) {
    base::CommandLine command_line_for_relaunch(
        initial_command_line_for_relaunch_.GetProgram());
    test_launcher_utils::RemoveCommandLineSwitch(
        initial_command_line_for_relaunch_, switches::kUserDataDir,
        &command_line_for_relaunch);
    command_line_for_relaunch.AppendSwitchPath(switches::kUserDataDir,
                                               user_data_dir_);

    if (first_run) {
      base::CommandLine tmp_command_line = command_line_for_relaunch;
      test_launcher_utils::RemoveCommandLineSwitch(
          tmp_command_line, switches::kNoFirstRun, &command_line_for_relaunch);
      command_line_for_relaunch.AppendSwitch(switches::kForceFirstRun);
    }

    // Try to get all threads to launch the app at the same time.
    // So let the test know we are ready.
    ready_event_.Signal();
    // And then wait for the test to tell us to GO!
    ASSERT_NE(nullptr, start_event);
    start_event->Wait();

    // Here we don't wait for the app to be terminated because one of the
    // process will stay alive while the others will be restarted. If we would
    // wait here, we would never get a handle to the main process...
    process_ =
        base::LaunchProcess(command_line_for_relaunch, base::LaunchOptions());
    ASSERT_TRUE(process_.IsValid());

    // We can wait on the handle here, we should get stuck on one and only
    // one process. The test below will take care of killing that process
    // to unstuck us once it confirms there is only one.
    process_terminated_ =
        process_.WaitForExitWithTimeout(timeout_, &exit_code_);
    // Let the test know we are done.
    done_event_.Signal();
  }

  // Public access to simplify the test code using them.
  base::WaitableEvent ready_event_;
  base::WaitableEvent done_event_;
  base::Process process_;
  bool process_terminated_;
  // Process exit code. Only meaningful if |process_terminated_| is true.
  int exit_code_;

 private:
  friend class base::RefCountedThreadSafe<ChromeStarter>;

  ~ChromeStarter() {}

  base::TimeDelta timeout_;
  base::FilePath user_data_dir_;
  base::CommandLine initial_command_line_for_relaunch_;
};

}  // namespace

// Our test fixture that initializes and holds onto a few global vars.
class ProcessSingletonTest : public InProcessBrowserTest {
 public:
  ProcessSingletonTest()
      // We use a manual reset so that all threads wake up at once when signaled
      // and thus we must manually reset it for each attempt.
      : threads_waker_(base::WaitableEvent::ResetPolicy::MANUAL,
                       base::WaitableEvent::InitialState::NOT_SIGNALED) {
    EXPECT_TRUE(temp_profile_dir_.CreateUniqueTempDir());
  }

  void TearDown() override {
    InProcessBrowserTest::TearDown();
    // Stop the threads.
    for (size_t i = 0; i < kNbThreads; ++i)
      chrome_starter_threads_[i]->Stop();
  }

  // This method is used to make sure we kill the main browser process after
  // all of its child processes have successfully attached to it. This was added
  // when we realized that if we just kill the parent process right away, we
  // sometimes end up with dangling child processes. If we Sleep for a certain
  // amount of time, we are OK... So we introduced this method to avoid a
  // flaky wait. Instead, we kill all descendants of the main process after we
  // killed it, relying on the fact that we can still get the parent id of a
  // child process, even when the parent dies.
  void KillProcessTree(const base::Process& process) {
    class ProcessTreeFilter : public base::ProcessFilter {
     public:
      explicit ProcessTreeFilter(base::ProcessId parent_pid) {
        ancestor_pids_.insert(parent_pid);
      }
      bool Includes(const base::ProcessEntry& entry) const override {
        if (ancestor_pids_.find(entry.parent_pid()) != ancestor_pids_.end()) {
          ancestor_pids_.insert(entry.pid());
          return true;
        } else {
          return false;
        }
      }
     private:
      mutable std::set<base::ProcessId> ancestor_pids_;
    } process_tree_filter(process.Pid());

    // Start by explicitly killing the main process we know about...
    static const int kExitCode = 42;
    EXPECT_TRUE(process.Terminate(kExitCode, true /* wait */));

    // Then loop until we can't find any of its descendant.
    // But don't try more than kNbTries times...
    static const int kNbTries = 10;
    int num_tries = 0;
    base::FilePath program;
    ASSERT_TRUE(base::PathService::Get(base::FILE_EXE, &program));
    base::FilePath::StringType exe_name = program.BaseName().value();
    while (base::GetProcessCount(exe_name, &process_tree_filter) > 0 &&
           num_tries++ < kNbTries) {
      base::KillProcesses(exe_name, kExitCode, &process_tree_filter);
    }
    DLOG_IF(ERROR, num_tries >= kNbTries) << "Failed to kill all processes!";
  }

  // Since this is a hard to reproduce problem, we make a few attempts.
  // We stop the attempts at the first error, and when there are no errors,
  // we don't time-out of any wait, so it executes quite fast anyway.
  static const size_t kNbAttempts = 5;

  // The idea is to start chrome from multiple threads all at once.
  static const size_t kNbThreads = 5;
  scoped_refptr<ChromeStarter> chrome_starters_[kNbThreads];
  std::unique_ptr<base::Thread> chrome_starter_threads_[kNbThreads];

  // The event that will get all threads to wake up simultaneously and try
  // to start a chrome process at the same time.
  base::WaitableEvent threads_waker_;

  // We don't want to use the default profile, but can't use UITest's since we
  // don't use UITest::LaunchBrowser.
  base::ScopedTempDir temp_profile_dir_;
};

// ChromeOS hits DCHECKS on ProcessSingleton rendezvous: crbug.com/782487
#if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_WIN)
#define MAYBE_StartupRaceCondition DISABLED_StartupRaceCondition
#else
#define MAYBE_StartupRaceCondition StartupRaceCondition
#endif
IN_PROC_BROWSER_TEST_F(ProcessSingletonTest, MAYBE_StartupRaceCondition) {
  // Start the threads and create the starters.
  for (size_t i = 0; i < kNbThreads; ++i) {
    chrome_starter_threads_[i] =
        std::make_unique<base::Thread>("ChromeStarter");
    ASSERT_TRUE(chrome_starter_threads_[i]->Start());
    chrome_starters_[i] = base::MakeRefCounted<ChromeStarter>(
        TestTimeouts::action_max_timeout(), temp_profile_dir_.GetPath(),
        GetCommandLineForRelaunch());
  }

  for (size_t attempt = 0; attempt < kNbAttempts && !HasFailure(); ++attempt) {
    SCOPED_TRACE(testing::Message() << "Attempt: " << attempt << ".");
    // We use a single event to get all threads to do the AppLaunch at the
    // same time...
    threads_waker_.Reset();

    // Test both with and without the first-run dialog, since they exercise
    // different paths.
#if defined(OS_POSIX)
    // TODO(mattm): test first run dialog singleton handling on linux too.
    // On posix if we test the first run dialog, GracefulShutdownHandler gets
    // the TERM signal, but since the message loop isn't running during the gtk
    // first run dialog, the ShutdownDetector never handles it, and KillProcess
    // has to time out (60 sec!) and SIGKILL.
    bool first_run = false;
#else
    // Test for races in both regular start up and first run start up cases.
    bool first_run = attempt % 2;
#endif

    // Here we prime all the threads with a ChromeStarter that will wait for
    // our signal to launch its chrome process.
    for (size_t i = 0; i < kNbThreads; ++i) {
      ASSERT_NE(static_cast<ChromeStarter*>(NULL), chrome_starters_[i].get());
      chrome_starters_[i]->Reset();

      ASSERT_TRUE(chrome_starter_threads_[i]->IsRunning());
      ASSERT_TRUE(chrome_starter_threads_[i]->task_runner());

      chrome_starter_threads_[i]->task_runner()->PostTask(
          FROM_HERE,
          base::BindOnce(&ChromeStarter::StartChrome, chrome_starters_[i],
                         &threads_waker_, first_run));
    }

    // Wait for all the starters to be ready.
    // We could replace this loop if we ever implement a WaitAll().
    for (size_t i = 0; i < kNbThreads; ++i) {
      SCOPED_TRACE(testing::Message() << "Waiting on thread: " << i << ".");
      chrome_starters_[i]->ready_event_.Wait();
    }
    // GO!
    threads_waker_.Signal();

    // As we wait for all threads to signal that they are done, we remove their
    // index from this vector so that we get left with only the index of
    // the thread that started the main process.
    std::vector<size_t> pending_starters(kNbThreads);
    for (size_t i = 0; i < kNbThreads; ++i)
      pending_starters[i] = i;

    // We use a local array of starter's done events we must wait on...
    // These are collected from the starters that we have not yet been removed
    // from the pending_starters vector.
    base::WaitableEvent* starters_done_events[kNbThreads];
    // At the end, "There can be only one" main browser process alive.
    while (pending_starters.size() > 1) {
      SCOPED_TRACE(testing::Message() << pending_starters.size() <<
                   " starters left.");
      for (size_t i = 0; i < pending_starters.size(); ++i) {
        starters_done_events[i] =
            &chrome_starters_[pending_starters[i]]->done_event_;
      }
      size_t done_index = base::WaitableEvent::WaitMany(
          starters_done_events, pending_starters.size());
      size_t starter_index = pending_starters[done_index];
      // If the starter is done but has not marked itself as terminated,
      // it is because it timed out of its WaitForExitCodeWithTimeout(). Only
      // the last one standing should be left waiting... So we failed...
      EXPECT_TRUE(chrome_starters_[starter_index]->process_terminated_)
          << "There is more than one main process.";
      if (chrome_starters_[starter_index]->process_terminated_) {
        // Generally PROCESS_NOTIFIED would be the expected exit code. In some
        // rare cases the ProcessSingleton race can result in PROFILE_IN_USE
        // exit code, which we also allow, though it would be ideal if that
        // never happened.
        // TODO(mattm): investigate why PROFILE_IN_USE occurs sometimes.
        EXPECT_THAT(
            chrome_starters_[starter_index]->exit_code_,
            AnyOf(Eq(chrome::RESULT_CODE_PROFILE_IN_USE),
                  Eq(chrome::RESULT_CODE_NORMAL_EXIT_PROCESS_NOTIFIED)));
      } else {
        // But we let the last loop turn finish so that we can properly
        // kill all remaining processes. Starting with this one...
        if (chrome_starters_[starter_index]->process_.IsValid()) {
          KillProcessTree(chrome_starters_[starter_index]->process_);
        }
      }
      pending_starters.erase(pending_starters.begin() + done_index);
    }

    // "There can be only one!" :-)
    ASSERT_EQ(static_cast<size_t>(1), pending_starters.size());
    size_t last_index = pending_starters.front();
    pending_starters.clear();
    if (chrome_starters_[last_index]->process_.IsValid()) {
      KillProcessTree(chrome_starters_[last_index]->process_);
      chrome_starters_[last_index]->done_event_.Wait();
    }
  }
}
