// Copyright (c) 2014 The Chromium OS 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 "login_manager/child_exit_dispatcher.h"

#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <memory>
#include <string>
#include <vector>

#include <base/message_loop/message_loop.h>
#include <base/run_loop.h>
#include <base/test/bind_test_util.h>
#include <brillo/asynchronous_signal_handler.h>
#include <brillo/message_loops/base_message_loop.h>
#include <gtest/gtest.h>

#include "login_manager/child_exit_handler.h"
#include "login_manager/system_utils_impl.h"

namespace login_manager {
namespace {

class ScopedSIGCHLDMask {
 public:
  ScopedSIGCHLDMask() {
    sigset_t signal_set;
    CHECK_EQ(sigemptyset(&signal_set), 0);
    CHECK_EQ(sigaddset(&signal_set, SIGCHLD), 0);
    CHECK_EQ(sigprocmask(SIG_BLOCK, &signal_set, &old_signal_set_), 0);
  }
  ~ScopedSIGCHLDMask() {
    CHECK_EQ(sigprocmask(SIG_SETMASK, &old_signal_set_, nullptr), 0);
  }

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

 private:
  sigset_t old_signal_set_;
};

// A fake child exit handler implementation for testing.
class FakeChildExitHandler : public ChildExitHandler {
 public:
  using HandleExitCallback = base::RepeatingCallback<bool(const siginfo_t&)>;

  explicit FakeChildExitHandler(const HandleExitCallback& callback)
      : callback_(callback) {}
  ~FakeChildExitHandler() override = default;

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

  // ChildExitHandler overrides.
  bool HandleExit(const siginfo_t& s) override { return callback_.Run(s); }

 private:
  HandleExitCallback callback_;
};

}  // namespace

class ChildExitDispatcherTest : public ::testing::Test {
 public:
  ChildExitDispatcherTest() = default;
  ~ChildExitDispatcherTest() override = default;

  void SetUp() override {
    brillo_loop_.SetAsCurrent();
  }

 protected:
  base::MessageLoopForIO loop_;
  brillo::BaseMessageLoop brillo_loop_{&loop_};
  SystemUtilsImpl system_utils_;
  brillo::AsynchronousSignalHandler signal_handler_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ChildExitDispatcherTest);
};

TEST_F(ChildExitDispatcherTest, ChildExit) {
  signal_handler_.Init();

  base::Optional<siginfo_t> siginfo;
  FakeChildExitHandler fake_handler(
      base::BindLambdaForTesting([&siginfo](const siginfo_t& s) {
        siginfo = s;
        brillo::MessageLoop::current()->BreakLoop();
        return true;
      }));
  auto dispatcher = std::make_unique<ChildExitDispatcher>(
      &signal_handler_, std::vector<ChildExitHandler*>{&fake_handler});

  // Fork off a child process that exits immediately.
  pid_t child_pid = system_utils_.fork();
  if (child_pid == 0) {
    _Exit(EXIT_SUCCESS);
  }

  // Spin the message loop.
  brillo_loop_.Run();

  // Verify child termination has been reported to |fake_handler|.
  ASSERT_TRUE(siginfo.has_value());
  EXPECT_EQ(child_pid, siginfo->si_pid);
  EXPECT_EQ(SIGCHLD, siginfo->si_signo);
  EXPECT_EQ(static_cast<int>(CLD_EXITED), siginfo->si_code);
  EXPECT_EQ(EXIT_SUCCESS, siginfo->si_status);
}

// Makes sure that even if ChildExitDispatcher is destroyed in the
// HandleExit, it should not cause a crash.
TEST_F(ChildExitDispatcherTest, DestroyInHandleExit) {
  // If multiple children are terminated, SIGCHLD will be squashed.
  // Practically this happens if children are terminated in a short period.
  // However, it is not easy to reproduce the situation reliably,
  // instead, this test sets up in the following approach to simulate it;
  // - Block SIGCHLD.
  // - Create a subprocess, and terminate it.
  // - Consume SIGCHLD via signalfd without waitpid.
  // - Create another subprocess, and terminate it.
  ScopedSIGCHLDMask scoped_mask;
  signal_handler_.Init();

  // Create the first subprocess.
  pid_t child_pid1 = system_utils_.fork();
  if (child_pid1 == 0) {
    _Exit(EXIT_SUCCESS);
  }

  // Consume SIGCHLD.
  signal_handler_.RegisterHandler(
      SIGCHLD, base::BindLambdaForTesting([](const struct signalfd_siginfo&) {
        brillo::MessageLoop::current()->BreakLoop();
        return true;
      }));
  brillo_loop_.Run();
  signal_handler_.UnregisterHandler(SIGCHLD);

  // Create the second subprocess.
  pid_t child_pid2 = system_utils_.fork();
  if (child_pid2 == 0) {
    _Exit(EXIT_SUCCESS);
  }

  // Set up ChildExitDispatcher.
  base::Optional<siginfo_t> siginfo;
  std::unique_ptr<ChildExitDispatcher> dispatcher;
  FakeChildExitHandler fake_handler(
      base::BindLambdaForTesting([&siginfo, &dispatcher](const siginfo_t& s) {
        siginfo = s;
        dispatcher = nullptr;  // Delete the dispatcher.
        brillo::MessageLoop::current()->BreakLoop();
        return true;
      }));
  dispatcher = std::make_unique<ChildExitDispatcher>(
      &signal_handler_, std::vector<ChildExitHandler*>{&fake_handler});

  // Spin the message loop.
  brillo_loop_.Run();

  // Verify child termination has been reported to |fake_handler|.
  ASSERT_TRUE(siginfo.has_value());
  EXPECT_EQ(child_pid1, siginfo->si_pid);
  EXPECT_EQ(SIGCHLD, siginfo->si_signo);
  EXPECT_EQ(static_cast<int>(CLD_EXITED), siginfo->si_code);
  EXPECT_EQ(EXIT_SUCCESS, siginfo->si_status);

  // No pending child is expected.
  siginfo_t info;
  ASSERT_EQ(-1, waitid(P_ALL, 0, &info, WEXITED | WNOHANG));
  EXPECT_EQ(errno, ECHILD);
}

}  // namespace login_manager
