// Copyright (c) 2012 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 "chromeos/process.h"

#include <unistd.h>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <gtest/gtest.h>

#include "chromeos/process_mock.h"
#include "chromeos/test_helpers.h"

using base::FilePath;

// This test assumes the following standard binaries are installed.
static const char kBinBash[] = "/bin/bash";
static const char kBinCat[] = "/bin/cat";
static const char kBinCp[] = "/bin/cp";
static const char kBinEcho[] = "/bin/echo";
static const char kBinFalse[] = "/bin/false";
static const char kBinSleep[] = "/bin/sleep";
static const char kBinTrue[] = "/bin/true";

namespace chromeos {

// Test that the mock has all the functions of the interface by
// instantiating it.  This variable is not used elsewhere.
struct CompileMocks {
  ProcessMock process_mock;
};

TEST(SimpleProcess, Basic) {
  // Log must be cleared before running this test, just as ProcessTest::SetUp.
  ClearLog();
  ProcessImpl process;
  process.AddArg(kBinEcho);
  EXPECT_EQ(0, process.Run());
  EXPECT_EQ("", GetLog());
}

TEST(SimpleProcess, NoSearchPath) {
  ProcessImpl process;
  process.AddArg("echo");
  EXPECT_EQ(127, process.Run());
}

TEST(SimpleProcess, SearchPath) {
  ProcessImpl process;
  process.AddArg("echo");
  process.SetSearchPath(true);
  EXPECT_EQ(EXIT_SUCCESS, process.Run());
}

TEST(SimpleProcess, BindFd) {
  int fds[2];
  char buf[16];
  static const char* kMsg = "hello, world!";
  ProcessImpl process;
  EXPECT_EQ(0, pipe(fds));
  process.AddArg(kBinEcho);
  process.AddArg(kMsg);
  process.BindFd(fds[1], 1);
  process.Start();
  memset(buf, 0, sizeof(buf));
  EXPECT_EQ(read(fds[0], buf, sizeof(buf) - 1), strlen(kMsg) + 1);
  EXPECT_EQ(std::string(kMsg) + "\n", std::string(buf));
}

class ProcessTest : public ::testing::Test {
 public:
  void SetUp() {
    test_path_ = FilePath("test");
    output_file_ = test_path_.Append("fork_out").value();
    base::DeleteFile(test_path_, true);
    base::CreateDirectory(test_path_);
    process_.RedirectOutput(output_file_);
    ClearLog();
  }

  void TearDown() { base::DeleteFile(test_path_, true); }

 protected:
  void CheckStderrCaptured();
  FilePath GetFdPath(int fd);

  ProcessImpl process_;
  std::vector<const char*> args_;
  std::string output_file_;
  FilePath test_path_;
};

TEST_F(ProcessTest, Basic) {
  process_.AddArg(kBinEcho);
  process_.AddArg("hello world");
  EXPECT_EQ(0, process_.Run());
  ExpectFileEquals("hello world\n", output_file_.c_str());
  EXPECT_EQ("", GetLog());
}

TEST_F(ProcessTest, AddStringOption) {
  process_.AddArg(kBinEcho);
  process_.AddStringOption("--hello", "world");
  EXPECT_EQ(0, process_.Run());
  ExpectFileEquals("--hello world\n", output_file_.c_str());
}

TEST_F(ProcessTest, AddIntValue) {
  process_.AddArg(kBinEcho);
  process_.AddIntOption("--answer", 42);
  EXPECT_EQ(0, process_.Run());
  ExpectFileEquals("--answer 42\n", output_file_.c_str());
}

TEST_F(ProcessTest, NonZeroReturnValue) {
  process_.AddArg(kBinFalse);
  EXPECT_EQ(1, process_.Run());
  ExpectFileEquals("", output_file_.c_str());
  EXPECT_EQ("", GetLog());
}

TEST_F(ProcessTest, BadOutputFile) {
  process_.AddArg(kBinEcho);
  process_.RedirectOutput("/bad/path");
  EXPECT_EQ(static_cast<pid_t>(Process::kErrorExitStatus), process_.Run());
}

TEST_F(ProcessTest, ExistingOutputFile) {
  process_.AddArg(kBinEcho);
  process_.AddArg("hello world");
  EXPECT_FALSE(base::PathExists(FilePath(output_file_)));
  EXPECT_EQ(0, process_.Run());
  EXPECT_TRUE(base::PathExists(FilePath(output_file_)));
  EXPECT_EQ(static_cast<pid_t>(Process::kErrorExitStatus), process_.Run());
}

TEST_F(ProcessTest, BadExecutable) {
  process_.AddArg("false");
  EXPECT_EQ(static_cast<pid_t>(Process::kErrorExitStatus), process_.Run());
}

void ProcessTest::CheckStderrCaptured() {
  std::string contents;
  process_.AddArg(kBinCp);
  EXPECT_EQ(1, process_.Run());
  EXPECT_TRUE(base::ReadFileToString(FilePath(output_file_), &contents));
  EXPECT_NE(std::string::npos, contents.find("missing file operand"));
  EXPECT_EQ("", GetLog());
}

TEST_F(ProcessTest, StderrCaptured) {
  CheckStderrCaptured();
}

TEST_F(ProcessTest, StderrCapturedWhenPreviouslyClosed) {
  int saved_stderr = dup(STDERR_FILENO);
  close(STDERR_FILENO);
  CheckStderrCaptured();
  dup2(saved_stderr, STDERR_FILENO);
}

FilePath ProcessTest::GetFdPath(int fd) {
  return FilePath(base::StringPrintf("/proc/self/fd/%d", fd));
}

TEST_F(ProcessTest, RedirectStderrUsingPipe) {
  std::string contents;
  process_.RedirectOutput("");
  process_.AddArg(kBinCp);
  process_.RedirectUsingPipe(STDERR_FILENO, false);
  EXPECT_EQ(-1, process_.GetPipe(STDERR_FILENO));
  EXPECT_EQ(1, process_.Run());
  int pipe_fd = process_.GetPipe(STDERR_FILENO);
  EXPECT_GE(pipe_fd, 0);
  EXPECT_EQ(-1, process_.GetPipe(STDOUT_FILENO));
  EXPECT_EQ(-1, process_.GetPipe(STDIN_FILENO));
  EXPECT_TRUE(base::ReadFileToString(GetFdPath(pipe_fd), &contents));
  EXPECT_NE(std::string::npos, contents.find("missing file operand"));
  EXPECT_EQ("", GetLog());
}

TEST_F(ProcessTest, RedirectStderrUsingPipeWhenPreviouslyClosed) {
  int saved_stderr = dup(STDERR_FILENO);
  close(STDERR_FILENO);
  process_.RedirectOutput("");
  process_.AddArg(kBinCp);
  process_.RedirectUsingPipe(STDERR_FILENO, false);
  EXPECT_FALSE(process_.Start());
  EXPECT_TRUE(FindLog("Unable to fstat fd 2:"));
  dup2(saved_stderr, STDERR_FILENO);
}

TEST_F(ProcessTest, RedirectStdoutUsingPipe) {
  std::string contents;
  process_.RedirectOutput("");
  process_.AddArg(kBinEcho);
  process_.AddArg("hello world\n");
  process_.RedirectUsingPipe(STDOUT_FILENO, false);
  EXPECT_EQ(-1, process_.GetPipe(STDOUT_FILENO));
  EXPECT_EQ(0, process_.Run());
  int pipe_fd = process_.GetPipe(STDOUT_FILENO);
  EXPECT_GE(pipe_fd, 0);
  EXPECT_EQ(-1, process_.GetPipe(STDERR_FILENO));
  EXPECT_EQ(-1, process_.GetPipe(STDIN_FILENO));
  EXPECT_TRUE(base::ReadFileToString(GetFdPath(pipe_fd), &contents));
  EXPECT_NE(std::string::npos, contents.find("hello world\n"));
  EXPECT_EQ("", GetLog());
}

TEST_F(ProcessTest, RedirectStdinUsingPipe) {
  std::string contents;
  const char kMessage[] = "made it!\n";
  process_.AddArg(kBinCat);
  process_.RedirectUsingPipe(STDIN_FILENO, true);
  process_.RedirectOutput(output_file_);
  EXPECT_TRUE(process_.Start());
  int write_fd = process_.GetPipe(STDIN_FILENO);
  EXPECT_EQ(-1, process_.GetPipe(STDERR_FILENO));
  EXPECT_TRUE(base::WriteFile(GetFdPath(write_fd), kMessage, strlen(kMessage)));
  close(write_fd);
  EXPECT_EQ(0, process_.Wait());
  ExpectFileEquals(kMessage, output_file_.c_str());
}

TEST_F(ProcessTest, WithSameUid) {
  gid_t uid = geteuid();
  process_.AddArg(kBinEcho);
  process_.SetUid(uid);
  EXPECT_EQ(0, process_.Run());
}

TEST_F(ProcessTest, WithSameGid) {
  gid_t gid = getegid();
  process_.AddArg(kBinEcho);
  process_.SetGid(gid);
  EXPECT_EQ(0, process_.Run());
}

TEST_F(ProcessTest, WithIllegalUid) {
  ASSERT_NE(0, geteuid());
  process_.AddArg(kBinEcho);
  process_.SetUid(0);
  EXPECT_EQ(static_cast<pid_t>(Process::kErrorExitStatus), process_.Run());
  std::string contents;
  EXPECT_TRUE(base::ReadFileToString(FilePath(output_file_), &contents));
  EXPECT_NE(std::string::npos, contents.find("Unable to set UID to 0: 1\n"));
}

TEST_F(ProcessTest, WithIllegalGid) {
  ASSERT_NE(0, getegid());
  process_.AddArg(kBinEcho);
  process_.SetGid(0);
  EXPECT_EQ(static_cast<pid_t>(Process::kErrorExitStatus), process_.Run());
  std::string contents;
  EXPECT_TRUE(base::ReadFileToString(FilePath(output_file_), &contents));
  EXPECT_NE(std::string::npos, contents.find("Unable to set GID to 0: 1\n"));
}

TEST_F(ProcessTest, NoParams) {
  EXPECT_EQ(static_cast<pid_t>(Process::kErrorExitStatus), process_.Run());
}

TEST_F(ProcessTest, SegFaultHandling) {
  process_.AddArg(kBinBash);
  process_.AddArg("-c");
  process_.AddArg("kill -SEGV $$");
  EXPECT_EQ(-1, process_.Run());
  EXPECT_TRUE(FindLog("did not exit normally: 11"));
}

TEST_F(ProcessTest, KillNoPid) {
  process_.Kill(SIGTERM, 0);
  EXPECT_TRUE(FindLog("Process not running"));
}

TEST_F(ProcessTest, ProcessExists) {
  EXPECT_FALSE(Process::ProcessExists(0));
  EXPECT_TRUE(Process::ProcessExists(1));
  EXPECT_TRUE(Process::ProcessExists(getpid()));
}

TEST_F(ProcessTest, ResetPidByFile) {
  FilePath pid_path = test_path_.Append("pid");
  EXPECT_FALSE(process_.ResetPidByFile(pid_path.value()));
  EXPECT_TRUE(base::WriteFile(pid_path, "456\n", 4));
  EXPECT_TRUE(process_.ResetPidByFile(pid_path.value()));
  EXPECT_EQ(456, process_.pid());
  // The purpose of this unit test is to check if Process::ResetPidByFile() can
  // properly read a pid from a file. We don't really want to kill the process
  // with pid 456, so update the pid to 0 to prevent the Process destructor from
  // killing any innocent process.
  process_.UpdatePid(0);
}

TEST_F(ProcessTest, KillSleeper) {
  process_.AddArg(kBinSleep);
  process_.AddArg("10000");
  ASSERT_TRUE(process_.Start());
  pid_t pid = process_.pid();
  ASSERT_GT(pid, 1);
  EXPECT_TRUE(process_.Kill(SIGTERM, 1));
  EXPECT_EQ(0, process_.pid());
}

TEST_F(ProcessTest, Reset) {
  process_.AddArg(kBinFalse);
  process_.Reset(0);
  process_.AddArg(kBinEcho);
  EXPECT_EQ(0, process_.Run());
}

bool ReturnFalse() { return false; }

TEST_F(ProcessTest, PreExecCallback) {
  process_.AddArg(kBinTrue);
  process_.SetPreExecCallback(base::Bind(&ReturnFalse));
  ASSERT_NE(0, process_.Run());
}

}  // namespace chromeos
