//
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "update_engine/common/subprocess.h"

#include <fcntl.h>
#include <poll.h>
#include <sys/types.h>
#include <unistd.h>

#include <set>
#include <string>
#include <vector>

#include <base/bind.h>
#include <base/files/scoped_temp_dir.h>
#include <base/location.h>
#include <base/message_loop/message_loop.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <base/time/time.h>
#include <brillo/message_loops/base_message_loop.h>
#include <brillo/message_loops/message_loop.h>
#include <brillo/message_loops/message_loop_utils.h>
#include <brillo/strings/string_utils.h>
#include <brillo/unittest_utils.h>
#include <gtest/gtest.h>

#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"

using base::TimeDelta;
using brillo::MessageLoop;
using std::string;
using std::unique_ptr;
using std::vector;

namespace {

#ifdef __ANDROID__
#define kBinPath "/system/bin"
#define kUsrBinPath "/system/bin"
#else
#define kBinPath "/bin"
#define kUsrBinPath "/usr/bin"
#endif  // __ANDROID__

}  // namespace

namespace chromeos_update_engine {

class SubprocessTest : public ::testing::Test {
 protected:
  void SetUp() override {
    loop_.SetAsCurrent();
    async_signal_handler_.Init();
    subprocess_.Init(&async_signal_handler_);
  }

  base::MessageLoopForIO base_loop_;
  brillo::BaseMessageLoop loop_{&base_loop_};
  brillo::AsynchronousSignalHandler async_signal_handler_;
  Subprocess subprocess_;
  unique_ptr<base::FileDescriptorWatcher::Controller> watcher_;

};

namespace {

void ExpectedResults(int expected_return_code,
                     const string& expected_output,
                     int return_code,
                     const string& output) {
  EXPECT_EQ(expected_return_code, return_code);
  EXPECT_EQ(expected_output, output);
  MessageLoop::current()->BreakLoop();
}

void ExpectedEnvVars(int return_code, const string& output) {
  EXPECT_EQ(0, return_code);
  const std::set<string> allowed_envs = {"LD_LIBRARY_PATH", "PATH"};
  for (const string& key_value : brillo::string_utils::Split(output, "\n")) {
    auto key_value_pair =
        brillo::string_utils::SplitAtFirst(key_value, "=", true);
    EXPECT_NE(allowed_envs.end(), allowed_envs.find(key_value_pair.first));
  }
  MessageLoop::current()->BreakLoop();
}

void ExpectedDataOnPipe(const Subprocess* subprocess,
                        pid_t* pid,
                        int child_fd,
                        const string& child_fd_data,
                        int expected_return_code,
                        int return_code,
                        const string& /* output */) {
  EXPECT_EQ(expected_return_code, return_code);

  // Verify that we can read the data from our end of |child_fd|.
  int fd = subprocess->GetPipeFd(*pid, child_fd);
  EXPECT_NE(-1, fd);
  vector<char> buf(child_fd_data.size() + 1);
  EXPECT_EQ(static_cast<ssize_t>(child_fd_data.size()),
            HANDLE_EINTR(read(fd, buf.data(), buf.size())));
  EXPECT_EQ(child_fd_data,
            string(buf.begin(), buf.begin() + child_fd_data.size()));

  MessageLoop::current()->BreakLoop();
}

}  // namespace

TEST_F(SubprocessTest, IsASingleton) {
  EXPECT_EQ(&subprocess_, &Subprocess::Get());
}

TEST_F(SubprocessTest, InactiveInstancesDontChangeTheSingleton) {
  std::unique_ptr<Subprocess> another_subprocess(new Subprocess());
  EXPECT_EQ(&subprocess_, &Subprocess::Get());
  another_subprocess.reset();
  EXPECT_EQ(&subprocess_, &Subprocess::Get());
}

TEST_F(SubprocessTest, SimpleTest) {
  EXPECT_TRUE(subprocess_.Exec({kBinPath "/false"},
                               base::Bind(&ExpectedResults, 1, "")));
  loop_.Run();
}

TEST_F(SubprocessTest, EchoTest) {
  EXPECT_TRUE(subprocess_.Exec(
      {kBinPath "/sh", "-c", "echo this is stdout; echo this is stderr >&2"},
      base::Bind(&ExpectedResults, 0, "this is stdout\nthis is stderr\n")));
  loop_.Run();
}

TEST_F(SubprocessTest, StderrNotIncludedInOutputTest) {
  EXPECT_TRUE(subprocess_.ExecFlags(
      {kBinPath "/sh", "-c", "echo on stdout; echo on stderr >&2"},
      0,
      {},
      base::Bind(&ExpectedResults, 0, "on stdout\n")));
  loop_.Run();
}

TEST_F(SubprocessTest, PipeRedirectFdTest) {
  pid_t pid;
  pid = subprocess_.ExecFlags(
      {kBinPath "/sh", "-c", "echo on pipe >&3"},
      0,
      {3},
      base::Bind(&ExpectedDataOnPipe, &subprocess_, &pid, 3, "on pipe\n", 0));
  EXPECT_NE(0, pid);

  // Wrong file descriptor values should return -1.
  EXPECT_EQ(-1, subprocess_.GetPipeFd(pid, 123));
  loop_.Run();
  // Calling GetPipeFd() after the callback runs is invalid.
  EXPECT_EQ(-1, subprocess_.GetPipeFd(pid, 3));
}

// Test that a pipe file descriptor open in the parent is not open in the child.
TEST_F(SubprocessTest, PipeClosedWhenNotRedirectedTest) {
  brillo::ScopedPipe pipe;

  // test_subprocess will return with the errno of fstat, which should be EBADF
  // if the passed file descriptor is closed in the child.
  const vector<string> cmd = {
      test_utils::GetBuildArtifactsPath("test_subprocess"),
      "fstat",
      std::to_string(pipe.writer)};
  EXPECT_TRUE(subprocess_.ExecFlags(
      cmd, 0, {}, base::Bind(&ExpectedResults, EBADF, "")));
  loop_.Run();
}

TEST_F(SubprocessTest, EnvVarsAreFiltered) {
  EXPECT_TRUE(
      subprocess_.Exec({kUsrBinPath "/env"}, base::Bind(&ExpectedEnvVars)));
  loop_.Run();
}

TEST_F(SubprocessTest, SynchronousTrueSearchsOnPath) {
  int rc = -1;
  EXPECT_TRUE(Subprocess::SynchronousExecFlags(
      {"true"}, Subprocess::kSearchPath, &rc, nullptr, nullptr));
  EXPECT_EQ(0, rc);
}

TEST_F(SubprocessTest, SynchronousEchoTest) {
  vector<string> cmd = {
      kBinPath "/sh", "-c", "echo -n stdout-here; echo -n stderr-there >&2"};
  int rc = -1;
  string stdout, stderr;
  ASSERT_TRUE(Subprocess::SynchronousExec(cmd, &rc, &stdout, &stderr));
  EXPECT_EQ(0, rc);
  EXPECT_EQ("stdout-here", stdout);
  EXPECT_EQ("stderr-there", stderr);
}

TEST_F(SubprocessTest, SynchronousEchoNoOutputTest) {
  int rc = -1;
  ASSERT_TRUE(Subprocess::SynchronousExec(
      {kBinPath "/sh", "-c", "echo test"}, &rc, nullptr, nullptr));
  EXPECT_EQ(0, rc);
}

namespace {
void CallbackBad(int return_code, const string& output) {
  ADD_FAILURE() << "should never be called.";
}
}  // namespace

// Test that you can cancel a program that's already running.
TEST_F(SubprocessTest, CancelTest) {
  base::ScopedTempDir tempdir;
  ASSERT_TRUE(tempdir.CreateUniqueTempDir());
  string fifo_path = tempdir.GetPath().Append("fifo").value();
  EXPECT_EQ(0, mkfifo(fifo_path.c_str(), 0666));

  // Start a process, make sure it is running and try to cancel it. We write
  // two bytes to the fifo, the first one marks that the program is running and
  // the second one marks that the process waited for a timeout and was not
  // killed. We should read the first byte but not the second one.
  vector<string> cmd = {
      kBinPath "/sh",
      "-c",
      base::StringPrintf(
          // The 'sleep' launched below could be left behind as an orphaned
          // process when the 'sh' process is terminated by SIGTERM. As a
          // remedy, trap SIGTERM and kill the 'sleep' process, which requires
          // launching 'sleep' in background and then waiting for it.
          "cleanup() { kill \"${sleep_pid}\"; exit 0; }; "
          "trap cleanup TERM; "
          "sleep 60 & "
          "sleep_pid=$!; "
          "printf X >\"%s\"; "
          "wait; "
          "printf Y >\"%s\"; "
          "exit 1",
          fifo_path.c_str(),
          fifo_path.c_str())};
  uint32_t tag = Subprocess::Get().Exec(cmd, base::Bind(&CallbackBad));
  EXPECT_NE(0U, tag);

  int fifo_fd = HANDLE_EINTR(open(fifo_path.c_str(), O_RDONLY));
  EXPECT_GE(fifo_fd, 0);

  watcher_ = base::FileDescriptorWatcher::WatchReadable(
      fifo_fd,
      base::Bind(
          [](unique_ptr<base::FileDescriptorWatcher::Controller>* watcher,
             int fifo_fd,
             uint32_t tag) {
            char c;
            EXPECT_EQ(1, HANDLE_EINTR(read(fifo_fd, &c, 1)));
            EXPECT_EQ('X', c);
            LOG(INFO) << "Killing tag " << tag;
            Subprocess::Get().KillExec(tag);
            *watcher = nullptr;
          },
          // watcher_ is no longer used outside the clousure.
          base::Unretained(&watcher_),
          fifo_fd,
          tag));

  // This test would leak a callback that runs when the child process exits
  // unless we wait for it to run.
  brillo::MessageLoopRunUntil(
      &loop_, TimeDelta::FromSeconds(20), base::Bind([] {
        return Subprocess::Get().subprocess_records_.empty();
      }));
  EXPECT_TRUE(Subprocess::Get().subprocess_records_.empty());
  // Check that there isn't anything else to read from the pipe.
  char c;
  EXPECT_EQ(0, HANDLE_EINTR(read(fifo_fd, &c, 1)));
  IGNORE_EINTR(close(fifo_fd));
}

}  // namespace chromeos_update_engine
