// Copyright 2018 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 "crash-reporter/util.h"

#include <stdlib.h>

#include <fcntl.h>
#include <limits>
#include <memory>
#include <sys/mman.h>

#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/rand_util.h>
#include <base/test/simple_test_clock.h>
#include <base/time/time.h>
#include <brillo/process/process.h>
#include <brillo/streams/memory_stream.h>
#include <gtest/gtest.h>

#include "crash-reporter/crash_sender_paths.h"
#include "crash-reporter/paths.h"
#include "crash-reporter/test_util.h"

// The QEMU emulator we use to run unit tests on simulated ARM boards does not
// support memfd_create. (https://bugs.launchpad.net/qemu/+bug/1734792) Skip
// tests that rely on memfd_create on ARM boards.
#if defined(ARCH_CPU_ARM_FAMILY)
#define DISABLED_ON_QEMU_FOR_MEMFD_CREATE(test_name) DISABLED_##test_name
#else
#define DISABLED_ON_QEMU_FOR_MEMFD_CREATE(test_name) test_name
#endif

namespace util {
namespace {

constexpr char kLsbReleaseContents[] =
    "CHROMEOS_RELEASE_BOARD=bob\n"
    "CHROMEOS_RELEASE_NAME=Chromium OS\n"
    "CHROMEOS_RELEASE_VERSION=10964.0.2018_08_13_1405\n";

constexpr char kHwClassContents[] = "fake_hwclass";

constexpr char kGzipPath[] = "/bin/gzip";

constexpr char kSemiRandomData[] =
    "ABJCI239AJSDLKJ;kalkjkjsd98723;KJHASD87;kqw3p088ad;lKJASDP823;KJ";
constexpr int kRandomDataMinLength = 32768;   // 32kB
constexpr int kRandomDataMaxLength = 262144;  // 256kB

constexpr char kReadFdToStreamContents[] = "1234567890";

// Verifies that |raw_file| corresponds to the gzip'd version of
// |compressed_file| by decompressing it and comparing the contents. Returns
// true if they match, false otherwise. This will overwrite the contents of
// |compressed_file| in the process of doing this.
bool VerifyCompression(const base::FilePath& raw_file,
                       const base::FilePath& compressed_file) {
  if (!base::PathExists(raw_file)) {
    LOG(ERROR) << "raw_file doesn't exist for verifying compression: "
               << raw_file.value();
    return false;
  }
  if (!base::PathExists(compressed_file)) {
    LOG(ERROR) << "compressed_file doesn't exist for verifying compression: "
               << compressed_file.value();
    return false;
  }
  brillo::ProcessImpl proc;
  proc.AddArg(kGzipPath);
  proc.AddArg("-d");  // decompress
  proc.AddArg(compressed_file.value());
  std::string error;
  const int res = util::RunAndCaptureOutput(&proc, STDERR_FILENO, &error);
  if (res < 0) {
    PLOG(ERROR) << "Failed to execute gzip";
    return false;
  }
  if (res != 0) {
    LOG(ERROR) << "Failed to un-gzip " << compressed_file.value();
    util::LogMultilineError(error);
    return false;
  }
  base::FilePath uncompressed_file = compressed_file.RemoveFinalExtension();
  std::string raw_contents;
  std::string uncompressed_contents;
  if (!base::ReadFileToString(raw_file, &raw_contents)) {
    LOG(ERROR) << "Failed reading in raw_file " << raw_file.value();
    return false;
  }
  if (!base::ReadFileToString(uncompressed_file, &uncompressed_contents)) {
    LOG(ERROR) << "Failed reading in uncompressed_file "
               << uncompressed_file.value();
    return false;
  }
  return raw_contents == uncompressed_contents;
}

// We use a somewhat random string of ASCII data to better reflect the data we
// would be compressing for real. We also shouldn't use something like
// base::RandBytesAsString() because that will generate uniformly random data
// which does not compress.
std::string CreateSemiRandomString(size_t size) {
  std::string result;
  result.reserve(size);
  while (result.length() < size) {
    int rem = size - result.length();
    if (rem > sizeof(kSemiRandomData) - 1)
      rem = sizeof(kSemiRandomData) - 1;
    int rand_start = base::RandInt(0, rem - 1);
    int rand_end = base::RandInt(rand_start + 1, rem);
    result.append(&kSemiRandomData[rand_start], rand_end - rand_start);
  }
  return result;
}

}  // namespace

class CrashCommonUtilTest : public testing::Test {
 protected:
  void SetUp() override {
    ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
    test_dir_ = scoped_temp_dir_.GetPath();
    paths::SetPrefixForTesting(test_dir_);
    base::FilePath file = scoped_temp_dir_.GetPath().Append("tmpfile");
    ASSERT_TRUE(test_util::CreateFile(file, kReadFdToStreamContents));
    fd_ = open(file.value().c_str(), O_RDONLY);
  }

  void TearDown() override { paths::SetPrefixForTesting(base::FilePath()); }

  base::FilePath test_dir_;
  base::ScopedTempDir scoped_temp_dir_;
  unsigned int fd_;
};

TEST_F(CrashCommonUtilTest, IsCrashTestInProgress) {
  EXPECT_FALSE(IsCrashTestInProgress());
  ASSERT_TRUE(
      test_util::CreateFile(paths::GetAt(paths::kSystemRunStateDirectory,
                                         paths::kCrashTestInProgress),
                            ""));
  EXPECT_TRUE(IsCrashTestInProgress());
}

TEST_F(CrashCommonUtilTest, IsDeviceCoredumpUploadAllowed) {
  EXPECT_FALSE(IsDeviceCoredumpUploadAllowed());
  ASSERT_TRUE(
      test_util::CreateFile(paths::GetAt(paths::kCrashReporterStateDirectory,
                                         paths::kDeviceCoredumpUploadAllowed),
                            ""));
  EXPECT_TRUE(IsDeviceCoredumpUploadAllowed());
}

TEST_F(CrashCommonUtilTest, IsDeveloperImage) {
  EXPECT_FALSE(IsDeveloperImage());

  ASSERT_TRUE(test_util::CreateFile(paths::Get(paths::kLeaveCoreFile), ""));
  EXPECT_TRUE(IsDeveloperImage());

  ASSERT_TRUE(
      test_util::CreateFile(paths::GetAt(paths::kSystemRunStateDirectory,
                                         paths::kCrashTestInProgress),
                            ""));
  EXPECT_FALSE(IsDeveloperImage());
}

TEST_F(CrashCommonUtilTest, IsTestImage) {
  EXPECT_FALSE(IsTestImage());

  // Should return false because the channel is stable.
  ASSERT_TRUE(test_util::CreateFile(
      paths::GetAt(paths::kEtcDirectory, paths::kLsbRelease),
      "CHROMEOS_RELEASE_TRACK=stable-channel"));
  EXPECT_FALSE(IsTestImage());

  // Should return true because the channel is testimage.
  ASSERT_TRUE(test_util::CreateFile(
      paths::GetAt(paths::kEtcDirectory, paths::kLsbRelease),
      "CHROMEOS_RELEASE_TRACK=testimage-channel"));
  EXPECT_TRUE(IsTestImage());

  // Should return false if kCrashTestInProgress is present.
  ASSERT_TRUE(
      test_util::CreateFile(paths::GetAt(paths::kSystemRunStateDirectory,
                                         paths::kCrashTestInProgress),
                            ""));
  EXPECT_FALSE(IsTestImage());
}

TEST_F(CrashCommonUtilTest, IsOfficialImage) {
  EXPECT_FALSE(IsOfficialImage());

  // Check if lsb-release is handled correctly.
  ASSERT_TRUE(test_util::CreateFile(
      paths::Get("/etc/lsb-release"),
      "CHROMEOS_RELEASE_DESCRIPTION=10964.0 (Test Build) developer-build"));
  EXPECT_FALSE(IsOfficialImage());

  ASSERT_TRUE(test_util::CreateFile(
      paths::Get("/etc/lsb-release"),
      "CHROMEOS_RELEASE_DESCRIPTION=10964.0 (Official Build) canary-channel"));
  EXPECT_TRUE(IsOfficialImage());
}

TEST_F(CrashCommonUtilTest, HasMockConsent) {
  ASSERT_TRUE(test_util::CreateFile(paths::Get("/etc/lsb-release"),
                                    "CHROMEOS_RELEASE_TRACK=testimage-channel\n"
                                    "CHROMEOS_RELEASE_DESCRIPTION=12985.0.0 "
                                    "(Official Build) dev-channel asuka test"));
  EXPECT_FALSE(HasMockConsent());
  ASSERT_TRUE(test_util::CreateFile(
      paths::GetAt(paths::kSystemRunStateDirectory, paths::kMockConsent), ""));
  EXPECT_TRUE(HasMockConsent());
}

TEST_F(CrashCommonUtilTest, GetOsTimestamp) {
  // If we can't read /etc/lsb-release then we should be returning the null
  // time.
  EXPECT_TRUE(util::GetOsTimestamp().is_null());

  base::FilePath lsb_file_path = paths::Get("/etc/lsb-release");
  ASSERT_TRUE(test_util::CreateFile(lsb_file_path, "foo=bar"));
  base::Time old_time = base::Time::Now() - base::TimeDelta::FromDays(366);
  ASSERT_TRUE(base::TouchFile(lsb_file_path, old_time, old_time));
  // ext2/ext3 seem to have a timestamp granularity of 1s.
  EXPECT_EQ(util::GetOsTimestamp().ToTimeVal().tv_sec,
            old_time.ToTimeVal().tv_sec);
}

TEST_F(CrashCommonUtilTest, IsOsTimestampTooOldForUploads) {
  base::SimpleTestClock clock;
  const base::Time now = test_util::GetDefaultTime();
  clock.SetNow(now);

  EXPECT_FALSE(util::IsOsTimestampTooOldForUploads(base::Time(), &clock));
  EXPECT_FALSE(util::IsOsTimestampTooOldForUploads(
      now - base::TimeDelta::FromDays(179), &clock));
  EXPECT_TRUE(util::IsOsTimestampTooOldForUploads(
      now - base::TimeDelta::FromDays(181), &clock));

  // Crashes with invalid timestamps should upload.
  EXPECT_FALSE(util::IsOsTimestampTooOldForUploads(
      now + base::TimeDelta::FromDays(1), &clock));
  EXPECT_FALSE(util::IsOsTimestampTooOldForUploads(
      base::Time::FromTimeT(std::numeric_limits<time_t>::min()), &clock));
}

TEST_F(CrashCommonUtilTest, GetHardwareClass) {
  EXPECT_EQ("undefined", GetHardwareClass());

  ASSERT_TRUE(test_util::CreateFile(
      paths::Get("/sys/devices/platform/chromeos_acpi/HWID"),
      kHwClassContents));
  EXPECT_EQ(kHwClassContents, GetHardwareClass());
}

TEST_F(CrashCommonUtilTest, GetBootModeString) {
  EXPECT_EQ("missing-crossystem", GetBootModeString());

  ASSERT_TRUE(
      test_util::CreateFile(paths::GetAt(paths::kSystemRunStateDirectory,
                                         paths::kCrashTestInProgress),
                            ""));
  EXPECT_EQ("", GetBootModeString());
}

TEST_F(CrashCommonUtilTest, GetCachedKeyValue) {
  ASSERT_TRUE(test_util::CreateFile(paths::Get("/etc/lsb-release"),
                                    kLsbReleaseContents));
  ASSERT_TRUE(test_util::CreateFile(paths::Get("/empty/lsb-release"), ""));

  std::string value;
  // No directories are specified.
  EXPECT_FALSE(GetCachedKeyValue(base::FilePath("lsb-release"),
                                 "CHROMEOS_RELEASE_VERSION", {}, &value));
  // A non-existent directory is specified.
  EXPECT_FALSE(GetCachedKeyValue(base::FilePath("lsb-release"),
                                 "CHROMEOS_RELEASE_VERSION",
                                 {paths::Get("/non-existent")}, &value));

  // A non-existent base name is specified.
  EXPECT_FALSE(GetCachedKeyValue(base::FilePath("non-existent"),
                                 "CHROMEOS_RELEASE_VERSION",
                                 {paths::Get("/etc")}, &value));

  // A wrong key is specified.
  EXPECT_FALSE(GetCachedKeyValue(base::FilePath("lsb-release"), "WRONG_KEY",
                                 {paths::Get("/etc")}, &value));

  // This should succeed.
  EXPECT_TRUE(GetCachedKeyValue(base::FilePath("lsb-release"),
                                "CHROMEOS_RELEASE_VERSION",
                                {paths::Get("/etc")}, &value));
  EXPECT_EQ("10964.0.2018_08_13_1405", value);

  // A non-existent directory is included, but this should still succeed.
  EXPECT_TRUE(GetCachedKeyValue(
      base::FilePath("lsb-release"), "CHROMEOS_RELEASE_VERSION",
      {paths::Get("/non-existent"), paths::Get("/etc")}, &value));
  EXPECT_EQ("10964.0.2018_08_13_1405", value);

  // A empty file is included, but this should still succeed.
  EXPECT_TRUE(GetCachedKeyValue(
      base::FilePath("lsb-release"), "CHROMEOS_RELEASE_VERSION",
      {paths::Get("/empty"), paths::Get("/etc")}, &value));
  EXPECT_EQ("10964.0.2018_08_13_1405", value);
}

TEST_F(CrashCommonUtilTest, GetCachedKeyValueDefault) {
  std::string value;
  EXPECT_FALSE(
      GetCachedKeyValueDefault(base::FilePath("test.txt"), "FOO", &value));

  // kEtcDirectory is the second candidate directory.
  ASSERT_TRUE(test_util::CreateFile(
      paths::GetAt(paths::kEtcDirectory, "test.txt"), "FOO=2\n"));
  EXPECT_TRUE(
      GetCachedKeyValueDefault(base::FilePath("test.txt"), "FOO", &value));
  EXPECT_EQ("2", value);

  // kCrashReporterStateDirectory is the first candidate directory.
  ASSERT_TRUE(test_util::CreateFile(
      paths::GetAt(paths::kCrashReporterStateDirectory, "test.txt"),
      "FOO=1\n"));
  EXPECT_TRUE(
      GetCachedKeyValueDefault(base::FilePath("test.txt"), "FOO", &value));
  EXPECT_EQ("1", value);
}

TEST_F(CrashCommonUtilTest, GetUserCrashDirectories) {
  auto mock =
      std::make_unique<org::chromium::SessionManagerInterfaceProxyMock>();

  std::vector<base::FilePath> directories;

  test_util::SetActiveSessions(mock.get(), {});
  EXPECT_TRUE(GetUserCrashDirectories(mock.get(), &directories));
  EXPECT_TRUE(directories.empty());

  test_util::SetActiveSessions(mock.get(),
                               {{"user1", "hash1"}, {"user2", "hash2"}});
  EXPECT_TRUE(GetUserCrashDirectories(mock.get(), &directories));
  EXPECT_EQ(2, directories.size());
  EXPECT_EQ(paths::Get("/home/user/hash1/crash").value(),
            directories[0].value());
  EXPECT_EQ(paths::Get("/home/user/hash2/crash").value(),
            directories[1].value());
}

TEST_F(CrashCommonUtilTest, GzipStream) {
  std::string content = CreateSemiRandomString(
      base::RandInt(kRandomDataMinLength, kRandomDataMaxLength));
  std::vector<unsigned char> compressed_content =
      util::GzipStream(brillo::MemoryStream::OpenCopyOf(
          content.c_str(), content.length(), nullptr));
  EXPECT_FALSE(compressed_content.empty());
  EXPECT_LT(compressed_content.size(), content.size())
      << "Didn't actually compress";
  base::FilePath raw_file;
  ASSERT_TRUE(base::CreateTemporaryFileInDir(test_dir_, &raw_file));
  base::FilePath compressed_file_name;
  ASSERT_TRUE(base::CreateTemporaryFileInDir(test_dir_, &compressed_file_name));
  // Remove the file we will decompress to or gzip will fail on decompression.
  ASSERT_TRUE(base::DeleteFile(compressed_file_name, false));
  compressed_file_name = compressed_file_name.AddExtension(".gz");
  ASSERT_EQ(base::WriteFile(raw_file, content.c_str(), content.length()),
            content.length());
  {
    base::File compressed_file(
        compressed_file_name, base::File::FLAG_WRITE | base::File::FLAG_CREATE);
    ASSERT_TRUE(compressed_file.IsValid());
    ssize_t write_result = HANDLE_EINTR(write(compressed_file.GetPlatformFile(),
                                              compressed_content.data(),
                                              compressed_content.size()));
    ASSERT_EQ(write_result, compressed_content.size());
  }
  EXPECT_TRUE(VerifyCompression(raw_file, compressed_file_name))
      << "Random input data: " << content;
}

TEST_F(CrashCommonUtilTest,
       DISABLED_ON_QEMU_FOR_MEMFD_CREATE(ReadMemfdToStringEmpty)) {
  int memfd = memfd_create("test_memfd", 0);
  std::string read_outs;
  EXPECT_FALSE(ReadMemfdToString(memfd, &read_outs));
}

TEST_F(CrashCommonUtilTest,
       DISABLED_ON_QEMU_FOR_MEMFD_CREATE(ReadMemfdToStringSuccess)) {
  int memfd = memfd_create("test_memfd", 0);
  const std::string write_ins = "Test data to write into memfd";
  ASSERT_EQ(write(memfd, write_ins.c_str(), strlen(write_ins.c_str())),
            strlen(write_ins.c_str()));
  std::string read_outs;
  EXPECT_TRUE(ReadMemfdToString(memfd, &read_outs));
  EXPECT_EQ(read_outs, write_ins);
}

TEST_F(CrashCommonUtilTest, ReadFdToStream) {
  std::stringstream stream;
  EXPECT_TRUE(ReadFdToStream(fd_, &stream));
  EXPECT_EQ(kReadFdToStreamContents, stream.str());
}

}  // namespace util
