// Copyright 2019 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 <dirent.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>

#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include <base/files/file_enumerator.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/posix/safe_strerror.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "debugd/src/crash_sender_tool.h"
#include "debugd/src/mock_process_with_id.h"

namespace debugd {
namespace {
using ::testing::_;
using ::testing::Invoke;
using ::testing::IsEmpty;
using ::testing::Pair;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::StartsWith;
using ::testing::TestParamInfo;
using ::testing::TestWithParam;
using ::testing::UnorderedElementsAre;
using ::testing::Values;

constexpr char kCrashDirectoryStart[] = "--crash_directory=/proc/self/fd/";

class CrashSenderToolWithMockCreateProcess : public CrashSenderTool {
 public:
  ProcessWithId* CreateProcess(bool sandboxed,
                               bool allow_root_mount_ns) override {
    return &mock_process_;
  }

  MockProcessWithId& mock_process() { return mock_process_; }

  // Expect all the args that CrashSenderTool always adds to ProcessWithId
  // when it runs a process.
  void ExpectStandardArgs() {
    EXPECT_CALL(mock_process_, AddArg(_)).Times(0);
    EXPECT_CALL(mock_process_, AddArg("/sbin/crash_sender")).Times(1);
    EXPECT_CALL(mock_process_, AddArg("--max_spread_time=0")).Times(1);
    EXPECT_CALL(mock_process_, AddArg("--ignore_rate_limits")).Times(1);
  }

  // Expect all the args that CrashSenderTool uses when invoking from
  // UploadSingleCrash. Also, captures the argument to --crash_directory in
  // |crash_directory_arg|.
  void ExpectSingleCrashArgs(std::string* crash_directory_arg) {
    ExpectStandardArgs();
    EXPECT_CALL(mock_process_, AddArg("--ignore_hold_off_time")).Times(1);
    EXPECT_CALL(mock_process_, AddArg(StartsWith(kCrashDirectoryStart)))
        .WillOnce(SaveArg<0>(crash_directory_arg));
  }

 private:
  MockProcessWithId mock_process_;
};

// Invoked during the call to mock_process_.Run(). Verifies that we were given
// a valid crash_directory argument, that the directory exists, and that the
// file descriptor points to the directory.
//
// |file_name_contents| will be filled in with file name + content pairs. Caller
// is responsible for using this to confirm that the correct set of files
// exists.
void VerifyStateInsideRun(
    const std::string& crash_directory_arg,
    const base::FilePath& expected_crash_directory,
    std::vector<std::pair<std::string, std::string>>* file_name_contents) {
  ASSERT_TRUE(base::DirectoryExists(expected_crash_directory));

  std::vector<std::string> actual_file_names;
  base::FileEnumerator file_list(
      expected_crash_directory, false,
      base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
  for (base::FilePath name = file_list.Next(); !name.empty();
       name = file_list.Next()) {
    auto info = file_list.GetInfo();
    EXPECT_FALSE(info.IsDirectory());
    std::string contents;
    EXPECT_TRUE(base::ReadFileToString(name, &contents));
    file_name_contents->emplace_back(name.value(), std::move(contents));
  }

  // crash_directory_arg should contain --crash_directory=/proc/self/fd/##,
  // where ## is a file descriptor that is open and reading /tmp/crash.1.
  ASSERT_GT(crash_directory_arg.size(), strlen(kCrashDirectoryStart));
  std::string fd_string =
      crash_directory_arg.substr(strlen(kCrashDirectoryStart));
  int fd = -1;
  ASSERT_TRUE(base::StringToInt(fd_string, &fd));
  struct stat stat_from_proc;
  int fstat_result = fstat(fd, &stat_from_proc);
  int saved_errno = errno;
  ASSERT_NE(fstat_result, -1) << "Error stating passing-in file descriptor: "
                              << base::safe_strerror(saved_errno);
  struct stat stat_from_tmp;
  int stat_result =
      stat(expected_crash_directory.value().c_str(), &stat_from_tmp);
  saved_errno = errno;
  ASSERT_NE(stat_result, -1)
      << "Error stating /tmp directory: " << base::safe_strerror(saved_errno);
  EXPECT_EQ(stat_from_tmp.st_dev, stat_from_proc.st_dev);
  EXPECT_EQ(stat_from_tmp.st_ino, stat_from_proc.st_ino);

  // In the real world, we would exec a new process during this call, so the
  // file descriptor must not be FD_CLOEXEC.
  int flags = fcntl(fd, F_GETFD);
  saved_errno = errno;
  EXPECT_NE(flags, -1) << "fnctl failed: " << base::safe_strerror(saved_errno);
  EXPECT_EQ(flags & FD_CLOEXEC, 0);
}

// Creates a temporary file and returns a file descriptor to it. The file will
// contain |contents|.
//
// Ideally, we would use memfd_create here instead of creating a file on disk
// (to better match the actual expected usage of UploadSingleCrash), but some
// unit test environments don't support memfd_create.
base::ScopedFD CreateFileWithContents(const std::string& contents) {
  base::FilePath temp_path;
  EXPECT_TRUE(GetTempDir(&temp_path));
  int fd =
      open(temp_path.value().c_str(), O_RDWR | O_TMPFILE, S_IRUSR | S_IWUSR);
  if (fd < 0) {
    int saved_errno = errno;
    ADD_FAILURE() << "Could not open temp file: "
                  << base::safe_strerror(saved_errno);
    return base::ScopedFD();
  }

  int result = write(fd, contents.data(), contents.size());
  if (result == -1) {
    int saved_errno = errno;
    ADD_FAILURE() << "write to temp file: " << base::safe_strerror(saved_errno);
  } else if (result < contents.size()) {
    ADD_FAILURE() << "Partial write to temp file";
  }

  return base::ScopedFD(fd);
}
}  // namespace

TEST(UploadCrashes, CallsCrashSenderWithoutCrashDirectoryOrIgnoreHoldOffTime) {
  CrashSenderToolWithMockCreateProcess test_tool;

  // No arguments except standard ones.
  test_tool.ExpectStandardArgs();
  EXPECT_CALL(test_tool.mock_process(), Run()).WillOnce(Return(0));

  test_tool.UploadCrashes();
}

TEST(UploadSingleCrash, CreatesDirectory) {
  const base::FilePath kExpectedCrashDirectory("/tmp/crash.1");
  // Tests aren't as hermetic as we'd like; make sure that stale crash
  // directories aren't left over from previous failures.
  base::DeleteFile(kExpectedCrashDirectory, true);

  std::vector<std::tuple<std::string, base::ScopedFD>> files;
  brillo::ErrorPtr error;

  CrashSenderToolWithMockCreateProcess test_tool;
  std::string crash_directory_arg;
  test_tool.ExpectSingleCrashArgs(&crash_directory_arg);

  auto run_state_verifier = [&crash_directory_arg, &kExpectedCrashDirectory]() {
    std::vector<std::pair<std::string, std::string>> file_name_contents;
    VerifyStateInsideRun(crash_directory_arg, kExpectedCrashDirectory,
                         &file_name_contents);
    EXPECT_THAT(file_name_contents, IsEmpty());
    return 0;
  };

  EXPECT_CALL(test_tool.mock_process(), Run())
      .WillOnce(Invoke(run_state_verifier));

  EXPECT_TRUE(test_tool.UploadSingleCrash(files, &error));
  EXPECT_EQ(error.get(), nullptr);

  // /tmp/crash.1 should now be deleted, and the file descriptor closed. We
  // don't check for the file descriptor being closed since some other part of
  // the system might have reused it.
  EXPECT_FALSE(base::PathExists(kExpectedCrashDirectory));
}

TEST(UploadSingleCrash, CreatesFilesInDirectory) {
  const base::FilePath kExpectedCrashDirectory("/tmp/crash.1");
  base::DeleteFile(kExpectedCrashDirectory, true);

  std::vector<std::tuple<std::string, base::ScopedFD>> files;
  constexpr char kFileAaaContents[] = "aaa";
  files.emplace_back("aaa.meta", CreateFileWithContents(kFileAaaContents));
  constexpr char kFileBbbContents[] = "123";
  files.emplace_back("bbb.version", CreateFileWithContents(kFileBbbContents));
  constexpr char kFileCccContents[] =
      "The quick brown fox jumped over the lazy dog.";
  files.emplace_back("ccc.log", CreateFileWithContents(kFileCccContents));
  brillo::ErrorPtr error;

  CrashSenderToolWithMockCreateProcess test_tool;
  std::string crash_directory_arg;
  test_tool.ExpectSingleCrashArgs(&crash_directory_arg);
  std::vector<std::pair<std::string, std::string>> file_name_contents;
  auto run_state_verifier = [&crash_directory_arg, &kExpectedCrashDirectory,
                             &file_name_contents]() {
    VerifyStateInsideRun(crash_directory_arg, kExpectedCrashDirectory,
                         &file_name_contents);
    return 0;
  };

  EXPECT_CALL(test_tool.mock_process(), Run())
      .WillOnce(Invoke(run_state_verifier));

  EXPECT_TRUE(test_tool.UploadSingleCrash(files, &error));
  EXPECT_EQ(error.get(), nullptr);
  EXPECT_FALSE(base::PathExists(kExpectedCrashDirectory));

  EXPECT_THAT(
      file_name_contents,
      UnorderedElementsAre(Pair("/tmp/crash.1/aaa.meta", kFileAaaContents),
                           Pair("/tmp/crash.1/bbb.version", kFileBbbContents),
                           Pair("/tmp/crash.1/ccc.log", kFileCccContents)));
}

TEST(UploadSingleCrash, CreatesEmptyFile) {
  const base::FilePath kExpectedCrashDirectory("/tmp/crash.1");
  base::DeleteFile(kExpectedCrashDirectory, true);

  std::vector<std::tuple<std::string, base::ScopedFD>> files;
  files.emplace_back("empty", base::ScopedFD(memfd_create("empty", 0)));
  brillo::ErrorPtr error;

  CrashSenderToolWithMockCreateProcess test_tool;
  std::string crash_directory_arg;
  test_tool.ExpectSingleCrashArgs(&crash_directory_arg);
  std::vector<std::pair<std::string, std::string>> file_name_contents;
  auto run_state_verifier = [&crash_directory_arg, &kExpectedCrashDirectory,
                             &file_name_contents]() {
    VerifyStateInsideRun(crash_directory_arg, kExpectedCrashDirectory,
                         &file_name_contents);
    return 0;
  };

  EXPECT_CALL(test_tool.mock_process(), Run())
      .WillOnce(Invoke(run_state_verifier));

  EXPECT_TRUE(test_tool.UploadSingleCrash(files, &error));
  EXPECT_EQ(error.get(), nullptr);
  EXPECT_FALSE(base::PathExists(kExpectedCrashDirectory));

  EXPECT_THAT(file_name_contents,
              UnorderedElementsAre(Pair("/tmp/crash.1/empty", "")));
}

TEST(UploadSingleCrash, CreatesLargeFilesCorrectly) {
  const base::FilePath kExpectedCrashDirectory("/tmp/crash.1");
  base::DeleteFile(kExpectedCrashDirectory, true);

  std::vector<std::tuple<std::string, base::ScopedFD>> files;
  std::string long_string;
  constexpr int kSize = 1 << 18;
  long_string.reserve(kSize);
  int i = 0;
  while (long_string.size() < kSize) {
    long_string += base::IntToString(i);
    i++;
  }
  files.emplace_back("long.log", CreateFileWithContents(long_string));
  constexpr char kFileAaaContents[] = "aaa";
  files.emplace_back("aaa.meta", CreateFileWithContents(kFileAaaContents));
  brillo::ErrorPtr error;

  CrashSenderToolWithMockCreateProcess test_tool;
  std::string crash_directory_arg;
  test_tool.ExpectSingleCrashArgs(&crash_directory_arg);
  std::vector<std::pair<std::string, std::string>> file_name_contents;
  auto run_state_verifier = [&crash_directory_arg, &kExpectedCrashDirectory,
                             &file_name_contents]() {
    VerifyStateInsideRun(crash_directory_arg, kExpectedCrashDirectory,
                         &file_name_contents);
    return 0;
  };

  EXPECT_CALL(test_tool.mock_process(), Run())
      .WillOnce(Invoke(run_state_verifier));

  EXPECT_TRUE(test_tool.UploadSingleCrash(files, &error));
  EXPECT_EQ(error.get(), nullptr);
  EXPECT_FALSE(base::PathExists(kExpectedCrashDirectory));

  EXPECT_THAT(
      file_name_contents,
      UnorderedElementsAre(Pair("/tmp/crash.1/aaa.meta", kFileAaaContents),
                           Pair("/tmp/crash.1/long.log", long_string)));
}

// Test that the filename given by the parameter will be rejected with a
// org.chromium.debugd.error.BadFileName error.
class BadFilenameTest : public TestWithParam<std::string> {
 public:
  BadFilenameTest() : file_name_(GetParam()) {}

 protected:
  // The bad file name. Taken from GetParam.
  const std::string file_name_;
};

TEST_P(BadFilenameTest, ReturnsBadFileNameError) {
  std::vector<std::tuple<std::string, base::ScopedFD>> files;
  files.emplace_back(file_name_, CreateFileWithContents("something"));
  brillo::ErrorPtr error;
  CrashSenderToolWithMockCreateProcess test_tool;

  // We should NOT run if there's a bad file name
  EXPECT_CALL(test_tool.mock_process(), Run()).Times(0);

  EXPECT_FALSE(test_tool.UploadSingleCrash(files, &error));
  ASSERT_TRUE(error);
  EXPECT_EQ(error->GetCode(), CrashSenderTool::kErrorBadFileName);
}

std::string FileNameToTestName(const TestParamInfo<std::string>& param) {
  // Result must be alphanumeric only. No _'s or other symbols, and no spaces.
  std::string result;
  for (char c : param.param) {
    switch (c) {
      case '/':
        result += "slash";
        break;
      case '.':
        result += "dot";
        break;
      default:
        if (base::IsAsciiAlpha(c) || base::IsAsciiDigit(c)) {
          result += c;
        } else {
          result += "something";
        }
        break;
    }
  }
  return result;
}

INSTANTIATE_TEST_CASE_P(
    BadFilenameTests,
    BadFilenameTest,
    Values("/tmp/absolute", ".", "..", "../backup", "non/basename", "/", "//"),
    FileNameToTestName);

}  // namespace debugd
