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

#include <fcntl.h>
#include <inttypes.h>
#include <stdlib.h>
#include <unistd.h>

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

#include <base/at_exit.h>
#include <base/bind.h>
#include <base/check.h>
#include <base/command_line.h>
#include <base/files/file.h>
#include <base/files/file_enumerator.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/json/json_reader.h>
#include <base/macros.h>
#include <base/stl_util.h>
#include <base/strings/string_split.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/strings/strcat.h>
#include <base/time/time.h>
#include <base/values.h>
#include <brillo/flag_helper.h>
#include <brillo/http/http_transport.h>
#include <brillo/http/http_transport_fake.h>
#include <brillo/key_value_store.h>
#include <brillo/mime_utils.h>
#include <brillo/process/process.h>
#include <chromeos/dbus/service_constants.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <metrics/metrics_library_mock.h>
#include <shill/dbus-proxy-mocks.h>

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

using ::testing::_;
using ::testing::DoAll;
using ::testing::ExitedWithCode;
using ::testing::HasSubstr;
using ::testing::Invoke;
using ::testing::IsEmpty;
using ::testing::Return;
using ::testing::UnorderedElementsAre;

using test_util::CreateClientIdFile;
using test_util::FakeSleep;
using test_util::kFakeClientId;

namespace util {
namespace {

// Enum types for setting the runtime conditions.
enum BuildType { kOfficialBuild, kUnofficialBuild };
enum SessionType { kSignInMode, kGuestMode };
enum MetricsFlag { kMetricsEnabled, kMetricsDisabled };

// This is what the kConnectionState property will get set to for mocked calls
// into shill flimflam manager.
std::string* g_connection_state;

// Simple mock for Clock. We can't use SimpleTestClock in some places because
// we need Now to return different values on different calls, and we don't have
// a hook to gain control in between the Now() calls.
class MockClock : public base::Clock {
 public:
  ~MockClock() override {}
  MOCK_METHOD(base::Time, Now, (), (const override));
};

// Reply with either a 200 or a 429 status code depending on what tests need.
void MockMethodHandler(bool success,
                       std::string response_text,
                       const brillo::http::fake::ServerRequest& request,
                       brillo::http::fake::ServerResponse* response) {
  int response_code;
  if (success) {
    response_code = brillo::http::status_code::Ok;
  } else {
    // If the response is a number, let's use it. Default to error 429
    if (!base::StringToInt(response_text, &response_code)) {
      response_code = brillo::http::status_code::TooManyRequests;
    }
  }
  LOG(INFO) << "Mock HTTP request - replying with status code: "
            << response_code << ", text: " << response_text;

  response->ReplyText(response_code, response_text, brillo::mime::text::kPlain);
}

// Replaces Sender's functionality with a predefined behavior.
class MockSender : public util::Sender {
 private:
  bool success_;
  std::string response_;

 protected:
  std::shared_ptr<brillo::http::Transport> GetTransport() override {
    std::shared_ptr<brillo::http::fake::Transport> fake_transport =
        std::make_shared<brillo::http::fake::Transport>();
    fake_transport->AddHandler(
        kReportUploadProdUrl, brillo::http::request_type::kPost,
        base::Bind(MockMethodHandler, success_, response_));

    return fake_transport;
  }

 public:
  MockSender(bool is_success,
             std::string response_text,
             std::unique_ptr<MetricsLibraryMock> metrics_lib,
             std::unique_ptr<base::Clock> clock,
             const Sender::Options& options)
      : Sender(std::move(metrics_lib), std::move(clock), options),
        success_(is_success),
        response_(std::move(response_text)) {}
};

// Parses the Chrome uploads.log file from Sender to a vector of items per line.
// Example:
//
// {"field1":"foo1","field2":"foo2"}
// {"field1":"bar1","field2":"bar2"}
//
// => [{"field1":"foo1","field2":"foo2"}, {"field1":"bar1","field2":"bar2"}]
//
std::vector<base::Optional<base::Value>> ParseChromeUploadsLog(
    const std::string& contents) {
  std::vector<base::Optional<base::Value>> rows;

  std::vector<std::string> lines = base::SplitString(
      contents, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  for (const auto& line : lines) {
    rows.push_back(base::JSONReader::Read(line));
  }

  return rows;
}

// Helper function for calling GetBasePartOfCrashFile() concisely for tests.
std::string GetBasePartHelper(const std::string& file_name) {
  return GetBasePartOfCrashFile(base::FilePath(file_name)).value();
}

// Creates lsb-release file with information about the build type.
bool CreateLsbReleaseFile(BuildType type) {
  std::string label = "Official build";
  if (type == kUnofficialBuild)
    label = "Test build";

  return test_util::CreateFile(paths::Get("/etc/lsb-release"),
                               "CHROMEOS_RELEASE_DESCRIPTION=" + label + "\n");
}

// Creates a file that indicates uploading of device coredumps is allowed.
bool CreateDeviceCoredumpUploadAllowedFile() {
  return test_util::CreateFile(
      paths::GetAt(paths::kCrashReporterStateDirectory,
                   paths::kDeviceCoredumpUploadAllowed),
      "");
}

// Returns file names found in |directory|.
std::vector<base::FilePath> GetFileNamesIn(const base::FilePath& directory) {
  std::vector<base::FilePath> files;
  base::FileEnumerator iter(directory, false /* recursive */,
                            base::FileEnumerator::FILES, "*");
  for (base::FilePath file = iter.Next(); !file.empty(); file = iter.Next())
    files.push_back(file);
  return files;
}

// Set the flag which indicates we are mocking crash sending, either
// successfully or as a a failure.
void SetMockCrashSending(bool success) {
  util::g_force_is_mock = true;
  util::g_force_is_mock_successful = success;
}

// Clears out the flag which indicates we're mocking crash sending.
void ClearMockCrashSending() {
  util::g_force_is_mock = false;
}

// Handles calls for getting the network state.
bool GetShillProperties(
    brillo::VariantDictionary* dict,
    brillo::ErrorPtr* error,
    int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) {
  dict->emplace(shill::kConnectionStateProperty, *g_connection_state);
  return true;
}

class CrashSenderUtilTest : public testing::Test {
 protected:
  void SetUp() override {
    // Grab executable path before TearDown() can reset base::CommandLine.
    if (build_directory_ == nullptr) {
      base::FilePath my_executable_path =
          base::CommandLine::ForCurrentProcess()->GetProgram();
      build_directory_ = new base::FilePath(my_executable_path.DirName());
    }
    metrics_lib_ = std::make_unique<MetricsLibraryMock>();
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    test_dir_ = temp_dir_.GetPath();
    paths::SetPrefixForTesting(test_dir_);

    // Make sure the directory for the lock file exists.
    const base::FilePath lock_file_path =
        paths::Get(paths::kCrashSenderLockFile);
    const base::FilePath lock_file_directory = lock_file_path.DirName();
    ASSERT_TRUE(base::CreateDirectory(lock_file_directory));

    // Creates the directory where crashes will be stored, normally done by
    // Chrome
    ASSERT_TRUE(
        base::CreateDirectory(paths::Get(paths::kChromeCrashLog).DirName()));

    // We need to properly init the CommandLine object for the command line
    // parsing tests.
    base::CommandLine::Init(0, nullptr);
  }

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

    // ParseCommandLine() uses base::CommandLine via
    // brillo::FlagHelper. Reset these here to avoid side effects.
    if (base::CommandLine::InitializedForCurrentProcess())
      base::CommandLine::Reset();
    brillo::FlagHelper::ResetForTesting();
  }

  // Checks to see if a file is locked by AcquireLockFileOrDie().
  bool IsFileLocked(const base::FilePath& file_name) {
    // AcquireLockFileOrDie creates the file when it runs, so count the file
    // not existing as "not locked".
    if (!base::PathExists(file_name)) {
      return false;
    }

    // There's no portable & reliable way for a process to test its own file
    // locks, so we have to spawn another process (which won't inherit the
    // locks) to do the testing.
    CHECK(build_directory_);
    base::FilePath lock_file_tester =
        build_directory_->Append("lock_file_tester");
    std::string command = lock_file_tester.value() + " " + file_name.value();
    int test_result = system(command.c_str());
    if (WIFEXITED(test_result)) {
      if (WEXITSTATUS(test_result) == 0) {
        return true;
      }
      if (WEXITSTATUS(test_result) == 1) {
        return false;
      }
      LOG(FATAL) << "lock_file_tester failed with exit code "
                 << WEXITSTATUS(test_result);
    }
    LOG(FATAL)
        << "lock_file_tester failed before exiting; complete wait status "
        << test_result;
    return false;
  }

  // Lock the indicated file |file_name| using base::File::Lock() so that
  // AcquireLockFileOrDie() will fail to acquire it. File will be created if
  // it doesn't exist. Returns when the file is actually locked. Since locks are
  // per-process, in order to prevent this process from locking the file, we
  // have to spawn a separate process to hold the lock; the process holding the
  // lock is returned. It can be killed to release the lock.
  std::unique_ptr<brillo::Process> LockFile(const base::FilePath& file_name) {
    auto lock_process = std::make_unique<brillo::ProcessImpl>();
    CHECK(build_directory_);
    base::FilePath lock_file_holder =
        build_directory_->Append("hold_lock_file");
    lock_process->AddArg(lock_file_holder.value());
    lock_process->AddArg(file_name.value());
    CHECK(lock_process->Start());

    // Wait for the file to actually be locked. Don't wait forever in case the
    // subprocess fails in some way.
    base::Time stop_time = base::Time::Now() + base::TimeDelta::FromMinutes(1);
    bool success = false;
    while (!success && base::Time::Now() < stop_time) {
      base::File lock_file(file_name, base::File::FLAG_OPEN |
                                          base::File::FLAG_READ |
                                          base::File::FLAG_WRITE);
      if (lock_file.IsValid()) {
        struct flock lock;
        lock.l_type = F_WRLCK;
        lock.l_whence = SEEK_SET;
        lock.l_start = 0;
        lock.l_len = 0;
        if (fcntl(lock_file.GetPlatformFile(), F_GETLK, &lock) == 0 &&
            lock.l_type == F_WRLCK) {
          success = true;
        }
      }

      if (!success) {
        base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(5));
      }
    }

    CHECK(success) << "Subprocess did not lock " << file_name.value();
    return lock_process;
  }

  // Creates a file at |file_path| with contents |content| and sets its access
  // and modification time to |timestamp|.
  bool CreateFile(const base::FilePath& file_path,
                  base::StringPiece content,
                  base::Time timestamp) {
    if (!test_util::CreateFile(file_path, content))
      return false;

    if (!test_util::TouchFileHelper(file_path, timestamp))
      return false;

    return true;
  }

  // Creates test crash files in |crash_directory|. Returns true on success.
  bool CreateTestCrashFiles(const base::FilePath& crash_directory) {
    const base::Time now = test_util::GetDefaultTime();
    const base::TimeDelta hour = base::TimeDelta::FromHours(1);

    // Choose timestamps so that the return value of GetMetaFiles() is sorted
    // per timestamps correctly.
    const base::Time good_meta_time = now - hour * 3;
    const base::Time absolute_meta_time = now - hour * 2;
    const base::Time recent_os_meta_time = now - hour;
    const base::Time devcore_meta_time = now;

    // These should be kept, since the payload is a known kind and exists.
    good_meta_ = crash_directory.Append("good.meta");
    good_log_ = crash_directory.Append("good.log");
    if (!CreateFile(good_meta_, "payload=good.log\ndone=1\n", good_meta_time))
      return false;
    if (!CreateFile(good_log_, "", now))
      return false;

    // These should be kept, the payload path is absolute but should be handled
    // properly.
    absolute_meta_ = crash_directory.Append("absolute.meta");
    absolute_log_ = crash_directory.Append("absolute.log");
    if (!CreateFile(absolute_meta_,
                    "payload=" + absolute_log_.value() + "\n" + "done=1\n",
                    absolute_meta_time))
      return false;
    if (!CreateFile(absolute_log_, "", now))
      return false;

    // These should be removed, since the `alreadyuploaded` file exists.
    uploaded_meta_ = crash_directory.Append("uploaded.meta");
    uploaded_log_ = crash_directory.Append("uploaded.log");
    uploaded_already_ = crash_directory.Append("uploaded.alreadyuploaded");
    if (!CreateFile(uploaded_meta_, "payload=uploaded.log\ndone=1\n",
                    good_meta_time))
      return false;
    if (!CreateFile(uploaded_log_, "", now))
      return false;
    if (!CreateFile(uploaded_already_, "", now))
      return false;

    // This should be ignored as corrupt. Payload can't be /.
    root_payload_meta_ = crash_directory.Append("root_payload.meta");
    if (!test_util::CreateFile(root_payload_meta_,
                               "payload=/\n"
                               "done=1\n"))
      return false;

    // These should be ignored, if uploading of device coredumps is not allowed.
    devcore_meta_ = crash_directory.Append("devcore.meta");
    devcore_devcore_ = crash_directory.Append("devcore.devcore");
    if (!CreateFile(devcore_meta_,
                    "payload=devcore.devcore\n"
                    "done=1\n",
                    devcore_meta_time))
      return false;
    if (!CreateFile(devcore_devcore_, "", now))
      return false;

    // This should be ignored, since the metadata is corrupted but the file is
    // still fairly new.
    new_corrupted_meta_ = crash_directory.Append("new_corrupted.meta");
    if (!CreateFile(new_corrupted_meta_, "foo\ndone=1\n", now))
      return false;

    // This should be removed, since metadata is corrupted.
    old_corrupted_meta_ = crash_directory.Append("old_corrupted.meta");
    if (!CreateFile(old_corrupted_meta_, "!@#$%^&*\ndone=1\n", now - hour * 1))
      return false;

    // This should be removed, since no payload info is recorded.
    empty_meta_ = crash_directory.Append("empty.meta");
    if (!CreateFile(empty_meta_, "done=1\n", now))
      return false;

    // This should be removed, since the payload file does not exist.
    nonexistent_meta_ = crash_directory.Append("nonexistent.meta");
    if (!CreateFile(nonexistent_meta_,
                    "payload=nonexistent.log\n"
                    "done=1\n",
                    now))
      return false;

    // These should be removed, since the payload is an unknown kind.
    unknown_meta_ = crash_directory.Append("unknown.meta");
    unknown_xxx_ = crash_directory.Append("unknown.xxx");
    if (!CreateFile(unknown_meta_,
                    "payload=unknown.xxx\n"
                    "done=1\n",
                    now))
      return false;
    if (!CreateFile(unknown_xxx_, "", now))
      return false;

    // This should be removed, since the meta file is old.
    old_incomplete_meta_ = crash_directory.Append("old_incomplete.meta");
    if (!CreateFile(old_incomplete_meta_, "payload=good.log\n", now))
      return false;
    if (!test_util::TouchFileHelper(old_incomplete_meta_, now - hour * 24))
      return false;

    // This should be ignored, even though the payload doesn't exist,
    // since the meta file is new.
    new_incomplete_meta_ = crash_directory.Append("new_incomplete.meta");
    if (!CreateFile(new_incomplete_meta_, "payload=nonexistent.log\n", now))
      return false;

    // This should be ignored, even though there's no payload, since the meta
    // file is new.
    new_empty_meta_ = crash_directory.Append("new_empty.meta");
    if (!CreateFile(new_empty_meta_, "", now))
      return false;

    // This should be kept since the OS timestamp is recent.
    recent_os_meta_ = crash_directory.Append("recent_os.meta");
    if (!CreateFile(recent_os_meta_,
                    base::StringPrintf(
                        "payload=recent_os.log\n"
                        "os_millis=%" PRId64 "\n"
                        "done=1\n",
                        (now - base::Time::UnixEpoch()).InMilliseconds()),
                    recent_os_meta_time)) {
      return false;
    }
    recent_os_log_ = crash_directory.Append("recent_os.log");
    if (!CreateFile(recent_os_log_, "", now))
      return false;

    // This should be removed since the OS timestamp is old.
    old_os_meta_ = crash_directory.Append("old_os.meta");
    if (!CreateFile(old_os_meta_,
                    base::StringPrintf("payload=good.log\n"
                                       "os_millis=%" PRId64 "\n"
                                       "done=1\n",
                                       ((now - base::Time::UnixEpoch()) -
                                        base::TimeDelta::FromDays(200))
                                           .InMilliseconds()),
                    now)) {
      return false;
    }

    // Create large metadata with the size of 1MiB + 1byte.
    large_meta_ = crash_directory.Append("large.meta");
    if (!CreateFile(large_meta_, std::string(1024 * 1024 + 1, 'x'), now)) {
      return false;
    }

    return true;
  }

  // Sets the runtime conditions that affect behaviors of ChooseAction().
  // Returns true on success.
  bool SetConditions(BuildType build_type,
                     SessionType session_type,
                     MetricsFlag metrics_flag) {
    return SetConditions(build_type, session_type, metrics_flag,
                         metrics_lib_.get());
  }

  // Version of SetConditions useful for tests that need to create a Sender.
  // Sender owns the MetricsLibraryInterface pointer, so metrics_lib_ is
  // usually nullptr in these tests.
  static bool SetConditions(BuildType build_type,
                            SessionType session_type,
                            MetricsFlag metrics_flag,
                            MetricsLibraryMock* metrics_lib) {
    if (!CreateLsbReleaseFile(build_type))
      return false;

    metrics_lib->set_guest_mode(session_type == kGuestMode);
    metrics_lib->set_metrics_enabled(metrics_flag == kMetricsEnabled);

    return true;
  }

  // Directory that the test executable lives in. We reset CommandLine during
  // TearDown, so we must grab this information early.
  static base::FilePath* build_directory_;
  base::AtExitManager at_exit_manager_;

  std::unique_ptr<MetricsLibraryMock> metrics_lib_;
  base::ScopedTempDir temp_dir_;
  base::FilePath test_dir_;

  base::FilePath good_meta_;
  base::FilePath good_log_;
  base::FilePath absolute_meta_;
  base::FilePath absolute_log_;
  base::FilePath uploaded_meta_;
  base::FilePath uploaded_log_;
  base::FilePath uploaded_already_;
  base::FilePath root_payload_meta_;
  base::FilePath devcore_meta_;
  base::FilePath devcore_devcore_;
  base::FilePath empty_meta_;
  base::FilePath new_corrupted_meta_;
  base::FilePath old_corrupted_meta_;
  base::FilePath nonexistent_meta_;
  base::FilePath unknown_meta_;
  base::FilePath unknown_xxx_;
  base::FilePath old_incomplete_meta_;
  base::FilePath new_incomplete_meta_;
  base::FilePath new_empty_meta_;
  base::FilePath recent_os_meta_;
  base::FilePath recent_os_log_;
  base::FilePath old_os_meta_;
  base::FilePath large_meta_;
};

base::FilePath* CrashSenderUtilTest::build_directory_ = nullptr;
using CrashSenderUtilDeathTest = CrashSenderUtilTest;

}  // namespace

TEST_F(CrashSenderUtilTest, ParseCommandLine_NoFlags) {
  const char* argv[] = {"crash_sender"};
  base::CommandLine command_line(base::size(argv), argv);
  brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
      &command_line);
  CommandLineFlags flags;
  ParseCommandLine(base::size(argv), argv, &flags);
  EXPECT_EQ(flags.max_spread_time.InSeconds(), kMaxSpreadTimeInSeconds);
  EXPECT_TRUE(flags.crash_directory.empty());
  EXPECT_FALSE(flags.ignore_rate_limits);
  EXPECT_FALSE(flags.ignore_hold_off_time);
  EXPECT_FALSE(flags.allow_dev_sending);
  EXPECT_FALSE(flags.ignore_pause_file);
  EXPECT_FALSE(flags.upload_old_reports);
}

TEST_F(CrashSenderUtilDeathTest, ParseCommandLine_InvalidMaxSpreadTime) {
  const char* argv[] = {"crash_sender", "--max_spread_time=-1"};
  base::CommandLine command_line(base::size(argv), argv);
  brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
      &command_line);
  CommandLineFlags flags;
  EXPECT_DEATH(ParseCommandLine(base::size(argv), argv, &flags),
               "Invalid value for max spread time: -1");
}

TEST_F(CrashSenderUtilTest, ParseCommandLine_ValidMaxSpreadTime) {
  const char* argv[] = {"crash_sender", "--max_spread_time=0"};
  base::CommandLine command_line(base::size(argv), argv);
  brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
      &command_line);
  CommandLineFlags flags;
  ParseCommandLine(base::size(argv), argv, &flags);
  EXPECT_EQ(base::TimeDelta::FromSeconds(0), flags.max_spread_time);
  EXPECT_TRUE(flags.crash_directory.empty());
  EXPECT_FALSE(flags.ignore_rate_limits);
  EXPECT_FALSE(flags.ignore_hold_off_time);
  EXPECT_FALSE(flags.allow_dev_sending);
  EXPECT_FALSE(flags.ignore_pause_file);
  EXPECT_FALSE(flags.upload_old_reports);
  EXPECT_FALSE(flags.force_upload_on_test_images);
}

TEST_F(CrashSenderUtilTest, ParseCommandLine_IgnoreRateLimits) {
  const char* argv[] = {"crash_sender", "--ignore_rate_limits"};
  base::CommandLine command_line(base::size(argv), argv);
  brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
      &command_line);
  CommandLineFlags flags;
  ParseCommandLine(base::size(argv), argv, &flags);
  EXPECT_EQ(flags.max_spread_time.InSeconds(), kMaxSpreadTimeInSeconds);
  EXPECT_TRUE(flags.crash_directory.empty());
  EXPECT_TRUE(flags.ignore_rate_limits);
  EXPECT_FALSE(flags.ignore_hold_off_time);
  EXPECT_FALSE(flags.allow_dev_sending);
  EXPECT_FALSE(flags.ignore_pause_file);
  EXPECT_FALSE(flags.upload_old_reports);
  EXPECT_FALSE(flags.force_upload_on_test_images);
}

TEST_F(CrashSenderUtilTest, ParseCommandLine_IgnoreHoldOffTime) {
  const char* argv[] = {"crash_sender", "--ignore_hold_off_time"};
  base::CommandLine command_line(base::size(argv), argv);
  brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
      &command_line);
  CommandLineFlags flags;
  ParseCommandLine(base::size(argv), argv, &flags);
  EXPECT_EQ(flags.max_spread_time.InSeconds(), kMaxSpreadTimeInSeconds);
  EXPECT_TRUE(flags.crash_directory.empty());
  EXPECT_FALSE(flags.ignore_rate_limits);
  EXPECT_TRUE(flags.ignore_hold_off_time);
  EXPECT_FALSE(flags.allow_dev_sending);
  EXPECT_FALSE(flags.ignore_pause_file);
  EXPECT_FALSE(flags.upload_old_reports);
  EXPECT_FALSE(flags.force_upload_on_test_images);
}

TEST_F(CrashSenderUtilTest, ParseCommandLine_CrashDirectory) {
  const char* argv[] = {"crash_sender", "--crash_directory=/tmp"};
  base::CommandLine command_line(base::size(argv), argv);
  brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
      &command_line);
  CommandLineFlags flags;
  ParseCommandLine(base::size(argv), argv, &flags);
  EXPECT_EQ(flags.max_spread_time.InSeconds(), kMaxSpreadTimeInSeconds);
  EXPECT_EQ(flags.crash_directory, "/tmp");
  EXPECT_FALSE(flags.ignore_rate_limits);
  EXPECT_FALSE(flags.ignore_hold_off_time);
  EXPECT_FALSE(flags.allow_dev_sending);
  EXPECT_FALSE(flags.ignore_pause_file);
  EXPECT_FALSE(flags.upload_old_reports);
  EXPECT_FALSE(flags.force_upload_on_test_images);
}

TEST_F(CrashSenderUtilTest, ParseCommandLine_Dev) {
  const char* argv[] = {"crash_sender", "--dev"};
  base::CommandLine command_line(base::size(argv), argv);
  brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
      &command_line);
  CommandLineFlags flags;
  ParseCommandLine(base::size(argv), argv, &flags);
  EXPECT_EQ(flags.max_spread_time.InSeconds(), kMaxSpreadTimeInSeconds);
  EXPECT_TRUE(flags.crash_directory.empty());
  EXPECT_FALSE(flags.ignore_rate_limits);
  EXPECT_FALSE(flags.ignore_hold_off_time);
  EXPECT_TRUE(flags.allow_dev_sending);
  EXPECT_FALSE(flags.ignore_pause_file);
  EXPECT_FALSE(flags.upload_old_reports);
  EXPECT_FALSE(flags.force_upload_on_test_images);
}

TEST_F(CrashSenderUtilTest, ParseCommandLine_IgnorePauseFile) {
  const char* argv[] = {"crash_sender", "--ignore_pause_file"};
  base::CommandLine command_line(base::size(argv), argv);
  brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
      &command_line);
  CommandLineFlags flags;
  ParseCommandLine(base::size(argv), argv, &flags);
  EXPECT_EQ(flags.max_spread_time.InSeconds(), kMaxSpreadTimeInSeconds);
  EXPECT_TRUE(flags.crash_directory.empty());
  EXPECT_FALSE(flags.ignore_rate_limits);
  EXPECT_FALSE(flags.ignore_hold_off_time);
  EXPECT_FALSE(flags.allow_dev_sending);
  EXPECT_TRUE(flags.ignore_pause_file);
  EXPECT_FALSE(flags.upload_old_reports);
  EXPECT_FALSE(flags.force_upload_on_test_images);
}

TEST_F(CrashSenderUtilTest, ParseCommandLine_UploadOldReports) {
  const char* argv[] = {"crash_sender", "--upload_old_reports"};
  base::CommandLine command_line(base::size(argv), argv);
  brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
      &command_line);
  CommandLineFlags flags;
  ParseCommandLine(base::size(argv), argv, &flags);
  EXPECT_EQ(flags.max_spread_time.InSeconds(), kMaxSpreadTimeInSeconds);
  EXPECT_TRUE(flags.crash_directory.empty());
  EXPECT_FALSE(flags.ignore_rate_limits);
  EXPECT_FALSE(flags.ignore_hold_off_time);
  EXPECT_FALSE(flags.allow_dev_sending);
  EXPECT_FALSE(flags.ignore_pause_file);
  EXPECT_TRUE(flags.upload_old_reports);
  EXPECT_FALSE(flags.force_upload_on_test_images);
}

TEST_F(CrashSenderUtilTest, ParseCommandLine_ForceUploadOnTestImages) {
  const char* argv[] = {"crash_sender", "--force_upload_on_test_images"};
  base::CommandLine command_line(base::size(argv), argv);
  brillo::FlagHelper::GetInstance()->set_command_line_for_testing(
      &command_line);
  CommandLineFlags flags;
  ParseCommandLine(base::size(argv), argv, &flags);
  EXPECT_EQ(flags.max_spread_time.InSeconds(), kMaxSpreadTimeInSeconds);
  EXPECT_TRUE(flags.crash_directory.empty());
  EXPECT_FALSE(flags.ignore_rate_limits);
  EXPECT_FALSE(flags.ignore_hold_off_time);
  EXPECT_FALSE(flags.allow_dev_sending);
  EXPECT_FALSE(flags.ignore_pause_file);
  EXPECT_FALSE(flags.upload_old_reports);
  EXPECT_TRUE(flags.force_upload_on_test_images);
}

TEST_F(CrashSenderUtilTest, DoesPauseFileExist) {
  EXPECT_FALSE(DoesPauseFileExist());

  ASSERT_TRUE(test_util::CreateFile(paths::Get(paths::kPauseCrashSending), ""));
  EXPECT_TRUE(DoesPauseFileExist());
}

TEST_F(CrashSenderUtilTest, GetBasePartOfCrashFile) {
  // The below are shorter than expected and shouldn't be touched
  EXPECT_EQ("foo", GetBasePartHelper("foo"));
  EXPECT_EQ("foo.1", GetBasePartHelper("foo.1"));
  EXPECT_EQ("foo.1.2", GetBasePartHelper("foo.1.2"));
  EXPECT_EQ("foo.1.2.3", GetBasePartHelper("foo.1.2.3"));

  // Parsed according to old, four-component, version
  EXPECT_EQ("foo.1.2.3", GetBasePartHelper("foo.1.2.3.4"));
  // Parsed according to new, five-component version
  EXPECT_EQ("foo.1.2.3.4", GetBasePartHelper("foo.1.2.3.4.log"));

  // Parsed according to old, four-component, version
  EXPECT_EQ("1.2.3.4", GetBasePartHelper("1.2.3.4.log.tar"));
  // Parsed according to new, five-component, version
  EXPECT_EQ("foo.1.2.3.4", GetBasePartHelper("foo.1.2.3.4.log.tar"));

  // Parsed according to old, four-component, version
  EXPECT_EQ("foo.1.2.3", GetBasePartHelper("foo.1.2.3.log.tar.gz"));
  // Parsed according to new, five-component, version
  EXPECT_EQ("foo.1.2.3.4", GetBasePartHelper("foo.1.2.3.4.log.tar.gz"));

  // Directory should be preserved.
  EXPECT_EQ("/d/1.2", GetBasePartHelper("/d/1.2"));
  EXPECT_EQ("/d/1.2.3.4", GetBasePartHelper("/d/1.2.3.4.log"));
  // Dots in directory name should not affect the function.
  EXPECT_EQ("/d.d.d.d/1.2.3.4", GetBasePartHelper("/d.d.d.d/1.2.3.4.log"));
}

TEST_F(CrashSenderUtilTest, RemoveOrphanedCrashFiles) {
  const base::FilePath crash_directory =
      paths::Get(paths::kSystemCrashDirectory);
  ASSERT_TRUE(base::CreateDirectory(crash_directory));

  const base::FilePath new_log = crash_directory.Append("0.0.0.0.0.log");
  const base::FilePath old1_log = crash_directory.Append("1.1.1.1.1.log");
  const base::FilePath old1_meta = crash_directory.Append("1.1.1.1.1.meta");
  const base::FilePath old2_log = crash_directory.Append("2.2.2.2.2.log");
  const base::FilePath old3_log = crash_directory.Append("3.3.3.3.3.log");
  const base::FilePath old4_log = crash_directory.Append("4.log");

  base::Time now = base::Time::Now();

  // new_log is new thus should not be removed.
  ASSERT_TRUE(test_util::CreateFile(new_log, ""));

  // old1_log is old but comes with the meta file thus should not be removed.
  ASSERT_TRUE(test_util::CreateFile(old1_log, ""));
  ASSERT_TRUE(test_util::CreateFile(old1_meta, ""));
  ASSERT_TRUE(test_util::TouchFileHelper(old1_log,
                                         now - base::TimeDelta::FromHours(24)));
  ASSERT_TRUE(test_util::TouchFileHelper(old1_meta,
                                         now - base::TimeDelta::FromHours(24)));

  // old2_log is old without the meta file thus should be removed.
  ASSERT_TRUE(test_util::CreateFile(old2_log, ""));
  ASSERT_TRUE(test_util::TouchFileHelper(old2_log,
                                         now - base::TimeDelta::FromHours(24)));

  // old3_log is very old without the meta file thus should be removed.
  ASSERT_TRUE(test_util::CreateFile(old3_log, ""));
  ASSERT_TRUE(test_util::TouchFileHelper(old3_log,
                                         now - base::TimeDelta::FromDays(365)));

  // old4_log is misnamed, but should be removed since it's old.
  ASSERT_TRUE(test_util::CreateFile(old4_log, ""));
  ASSERT_TRUE(test_util::TouchFileHelper(old4_log,
                                         now - base::TimeDelta::FromHours(24)));

  RemoveOrphanedCrashFiles(crash_directory);

  // Check what files were removed.
  EXPECT_TRUE(base::PathExists(new_log));
  EXPECT_TRUE(base::PathExists(old1_log));
  EXPECT_TRUE(base::PathExists(old1_meta));
  EXPECT_FALSE(base::PathExists(old2_log));
  EXPECT_FALSE(base::PathExists(old3_log));
  EXPECT_FALSE(base::PathExists(old4_log));
}

TEST_F(CrashSenderUtilTest, ChooseAction) {
  ASSERT_TRUE(SetConditions(kOfficialBuild, kSignInMode, kMetricsEnabled));

  const base::FilePath crash_directory =
      paths::Get(paths::kSystemCrashDirectory);
  ASSERT_TRUE(CreateDirectory(crash_directory));
  ASSERT_TRUE(CreateTestCrashFiles(crash_directory));
  MetricsLibraryMock* raw_metrics_lib = metrics_lib_.get();

  Sender::Options options;
  Sender sender(std::move(metrics_lib_),
                std::make_unique<test_util::AdvancingClock>(), options);

  std::string reason;
  CrashInfo info;
  // The following files should be sent.
  EXPECT_CALL(*raw_metrics_lib,
              SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason", _, _))
      .Times(0);
  EXPECT_EQ(Sender::kSend, sender.ChooseAction(good_meta_, &reason, &info));
  EXPECT_EQ(Sender::kSend,
            sender.ChooseAction(recent_os_meta_, &reason, &info));
  EXPECT_EQ(Sender::kSend, sender.ChooseAction(absolute_meta_, &reason, &info));
  // Verify that RemoveReason wasn't sent
  testing::Mock::VerifyAndClearExpectations(raw_metrics_lib);

  // Basic check that the valid crash info is returned.
  std::string value;
  EXPECT_EQ(absolute_log_.value(), info.payload_file.value());
  EXPECT_EQ("log", info.payload_kind);
  EXPECT_TRUE(info.metadata.GetString("payload", &value));

  const base::FilePath processing = good_meta_.ReplaceExtension(".processing");
  // ChooseAction was successful, so it should remove the file.
  EXPECT_FALSE(base::PathExists(processing));

  // If a ".processing" file exists, the meta file shouldn't be uploaded.
  ASSERT_TRUE(test_util::CreateFile(processing, ""));

  // Following calls should be in order.
  testing::InSequence seq;
  EXPECT_CALL(
      *raw_metrics_lib,
      SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                    Sender::kProcessingFileExists, Sender::kSendReasonCount));
  EXPECT_EQ(Sender::kRemove, sender.ChooseAction(good_meta_, &reason, &info));
  EXPECT_THAT(reason, HasSubstr(".processing file already exists"));
  ASSERT_TRUE(base::DeleteFile(processing));

  // The following file should be removed.
  EXPECT_CALL(
      *raw_metrics_lib,
      SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                    Sender::kAlreadyUploaded, Sender::kSendReasonCount));
  EXPECT_EQ(Sender::kRemove,
            sender.ChooseAction(uploaded_meta_, &reason, &info));
  EXPECT_THAT(reason, HasSubstr("Removing already-uploaded crash"));
  EXPECT_FALSE(
      base::PathExists(uploaded_meta_.ReplaceExtension(".processing")));

  // The following files should be ignored.
  EXPECT_EQ(Sender::kIgnore,
            sender.ChooseAction(new_incomplete_meta_, &reason, &info));
  EXPECT_THAT(reason, HasSubstr("Recent incomplete metadata"));
  EXPECT_FALSE(
      base::PathExists(new_incomplete_meta_.ReplaceExtension(".processing")));

  EXPECT_EQ(Sender::kIgnore,
            sender.ChooseAction(new_empty_meta_, &reason, &info));
  EXPECT_THAT(reason, HasSubstr("Recent incomplete metadata"));
  EXPECT_FALSE(
      base::PathExists(new_empty_meta_.ReplaceExtension(".processing")));

  // Device coredump should be ignored by default.
  EXPECT_EQ(Sender::kIgnore,
            sender.ChooseAction(devcore_meta_, &reason, &info));
  EXPECT_THAT(reason, HasSubstr("Device coredump upload not allowed"));
  EXPECT_FALSE(base::PathExists(devcore_meta_.ReplaceExtension(".processing")));

  // Device coredump should be sent, if uploading is allowed.
  CreateDeviceCoredumpUploadAllowedFile();
  EXPECT_EQ(Sender::kSend, sender.ChooseAction(devcore_meta_, &reason, &info));

  // The following files should be removed.
  EXPECT_CALL(
      *raw_metrics_lib,
      SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                    Sender::kPayloadUnspecified, Sender::kSendReasonCount));
  EXPECT_EQ(Sender::kRemove, sender.ChooseAction(empty_meta_, &reason, &info));
  EXPECT_THAT(reason, HasSubstr("Payload is not found"));
  EXPECT_FALSE(base::PathExists(empty_meta_.ReplaceExtension(".processing")));

  EXPECT_EQ(Sender::kIgnore,
            sender.ChooseAction(new_corrupted_meta_, &reason, &info));
  EXPECT_THAT(reason, HasSubstr("Recent incomplete metadata"));
  EXPECT_FALSE(
      base::PathExists(new_corrupted_meta_.ReplaceExtension(".processing")));

  EXPECT_CALL(
      *raw_metrics_lib,
      SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                    Sender::kUnparseableMetaFile, Sender::kSendReasonCount));
  EXPECT_EQ(Sender::kRemove,
            sender.ChooseAction(old_corrupted_meta_, &reason, &info));
  EXPECT_THAT(reason, HasSubstr("Corrupted metadata"));
  EXPECT_FALSE(
      base::PathExists(old_corrupted_meta_.ReplaceExtension(".processing")));

  EXPECT_CALL(
      *raw_metrics_lib,
      SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                    Sender::kPayloadNonexistent, Sender::kSendReasonCount));
  EXPECT_EQ(Sender::kRemove,
            sender.ChooseAction(nonexistent_meta_, &reason, &info));
  EXPECT_THAT(reason, HasSubstr("Missing payload"));
  EXPECT_FALSE(
      base::PathExists(nonexistent_meta_.ReplaceExtension(".processing")));

  EXPECT_CALL(
      *raw_metrics_lib,
      SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                    Sender::kPayloadKindUnknown, Sender::kSendReasonCount));
  EXPECT_EQ(Sender::kRemove,
            sender.ChooseAction(unknown_meta_, &reason, &info));
  EXPECT_THAT(reason, HasSubstr("Unknown kind"));
  EXPECT_FALSE(base::PathExists(unknown_meta_.ReplaceExtension(".processing")));

  EXPECT_CALL(
      *raw_metrics_lib,
      SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                    Sender::kOldIncompleteMeta, Sender::kSendReasonCount));
  EXPECT_EQ(Sender::kRemove,
            sender.ChooseAction(old_incomplete_meta_, &reason, &info));
  EXPECT_THAT(reason, HasSubstr("Removing old incomplete metadata"));
  EXPECT_FALSE(
      base::PathExists(old_incomplete_meta_.ReplaceExtension(".processing")));

  EXPECT_CALL(
      *raw_metrics_lib,
      SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                    Sender::kOSVersionTooOld, Sender::kSendReasonCount));
  EXPECT_EQ(Sender::kRemove, sender.ChooseAction(old_os_meta_, &reason, &info));
  EXPECT_THAT(reason, HasSubstr("Old OS version"));
  EXPECT_FALSE(base::PathExists(old_os_meta_.ReplaceExtension(".processing")));

  EXPECT_CALL(
      *raw_metrics_lib,
      SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                    Sender::kPayloadAbsolute, Sender::kSendReasonCount));
  EXPECT_EQ(Sender::kRemove,
            sender.ChooseAction(root_payload_meta_, &reason, &info));
  EXPECT_THAT(reason, HasSubstr("payload path is absolute"));
  EXPECT_FALSE(
      base::PathExists(root_payload_meta_.ReplaceExtension(".processing")));

  EXPECT_CALL(*raw_metrics_lib,
              SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                            Sender::kLargeMetaFile, Sender::kSendReasonCount));
  EXPECT_EQ(Sender::kRemove, sender.ChooseAction(large_meta_, &reason, &info));
  EXPECT_THAT(reason, HasSubstr("Metadata file is unusually large"));
  EXPECT_FALSE(base::PathExists(large_meta_.ReplaceExtension(".processing")));

  EXPECT_CALL(
      *raw_metrics_lib,
      SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                    Sender::kNotOfficialImage, Sender::kSendReasonCount));
  ASSERT_TRUE(SetConditions(kUnofficialBuild, kSignInMode, kMetricsEnabled,
                            raw_metrics_lib));
  EXPECT_EQ(Sender::kRemove, sender.ChooseAction(good_meta_, &reason, &info));
  EXPECT_THAT(reason, HasSubstr("Not an official OS version"));
  EXPECT_FALSE(base::PathExists(good_meta_.ReplaceExtension(".processing")));

  ASSERT_TRUE(SetConditions(kOfficialBuild, kSignInMode, kMetricsDisabled,
                            raw_metrics_lib));
  EXPECT_CALL(
      *raw_metrics_lib,
      SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                    Sender::kNoMetricsConsent, Sender::kSendReasonCount));
  EXPECT_EQ(Sender::kRemove, sender.ChooseAction(good_meta_, &reason, &info));
  EXPECT_THAT(reason, HasSubstr("Crash reporting is disabled"));
  EXPECT_FALSE(base::PathExists(good_meta_.ReplaceExtension(".processing")));

  // Valid crash files should be kept in the guest mode.
  ASSERT_TRUE(SetConditions(kOfficialBuild, kGuestMode, kMetricsDisabled,
                            raw_metrics_lib));
  EXPECT_EQ(Sender::kIgnore, sender.ChooseAction(good_meta_, &reason, &info));
}

// Test that when force_upload_on_test_images is set, we set hwtest_suite_run.
TEST_F(CrashSenderUtilTest, ChooseAction_SetsHwtestSuiteRun) {
  ASSERT_TRUE(SetConditions(kOfficialBuild, kSignInMode, kMetricsEnabled));

  const base::FilePath crash_directory =
      paths::Get(paths::kSystemCrashDirectory);
  ASSERT_TRUE(CreateDirectory(crash_directory));
  ASSERT_TRUE(CreateTestCrashFiles(crash_directory));

  Sender::Options options;
  options.force_upload_on_test_images = true;
  Sender sender(std::move(metrics_lib_),
                std::make_unique<test_util::AdvancingClock>(), options);

  std::string reason;
  CrashInfo info;
  // The file should be sent.
  EXPECT_EQ(Sender::kSend, sender.ChooseAction(good_meta_, &reason, &info));
  std::string out;
  EXPECT_EQ(info.metadata.GetString("hwtest_suite_run", &out), true);
  EXPECT_EQ(out, "true");

  EXPECT_EQ(info.metadata.GetString("hwtest_sender_direct", &out), true);
  EXPECT_EQ(out, "true");
}

// Test that when force_upload_on_test_images is unset, we don't set
// hwtest_suite_run.
TEST_F(CrashSenderUtilTest, ChooseAction_NonForceNoHwTestSuiteRun) {
  ASSERT_TRUE(SetConditions(kOfficialBuild, kSignInMode, kMetricsEnabled));

  const base::FilePath crash_directory =
      paths::Get(paths::kSystemCrashDirectory);
  ASSERT_TRUE(CreateDirectory(crash_directory));
  ASSERT_TRUE(CreateTestCrashFiles(crash_directory));

  Sender::Options options;
  Sender sender(std::move(metrics_lib_),
                std::make_unique<test_util::AdvancingClock>(), options);

  std::string reason;
  CrashInfo info;
  // The file should be sent.
  EXPECT_EQ(Sender::kSend, sender.ChooseAction(good_meta_, &reason, &info));
  std::string out;
  EXPECT_EQ(info.metadata.GetString("hwtest_suite_run", &out), false);
  EXPECT_EQ(info.metadata.GetString("hwtest_sender_direct", &out), false);
}

TEST_F(CrashSenderUtilDeathTest, ChooseActionCrash) {
  ASSERT_TRUE(SetConditions(kOfficialBuild, kSignInMode, kMetricsEnabled));

  const base::FilePath crash_directory =
      paths::Get(paths::kSystemCrashDirectory);
  ASSERT_TRUE(CreateDirectory(crash_directory));
  ASSERT_TRUE(CreateTestCrashFiles(crash_directory));

  Sender::Options options;
  MockSender sender(true,   // success=true
                    "123",  // Response
                    std::move(metrics_lib_),
                    std::make_unique<test_util::AdvancingClock>(), options);

  SetMockCrashSending(true);
  sender.SetCrashDuringSendForTesting(true);

  std::string reason;
  CrashInfo info;
  EXPECT_DEATH(sender.ChooseAction(good_meta_, &reason, &info),
               "crashing as requested");

  // ChooseAction crashed so the file should remain.
  EXPECT_TRUE(base::PathExists(good_meta_.ReplaceExtension(".processing")));
}

TEST_F(CrashSenderUtilTest, ChooseActionDevMode) {
  // If we set allow_dev_sending, then the OS check will be skipped.
  ASSERT_TRUE(SetConditions(kUnofficialBuild, kSignInMode, kMetricsEnabled));

  const base::FilePath crash_directory =
      paths::Get(paths::kSystemCrashDirectory);
  ASSERT_TRUE(CreateDirectory(crash_directory));
  ASSERT_TRUE(CreateTestCrashFiles(crash_directory));

  Sender::Options options;
  options.allow_dev_sending = true;
  Sender sender(std::move(metrics_lib_),
                std::make_unique<test_util::AdvancingClock>(), options);

  std::string reason;
  CrashInfo info;

  EXPECT_EQ(Sender::kSend, sender.ChooseAction(good_meta_, &reason, &info));
  EXPECT_EQ(Sender::kSend, sender.ChooseAction(old_os_meta_, &reason, &info));
}

TEST_F(CrashSenderUtilTest, ChooseActionUploadOldReports) {
  ASSERT_TRUE(SetConditions(kOfficialBuild, kSignInMode, kMetricsEnabled));

  const base::FilePath crash_directory =
      paths::Get(paths::kSystemCrashDirectory);
  ASSERT_TRUE(CreateDirectory(crash_directory));
  ASSERT_TRUE(CreateTestCrashFiles(crash_directory));

  Sender::Options options;
  options.upload_old_reports = true;
  Sender sender(std::move(metrics_lib_),
                std::make_unique<test_util::AdvancingClock>(), options);

  std::string reason;
  CrashInfo info;

  EXPECT_EQ(Sender::kSend, sender.ChooseAction(old_os_meta_, &reason, &info));
}

TEST_F(CrashSenderUtilTest, RemoveAndPickCrashFiles) {
  auto mock =
      std::make_unique<org::chromium::SessionManagerInterfaceProxyMock>();
  test_util::SetActiveSessions(mock.get(),
                               {{"user1", "hash1"}, {"user2", "hash2"}});
  MetricsLibraryMock* raw_metrics_lib = metrics_lib_.get();

  Sender::Options options;
  options.session_manager_proxy = mock.release();
  Sender sender(std::move(metrics_lib_),
                std::make_unique<test_util::AdvancingClock>(), options);

  ASSERT_TRUE(SetConditions(kOfficialBuild, kSignInMode, kMetricsEnabled,
                            raw_metrics_lib));

  const base::FilePath crash_directory =
      paths::Get(paths::kSystemCrashDirectory);
  ASSERT_TRUE(CreateDirectory(crash_directory));
  ASSERT_TRUE(CreateTestCrashFiles(crash_directory));

  std::vector<MetaFile> to_send;
  sender.RemoveAndPickCrashFiles(crash_directory, &to_send);

  // Check what files were removed.
  EXPECT_TRUE(base::PathExists(good_meta_));
  EXPECT_TRUE(base::PathExists(good_log_));
  EXPECT_TRUE(base::PathExists(absolute_meta_));
  EXPECT_TRUE(base::PathExists(absolute_log_));
  EXPECT_FALSE(base::PathExists(uploaded_meta_));
  EXPECT_FALSE(base::PathExists(uploaded_log_));
  EXPECT_TRUE(base::PathExists(new_incomplete_meta_));
  EXPECT_TRUE(base::PathExists(new_empty_meta_));
  EXPECT_TRUE(base::PathExists(recent_os_meta_));
  EXPECT_TRUE(base::PathExists(recent_os_log_));
  EXPECT_FALSE(base::PathExists(empty_meta_));
  EXPECT_TRUE(base::PathExists(new_corrupted_meta_));
  EXPECT_FALSE(base::PathExists(old_corrupted_meta_));
  EXPECT_FALSE(base::PathExists(nonexistent_meta_));
  EXPECT_FALSE(base::PathExists(unknown_meta_));
  EXPECT_FALSE(base::PathExists(unknown_xxx_));
  EXPECT_FALSE(base::PathExists(old_incomplete_meta_));
  EXPECT_FALSE(base::PathExists(old_os_meta_));
  EXPECT_FALSE(base::PathExists(root_payload_meta_));
  // Check what files were picked for sending.
  EXPECT_EQ(3, to_send.size());
  EXPECT_EQ(good_meta_.value(), to_send[0].first.value());
  EXPECT_EQ(absolute_meta_.value(), to_send[1].first.value());
  EXPECT_EQ(recent_os_meta_.value(), to_send[2].first.value());

  // Basic check that the valid crash info is returned.
  std::string value;
  EXPECT_EQ(good_log_.value(), to_send[0].second.payload_file.value());
  EXPECT_EQ("log", to_send[0].second.payload_kind);
  EXPECT_TRUE(to_send[0].second.metadata.GetString("payload", &value));

  // All crash files should be removed for an unofficial build.
  ASSERT_TRUE(CreateTestCrashFiles(crash_directory));
  ASSERT_TRUE(SetConditions(kUnofficialBuild, kSignInMode, kMetricsEnabled,
                            raw_metrics_lib));
  to_send.clear();
  sender.RemoveAndPickCrashFiles(crash_directory, &to_send);
  EXPECT_TRUE(base::IsDirectoryEmpty(crash_directory));
  EXPECT_TRUE(to_send.empty());

  // All crash files should be removed if metrics are disabled.
  ASSERT_TRUE(CreateTestCrashFiles(crash_directory));
  ASSERT_TRUE(SetConditions(kOfficialBuild, kSignInMode, kMetricsDisabled,
                            raw_metrics_lib));
  to_send.clear();
  sender.RemoveAndPickCrashFiles(crash_directory, &to_send);
  EXPECT_TRUE(base::IsDirectoryEmpty(crash_directory));
  EXPECT_TRUE(to_send.empty());

  // Valid crash files should be kept in the guest mode, thus the directory
  // won't be empty. None should be selected for sending.
  ASSERT_TRUE(CreateTestCrashFiles(crash_directory));
  ASSERT_TRUE(SetConditions(kOfficialBuild, kGuestMode, kMetricsDisabled,
                            raw_metrics_lib));
  to_send.clear();
  sender.RemoveAndPickCrashFiles(crash_directory, &to_send);
  EXPECT_FALSE(base::IsDirectoryEmpty(crash_directory));
  EXPECT_TRUE(to_send.empty());

  // devcore_meta_ should be included in to_send, if uploading of device
  // coredumps is allowed.
  ASSERT_TRUE(CreateTestCrashFiles(crash_directory));
  ASSERT_TRUE(SetConditions(kOfficialBuild, kSignInMode, kMetricsEnabled,
                            raw_metrics_lib));
  CreateDeviceCoredumpUploadAllowedFile();
  to_send.clear();
  sender.RemoveAndPickCrashFiles(crash_directory, &to_send);
  EXPECT_EQ(4, to_send.size());
  EXPECT_EQ(devcore_meta_.value(), to_send[3].first.value());
}

TEST_F(CrashSenderUtilTest, RemoveReportFiles) {
  Sender::Options options;
  MetricsLibraryMock* raw_metrics_lib = metrics_lib_.get();
  Sender sender(std::move(metrics_lib_),
                std::make_unique<test_util::AdvancingClock>(), options);

  EXPECT_CALL(*raw_metrics_lib,
              SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                            Sender::kTotalRemoval, Sender::kSendReasonCount))
      .Times(1);

  const base::FilePath crash_directory =
      paths::Get(paths::kSystemCrashDirectory);
  ASSERT_TRUE(base::CreateDirectory(crash_directory));

  const base::FilePath foo_meta = crash_directory.Append("foo.meta");
  const base::FilePath foo_log = crash_directory.Append("foo.log");
  const base::FilePath foo_dmp = crash_directory.Append("foo.dmp");
  const base::FilePath bar_log = crash_directory.Append("bar.log");

  ASSERT_TRUE(test_util::CreateFile(foo_meta, ""));
  ASSERT_TRUE(test_util::CreateFile(foo_log, ""));
  ASSERT_TRUE(test_util::CreateFile(foo_dmp, ""));
  ASSERT_TRUE(test_util::CreateFile(bar_log, ""));
  // This should remove foo.*.
  sender.RemoveReportFiles(foo_meta);
  // This should do nothing because the suffix is not ".meta".
  sender.RemoveReportFiles(bar_log);

  // Check what files were removed.
  EXPECT_FALSE(base::PathExists(foo_meta));
  EXPECT_FALSE(base::PathExists(foo_log));
  EXPECT_FALSE(base::PathExists(foo_dmp));
  EXPECT_TRUE(base::PathExists(bar_log));
}

TEST_F(CrashSenderUtilTest, FailRemoveReportFilesSendsMetric) {
  Sender::Options options;
  EXPECT_CALL(*metrics_lib_,
              SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                            Sender::kTotalRemoval, Sender::kSendReasonCount))
      .WillOnce(Return(true));
  EXPECT_CALL(*metrics_lib_,
              SendCrosEventToUMA("Crash.Sender.AttemptedCrashRemoval"))
      .WillOnce(Return(true));
  EXPECT_CALL(*metrics_lib_,
              SendCrosEventToUMA("Crash.Sender.FailedCrashRemoval"))
      .WillOnce(Return(true));

  MockSender sender(true,   // success
                    "123",  // Response (report ID)
                    std::move(metrics_lib_),
                    std::make_unique<test_util::AdvancingClock>(), options);
  // Should return true because the channel is testimage.
  LOG(WARNING) << "Creating release track image";
  ASSERT_TRUE(test_util::CreateFile(
      paths::GetAt(paths::kEtcDirectory, paths::kLsbRelease),
      "CHROMEOS_RELEASE_TRACK=testimage-channel"));
  EXPECT_TRUE(IsTestImage());
  // Set up a crash consent file
  LOG(WARNING) << "Creating consent file";
  ASSERT_TRUE(test_util::CreateFile(
      paths::GetAt(paths::kSystemRunStateDirectory, paths::kMockConsent), ""));
  EXPECT_TRUE(util::HasMockConsent());

  const base::FilePath crash_directory =
      paths::Get(paths::kSystemCrashDirectory);
  ASSERT_FALSE(base::DirectoryExists(crash_directory));
  ASSERT_TRUE(base::CreateDirectory(crash_directory));

  const base::FilePath foo_meta = crash_directory.Append("foo.meta");
  ASSERT_TRUE(test_util::CreateFile(foo_meta, ""));
  const base::FilePath foo_log = crash_directory.Append("foo.log");
  ASSERT_TRUE(test_util::CreateFile(foo_log, ""));

  // chmod the file so RemoveReportFiles fails
  ASSERT_EQ(chmod(crash_directory.value().c_str(), 0500), 0);

  sender.RemoveReportFiles(foo_meta);

  // Clean up after ourselves
  EXPECT_EQ(chmod(crash_directory.value().c_str(), 0700), 0);
  EXPECT_TRUE(base::DeletePathRecursively(crash_directory));
}

TEST_F(CrashSenderUtilTest, GetMetaFiles) {
  const base::FilePath crash_directory =
      paths::Get(paths::kSystemCrashDirectory);
  ASSERT_TRUE(base::CreateDirectory(crash_directory));

  // Use unsorted file names, to check that GetMetaFiles() sort files by
  // timestamps, not file names.
  const base::FilePath meta_1 = crash_directory.Append("a.meta");
  const base::FilePath meta_2 = crash_directory.Append("s.meta");
  const base::FilePath meta_3 = crash_directory.Append("d.meta");
  const base::FilePath meta_4 = crash_directory.Append("f.meta");
  // This one should not appear in the result.
  const base::FilePath metal_5 = crash_directory.Append("g.metal");

  ASSERT_TRUE(test_util::CreateFile(meta_1, ""));
  ASSERT_TRUE(test_util::CreateFile(meta_2, ""));
  ASSERT_TRUE(test_util::CreateFile(meta_3, ""));
  ASSERT_TRUE(test_util::CreateFile(meta_4, ""));
  ASSERT_TRUE(test_util::CreateFile(metal_5, ""));

  // Change timestamps so that meta_1 is the newest and metal_5 is the oldest.
  base::Time now = base::Time::Now();
  ASSERT_TRUE(
      test_util::TouchFileHelper(meta_1, now - base::TimeDelta::FromHours(1)));
  ASSERT_TRUE(
      test_util::TouchFileHelper(meta_2, now - base::TimeDelta::FromHours(2)));
  ASSERT_TRUE(
      test_util::TouchFileHelper(meta_3, now - base::TimeDelta::FromHours(3)));
  ASSERT_TRUE(
      test_util::TouchFileHelper(meta_4, now - base::TimeDelta::FromHours(4)));
  ASSERT_TRUE(
      test_util::TouchFileHelper(metal_5, now - base::TimeDelta::FromHours(5)));

  std::vector<base::FilePath> meta_files = GetMetaFiles(crash_directory);
  ASSERT_EQ(4, meta_files.size());
  // Confirm that files are sorted in the old-to-new order.
  EXPECT_EQ(meta_4.value(), meta_files[0].value());
  EXPECT_EQ(meta_3.value(), meta_files[1].value());
  EXPECT_EQ(meta_2.value(), meta_files[2].value());
  EXPECT_EQ(meta_1.value(), meta_files[3].value());
}

TEST_F(CrashSenderUtilTest, IsTimestampNewEnough) {
  base::FilePath file;
  ASSERT_TRUE(base::CreateTemporaryFileInDir(test_dir_, &file));

  // Should be new enough as it's just created.
  ASSERT_TRUE(IsTimestampNewEnough(file));

  // Make it older than 24 hours.
  const base::Time now = base::Time::Now();
  ASSERT_TRUE(
      test_util::TouchFileHelper(file, now - base::TimeDelta::FromHours(25)));

  // Should be no longer new enough.
  ASSERT_FALSE(IsTimestampNewEnough(file));
}

TEST_F(CrashSenderUtilTest, IsBelowRateReachesMaxRate) {
  const int kMaxRate = 3;
  const int kMaxBytes = 50;
  const base::FilePath timestamp_dir =
      test_dir_.Append("IsBelowRateReachesMaxRate");

  EXPECT_TRUE(IsBelowRate(timestamp_dir, kMaxRate, kMaxBytes));
  RecordSendAttempt(timestamp_dir, kMaxBytes - 5);
  EXPECT_TRUE(IsBelowRate(timestamp_dir, kMaxRate, kMaxBytes));
  RecordSendAttempt(timestamp_dir, kMaxBytes - 5);
  // Exceeds max bytes; should be allowed to upload since we have not hit max
  // rate.
  EXPECT_TRUE(IsBelowRate(timestamp_dir, kMaxRate, kMaxBytes));
  RecordSendAttempt(timestamp_dir, kMaxBytes - 5);

  // Should not pass the rate + byte limit.
  EXPECT_FALSE(IsBelowRate(timestamp_dir, kMaxRate, kMaxBytes));

  // Three files should be created for tracking timestamps.
  std::vector<base::FilePath> files = GetFileNamesIn(timestamp_dir);
  ASSERT_EQ(3, files.size());

  const base::Time now = base::Time::Now();

  // Make one of them older than 24 hours.
  ASSERT_TRUE(test_util::TouchFileHelper(files[0],
                                         now - base::TimeDelta::FromHours(25)));

  // It should now pass the rate limit.
  EXPECT_TRUE(IsBelowRate(timestamp_dir, kMaxRate, kMaxBytes));
  // The old file should now be gone.
  EXPECT_TRUE(!base::PathExists(files[0]));
}

TEST_F(CrashSenderUtilTest, IsBelowRateReachesMaxBytes) {
  const int kMaxRate = 3;
  const int kMaxBytes = 100;
  const base::FilePath timestamp_dir =
      test_dir_.Append("IsBelowRateReachesMaxBytes");

  EXPECT_TRUE(IsBelowRate(timestamp_dir, kMaxRate, kMaxBytes));
  RecordSendAttempt(timestamp_dir, 50);
  EXPECT_TRUE(IsBelowRate(timestamp_dir, kMaxRate, kMaxBytes));
  RecordSendAttempt(timestamp_dir, 20);
  EXPECT_TRUE(IsBelowRate(timestamp_dir, kMaxRate, kMaxBytes));
  RecordSendAttempt(timestamp_dir, 5);
  // Exceeds max rate, but passes because it's below max bytes.
  EXPECT_TRUE(IsBelowRate(timestamp_dir, kMaxRate, kMaxBytes));
  RecordSendAttempt(timestamp_dir, 5);
  EXPECT_TRUE(IsBelowRate(timestamp_dir, kMaxRate, kMaxBytes));
  RecordSendAttempt(timestamp_dir, 20);

  // Exceeds max bytes.
  EXPECT_FALSE(IsBelowRate(timestamp_dir, kMaxRate, kMaxBytes));

  // Make one file older than 24 hours, and we should get some bandwidth
  // marked available again.
  std::vector<base::FilePath> files = GetFileNamesIn(timestamp_dir);
  ASSERT_EQ(5, files.size());
  const base::Time now = base::Time::Now();
  ASSERT_TRUE(test_util::TouchFileHelper(files[0],
                                         now - base::TimeDelta::FromHours(25)));
  EXPECT_TRUE(IsBelowRate(timestamp_dir, kMaxRate, kMaxBytes));
}

TEST_F(CrashSenderUtilTest, SortReports) {
  // Crashes from oldest to youngest will be a, b, c.
  CrashInfo crash_info_a;
  EXPECT_TRUE(base::Time::FromString("15 Nov 2018 12:45:26 GMT",
                                     &crash_info_a.last_modified));
  crash_info_a.metadata.SetString("order", "1");
  MetaFile file_a(base::FilePath("a"), std::move(crash_info_a));

  CrashInfo crash_info_b;
  EXPECT_TRUE(base::Time::FromString("7 Feb 2019 12:45:26 GMT",
                                     &crash_info_b.last_modified));
  crash_info_b.metadata.SetString("order", "2");
  MetaFile file_b(base::FilePath("b"), std::move(crash_info_b));

  CrashInfo crash_info_c;
  EXPECT_TRUE(base::Time::FromString("7 Feb 2019 12:48:26 GMT",
                                     &crash_info_c.last_modified));
  crash_info_c.metadata.SetString("order", "3");
  MetaFile file_c(base::FilePath("c"), std::move(crash_info_c));

  // Add out of order
  std::vector<MetaFile> crashes;
  crashes.emplace_back(std::move(file_c));
  crashes.emplace_back(std::move(file_b));
  crashes.emplace_back(std::move(file_a));
  SortReports(&crashes);

  ASSERT_EQ(crashes.size(), 3);

  EXPECT_EQ(crashes[0].first, base::FilePath("a"));
  std::string order_string;
  EXPECT_TRUE(crashes[0].second.metadata.GetString("order", &order_string));
  EXPECT_EQ(order_string, "1");

  EXPECT_EQ(crashes[1].first, base::FilePath("b"));
  EXPECT_TRUE(crashes[1].second.metadata.GetString("order", &order_string));
  EXPECT_EQ(order_string, "2");

  EXPECT_EQ(crashes[2].first, base::FilePath("c"));
  EXPECT_TRUE(crashes[2].second.metadata.GetString("order", &order_string));
  EXPECT_EQ(order_string, "3");
}

TEST_F(CrashSenderUtilTest, GetUserCrashDirectories) {
  auto mock =
      std::make_unique<org::chromium::SessionManagerInterfaceProxyMock>();
  test_util::SetActiveSessions(mock.get(),
                               {{"user1", "hash1"}, {"user2", "hash2"}});
  Sender::Options options;
  options.session_manager_proxy = mock.release();
  Sender sender(std::move(metrics_lib_),
                std::make_unique<test_util::AdvancingClock>(), options);

  EXPECT_THAT(
      sender.GetUserCrashDirectories(),
      UnorderedElementsAre(paths::Get("/home/user/hash1/crash"),
                           paths::Get("/home/user/hash2/crash"),
                           paths::Get("/run/daemon-store/crash/hash1"),
                           paths::Get("/run/daemon-store/crash/hash2")));
}

enum MissingFile {
  kNone,
  kPayloadFile,
  kLogFile,
  kTextFile,
  kBinFile,
};

class CreateCrashFormDataTest
    : public CrashSenderUtilTest,
      public ::testing::WithParamInterface<std::tuple<bool, MissingFile>> {
 protected:
  void SetUp() override {
    std::tie(absolute_paths_, missing_file_) = GetParam();
    CrashSenderUtilTest::SetUp();
  }
  bool absolute_paths_;
  MissingFile missing_file_;
};

TEST_P(CreateCrashFormDataTest, TestCreateCrashFormData) {
  const base::FilePath system_dir = paths::Get(paths::kSystemCrashDirectory);
  ASSERT_TRUE(base::CreateDirectory(system_dir));

  const base::FilePath payload_file_relative("0.0.0.0.0.payload");
  const base::FilePath payload_file_absolute =
      system_dir.Append(payload_file_relative);
  const std::string payload_contents = "foobar_payload";
  if (missing_file_ != kPayloadFile) {
    ASSERT_TRUE(test_util::CreateFile(payload_file_absolute, payload_contents));
  }
  const base::FilePath& payload_file =
      absolute_paths_ ? payload_file_absolute : payload_file_relative;

  const base::FilePath log_file_relative("0.0.0.0.0.log");
  const base::FilePath log_file_absolute = system_dir.Append(log_file_relative);
  const std::string log_contents = "foobar_log";
  if (missing_file_ != kLogFile) {
    ASSERT_TRUE(test_util::CreateFile(log_file_absolute, log_contents));
  }
  const base::FilePath& log_file =
      absolute_paths_ ? log_file_absolute : log_file_relative;

  const base::FilePath text_var_file_relative("data.txt");
  const base::FilePath text_var_file_absolute =
      system_dir.Append(text_var_file_relative);
  const std::string text_var_contents = "upload_text_contents";
  if (missing_file_ != kTextFile) {
    ASSERT_TRUE(
        test_util::CreateFile(text_var_file_absolute, text_var_contents));
  }
  const base::FilePath& text_var_file =
      absolute_paths_ ? text_var_file_absolute : text_var_file_relative;

  const base::FilePath file_var_file_relative("data.bin");
  const base::FilePath file_var_file_absolute =
      system_dir.Append(file_var_file_relative);
  const std::string file_var_contents = "upload_file_contents";
  if (missing_file_ != kBinFile) {
    ASSERT_TRUE(
        test_util::CreateFile(file_var_file_absolute, file_var_contents));
  }
  const base::FilePath& file_var_file =
      absolute_paths_ ? file_var_file_absolute : file_var_file_relative;

  brillo::KeyValueStore metadata;
  metadata.SetString("exec_name", "fake_exec_name");
  metadata.SetString("ver", "fake_chromeos_ver");
  metadata.SetString("upload_var_prod", "fake_product");
  metadata.SetString("upload_var_ver", "fake_version");
  metadata.SetString("sig", "fake_sig");
  metadata.SetString("upload_var_guid", "SHOULD_NOT_BE_USED");
  metadata.SetString("upload_var_foovar", "bar");
  metadata.SetString("upload_text_footext", text_var_file.value());
  metadata.SetString("upload_file_log", log_file.value());
  metadata.SetString("upload_file_foofile", file_var_file.value());
  metadata.SetString("error_type", "fake_error");

  CrashDetails details = {
      .meta_file = base::FilePath(system_dir).Append("0.0.0.0.0.meta"),
      .payload_file = payload_file,
      .payload_kind = "fake_payload",
      .client_id = kFakeClientId,
      .metadata = metadata,
  };

  Sender::Options options;
  options.form_data_boundary = "boundary";

  Sender sender(nullptr, std::make_unique<test_util::AdvancingClock>(),
                options);

  std::unique_ptr<brillo::http::FormData> form_data =
      sender.CreateCrashFormData(details, nullptr);
  if (missing_file_ == kPayloadFile) {
    EXPECT_EQ(form_data, nullptr);
    return;
  }

  brillo::StreamPtr stream = form_data->ExtractDataStream();
  std::vector<uint8_t> data(stream->GetSize());
  ASSERT_TRUE(stream->ReadAllBlocking(data.data(), data.size(), nullptr));

  std::string expected_data = base::StrCat(
      {"--boundary\r\n"
       "Content-Disposition: form-data; name=\"exec_name\"\r\n"
       "\r\n"
       "fake_exec_name\r\n"
       "--boundary\r\n"
       "Content-Disposition: form-data; name=\"board\"\r\n"
       "\r\n"
       "undefined\r\n"
       "--boundary\r\n"
       "Content-Disposition: form-data; name=\"hwclass\"\r\n"
       "\r\n"
       "undefined\r\n"
       "--boundary\r\n"
       "Content-Disposition: form-data; name=\"prod\"\r\n"
       "\r\n"
       "fake_product\r\n"
       "--boundary\r\n"
       "Content-Disposition: form-data; name=\"ver\"\r\n"
       "\r\n"
       "fake_version\r\n"
       "--boundary\r\n"
       "Content-Disposition: form-data; name=\"sig\"\r\n"
       "\r\n"
       "fake_sig\r\n"
       "--boundary\r\n"
       "Content-Disposition: form-data; name=\"sig2\"\r\n"
       "\r\n"
       "fake_sig\r\n"
       "--boundary\r\n"
       "Content-Disposition: form-data; name=\"upload_file_fake_payload\"; "
       "filename=\"0.0.0.0.0.payload\"\r\n"
       "Content-Transfer-Encoding: binary\r\n"
       "\r\n"
       "foobar_payload\r\n",
       missing_file_ == kTextFile
           ? ""
           : "--boundary\r\n"
             "Content-Disposition: form-data; name=\"footext\"\r\n"
             "\r\n"
             "upload_text_contents\r\n",
       "--boundary\r\n"
       "Content-Disposition: form-data; name=\"foovar\"\r\n"
       "\r\n"
       "bar\r\n",
       missing_file_ == kBinFile
           ? ""
           : "--boundary\r\n"
             "Content-Disposition: form-data; name=\"foofile\"; "
             "filename=\"data.bin\"\r\n"
             "Content-Transfer-Encoding: binary\r\n"
             "\r\n"
             "upload_file_contents\r\n",
       missing_file_ == kLogFile
           ? ""
           : "--boundary\r\n"
             "Content-Disposition: form-data; name=\"log\"; "
             "filename=\"0.0.0.0.0.log\"\r\n"
             "Content-Transfer-Encoding: binary\r\n"
             "\r\n"
             "foobar_log\r\n",
       "--boundary\r\n"
       "Content-Disposition: form-data; name=\"boot_mode\"\r\n"
       "\r\n"
       "missing-crossystem\r\n"
       "--boundary\r\n"
       "Content-Disposition: form-data; name=\"error_type\"\r\n"
       "\r\n"
       "fake_error\r\n"
       "--boundary\r\n"
       "Content-Disposition: form-data; name=\"guid\"\r\n"
       "\r\n"
       "00112233445566778899aabbccddeeff\r\n"
       "--boundary--\r\n"});

  EXPECT_EQ(expected_data, std::string(data.begin(), data.end()));
}

INSTANTIATE_TEST_SUITE_P(
    CreateCrashFormDataInstantiation,
    CreateCrashFormDataTest,
    testing::Combine(
        testing::Bool(),
        testing::Values(kNone, kPayloadFile, kLogFile, kTextFile, kBinFile)));

TEST_F(CrashSenderUtilTest, SendCrashes) {
  // Set up the mock session manager client.
  auto mock =
      std::make_unique<org::chromium::SessionManagerInterfaceProxyMock>();
  test_util::SetActiveSessions(mock.get(), {{"user", "hash"}});
  std::vector<MetaFile> crashes_to_send;

  // Establish the client ID.
  ASSERT_TRUE(CreateClientIdFile());

  // Create the system crash directory, and crash files in it.
  const base::FilePath system_dir = paths::Get(paths::kSystemCrashDirectory);
  ASSERT_TRUE(base::CreateDirectory(system_dir));
  const base::FilePath system_meta_file = system_dir.Append("0.0.0.0.0.meta");
  const base::FilePath system_log = system_dir.Append("0.0.0.0.0.log");
  const base::FilePath system_processing =
      system_dir.Append("0.0.0.0.0.processing");
  const char system_meta[] =
      "payload=0.0.0.0.0.log\n"
      "exec_name=exec_foo\n"
      "fake_report_id=123\n"
      "upload_var_prod=foo\n"
      "done=1\n"
      "upload_var_reportTimeMillis=1000000\n";
  ASSERT_TRUE(test_util::CreateFile(system_meta_file, system_meta));
  ASSERT_TRUE(test_util::CreateFile(system_log, ""));
  CrashInfo system_info;
  EXPECT_TRUE(system_info.metadata.LoadFromString(system_meta));
  system_info.payload_file = system_log;
  system_info.payload_kind = "log";
  EXPECT_TRUE(base::Time::FromString("25 Apr 2018 1:23:44 GMT",
                                     &system_info.last_modified));
  crashes_to_send.emplace_back(system_meta_file, std::move(system_info));

  // Create a user crash directory, and crash files in it.
  const base::FilePath user_dir = paths::Get("/home/user/hash/crash");
  ASSERT_TRUE(base::CreateDirectory(user_dir));
  const base::FilePath user_meta_file = user_dir.Append("0.0.0.0.0.meta");
  const base::FilePath user_log = user_dir.Append("0.0.0.0.0.log");
  const base::FilePath user_processing =
      user_dir.Append("0.0.0.0.0.processing");
  const char user_meta[] =
      "payload=0.0.0.0.0.log\n"
      "exec_name=exec_bar\n"
      "fake_report_id=456\n"
      "upload_var_prod=bar\n"
      "done=1\n"
      "upload_var_reportTimeMillis=2000000\n";
  ASSERT_TRUE(test_util::CreateFile(user_meta_file, user_meta));
  ASSERT_TRUE(test_util::CreateFile(user_log, ""));
  CrashInfo user_info;
  EXPECT_TRUE(user_info.metadata.LoadFromString(user_meta));
  user_info.payload_file = user_log;
  user_info.payload_kind = "log";
  EXPECT_TRUE(base::Time::FromString("25 Apr 2018 1:24:01 GMT",
                                     &user_info.last_modified));
  crashes_to_send.emplace_back(user_meta_file, std::move(user_info));

  // Create another user crash in "user". This will be skipped since the max
  // crash rate will be set to 2.
  const base::FilePath user_meta_file2 = user_dir.Append("1.1.1.1.1.meta");
  const base::FilePath user_log2 = user_dir.Append("1.1.1.1.1.log");
  const char user_meta2[] =
      "payload=1.1.1.1.1.log\n"
      "exec_name=exec_baz\n"
      "fake_report_id=789\n"
      "upload_var_prod=baz\n"
      "done=1\n";
  ASSERT_TRUE(test_util::CreateFile(user_meta_file2, user_meta2));
  ASSERT_TRUE(test_util::CreateFile(user_log2, ""));
  CrashInfo user_info2;
  EXPECT_TRUE(user_info2.metadata.LoadFromString(user_meta2));
  user_info2.payload_file = user_log2;
  user_info2.payload_kind = "log";
  EXPECT_TRUE(base::Time::FromString("25 Apr 2018 1:24:05 GMT",
                                     &user_info2.last_modified));
  crashes_to_send.emplace_back(user_meta_file2, std::move(user_info2));

  // Set up the conditions to emulate a device in guest mode; metrics are
  // disabled in guest mode.
  ASSERT_TRUE(SetConditions(kOfficialBuild, kGuestMode, kMetricsDisabled));
  // Keep the raw pointer, that's needed to exit from guest mode later.
  MetricsLibraryMock* raw_metrics_lib = metrics_lib_.get();

  // Set up the crash sender so that it succeeds.
  SetMockCrashSending(true);

  // Set up the sender.
  std::vector<base::TimeDelta> sleep_times;
  Sender::Options options;
  options.session_manager_proxy = mock.release();
  options.max_crash_rate = 2;
  // Setting max_crash_bytes to 0 will limit to the uploader to max_crash_rate.
  options.max_crash_bytes = 0;
  options.sleep_function = base::Bind(&FakeSleep, &sleep_times);
  options.always_write_uploads_log = true;
  MockSender sender(true /*success*/,
                    "123",  // upload_id
                    std::move(metrics_lib_),
                    std::make_unique<test_util::AdvancingClock>(), options);

  // Send crashes.
  EXPECT_CALL(
      *raw_metrics_lib,
      SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                    Sender::kFinishedUploading, Sender::kSendReasonCount))
      .Times(0);

  sender.SendCrashes(crashes_to_send);
  testing::Mock::VerifyAndClearExpectations(raw_metrics_lib);

  // We shouldn't be processing any crashes still.
  EXPECT_FALSE(base::PathExists(system_processing));
  EXPECT_FALSE(base::PathExists(user_processing));

  // The Chrome uploads.log file shouldn't exist because we had nothing to
  // upload, but we will have slept once until we determined we shouldn't be
  // doing uploads.
  EXPECT_FALSE(base::PathExists(paths::Get(paths::kChromeCrashLog)));
  EXPECT_EQ(1, sleep_times.size());
  sleep_times.clear();

  // Exit from guest mode/re-enable metrics, and send crashes again.
  LOG(INFO) << "Reenabling metrics to send crashes again";
  raw_metrics_lib->set_guest_mode(false);
  raw_metrics_lib->set_metrics_enabled(true);

  // 2 times because there are 2 valid crashes to send
  EXPECT_CALL(
      *raw_metrics_lib,
      SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                    Sender::kFinishedUploading, Sender::kSendReasonCount))
      .Times(2);
  EXPECT_CALL(*raw_metrics_lib,
              SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                            Sender::kTotalRemoval, Sender::kSendReasonCount))
      .Times(2);
  sender.SendCrashes(crashes_to_send);

  // We shouldn't be processing any crashes still.
  EXPECT_FALSE(base::PathExists(system_processing));
  EXPECT_FALSE(base::PathExists(user_processing));

  // Check the upload log from crash_sender.
  std::string contents;
  ASSERT_TRUE(
      base::ReadFileToString(paths::Get(paths::kChromeCrashLog), &contents));
  std::vector<base::Optional<base::Value>> rows =
      ParseChromeUploadsLog(contents);
  // Should only contain two results, since max_crash_rate is set to 2.
  // FakeSleep should be called three times since we sleep before we check the
  // crash rate.
  ASSERT_EQ(2, rows.size());
  EXPECT_EQ(3, sleep_times.size());

  // Each line of the uploads.log file is "{"upload_time":<value>,"upload_id":
  // <value>,"local_id":<value>,"capture_time":<value>,"state":<value>,"source":
  // <value>}".
  // The first run should be for the meta file in the system directory.
  base::Optional<base::Value> row = std::move(rows[0]);
  ASSERT_TRUE(row.has_value());
  ASSERT_EQ(6, row->DictSize());
  EXPECT_TRUE(row->FindKey("upload_time"));
  EXPECT_EQ("123", row->FindKey("upload_id")->GetString());
  EXPECT_EQ("foo", row->FindKey("local_id")->GetString());
  EXPECT_EQ("1000", row->FindKey("capture_time")->GetString());
  EXPECT_EQ(3, row->FindKey("state")->GetInt());
  EXPECT_EQ("exec_foo", row->FindKey("source")->GetString());

  // The second run should be for the meta file in the "user" directory.
  row = std::move(rows[1]);
  ASSERT_TRUE(row.has_value());
  ASSERT_EQ(6, row->DictSize());
  EXPECT_TRUE(row->FindKey("upload_time"));
  EXPECT_EQ("123", row->FindKey("upload_id")
                       ->GetString());  // This is the value we set before
  EXPECT_EQ("bar", row->FindKey("local_id")->GetString());
  EXPECT_EQ("2000", row->FindKey("capture_time")->GetString());
  EXPECT_EQ(3, row->FindKey("state")->GetInt());
  EXPECT_EQ("REDACTED", row->FindKey("source")->GetString());

  // The uploaded crash files should be removed now.
  EXPECT_FALSE(base::PathExists(system_meta_file));
  EXPECT_FALSE(base::PathExists(system_log));
  EXPECT_FALSE(base::PathExists(user_meta_file));
  EXPECT_FALSE(base::PathExists(user_log));

  // The following should be kept since the crash report was not uploaded.
  EXPECT_TRUE(base::PathExists(user_meta_file2));
  EXPECT_TRUE(base::PathExists(user_log2));
}

TEST_F(CrashSenderUtilTest, SendCrashes_TooManyRequests) {
  // Set up the mock session manager client.
  auto mock =
      std::make_unique<org::chromium::SessionManagerInterfaceProxyMock>();
  test_util::SetActiveSessions(mock.get(), {{"user", "hash"}});
  std::vector<MetaFile> crashes_to_send;

  // Establish the client ID.
  ASSERT_TRUE(CreateClientIdFile());

  // Create a user crash directory, and crash files in it.
  const base::FilePath user_dir = paths::Get("/home/user/hash/crash");
  ASSERT_TRUE(base::CreateDirectory(user_dir));
  const base::FilePath user_meta_file = user_dir.Append("0.0.0.0.0.meta");
  const base::FilePath user_log = user_dir.Append("0.0.0.0.0.log");
  const base::FilePath user_processing =
      user_dir.Append("0.0.0.0.0.processing");
  const char user_meta[] =
      "payload=0.0.0.0.0.log\n"
      "exec_name=exec_bar\n"
      "fake_report_id=456\n"
      "upload_var_prod=bar\n"
      "done=1\n"
      "upload_var_reportTimeMillis=2000000\n";
  ASSERT_TRUE(test_util::CreateFile(user_meta_file, user_meta));
  ASSERT_TRUE(test_util::CreateFile(user_log, ""));
  CrashInfo user_info;
  EXPECT_TRUE(user_info.metadata.LoadFromString(user_meta));
  user_info.payload_file = user_log;
  user_info.payload_kind = "log";
  EXPECT_TRUE(base::Time::FromString("25 Apr 2018 1:24:01 GMT",
                                     &user_info.last_modified));
  crashes_to_send.emplace_back(user_meta_file, std::move(user_info));

  // Set up the conditions to emulate a device with metrics enabled.
  ASSERT_TRUE(SetConditions(kOfficialBuild, kSignInMode, kMetricsEnabled));
  // Keep the raw pointer, that's needed to exit from guest mode later.
  MetricsLibraryMock* raw_metrics_lib = metrics_lib_.get();

  // Set up the crash sender so that it succeeds.
  SetMockCrashSending(true);

  // Set up the sender.
  std::vector<base::TimeDelta> sleep_times;
  Sender::Options options;
  options.session_manager_proxy = mock.release();
  options.max_crash_rate = 2;
  // Setting max_crash_bytes to 0 will limit to the uploader to max_crash_rate.
  options.max_crash_bytes = 0;
  options.sleep_function = base::Bind(&FakeSleep, &sleep_times);
  options.always_write_uploads_log = true;
  MockSender sender(false,                // success=false
                    "Too Many Requests",  // Response
                    std::move(metrics_lib_),
                    std::make_unique<test_util::AdvancingClock>(), options);

  // Send crashes.
  EXPECT_CALL(*raw_metrics_lib,
              SendCrosEventToUMA("Crash.Sender.AttemptedCrashRemoval"))
      .WillOnce(Return(true));
  EXPECT_CALL(*raw_metrics_lib,
              SendCrosEventToUMA("Crash.Sender.FailedCrashRemoval"))
      .Times(0);  // We don't expect it to record failure
  EXPECT_CALL(*raw_metrics_lib,
              SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                            Sender::kTotalRemoval, Sender::kSendReasonCount))
      .Times(1);  // Record as if we did all of the uploads
  EXPECT_CALL(*raw_metrics_lib,
              SendEnumToUMA("Platform.CrOS.CrashSenderRemoveReason",
                            Sender::kTooManyRequests, Sender::kSendReasonCount))
      .Times(1);  // We should be removing the Crash after being throttled

  sender.SendCrashes(crashes_to_send);

  // We shouldn't be processing any crashes still.
  EXPECT_FALSE(base::PathExists(user_processing));
}

TEST_F(CrashSenderUtilTest, SendCrashes_Fail) {
  // Set up the mock session manager client.
  auto mock =
      std::make_unique<org::chromium::SessionManagerInterfaceProxyMock>();
  test_util::SetActiveSessions(mock.get(), {{"user", "hash"}});
  std::vector<MetaFile> crashes_to_send;

  // Create the system crash directory, and crash files in it.
  const base::FilePath system_dir = paths::Get(paths::kSystemCrashDirectory);
  ASSERT_TRUE(base::CreateDirectory(system_dir));
  const base::FilePath system_meta_file = system_dir.Append("0.0.0.0.0.meta");
  const base::FilePath system_log = system_dir.Append("0.0.0.0.0.log");
  const base::FilePath system_processing =
      system_dir.Append("0.0.0.0.0.processing");
  const char system_meta[] =
      "payload=0.0.0.0.0.log\n"
      "done=1\n";
  ASSERT_TRUE(test_util::CreateFile(system_meta_file, system_meta));
  ASSERT_TRUE(test_util::CreateFile(system_log, ""));
  CrashInfo system_info;
  EXPECT_TRUE(system_info.metadata.LoadFromString(system_meta));
  system_info.payload_file = system_log;
  system_info.payload_kind = "log";
  EXPECT_TRUE(base::Time::FromString("25 Apr 2018 1:23:44 GMT",
                                     &system_info.last_modified));
  crashes_to_send.emplace_back(system_meta_file, std::move(system_info));

  ASSERT_TRUE(SetConditions(kOfficialBuild, kSignInMode, kMetricsEnabled));

  // Set up the crash sender so that it fails.
  SetMockCrashSending(false);

  // Set up the sender.
  std::vector<base::TimeDelta> sleep_times;
  Sender::Options options;
  options.session_manager_proxy = mock.release();
  options.max_crash_rate = 2;
  options.sleep_function = base::Bind(&FakeSleep, &sleep_times);
  options.always_write_uploads_log = true;
  MockSender sender(false,  // success=false
                    "500",  // Response code
                    std::move(metrics_lib_),
                    std::make_unique<test_util::AdvancingClock>(), options);

  sender.SendCrashes(crashes_to_send);

  // We shouldn't be processing the crash still -- sending failed, but didn't
  // crash.
  EXPECT_FALSE(base::PathExists(system_processing));

  // The followings should be kept since the crash report was not uploaded.
  EXPECT_TRUE(base::PathExists(system_meta_file));
  EXPECT_TRUE(base::PathExists(system_log));

  // The Chrome uploads.log file shouldn't exist because we had nothing to
  // report.
  EXPECT_FALSE(base::PathExists(paths::Get(paths::kChromeCrashLog)));
}

// Verify behavior when SendCrashes itself crashes.
TEST_F(CrashSenderUtilDeathTest, SendCrashes_Crash) {
  // Set up the mock session manager client.
  auto mock =
      std::make_unique<org::chromium::SessionManagerInterfaceProxyMock>();
  test_util::SetActiveSessions(mock.get(), {{"user", "hash"}});
  std::vector<MetaFile> crashes_to_send;

  // Create the system crash directory, and crash files in it.
  const base::FilePath system_dir = paths::Get(paths::kSystemCrashDirectory);
  ASSERT_TRUE(base::CreateDirectory(system_dir));
  const base::FilePath system_meta_file = system_dir.Append("0.0.0.0.0.meta");
  const base::FilePath system_log = system_dir.Append("0.0.0.0.0.log");
  const base::FilePath system_processing =
      system_dir.Append("0.0.0.0.0.processing");
  const char system_meta[] =
      "payload=0.0.0.0.0.log\n"
      "done=1\n";
  ASSERT_TRUE(test_util::CreateFile(system_meta_file, system_meta));
  ASSERT_TRUE(test_util::CreateFile(system_log, ""));
  CrashInfo system_info;
  EXPECT_TRUE(system_info.metadata.LoadFromString(system_meta));
  system_info.payload_file = system_log;
  system_info.payload_kind = "log";
  EXPECT_TRUE(base::Time::FromString("25 Apr 2018 1:23:44 GMT",
                                     &system_info.last_modified));
  crashes_to_send.emplace_back(system_meta_file, std::move(system_info));

  ASSERT_TRUE(SetConditions(kOfficialBuild, kSignInMode, kMetricsEnabled));

  std::vector<base::TimeDelta> sleep_times;
  Sender::Options options;
  options.session_manager_proxy = mock.release();
  options.max_crash_rate = 2;
  options.sleep_function = base::Bind(&FakeSleep, &sleep_times);
  options.always_write_uploads_log = true;
  MockSender sender(true,                 // success=true
                    "Too Many Requests",  // Response
                    std::move(metrics_lib_),
                    std::make_unique<test_util::AdvancingClock>(), options);

  SetMockCrashSending(true);
  sender.SetCrashDuringSendForTesting(true);
  EXPECT_DEATH(sender.SendCrashes(crashes_to_send), "crashing as requested");

  // We crashed, so the ".processing" file should still exist.
  EXPECT_TRUE(base::PathExists(system_processing));
}

TEST_F(CrashSenderUtilTest, LockFile) {
  auto clock = std::make_unique<MockClock>();
  base::Time start_time;
  ASSERT_TRUE(base::Time::FromUTCString("2019-04-20 13:53", &start_time));
  // Called twice -- once to get start time, once to see if we're already
  // past the start time + 5 minutes
  EXPECT_CALL(*clock, Now()).Times(2).WillRepeatedly(Return(start_time));
  std::vector<base::TimeDelta> sleep_times;
  Sender::Options options;
  options.sleep_function = base::Bind(&FakeSleep, &sleep_times);
  Sender sender(std::move(metrics_lib_), std::move(clock), options);

  EXPECT_FALSE(IsFileLocked(paths::Get(paths::kCrashSenderLockFile)));
  base::File lock(sender.AcquireLockFileOrDie());
  EXPECT_TRUE(IsFileLocked(paths::Get(paths::kCrashSenderLockFile)));
  // Should not have slept acquiring lock since the file was unlocked.
  EXPECT_THAT(sleep_times, IsEmpty());
}

TEST_F(CrashSenderUtilTest, LockFileTriesAgainIfFirstAttemptFails) {
  base::FilePath lock_file_path = paths::Get(paths::kCrashSenderLockFile);
  auto lock_process = LockFile(lock_file_path);

  auto clock = std::make_unique<MockClock>();
  base::Time start_time;
  ASSERT_TRUE(base::Time::FromUTCString("2019-04-20 13:53", &start_time));

  // Make AcquireLockFileOrDie sleep several times, and then unlock the file.
  EXPECT_CALL(*clock, Now())
      .WillOnce(Return(start_time))
      .WillOnce(Return(start_time))
      .WillOnce(Return(start_time + base::TimeDelta::FromMinutes(1)))
      .WillOnce(Return(start_time + base::TimeDelta::FromMinutes(2)))
      .WillOnce(Return(start_time + base::TimeDelta::FromMinutes(3)))
      .WillOnce(Invoke([&lock_process, start_time]() {
        lock_process->Kill(SIGKILL, 10);
        lock_process->Wait();
        return start_time + base::TimeDelta::FromMinutes(4);
      }));
  std::vector<base::TimeDelta> sleep_times;
  Sender::Options options;
  options.sleep_function = base::Bind(&FakeSleep, &sleep_times);
  Sender sender(std::move(metrics_lib_), std::move(clock), options);

  base::File lock(sender.AcquireLockFileOrDie());
  EXPECT_TRUE(IsFileLocked(lock_file_path));
  EXPECT_EQ(sleep_times.size(), 4);
}

TEST_F(CrashSenderUtilTest, LockFileTriesOneLastTimeAfterTimeout) {
  base::FilePath lock_file_path = paths::Get(paths::kCrashSenderLockFile);
  auto lock_process = LockFile(lock_file_path);

  auto clock = std::make_unique<MockClock>();
  base::Time start_time;
  ASSERT_TRUE(base::Time::FromUTCString("2019-04-20 13:53", &start_time));

  // Make AcquireLockFileOrDie sleep enough that the loop exits, then unlock the
  // file.
  EXPECT_CALL(*clock, Now())
      .WillOnce(Return(start_time))
      .WillOnce(Return(start_time))
      .WillOnce(Return(start_time + base::TimeDelta::FromMinutes(1)))
      .WillOnce(Return(start_time + base::TimeDelta::FromMinutes(2)))
      .WillOnce(Return(start_time + base::TimeDelta::FromMinutes(3)))
      .WillOnce(Return(start_time + base::TimeDelta::FromMinutes(4)))
      .WillOnce(Invoke([&lock_process, start_time]() {
        lock_process->Kill(SIGKILL, 10);
        lock_process->Wait();
        return start_time + base::TimeDelta::FromMinutes(6);
      }));
  std::vector<base::TimeDelta> sleep_times;
  Sender::Options options;
  options.sleep_function = base::Bind(&FakeSleep, &sleep_times);
  Sender sender(std::move(metrics_lib_), std::move(clock), options);

  base::File lock(sender.AcquireLockFileOrDie());
  EXPECT_TRUE(IsFileLocked(lock_file_path));
  EXPECT_EQ(sleep_times.size(), 5);
}

TEST_F(CrashSenderUtilDeathTest, LockFileDiesIfFileIsLocked) {
  base::FilePath lock_file_path = paths::Get(paths::kCrashSenderLockFile);
  auto lock_process = LockFile(lock_file_path);
  std::vector<base::TimeDelta> sleep_times;
  Sender::Options options;
  options.sleep_function = base::Bind(&FakeSleep, &sleep_times);
  Sender sender(std::move(metrics_lib_),
                std::make_unique<test_util::AdvancingClock>(), options);
  EXPECT_EXIT(sender.AcquireLockFileOrDie(), ExitedWithCode(EXIT_FAILURE),
              "Failed to acquire a lock");
}

class IsNetworkOnlineTest : public CrashSenderUtilTest {
 public:
  void TestIsNetworkOnline(std::string connection_state,
                           bool get_properties_retval,
                           bool expected_result);
};

void IsNetworkOnlineTest::TestIsNetworkOnline(std::string connection_state,
                                              bool get_properties_retval,
                                              bool expected_result) {
  g_connection_state = &connection_state;
  // Set up the shill flimflam manager client.
  auto mock = std::make_unique<org::chromium::flimflam::ManagerProxyMock>();
  EXPECT_CALL(*mock, GetProperties(_, _, _))
      .WillOnce(
          DoAll(Invoke(&GetShillProperties), Return(get_properties_retval)));

  Sender::Options options;
  options.shill_proxy = mock.release();
  Sender sender(std::move(metrics_lib_),
                std::make_unique<test_util::AdvancingClock>(), options);
  EXPECT_EQ(sender.IsNetworkOnline(), expected_result);
}

TEST_F(IsNetworkOnlineTest, Online) {
  TestIsNetworkOnline("online", true, true);
}

TEST_F(IsNetworkOnlineTest, Offline) {
  TestIsNetworkOnline("offline", true, false);
}

TEST_F(IsNetworkOnlineTest, Fail) {
  TestIsNetworkOnline("", false, true);
}

}  // namespace util
