// Copyright 2015 The Crashpad Authors. All rights reserved.
//
// 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 "client/crash_report_database.h"

#include "build/build_config.h"
#include "client/settings.h"
#include "gtest/gtest.h"
#include "test/errors.h"
#include "test/file.h"
#include "test/filesystem.h"
#include "test/scoped_temp_dir.h"
#include "util/file/file_io.h"
#include "util/file/filesystem.h"

namespace crashpad {
namespace test {
namespace {

class CrashReportDatabaseTest : public testing::Test {
 public:
  CrashReportDatabaseTest() {
  }

 protected:
  // testing::Test:
  void SetUp() override {
    db_ = CrashReportDatabase::Initialize(path());
    ASSERT_TRUE(db_);
  }

  void ResetDatabase() {
    db_.reset();
  }

  CrashReportDatabase* db() { return db_.get(); }
  base::FilePath path() const {
    return temp_dir_.path().Append(FILE_PATH_LITERAL("crashpad_test_database"));
  }

  void CreateCrashReport(CrashReportDatabase::Report* report) {
    std::unique_ptr<CrashReportDatabase::NewReport> new_report;
    ASSERT_EQ(db_->PrepareNewCrashReport(&new_report),
              CrashReportDatabase::kNoError);
    static constexpr char kTest[] = "test";
    ASSERT_TRUE(new_report->Writer()->Write(kTest, sizeof(kTest)));

    UUID uuid;
    EXPECT_EQ(db_->FinishedWritingCrashReport(std::move(new_report), &uuid),
              CrashReportDatabase::kNoError);

    EXPECT_EQ(db_->LookUpCrashReport(uuid, report),
              CrashReportDatabase::kNoError);
    ExpectPreparedCrashReport(*report);
  }

  void UploadReport(const UUID& uuid, bool successful, const std::string& id) {
    Settings* const settings = db_->GetSettings();
    ASSERT_TRUE(settings);
    time_t times[2];
    ASSERT_TRUE(settings->GetLastUploadAttemptTime(&times[0]));

    std::unique_ptr<const CrashReportDatabase::UploadReport> report;
    ASSERT_EQ(db_->GetReportForUploading(uuid, &report),
              CrashReportDatabase::kNoError);
    EXPECT_NE(report->uuid, UUID());
    EXPECT_FALSE(report->file_path.empty());
    EXPECT_TRUE(FileExists(report->file_path)) << report->file_path.value();
    EXPECT_GT(report->creation_time, 0);
    if (successful) {
      EXPECT_EQ(db_->RecordUploadComplete(std::move(report), id),
                CrashReportDatabase::kNoError);
    } else {
      report.reset();
    }

    ASSERT_TRUE(settings->GetLastUploadAttemptTime(&times[1]));
    EXPECT_NE(times[1], 0);
    EXPECT_GE(times[1], times[0]);
  }

  void ExpectPreparedCrashReport(const CrashReportDatabase::Report& report) {
    EXPECT_NE(report.uuid, UUID());
    EXPECT_FALSE(report.file_path.empty());
    EXPECT_TRUE(FileExists(report.file_path)) << report.file_path.value();
    EXPECT_TRUE(report.id.empty());
    EXPECT_GT(report.creation_time, 0);
    EXPECT_FALSE(report.uploaded);
    EXPECT_EQ(report.last_upload_attempt_time, 0);
    EXPECT_EQ(report.upload_attempts, 0);
    EXPECT_FALSE(report.upload_explicitly_requested);
  }

  void RelocateDatabase() {
    ResetDatabase();
    temp_dir_.Rename();
    SetUp();
  }

  CrashReportDatabase::OperationStatus RequestUpload(const UUID& uuid) {
    CrashReportDatabase::OperationStatus os = db()->RequestUpload(uuid);

    CrashReportDatabase::Report report;
    EXPECT_EQ(db_->LookUpCrashReport(uuid, &report),
              CrashReportDatabase::kNoError);

    return os;
  }

 private:
  ScopedTempDir temp_dir_;
  std::unique_ptr<CrashReportDatabase> db_;

  DISALLOW_COPY_AND_ASSIGN(CrashReportDatabaseTest);
};

TEST_F(CrashReportDatabaseTest, Initialize) {
  // Initialize the database for the first time, creating it.
  ASSERT_TRUE(db());

  Settings* settings = db()->GetSettings();

  UUID client_ids[3];
  ASSERT_TRUE(settings->GetClientID(&client_ids[0]));
  EXPECT_NE(client_ids[0], UUID());

  time_t last_upload_attempt_time;
  ASSERT_TRUE(settings->GetLastUploadAttemptTime(&last_upload_attempt_time));
  EXPECT_EQ(last_upload_attempt_time, 0);

  // Close and reopen the database at the same path.
  ResetDatabase();
  EXPECT_FALSE(db());
  auto db = CrashReportDatabase::InitializeWithoutCreating(path());
  ASSERT_TRUE(db);

  settings = db->GetSettings();

  ASSERT_TRUE(settings->GetClientID(&client_ids[1]));
  EXPECT_EQ(client_ids[1], client_ids[0]);

  ASSERT_TRUE(settings->GetLastUploadAttemptTime(&last_upload_attempt_time));
  EXPECT_EQ(last_upload_attempt_time, 0);

  // Check that the database can also be opened by the method that is permitted
  // to create it.
  db = CrashReportDatabase::Initialize(path());
  ASSERT_TRUE(db);

  settings = db->GetSettings();

  ASSERT_TRUE(settings->GetClientID(&client_ids[2]));
  EXPECT_EQ(client_ids[2], client_ids[0]);

  ASSERT_TRUE(settings->GetLastUploadAttemptTime(&last_upload_attempt_time));
  EXPECT_EQ(last_upload_attempt_time, 0);

  std::vector<CrashReportDatabase::Report> reports;
  EXPECT_EQ(db->GetPendingReports(&reports), CrashReportDatabase::kNoError);
  EXPECT_TRUE(reports.empty());
  reports.clear();
  EXPECT_EQ(db->GetCompletedReports(&reports), CrashReportDatabase::kNoError);
  EXPECT_TRUE(reports.empty());

  // InitializeWithoutCreating() shouldn’t create a nonexistent database.
  base::FilePath non_database_path =
      path().DirName().Append(FILE_PATH_LITERAL("not_a_database"));
  db = CrashReportDatabase::InitializeWithoutCreating(non_database_path);
  EXPECT_FALSE(db);
}

TEST_F(CrashReportDatabaseTest, NewCrashReport) {
  std::unique_ptr<CrashReportDatabase::NewReport> new_report;
  EXPECT_EQ(db()->PrepareNewCrashReport(&new_report),
            CrashReportDatabase::kNoError);
  UUID expect_uuid = new_report->ReportID();
  UUID uuid;
  EXPECT_EQ(db()->FinishedWritingCrashReport(std::move(new_report), &uuid),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(uuid, expect_uuid);

  CrashReportDatabase::Report report;
  EXPECT_EQ(db()->LookUpCrashReport(uuid, &report),
            CrashReportDatabase::kNoError);
  ExpectPreparedCrashReport(report);

  std::vector<CrashReportDatabase::Report> reports;
  EXPECT_EQ(db()->GetPendingReports(&reports), CrashReportDatabase::kNoError);
  ASSERT_EQ(reports.size(), 1u);
  EXPECT_EQ(reports[0].uuid, report.uuid);

  reports.clear();
  EXPECT_EQ(db()->GetCompletedReports(&reports), CrashReportDatabase::kNoError);
  EXPECT_TRUE(reports.empty());
}

TEST_F(CrashReportDatabaseTest, LookUpCrashReport) {
  UUID uuid;

  {
    CrashReportDatabase::Report report;
    CreateCrashReport(&report);
    uuid = report.uuid;
  }

  {
    CrashReportDatabase::Report report;
    EXPECT_EQ(db()->LookUpCrashReport(uuid, &report),
              CrashReportDatabase::kNoError);
    EXPECT_EQ(report.uuid, uuid);
    EXPECT_NE(report.file_path.value().find(path().value()), std::string::npos);
    EXPECT_EQ(report.id, std::string());
    EXPECT_FALSE(report.uploaded);
    EXPECT_EQ(report.last_upload_attempt_time, 0);
    EXPECT_EQ(report.upload_attempts, 0);
    EXPECT_FALSE(report.upload_explicitly_requested);
  }

  UploadReport(uuid, true, "test");

  {
    CrashReportDatabase::Report report;
    EXPECT_EQ(db()->LookUpCrashReport(uuid, &report),
              CrashReportDatabase::kNoError);
    EXPECT_EQ(report.uuid, uuid);
    EXPECT_NE(report.file_path.value().find(path().value()), std::string::npos);
    EXPECT_EQ(report.id, "test");
    EXPECT_TRUE(report.uploaded);
    EXPECT_NE(report.last_upload_attempt_time, 0);
    EXPECT_EQ(report.upload_attempts, 1);
    EXPECT_FALSE(report.upload_explicitly_requested);
  }
}

TEST_F(CrashReportDatabaseTest, RecordUploadAttempt) {
  std::vector<CrashReportDatabase::Report> reports(3);
  CreateCrashReport(&reports[0]);
  CreateCrashReport(&reports[1]);
  CreateCrashReport(&reports[2]);

  // Record two attempts: one successful, one not.
  UploadReport(reports[1].uuid, false, std::string());
  UploadReport(reports[2].uuid, true, "abc123");

  std::vector<CrashReportDatabase::Report> query(3);
  EXPECT_EQ(db()->LookUpCrashReport(reports[0].uuid, &query[0]),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(db()->LookUpCrashReport(reports[1].uuid, &query[1]),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(db()->LookUpCrashReport(reports[2].uuid, &query[2]),
            CrashReportDatabase::kNoError);

  EXPECT_EQ(query[0].id, std::string());
  EXPECT_EQ(query[1].id, std::string());
  EXPECT_EQ(query[2].id, "abc123");

  EXPECT_FALSE(query[0].uploaded);
  EXPECT_FALSE(query[1].uploaded);
  EXPECT_TRUE(query[2].uploaded);

  EXPECT_EQ(query[0].last_upload_attempt_time, 0);
  EXPECT_NE(query[1].last_upload_attempt_time, 0);
  EXPECT_NE(query[2].last_upload_attempt_time, 0);

  EXPECT_EQ(query[0].upload_attempts, 0);
  EXPECT_EQ(query[1].upload_attempts, 1);
  EXPECT_EQ(query[2].upload_attempts, 1);

  // Attempt to upload and fail again.
  UploadReport(reports[1].uuid, false, std::string());

  time_t report_2_upload_time = query[2].last_upload_attempt_time;

  EXPECT_EQ(db()->LookUpCrashReport(reports[0].uuid, &query[0]),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(db()->LookUpCrashReport(reports[1].uuid, &query[1]),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(db()->LookUpCrashReport(reports[2].uuid, &query[2]),
            CrashReportDatabase::kNoError);

  EXPECT_FALSE(query[0].uploaded);
  EXPECT_FALSE(query[1].uploaded);
  EXPECT_TRUE(query[2].uploaded);

  EXPECT_EQ(query[0].last_upload_attempt_time, 0);
  EXPECT_GE(query[1].last_upload_attempt_time, report_2_upload_time);
  EXPECT_EQ(query[2].last_upload_attempt_time, report_2_upload_time);

  EXPECT_EQ(query[0].upload_attempts, 0);
  EXPECT_EQ(query[1].upload_attempts, 2);
  EXPECT_EQ(query[2].upload_attempts, 1);

  // Third time's the charm: upload and succeed.
  UploadReport(reports[1].uuid, true, "666hahaha");

  time_t report_1_upload_time = query[1].last_upload_attempt_time;

  EXPECT_EQ(db()->LookUpCrashReport(reports[0].uuid, &query[0]),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(db()->LookUpCrashReport(reports[1].uuid, &query[1]),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(db()->LookUpCrashReport(reports[2].uuid, &query[2]),
            CrashReportDatabase::kNoError);

  EXPECT_FALSE(query[0].uploaded);
  EXPECT_TRUE(query[1].uploaded);
  EXPECT_TRUE(query[2].uploaded);

  EXPECT_EQ(query[0].last_upload_attempt_time, 0);
  EXPECT_GE(query[1].last_upload_attempt_time, report_1_upload_time);
  EXPECT_EQ(query[2].last_upload_attempt_time, report_2_upload_time);

  EXPECT_EQ(query[0].upload_attempts, 0);
  EXPECT_EQ(query[1].upload_attempts, 3);
  EXPECT_EQ(query[2].upload_attempts, 1);
}

// This test covers both query functions since they are related.
TEST_F(CrashReportDatabaseTest, GetCompletedAndNotUploadedReports) {
  std::vector<CrashReportDatabase::Report> reports(5);
  CreateCrashReport(&reports[0]);
  CreateCrashReport(&reports[1]);
  CreateCrashReport(&reports[2]);
  CreateCrashReport(&reports[3]);
  CreateCrashReport(&reports[4]);

  const UUID& report_0_uuid = reports[0].uuid;
  const UUID& report_1_uuid = reports[1].uuid;
  const UUID& report_2_uuid = reports[2].uuid;
  const UUID& report_3_uuid = reports[3].uuid;
  const UUID& report_4_uuid = reports[4].uuid;

  std::vector<CrashReportDatabase::Report> pending;
  EXPECT_EQ(db()->GetPendingReports(&pending), CrashReportDatabase::kNoError);

  std::vector<CrashReportDatabase::Report> completed;
  EXPECT_EQ(db()->GetCompletedReports(&completed),
            CrashReportDatabase::kNoError);

  EXPECT_EQ(pending.size(), reports.size());
  EXPECT_EQ(completed.size(), 0u);

  // Upload one report successfully.
  UploadReport(report_1_uuid, true, "report1");

  pending.clear();
  EXPECT_EQ(db()->GetPendingReports(&pending), CrashReportDatabase::kNoError);
  completed.clear();
  EXPECT_EQ(db()->GetCompletedReports(&completed),
            CrashReportDatabase::kNoError);

  EXPECT_EQ(pending.size(), 4u);
  ASSERT_EQ(completed.size(), 1u);

  for (const auto& report : pending) {
    EXPECT_NE(report.uuid, report_1_uuid);
    EXPECT_FALSE(report.file_path.empty());
  }
  EXPECT_EQ(completed[0].uuid, report_1_uuid);
  EXPECT_EQ(completed[0].id, "report1");
  EXPECT_EQ(completed[0].uploaded, true);
  EXPECT_GT(completed[0].last_upload_attempt_time, 0);
  EXPECT_EQ(completed[0].upload_attempts, 1);

  // Fail to upload one report.
  UploadReport(report_2_uuid, false, std::string());

  pending.clear();
  EXPECT_EQ(db()->GetPendingReports(&pending), CrashReportDatabase::kNoError);
  completed.clear();
  EXPECT_EQ(db()->GetCompletedReports(&completed),
            CrashReportDatabase::kNoError);

  EXPECT_EQ(pending.size(), 4u);
  ASSERT_EQ(completed.size(), 1u);

  for (const auto& report : pending) {
    if (report.upload_attempts != 0) {
      EXPECT_EQ(report.uuid, report_2_uuid);
      EXPECT_GT(report.last_upload_attempt_time, 0);
      EXPECT_FALSE(report.uploaded);
      EXPECT_TRUE(report.id.empty());
    }
    EXPECT_FALSE(report.file_path.empty());
  }

  // Upload a second report.
  UploadReport(report_4_uuid, true, "report_4");

  pending.clear();
  EXPECT_EQ(db()->GetPendingReports(&pending), CrashReportDatabase::kNoError);
  completed.clear();
  EXPECT_EQ(db()->GetCompletedReports(&completed),
            CrashReportDatabase::kNoError);

  EXPECT_EQ(pending.size(), 3u);
  ASSERT_EQ(completed.size(), 2u);

  // Succeed the failed report.
  UploadReport(report_2_uuid, true, "report 2");

  pending.clear();
  EXPECT_EQ(db()->GetPendingReports(&pending), CrashReportDatabase::kNoError);
  completed.clear();
  EXPECT_EQ(db()->GetCompletedReports(&completed),
            CrashReportDatabase::kNoError);

  EXPECT_EQ(pending.size(), 2u);
  ASSERT_EQ(completed.size(), 3u);

  for (const auto& report : pending) {
    EXPECT_TRUE(report.uuid == report_0_uuid || report.uuid == report_3_uuid);
    EXPECT_FALSE(report.file_path.empty());
  }

  // Skip upload for one report.
  EXPECT_EQ(db()->SkipReportUpload(
                report_3_uuid, Metrics::CrashSkippedReason::kUploadsDisabled),
            CrashReportDatabase::kNoError);

  pending.clear();
  EXPECT_EQ(db()->GetPendingReports(&pending), CrashReportDatabase::kNoError);
  completed.clear();
  EXPECT_EQ(db()->GetCompletedReports(&completed),
            CrashReportDatabase::kNoError);

  ASSERT_EQ(pending.size(), 1u);
  ASSERT_EQ(completed.size(), 4u);

  EXPECT_EQ(pending[0].uuid, report_0_uuid);

  for (const auto& report : completed) {
    if (report.uuid == report_3_uuid) {
      EXPECT_FALSE(report.uploaded);
      EXPECT_EQ(report.upload_attempts, 0);
      EXPECT_EQ(report.last_upload_attempt_time, 0);
    } else {
      EXPECT_TRUE(report.uploaded);
      EXPECT_GT(report.upload_attempts, 0);
      EXPECT_GT(report.last_upload_attempt_time, 0);
    }
    EXPECT_FALSE(report.file_path.empty());
  }
}

TEST_F(CrashReportDatabaseTest, DuelingUploads) {
  CrashReportDatabase::Report report;
  CreateCrashReport(&report);

  std::unique_ptr<const CrashReportDatabase::UploadReport> upload_report;
  EXPECT_EQ(db()->GetReportForUploading(report.uuid, &upload_report),
            CrashReportDatabase::kNoError);

  std::unique_ptr<const CrashReportDatabase::UploadReport> upload_report_2;
  EXPECT_EQ(db()->GetReportForUploading(report.uuid, &upload_report_2),
            CrashReportDatabase::kBusyError);
  EXPECT_FALSE(upload_report_2);

  EXPECT_EQ(db()->RecordUploadComplete(std::move(upload_report), std::string()),
            CrashReportDatabase::kNoError);
}

TEST_F(CrashReportDatabaseTest, UploadAlreadyUploaded) {
  CrashReportDatabase::Report report;
  CreateCrashReport(&report);

  std::unique_ptr<const CrashReportDatabase::UploadReport> upload_report;
  EXPECT_EQ(db()->GetReportForUploading(report.uuid, &upload_report),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(db()->RecordUploadComplete(std::move(upload_report), std::string()),
            CrashReportDatabase::kNoError);

  std::unique_ptr<const CrashReportDatabase::UploadReport> upload_report_2;
  EXPECT_EQ(db()->GetReportForUploading(report.uuid, &upload_report_2),
            CrashReportDatabase::kReportNotFound);
  EXPECT_FALSE(upload_report_2.get());
}

TEST_F(CrashReportDatabaseTest, MoveDatabase) {
  std::unique_ptr<CrashReportDatabase::NewReport> new_report;
  EXPECT_EQ(db()->PrepareNewCrashReport(&new_report),
            CrashReportDatabase::kNoError);
  UUID uuid;
  EXPECT_EQ(db()->FinishedWritingCrashReport(std::move(new_report), &uuid),
            CrashReportDatabase::kNoError);

  RelocateDatabase();

  CrashReportDatabase::Report report;
  EXPECT_EQ(db()->LookUpCrashReport(uuid, &report),
            CrashReportDatabase::kNoError);
  ExpectPreparedCrashReport(report);
}

TEST_F(CrashReportDatabaseTest, ReportRemoved) {
  std::unique_ptr<CrashReportDatabase::NewReport> new_report;
  EXPECT_EQ(db()->PrepareNewCrashReport(&new_report),
            CrashReportDatabase::kNoError);

  UUID uuid;
  EXPECT_EQ(db()->FinishedWritingCrashReport(std::move(new_report), &uuid),
            CrashReportDatabase::kNoError);

  CrashReportDatabase::Report report;
  EXPECT_EQ(db()->LookUpCrashReport(uuid, &report),
            CrashReportDatabase::kNoError);

  EXPECT_TRUE(LoggingRemoveFile(report.file_path));

  EXPECT_EQ(db()->LookUpCrashReport(uuid, &report),
            CrashReportDatabase::kReportNotFound);
}

TEST_F(CrashReportDatabaseTest, DeleteReport) {
  CrashReportDatabase::Report keep_pending;
  CrashReportDatabase::Report delete_pending;
  CrashReportDatabase::Report keep_completed;
  CrashReportDatabase::Report delete_completed;

  CreateCrashReport(&keep_pending);
  CreateCrashReport(&delete_pending);
  CreateCrashReport(&keep_completed);
  CreateCrashReport(&delete_completed);

  EXPECT_TRUE(FileExists(keep_pending.file_path));
  EXPECT_TRUE(FileExists(delete_pending.file_path));
  EXPECT_TRUE(FileExists(keep_completed.file_path));
  EXPECT_TRUE(FileExists(delete_completed.file_path));

  UploadReport(keep_completed.uuid, true, "1");
  UploadReport(delete_completed.uuid, true, "2");

  EXPECT_EQ(db()->LookUpCrashReport(keep_completed.uuid, &keep_completed),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(db()->LookUpCrashReport(delete_completed.uuid, &delete_completed),
            CrashReportDatabase::kNoError);

  EXPECT_TRUE(FileExists(keep_completed.file_path));
  EXPECT_TRUE(FileExists(delete_completed.file_path));

  EXPECT_EQ(db()->DeleteReport(delete_pending.uuid),
            CrashReportDatabase::kNoError);
  EXPECT_FALSE(FileExists(delete_pending.file_path));
  EXPECT_EQ(db()->LookUpCrashReport(delete_pending.uuid, &delete_pending),
            CrashReportDatabase::kReportNotFound);
  EXPECT_EQ(db()->DeleteReport(delete_pending.uuid),
            CrashReportDatabase::kReportNotFound);

  EXPECT_EQ(db()->DeleteReport(delete_completed.uuid),
            CrashReportDatabase::kNoError);
  EXPECT_FALSE(FileExists(delete_completed.file_path));
  EXPECT_EQ(db()->LookUpCrashReport(delete_completed.uuid, &delete_completed),
            CrashReportDatabase::kReportNotFound);
  EXPECT_EQ(db()->DeleteReport(delete_completed.uuid),
            CrashReportDatabase::kReportNotFound);

  EXPECT_EQ(db()->LookUpCrashReport(keep_pending.uuid, &keep_pending),
            CrashReportDatabase::kNoError);
  EXPECT_EQ(db()->LookUpCrashReport(keep_completed.uuid, &keep_completed),
            CrashReportDatabase::kNoError);
}

TEST_F(CrashReportDatabaseTest, DeleteReportEmptyingDatabase) {
  CrashReportDatabase::Report report;
  CreateCrashReport(&report);

  EXPECT_TRUE(FileExists(report.file_path));

  UploadReport(report.uuid, true, "1");

  EXPECT_EQ(db()->LookUpCrashReport(report.uuid, &report),
            CrashReportDatabase::kNoError);

  EXPECT_TRUE(FileExists(report.file_path));

  // This causes an empty database to be written, make sure this is handled.
  EXPECT_EQ(db()->DeleteReport(report.uuid), CrashReportDatabase::kNoError);
  EXPECT_FALSE(FileExists(report.file_path));
}

TEST_F(CrashReportDatabaseTest, ReadEmptyDatabase) {
  CrashReportDatabase::Report report;
  CreateCrashReport(&report);
  EXPECT_EQ(db()->DeleteReport(report.uuid), CrashReportDatabase::kNoError);

  // Deleting and the creating another report causes an empty database to be
  // loaded. Make sure this is handled.

  CrashReportDatabase::Report report2;
  CreateCrashReport(&report2);
}

TEST_F(CrashReportDatabaseTest, RequestUpload) {
  std::vector<CrashReportDatabase::Report> reports(2);
  CreateCrashReport(&reports[0]);
  CreateCrashReport(&reports[1]);

  const UUID& report_0_uuid = reports[0].uuid;
  const UUID& report_1_uuid = reports[1].uuid;

  // Skipped report gets back to pending state after RequestUpload is called.
  EXPECT_EQ(db()->SkipReportUpload(
                report_1_uuid, Metrics::CrashSkippedReason::kUploadsDisabled),
            CrashReportDatabase::kNoError);

  std::vector<CrashReportDatabase::Report> pending_reports;
  CrashReportDatabase::OperationStatus os =
      db()->GetPendingReports(&pending_reports);
  EXPECT_EQ(os, CrashReportDatabase::kNoError);
  ASSERT_EQ(pending_reports.size(), 1u);
  EXPECT_EQ(report_0_uuid, pending_reports[0].uuid);

  pending_reports.clear();
  EXPECT_EQ(RequestUpload(report_1_uuid), CrashReportDatabase::kNoError);
  os = db()->GetPendingReports(&pending_reports);
  EXPECT_EQ(os, CrashReportDatabase::kNoError);
  ASSERT_EQ(pending_reports.size(), 2u);

  // Check individual reports.
  const CrashReportDatabase::Report* explicitly_requested_report;
  const CrashReportDatabase::Report* pending_report;
  if (pending_reports[0].uuid == report_0_uuid) {
    pending_report = &pending_reports[0];
    explicitly_requested_report = &pending_reports[1];
  } else {
    pending_report = &pending_reports[1];
    explicitly_requested_report = &pending_reports[0];
  }

  EXPECT_EQ(pending_report->uuid, report_0_uuid);
  EXPECT_FALSE(pending_report->upload_explicitly_requested);

  EXPECT_EQ(explicitly_requested_report->uuid, report_1_uuid);
  EXPECT_TRUE(explicitly_requested_report->upload_explicitly_requested);

  // Explicitly requested reports will not have upload_explicitly_requested bit
  // after getting skipped.
  EXPECT_EQ(db()->SkipReportUpload(
                report_1_uuid, Metrics::CrashSkippedReason::kUploadsDisabled),
            CrashReportDatabase::kNoError);
  CrashReportDatabase::Report report;
  EXPECT_EQ(db()->LookUpCrashReport(report_1_uuid, &report),
            CrashReportDatabase::kNoError);
  EXPECT_FALSE(report.upload_explicitly_requested);

  // Pending report gets correctly affected after RequestUpload is called.
  pending_reports.clear();
  EXPECT_EQ(RequestUpload(report_0_uuid), CrashReportDatabase::kNoError);
  os = db()->GetPendingReports(&pending_reports);
  EXPECT_EQ(os, CrashReportDatabase::kNoError);
  EXPECT_EQ(pending_reports.size(), 1u);
  EXPECT_EQ(report_0_uuid, pending_reports[0].uuid);
  EXPECT_TRUE(pending_reports[0].upload_explicitly_requested);

  // Already uploaded report cannot be requested for the new upload.
  UploadReport(report_0_uuid, true, "1");
  EXPECT_EQ(RequestUpload(report_0_uuid),
            CrashReportDatabase::kCannotRequestUpload);
}

// This test uses knowledge of the database format to break it, so it only
// applies to the unfified database implementation.
#if !defined(OS_MACOSX) && !defined(OS_WIN)
TEST_F(CrashReportDatabaseTest, CleanBrokenDatabase) {
  // Remove report files if metadata goes missing.
  CrashReportDatabase::Report report;
  ASSERT_NO_FATAL_FAILURE(CreateCrashReport(&report));

  const base::FilePath metadata(
      report.file_path.RemoveFinalExtension().value() +
      FILE_PATH_LITERAL(".meta"));
  ASSERT_TRUE(PathExists(report.file_path));
  ASSERT_TRUE(PathExists(metadata));

  ASSERT_TRUE(LoggingRemoveFile(metadata));
  EXPECT_EQ(db()->CleanDatabase(0), 1);

  EXPECT_FALSE(PathExists(report.file_path));
  EXPECT_FALSE(PathExists(metadata));

  // Remove metadata files if reports go missing.
  ASSERT_NO_FATAL_FAILURE(CreateCrashReport(&report));
  const base::FilePath metadata2(
      report.file_path.RemoveFinalExtension().value() +
      FILE_PATH_LITERAL(".meta"));
  ASSERT_TRUE(PathExists(report.file_path));
  ASSERT_TRUE(PathExists(metadata2));

  ASSERT_TRUE(LoggingRemoveFile(report.file_path));
  EXPECT_EQ(db()->CleanDatabase(0), 1);

  EXPECT_FALSE(PathExists(report.file_path));
  EXPECT_FALSE(PathExists(metadata2));

  // Remove stale new files.
  std::unique_ptr<CrashReportDatabase::NewReport> new_report;
  EXPECT_EQ(db()->PrepareNewCrashReport(&new_report),
            CrashReportDatabase::kNoError);
  new_report->Writer()->Close();
  EXPECT_EQ(db()->CleanDatabase(0), 1);

  // Remove stale lock files and their associated reports.
  ASSERT_NO_FATAL_FAILURE(CreateCrashReport(&report));
  const base::FilePath metadata3(
      report.file_path.RemoveFinalExtension().value() +
      FILE_PATH_LITERAL(".meta"));
  ASSERT_TRUE(PathExists(report.file_path));
  ASSERT_TRUE(PathExists(metadata3));

  const base::FilePath lockpath(
      report.file_path.RemoveFinalExtension().value() +
      FILE_PATH_LITERAL(".lock"));
  ScopedFileHandle handle(LoggingOpenFileForWrite(
      lockpath, FileWriteMode::kCreateOrFail, FilePermissions::kOwnerOnly));
  ASSERT_TRUE(handle.is_valid());

  time_t expired_timestamp = time(nullptr) - 60 * 60 * 24 * 3;

  ASSERT_TRUE(LoggingWriteFile(
      handle.get(), &expired_timestamp, sizeof(expired_timestamp)));
  ASSERT_TRUE(LoggingCloseFile(handle.get()));
  ignore_result(handle.release());

  EXPECT_EQ(db()->CleanDatabase(0), 1);

  EXPECT_FALSE(PathExists(report.file_path));
  EXPECT_FALSE(PathExists(metadata3));
}
#endif  // !OS_MACOSX && !OS_WIN

}  // namespace
}  // namespace test
}  // namespace crashpad
