/*
 * 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 "crash_collector_test.h"

#include <unistd.h>
#include <utility>

#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <brillo/syslog_logging.h>
#include <gtest/gtest.h>

#include "crash_collector.h"

using base::FilePath;
using base::StringPrintf;
using brillo::FindLog;
using ::testing::Invoke;
using ::testing::Return;

namespace {

void CountCrash() {
  ADD_FAILURE();
}

bool IsMetrics() {
  ADD_FAILURE();
  return false;
}

}  // namespace

class CrashCollectorTest : public ::testing::Test {
 public:
  void SetUp() {
    EXPECT_CALL(collector_, SetUpDBus()).WillRepeatedly(Return());

    collector_.Initialize(CountCrash, IsMetrics);
    EXPECT_TRUE(test_dir_.CreateUniqueTempDir());
    brillo::ClearLog();
  }

  bool CheckHasCapacity();

 protected:
  CrashCollectorMock collector_;

  // Temporary directory used for tests.
  base::ScopedTempDir test_dir_;
};

TEST_F(CrashCollectorTest, Initialize) {
  ASSERT_TRUE(CountCrash == collector_.count_crash_function_);
  ASSERT_TRUE(IsMetrics == collector_.is_feedback_allowed_function_);
}

TEST_F(CrashCollectorTest, WriteNewFile) {
  FilePath test_file = test_dir_.path().Append("test_new");
  const char kBuffer[] = "buffer";
  unsigned int numBytesWritten = collector_.WriteNewFile(
      test_file,
      kBuffer,
      strlen(kBuffer));
  EXPECT_EQ(strlen(kBuffer), numBytesWritten);
  EXPECT_LT(collector_.WriteNewFile(test_file,
                                    kBuffer,
                                    strlen(kBuffer)), 0);
}

TEST_F(CrashCollectorTest, Sanitize) {
  EXPECT_EQ("chrome", collector_.Sanitize("chrome"));
  EXPECT_EQ("CHROME", collector_.Sanitize("CHROME"));
  EXPECT_EQ("1chrome2", collector_.Sanitize("1chrome2"));
  EXPECT_EQ("chrome__deleted_", collector_.Sanitize("chrome (deleted)"));
  EXPECT_EQ("foo_bar", collector_.Sanitize("foo.bar"));
  EXPECT_EQ("", collector_.Sanitize(""));
  EXPECT_EQ("_", collector_.Sanitize(" "));
}

TEST_F(CrashCollectorTest, FormatDumpBasename) {
  struct tm tm = {};
  tm.tm_sec = 15;
  tm.tm_min = 50;
  tm.tm_hour = 13;
  tm.tm_mday = 23;
  tm.tm_mon = 4;
  tm.tm_year = 110;
  tm.tm_isdst = -1;
  std::string basename =
      collector_.FormatDumpBasename("foo", mktime(&tm), 100);
  ASSERT_EQ("foo.20100523.135015.100", basename);
}

TEST_F(CrashCollectorTest, GetCrashPath) {
  EXPECT_EQ("/var/spool/crash/myprog.20100101.1200.1234.core",
            collector_.GetCrashPath(FilePath("/var/spool/crash"),
                                    "myprog.20100101.1200.1234",
                                    "core").value());
  EXPECT_EQ("/home/chronos/user/crash/chrome.20100101.1200.1234.dmp",
            collector_.GetCrashPath(FilePath("/home/chronos/user/crash"),
                                    "chrome.20100101.1200.1234",
                                    "dmp").value());
}


bool CrashCollectorTest::CheckHasCapacity() {
  const char* kFullMessage =
      StringPrintf("Crash directory %s already full",
                   test_dir_.path().value().c_str()).c_str();
  bool has_capacity = collector_.CheckHasCapacity(test_dir_.path());
  bool has_message = FindLog(kFullMessage);
  EXPECT_EQ(has_message, !has_capacity);
  return has_capacity;
}

TEST_F(CrashCollectorTest, CheckHasCapacityUsual) {
  // Test kMaxCrashDirectorySize - 1 non-meta files can be added.
  for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 1; ++i) {
    base::WriteFile(test_dir_.path().Append(StringPrintf("file%d.core", i)),
                    "", 0);
    EXPECT_TRUE(CheckHasCapacity());
  }

  // Test an additional kMaxCrashDirectorySize - 1 meta files fit.
  for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 1; ++i) {
    base::WriteFile(test_dir_.path().Append(StringPrintf("file%d.meta", i)),
                    "", 0);
    EXPECT_TRUE(CheckHasCapacity());
  }

  // Test an additional kMaxCrashDirectorySize meta files don't fit.
  for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize; ++i) {
    base::WriteFile(test_dir_.path().Append(StringPrintf("overage%d.meta", i)),
                    "", 0);
    EXPECT_FALSE(CheckHasCapacity());
  }
}

TEST_F(CrashCollectorTest, CheckHasCapacityCorrectBasename) {
  // Test kMaxCrashDirectorySize - 1 files can be added.
  for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 1; ++i) {
    base::WriteFile(test_dir_.path().Append(StringPrintf("file.%d.core", i)),
                    "", 0);
    EXPECT_TRUE(CheckHasCapacity());
  }
  base::WriteFile(test_dir_.path().Append("file.last.core"), "", 0);
  EXPECT_FALSE(CheckHasCapacity());
}

TEST_F(CrashCollectorTest, CheckHasCapacityStrangeNames) {
  // Test many files with different extensions and same base fit.
  for (int i = 0; i < 5 * CrashCollector::kMaxCrashDirectorySize; ++i) {
    base::WriteFile(test_dir_.path().Append(StringPrintf("a.%d", i)), "", 0);
    EXPECT_TRUE(CheckHasCapacity());
  }
  // Test dot files are treated as individual files.
  for (int i = 0; i < CrashCollector::kMaxCrashDirectorySize - 2; ++i) {
    base::WriteFile(test_dir_.path().Append(StringPrintf(".file%d", i)), "", 0);
    EXPECT_TRUE(CheckHasCapacity());
  }
  base::WriteFile(test_dir_.path().Append("normal.meta"), "", 0);
  EXPECT_FALSE(CheckHasCapacity());
}

TEST_F(CrashCollectorTest, MetaData) {
  const char kMetaFileBasename[] = "generated.meta";
  FilePath meta_file = test_dir_.path().Append(kMetaFileBasename);
  FilePath payload_file = test_dir_.path().Append("payload-file");
  FilePath osreleased_directory =
      test_dir_.path().Append("etc").Append("os-release.d");
  ASSERT_TRUE(base::CreateDirectory(osreleased_directory));
  collector_.ForceOsReleaseDDirectory(test_dir_.path());

  std::string contents;
  const char kPayload[] = "foo";
  ASSERT_TRUE(base::WriteFile(payload_file, kPayload, strlen(kPayload)));
  const char kBdkVersion[] = "1";
  ASSERT_TRUE(base::WriteFile(osreleased_directory.Append("bdk_version"),
                              kBdkVersion,
                              strlen(kBdkVersion)));
  const char kProductId[] = "baz";
  ASSERT_TRUE(base::WriteFile(osreleased_directory.Append("product_id"),
                              kProductId,
                              strlen(kProductId)));
  const char kProductVersion[] = "1.2.3.4";
  ASSERT_TRUE(base::WriteFile(osreleased_directory.Append("product_version"),
                              kProductVersion,
                              strlen(kProductVersion)));
  collector_.AddCrashMetaData("foo", "bar");
  collector_.WriteCrashMetaData(meta_file, "kernel", payload_file.value());
  EXPECT_TRUE(base::ReadFileToString(meta_file, &contents));
  const std::string kExpectedMeta =
      StringPrintf("foo=bar\n"
          "exec_name=kernel\n"
          "payload=%s\n"
          "payload_size=3\n"
          "bdk_version=1\n"
          "product_id=baz\n"
          "product_version=1.2.3.4\n"
          "done=1\n",
          test_dir_.path().Append("payload-file").value().c_str());
  EXPECT_EQ(kExpectedMeta, contents);

  // Test target of symlink is not overwritten.
  payload_file = test_dir_.path().Append("payload2-file");
  ASSERT_TRUE(base::WriteFile(payload_file, kPayload, strlen(kPayload)));
  FilePath meta_symlink_path = test_dir_.path().Append("symlink.meta");
  ASSERT_EQ(0,
            symlink(kMetaFileBasename,
                    meta_symlink_path.value().c_str()));
  ASSERT_TRUE(base::PathExists(meta_symlink_path));
  brillo::ClearLog();
  collector_.WriteCrashMetaData(meta_symlink_path,
                                "kernel",
                                payload_file.value());
  // Target metadata contents should have stayed the same.
  contents.clear();
  EXPECT_TRUE(base::ReadFileToString(meta_file, &contents));
  EXPECT_EQ(kExpectedMeta, contents);
  EXPECT_TRUE(FindLog("Unable to write"));

  // Test target of dangling symlink is not created.
  base::DeleteFile(meta_file, false);
  ASSERT_FALSE(base::PathExists(meta_file));
  brillo::ClearLog();
  collector_.WriteCrashMetaData(meta_symlink_path, "kernel",
                                payload_file.value());
  EXPECT_FALSE(base::PathExists(meta_file));
  EXPECT_TRUE(FindLog("Unable to write"));
}

TEST_F(CrashCollectorTest, GetLogContents) {
  FilePath config_file = test_dir_.path().Append("crash_config");
  FilePath output_file = test_dir_.path().Append("crash_log");
  const char kConfigContents[] =
      "foobar=echo hello there | \\\n  sed -e \"s/there/world/\"";
  ASSERT_TRUE(
      base::WriteFile(config_file, kConfigContents, strlen(kConfigContents)));
  base::DeleteFile(FilePath(output_file), false);
  EXPECT_FALSE(collector_.GetLogContents(config_file,
                                         "barfoo",
                                         output_file));
  EXPECT_FALSE(base::PathExists(output_file));
  base::DeleteFile(FilePath(output_file), false);
  EXPECT_TRUE(collector_.GetLogContents(config_file,
                                        "foobar",
                                        output_file));
  ASSERT_TRUE(base::PathExists(output_file));
  std::string contents;
  EXPECT_TRUE(base::ReadFileToString(output_file, &contents));
  EXPECT_EQ("hello world\n", contents);
}
