// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/domain_reliability/context.h"

#include <stddef.h>

#include <map>
#include <memory>
#include <string>
#include <utility>

#include "base/functional/bind.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/values_test_util.h"
#include "base/time/time.h"
#include "components/domain_reliability/beacon.h"
#include "components/domain_reliability/dispatcher.h"
#include "components/domain_reliability/scheduler.h"
#include "components/domain_reliability/test_util.h"
#include "components/domain_reliability/uploader.h"
#include "net/base/net_errors.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace domain_reliability {
namespace {

using base::Value;

typedef std::vector<const DomainReliabilityBeacon*> BeaconVector;

const char kBeaconOutcomeHistogram[] = "Net.DomainReliability.BeaconOutcome";

std::unique_ptr<DomainReliabilityBeacon> MakeCustomizedBeacon(
    MockableTime* time,
    std::string status,
    std::string quic_error,
    bool quic_port_migration_detected) {
  std::unique_ptr<DomainReliabilityBeacon> beacon(
      new DomainReliabilityBeacon());
  beacon->url = GURL("https://localhost/");
  beacon->status = status;
  beacon->quic_error = quic_error;
  beacon->chrome_error = net::ERR_CONNECTION_RESET;
  beacon->server_ip = "127.0.0.1";
  beacon->was_proxied = false;
  beacon->protocol = "HTTP";
  beacon->details.quic_broken = true;
  beacon->details.quic_port_migration_detected = quic_port_migration_detected;
  beacon->http_response_code = -1;
  beacon->elapsed = base::Milliseconds(250);
  beacon->start_time = time->NowTicks() - beacon->elapsed;
  beacon->upload_depth = 0;
  beacon->sample_rate = 1.0;
  beacon->network_anonymization_key = net::NetworkAnonymizationKey();
  return beacon;
}

std::unique_ptr<DomainReliabilityBeacon> MakeBeacon(MockableTime* time) {
  return MakeCustomizedBeacon(time, "tcp.connection_reset" /* status */,
                              "" /* quic_error */,
                              false /* quic_port_migration_detected */);
}

std::unique_ptr<DomainReliabilityBeacon> MakeBeaconWithNetworkAnonymizationKey(
    MockableTime* time,
    const std::string& status,
    const net::NetworkAnonymizationKey& network_anonymization_key) {
  std::unique_ptr<DomainReliabilityBeacon> beacon =
      MakeCustomizedBeacon(time, status, "" /* quic_error */,
                           false /* quic_port_migration_detected */);
  beacon->network_anonymization_key = network_anonymization_key;
  return beacon;
}

// Create a status string from in integer. For eviction tests. Include string
// values before and after the string representation of the integer, to make
// sure only exact matches are found when searching a JSON string.
std::string StatusFromInt(int i) {
  return base::StringPrintf("status%i.test", i);
}

template <typename ValueTypeFindResult,
          typename ValueType,
          ValueTypeFindResult (Value::Dict::*FindValueType)(base::StringPiece)
              const>
struct HasValue {
  bool operator()(const Value::Dict& dict,
                  const std::string& key,
                  ValueType expected_value) {
    ValueTypeFindResult actual_value = (dict.*FindValueType)(key);
    if (actual_value)
      EXPECT_EQ(expected_value, *actual_value);
    return actual_value && (expected_value == *actual_value);
  }
};

HasValue<std::optional<bool>, bool, &Value::Dict::FindBoolByDottedPath>
    HasBooleanValue;
HasValue<std::optional<double>, double, &Value::Dict::FindDoubleByDottedPath>
    HasDoubleValue;
HasValue<std::optional<int>, int, &Value::Dict::FindIntByDottedPath>
    HasIntegerValue;
HasValue<const std::string*, std::string, &Value::Dict::FindStringByDottedPath>
    HasStringValue;

const Value::Dict* GetEntryFromReport(const Value::Dict& report, size_t index) {
  const Value::List* entries = report.FindList("entries");
  if (!entries || index >= entries->size()) {
    return nullptr;
  }
  const Value& entry = (*entries)[index];
  if (!entry.is_dict()) {
    return nullptr;
  }
  return &entry.GetDict();
}

class DomainReliabilityContextTest : public testing::Test {
 protected:
  DomainReliabilityContextTest()
      : last_network_change_time_(time_.NowTicks()),
        dispatcher_(&time_),
        params_(MakeTestSchedulerParams()),
        uploader_(
            base::BindRepeating(&DomainReliabilityContextTest::OnUploadRequest,
                                base::Unretained(this))),
        upload_reporter_string_("test-reporter"),
        upload_allowed_callback_(base::BindRepeating(
            &DomainReliabilityContextTest::UploadAllowedCallback,
            base::Unretained(this))),
        upload_pending_(false) {
    // Make sure that the last network change does not overlap requests
    // made in test cases, which start 250ms in the past (see |MakeBeacon|).
    last_network_change_time_ = time_.NowTicks();
    time_.Advance(base::Seconds(1));
  }

  void InitContext(std::unique_ptr<const DomainReliabilityConfig> config) {
    context_ = std::make_unique<DomainReliabilityContext>(
        &time_, params_, upload_reporter_string_, &last_network_change_time_,
        upload_allowed_callback_, &dispatcher_, &uploader_, std::move(config));
  }

  void ShutDownContext() { context_.reset(); }

  base::TimeDelta min_delay() const { return params_.minimum_upload_delay; }
  base::TimeDelta max_delay() const { return params_.maximum_upload_delay; }
  base::TimeDelta retry_interval() const {
    return params_.upload_retry_interval;
  }
  base::TimeDelta zero_delta() const { return base::Microseconds(0); }

  bool upload_allowed_callback_pending() const {
    return !upload_allowed_result_callback_.is_null();
  }

  bool upload_pending() const { return upload_pending_; }

  const std::string& upload_report() const {
    EXPECT_TRUE(upload_pending_);
    return upload_report_;
  }

  int upload_max_depth() const {
    EXPECT_TRUE(upload_pending_);
    return upload_max_depth_;
  }

  const GURL& upload_url() const {
    EXPECT_TRUE(upload_pending_);
    return upload_url_;
  }

  const net::NetworkAnonymizationKey& upload_network_anonymization_key() const {
    EXPECT_TRUE(upload_pending_);
    return upload_network_anonymization_key_;
  }

  void CallUploadCallback(DomainReliabilityUploader::UploadResult result) {
    ASSERT_TRUE(upload_pending_);
    std::move(upload_callback_).Run(result);
    upload_pending_ = false;
    ++num_uploads_completed_;
    EXPECT_EQ(num_uploads_completed_, num_uploads_);
  }

  bool CheckNoBeacons() {
    BeaconVector beacons;
    context_->GetQueuedBeaconsForTesting(&beacons);
    return beacons.empty();
  }

  const url::Origin& upload_allowed_origin() { return upload_allowed_origin_; }

  void CallUploadAllowedResultCallback(bool allowed) {
    DCHECK(!upload_allowed_result_callback_.is_null());
    std::move(upload_allowed_result_callback_).Run(allowed);
  }

  MockTime time_;
  base::TimeTicks last_network_change_time_;
  DomainReliabilityDispatcher dispatcher_;
  DomainReliabilityScheduler::Params params_;
  MockUploader uploader_;
  std::string upload_reporter_string_;
  DomainReliabilityContext::UploadAllowedCallback upload_allowed_callback_;
  std::unique_ptr<DomainReliabilityContext> context_;

 private:
  void OnUploadRequest(
      const std::string& report_json,
      int max_upload_depth,
      const GURL& upload_url,
      const net::NetworkAnonymizationKey& network_anonymization_key,
      DomainReliabilityUploader::UploadCallback callback) {
    EXPECT_EQ(num_uploads_completed_, num_uploads_);
    ASSERT_FALSE(upload_pending_);
    upload_report_ = report_json;
    upload_max_depth_ = max_upload_depth;
    upload_url_ = upload_url;
    upload_network_anonymization_key_ = network_anonymization_key;
    upload_callback_ = std::move(callback);
    upload_pending_ = true;
    ++num_uploads_;
  }

  void UploadAllowedCallback(const url::Origin& origin,
                             base::OnceCallback<void(bool)> callback) {
    upload_allowed_origin_ = origin;
    upload_allowed_result_callback_ = std::move(callback);
  }

  int num_uploads_ = 0;
  int num_uploads_completed_ = 0;

  bool upload_pending_;
  std::string upload_report_;
  int upload_max_depth_;
  GURL upload_url_;
  net::NetworkAnonymizationKey upload_network_anonymization_key_;
  DomainReliabilityUploader::UploadCallback upload_callback_;

  url::Origin upload_allowed_origin_;
  base::OnceCallback<void(bool)> upload_allowed_result_callback_;
};

TEST_F(DomainReliabilityContextTest, Create) {
  InitContext(MakeTestConfig());
  EXPECT_TRUE(CheckNoBeacons());
}

TEST_F(DomainReliabilityContextTest, QueueBeacon) {
  base::HistogramTester histograms;
  InitContext(MakeTestConfig());
  context_->OnBeacon(MakeBeacon(&time_));

  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());

  ShutDownContext();
  histograms.ExpectBucketCount(
      kBeaconOutcomeHistogram,
      DomainReliabilityBeacon::Outcome::kContextShutDown, 1);
  histograms.ExpectTotalCount(kBeaconOutcomeHistogram, 1);
}

TEST_F(DomainReliabilityContextTest, MaxNestedBeaconSchedules) {
  InitContext(MakeTestConfig());
  GURL url("http://example/always_report");
  std::unique_ptr<DomainReliabilityBeacon> beacon = MakeBeacon(&time_);
  beacon->upload_depth = DomainReliabilityContext::kMaxUploadDepthToSchedule;
  context_->OnBeacon(std::move(beacon));

  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());

  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
}

TEST_F(DomainReliabilityContextTest, OverlyNestedBeaconDoesNotSchedule) {
  InitContext(MakeTestConfig());
  GURL url("http://example/always_report");
  std::unique_ptr<DomainReliabilityBeacon> beacon = MakeBeacon(&time_);
  beacon->upload_depth =
      DomainReliabilityContext::kMaxUploadDepthToSchedule + 1;
  context_->OnBeacon(std::move(beacon));

  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());

  time_.Advance(max_delay());
  EXPECT_FALSE(upload_allowed_callback_pending());
}

TEST_F(DomainReliabilityContextTest,
    MaxNestedBeaconAfterOverlyNestedBeaconSchedules) {
  base::HistogramTester histograms;
  InitContext(MakeTestConfig());
  // Add a beacon for a report that's too nested to schedule a beacon.
  std::unique_ptr<DomainReliabilityBeacon> beacon = MakeBeacon(&time_);
  beacon->upload_depth =
      DomainReliabilityContext::kMaxUploadDepthToSchedule + 1;
  context_->OnBeacon(std::move(beacon));

  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());

  time_.Advance(max_delay());
  EXPECT_FALSE(upload_allowed_callback_pending());

  // Add a beacon for a report that should schedule a beacon, and make sure it
  // doesn't schedule until the deadline.
  beacon = MakeBeacon(&time_);
  beacon->upload_depth = DomainReliabilityContext::kMaxUploadDepthToSchedule;
  context_->OnBeacon(std::move(beacon));

  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(2u, beacons.size());

  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());

  // Check that both beacons were uploaded.
  DomainReliabilityUploader::UploadResult result;
  result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  CallUploadCallback(result);

  histograms.ExpectBucketCount(kBeaconOutcomeHistogram,
                               DomainReliabilityBeacon::Outcome::kUploaded, 2);
  histograms.ExpectTotalCount(kBeaconOutcomeHistogram, 2);

  EXPECT_TRUE(CheckNoBeacons());
  ShutDownContext();
  histograms.ExpectTotalCount(kBeaconOutcomeHistogram, 2);
}

TEST_F(DomainReliabilityContextTest, ReportUpload) {
  base::HistogramTester histograms;
  InitContext(MakeTestConfig());
  context_->OnBeacon(
      MakeCustomizedBeacon(&time_, "tcp.connection_reset", "", true));

  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());

  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  EXPECT_EQ(0, upload_max_depth());
  EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());

  base::Value::Dict value = base::test::ParseJsonDict(upload_report());
  const Value::Dict* entry = GetEntryFromReport(value, 0);
  ASSERT_TRUE(entry);
  EXPECT_TRUE(HasStringValue(*entry, "failure_data.custom_error",
                             "net::ERR_CONNECTION_RESET"));
  EXPECT_TRUE(HasBooleanValue(*entry, "network_changed", false));
  EXPECT_TRUE(HasStringValue(*entry, "protocol", "HTTP"));
  EXPECT_TRUE(HasBooleanValue(*entry, "quic_broken", true));
  EXPECT_TRUE(HasBooleanValue(*entry, "quic_port_migration_detected", true));
  // N.B.: Assumes max_delay is 5 minutes.
  EXPECT_TRUE(HasIntegerValue(*entry, "request_age_ms", 300250));
  EXPECT_TRUE(HasIntegerValue(*entry, "request_elapsed_ms", 250));
  EXPECT_TRUE(HasDoubleValue(*entry, "sample_rate", 1.0));
  EXPECT_TRUE(HasStringValue(*entry, "server_ip", "127.0.0.1"));
  EXPECT_TRUE(HasStringValue(*entry, "status", "tcp.connection_reset"));
  EXPECT_TRUE(HasStringValue(*entry, "url", "https://localhost/"));
  EXPECT_TRUE(HasBooleanValue(*entry, "was_proxied", false));

  DomainReliabilityUploader::UploadResult result;
  result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  CallUploadCallback(result);

  histograms.ExpectBucketCount(kBeaconOutcomeHistogram,
                               DomainReliabilityBeacon::Outcome::kUploaded, 1);
  histograms.ExpectTotalCount(kBeaconOutcomeHistogram, 1);

  EXPECT_TRUE(CheckNoBeacons());
  ShutDownContext();
  histograms.ExpectTotalCount(kBeaconOutcomeHistogram, 1);
}

TEST_F(DomainReliabilityContextTest, ReportUploadFails) {
  InitContext(MakeTestConfig());
  context_->OnBeacon(
      MakeCustomizedBeacon(&time_, "tcp.connection_reset", "", true));

  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());

  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  EXPECT_EQ(0, upload_max_depth());
  EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());

  // The upload fails.
  DomainReliabilityUploader::UploadResult result;
  result.status = DomainReliabilityUploader::UploadResult::FAILURE;
  CallUploadCallback(result);

  // The beacon should still be pending.
  beacons.clear();
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());

  // Another upload should be queued.
  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
}

// Make sure that requests with only one NetworkAnonymizationKey are uploaded at
// a time, in FIFO order.
TEST_F(DomainReliabilityContextTest, ReportUploadNetworkAnonymizationKey) {
  const net::NetworkAnonymizationKey kNetworkAnonymizationKey1 =
      net::NetworkAnonymizationKey::CreateTransient();
  const net::NetworkAnonymizationKey kNetworkAnonymizationKey2 =
      net::NetworkAnonymizationKey::CreateTransient();
  const net::NetworkAnonymizationKey kNetworkAnonymizationKey3 =
      net::NetworkAnonymizationKey::CreateTransient();

  InitContext(MakeTestConfig());

  // Three beacons with kNetworkAnonymizationKey1, two with
  // kNetworkAnonymizationKey2, and one with kNetworkAnonymizationKey3. Have
  // beacons with the same key both adjacent to each other, and separated by
  // beacons with other keys. Give each a unique status, so it's easy to check
  // which beacons are included in each report.
  const char kStatusNik11[] = "nik1.status1";
  const char kStatusNik12[] = "nik1.status2";
  const char kStatusNik13[] = "nik1.status3";
  const char kStatusNik21[] = "nik2.status1";
  const char kStatusNik22[] = "nik2.status2";
  const char kStatusNik31[] = "nik3.status1";
  context_->OnBeacon(MakeBeaconWithNetworkAnonymizationKey(
      &time_, kStatusNik11, kNetworkAnonymizationKey1));
  context_->OnBeacon(MakeBeaconWithNetworkAnonymizationKey(
      &time_, kStatusNik12, kNetworkAnonymizationKey1));
  context_->OnBeacon(MakeBeaconWithNetworkAnonymizationKey(
      &time_, kStatusNik21, kNetworkAnonymizationKey2));
  context_->OnBeacon(MakeBeaconWithNetworkAnonymizationKey(
      &time_, kStatusNik31, kNetworkAnonymizationKey3));
  context_->OnBeacon(MakeBeaconWithNetworkAnonymizationKey(
      &time_, kStatusNik13, kNetworkAnonymizationKey1));
  context_->OnBeacon(MakeBeaconWithNetworkAnonymizationKey(
      &time_, kStatusNik22, kNetworkAnonymizationKey2));

  // All the beacons should be queued, in FIFO order.
  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(6u, beacons.size());
  EXPECT_EQ(kNetworkAnonymizationKey1, beacons[0]->network_anonymization_key);
  EXPECT_EQ(kStatusNik11, beacons[0]->status);
  EXPECT_EQ(kNetworkAnonymizationKey1, beacons[1]->network_anonymization_key);
  EXPECT_EQ(kStatusNik12, beacons[1]->status);
  EXPECT_EQ(kNetworkAnonymizationKey2, beacons[2]->network_anonymization_key);
  EXPECT_EQ(kStatusNik21, beacons[2]->status);
  EXPECT_EQ(kNetworkAnonymizationKey3, beacons[3]->network_anonymization_key);
  EXPECT_EQ(kStatusNik31, beacons[3]->status);
  EXPECT_EQ(kNetworkAnonymizationKey1, beacons[4]->network_anonymization_key);
  EXPECT_EQ(kStatusNik13, beacons[4]->status);
  EXPECT_EQ(kNetworkAnonymizationKey2, beacons[5]->network_anonymization_key);
  EXPECT_EQ(kStatusNik22, beacons[5]->status);

  // Wait for the report to start being uploaded.
  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  EXPECT_EQ(0, upload_max_depth());
  EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
  EXPECT_EQ(kNetworkAnonymizationKey1, upload_network_anonymization_key());

  // Check that only the strings associated with the first NIK are present in
  // the report.
  EXPECT_NE(upload_report().find(kStatusNik11), std::string::npos);
  EXPECT_NE(upload_report().find(kStatusNik12), std::string::npos);
  EXPECT_NE(upload_report().find(kStatusNik13), std::string::npos);
  EXPECT_EQ(upload_report().find(kStatusNik21), std::string::npos);
  EXPECT_EQ(upload_report().find(kStatusNik22), std::string::npos);
  EXPECT_EQ(upload_report().find(kStatusNik31), std::string::npos);

  // Complete upload.
  DomainReliabilityUploader::UploadResult successful_result;
  successful_result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  CallUploadCallback(successful_result);

  // There should still be 3 beacons queued, in the same order as before.
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(3u, beacons.size());
  EXPECT_EQ(kNetworkAnonymizationKey2, beacons[0]->network_anonymization_key);
  EXPECT_EQ(kStatusNik21, beacons[0]->status);
  EXPECT_EQ(kNetworkAnonymizationKey3, beacons[1]->network_anonymization_key);
  EXPECT_EQ(kStatusNik31, beacons[1]->status);
  EXPECT_EQ(kNetworkAnonymizationKey2, beacons[2]->network_anonymization_key);
  EXPECT_EQ(kStatusNik22, beacons[2]->status);

  // The next upload should automatically trigger.
  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  EXPECT_EQ(0, upload_max_depth());
  EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
  EXPECT_EQ(kNetworkAnonymizationKey2, upload_network_anonymization_key());

  // Check that only the strings associated with the second NIK are present in
  // the report.
  EXPECT_EQ(upload_report().find(kStatusNik11), std::string::npos);
  EXPECT_EQ(upload_report().find(kStatusNik12), std::string::npos);
  EXPECT_EQ(upload_report().find(kStatusNik13), std::string::npos);
  EXPECT_NE(upload_report().find(kStatusNik21), std::string::npos);
  EXPECT_NE(upload_report().find(kStatusNik22), std::string::npos);
  EXPECT_EQ(upload_report().find(kStatusNik31), std::string::npos);
  // Complete upload.
  CallUploadCallback(successful_result);

  // There should still be 1 beacon queued.
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(1u, beacons.size());
  EXPECT_EQ(kNetworkAnonymizationKey3, beacons[0]->network_anonymization_key);
  EXPECT_EQ(kStatusNik31, beacons[0]->status);

  // The next upload should automatically trigger.
  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  EXPECT_EQ(0, upload_max_depth());
  EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
  EXPECT_EQ(kNetworkAnonymizationKey3, upload_network_anonymization_key());

  // Check that only the strings associated with the third NIK are present in
  // the report.
  EXPECT_EQ(upload_report().find(kStatusNik11), std::string::npos);
  EXPECT_EQ(upload_report().find(kStatusNik12), std::string::npos);
  EXPECT_EQ(upload_report().find(kStatusNik13), std::string::npos);
  EXPECT_EQ(upload_report().find(kStatusNik21), std::string::npos);
  EXPECT_EQ(upload_report().find(kStatusNik22), std::string::npos);
  EXPECT_NE(upload_report().find(kStatusNik31), std::string::npos);
  // Complete upload.
  CallUploadCallback(successful_result);

  EXPECT_TRUE(CheckNoBeacons());
}

// Make sure that kMaxUploadDepthToSchedule is respected when requests have
// different NetworkAnonymizationKeys.
TEST_F(DomainReliabilityContextTest, ReportUploadDepthNetworkAnonymizationKey) {
  const net::NetworkAnonymizationKey kNetworkAnonymizationKey1 =
      net::NetworkAnonymizationKey::CreateTransient();
  const net::NetworkAnonymizationKey kNetworkAnonymizationKey2 =
      net::NetworkAnonymizationKey::CreateTransient();

  InitContext(MakeTestConfig());

  const char kStatusNik1ExceedsMaxDepth[] = "nik1.exceeds_max_depth";
  const char kStatusNik2ExceedsMaxDepth[] = "nik2.exceeds_max_depth";
  const char kStatusNik2MaxDepth[] = "nik2.max_depth";

  // Add a beacon with kNetworkAnonymizationKey1 and a depth that exceeds the
  // max depth to trigger an upload. No upload should be queued.
  std::unique_ptr<DomainReliabilityBeacon> beacon =
      MakeBeaconWithNetworkAnonymizationKey(&time_, kStatusNik1ExceedsMaxDepth,
                                            kNetworkAnonymizationKey1);
  beacon->upload_depth =
      DomainReliabilityContext::kMaxUploadDepthToSchedule + 1;
  context_->OnBeacon(std::move(beacon));
  time_.Advance(max_delay());
  EXPECT_FALSE(upload_allowed_callback_pending());

  // Add a beacon with kNetworkAnonymizationKey2 and a depth that exceeds the
  // max depth to trigger an upload. No upload should be queued.
  beacon = MakeBeaconWithNetworkAnonymizationKey(
      &time_, kStatusNik2ExceedsMaxDepth, kNetworkAnonymizationKey2);
  beacon->upload_depth =
      DomainReliabilityContext::kMaxUploadDepthToSchedule + 1;
  context_->OnBeacon(std::move(beacon));
  time_.Advance(max_delay());
  EXPECT_FALSE(upload_allowed_callback_pending());

  // Add a beacon with kNetworkAnonymizationKey2 and a depth that equals the max
  // depth to trigger an upload. An upload should be queued.
  beacon = MakeBeaconWithNetworkAnonymizationKey(&time_, kStatusNik2MaxDepth,
                                                 kNetworkAnonymizationKey2);
  beacon->upload_depth = DomainReliabilityContext::kMaxUploadDepthToSchedule;
  context_->OnBeacon(std::move(beacon));
  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());

  // All the beacons should still be queued.
  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(3u, beacons.size());
  EXPECT_EQ(kNetworkAnonymizationKey1, beacons[0]->network_anonymization_key);
  EXPECT_EQ(kStatusNik1ExceedsMaxDepth, beacons[0]->status);
  EXPECT_EQ(DomainReliabilityContext::kMaxUploadDepthToSchedule + 1,
            beacons[0]->upload_depth);
  EXPECT_EQ(kNetworkAnonymizationKey2, beacons[1]->network_anonymization_key);
  EXPECT_EQ(kStatusNik2ExceedsMaxDepth, beacons[1]->status);
  EXPECT_EQ(DomainReliabilityContext::kMaxUploadDepthToSchedule + 1,
            beacons[1]->upload_depth);
  EXPECT_EQ(kNetworkAnonymizationKey2, beacons[2]->network_anonymization_key);
  EXPECT_EQ(kStatusNik2MaxDepth, beacons[2]->status);
  EXPECT_EQ(DomainReliabilityContext::kMaxUploadDepthToSchedule,
            beacons[2]->upload_depth);

  // Start the upload.
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  EXPECT_EQ(DomainReliabilityContext::kMaxUploadDepthToSchedule + 1,
            upload_max_depth());
  EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());
  EXPECT_EQ(kNetworkAnonymizationKey2, upload_network_anonymization_key());

  // Check that only the strings associated with the second NIK are present in
  // the report.
  EXPECT_EQ(upload_report().find(kStatusNik1ExceedsMaxDepth),
            std::string::npos);
  EXPECT_NE(upload_report().find(kStatusNik2ExceedsMaxDepth),
            std::string::npos);
  EXPECT_NE(upload_report().find(kStatusNik2MaxDepth), std::string::npos);

  // Complete upload.
  DomainReliabilityUploader::UploadResult successful_result;
  successful_result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  CallUploadCallback(successful_result);

  // There should still be 1 beacon queued.
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(1u, beacons.size());
  EXPECT_EQ(kNetworkAnonymizationKey1, beacons[0]->network_anonymization_key);
  EXPECT_EQ(kStatusNik1ExceedsMaxDepth, beacons[0]->status);
  EXPECT_EQ(DomainReliabilityContext::kMaxUploadDepthToSchedule + 1,
            beacons[0]->upload_depth);

  // No upload should be queued, since the depth is too high.
  time_.Advance(max_delay());
  EXPECT_FALSE(upload_allowed_callback_pending());
}

TEST_F(DomainReliabilityContextTest, UploadForbidden) {
  InitContext(MakeTestConfig());
  context_->OnBeacon(
      MakeCustomizedBeacon(&time_, "tcp.connection_reset", "", true));

  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());

  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(false);
  EXPECT_FALSE(upload_pending());
}

TEST_F(DomainReliabilityContextTest, NetworkChanged) {
  InitContext(MakeTestConfig());
  context_->OnBeacon(MakeBeacon(&time_));

  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());

  // Simulate a network change after the request but before the upload.
  last_network_change_time_ = time_.NowTicks();
  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  EXPECT_EQ(0, upload_max_depth());
  EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());

  base::Value::Dict value = base::test::ParseJsonDict(upload_report());
  const Value::Dict* entry = GetEntryFromReport(value, 0);
  ASSERT_TRUE(entry);
  EXPECT_TRUE(HasBooleanValue(*entry, "network_changed", true));

  DomainReliabilityUploader::UploadResult result;
  result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  CallUploadCallback(result);

  EXPECT_TRUE(CheckNoBeacons());
}

// Always expecting granular QUIC errors if status is quic.protocol error.
TEST_F(DomainReliabilityContextTest,
       ReportUploadWithQuicProtocolErrorAndQuicError) {
  InitContext(MakeTestConfig());
  context_->OnBeacon(MakeCustomizedBeacon(&time_, "quic.protocol",
                                          "quic.invalid.stream_data", true));

  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());

  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  EXPECT_EQ(0, upload_max_depth());
  EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());

  base::Value::Dict value = base::test::ParseJsonDict(upload_report());
  const Value::Dict* entry = GetEntryFromReport(value, 0);
  ASSERT_TRUE(entry);

  EXPECT_TRUE(HasBooleanValue(*entry, "quic_broken", true));
  EXPECT_TRUE(HasBooleanValue(*entry, "quic_port_migration_detected", true));
  EXPECT_TRUE(HasStringValue(*entry, "status", "quic.protocol"));
  EXPECT_TRUE(HasStringValue(*entry, "quic_error", "quic.invalid.stream_data"));

  DomainReliabilityUploader::UploadResult result;
  result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  CallUploadCallback(result);

  EXPECT_TRUE(CheckNoBeacons());
}

// If status is not quic.protocol, expect no granular QUIC error to be reported.
TEST_F(DomainReliabilityContextTest,
       ReportUploadWithNonQuicProtocolErrorAndNoQuicError) {
  InitContext(MakeTestConfig());
  context_->OnBeacon(MakeBeacon(&time_));

  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());

  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  EXPECT_EQ(0, upload_max_depth());
  EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());

  base::Value::Dict value = base::test::ParseJsonDict(upload_report());
  const Value::Dict* entry = GetEntryFromReport(value, 0);
  ASSERT_TRUE(entry);

  EXPECT_TRUE(HasStringValue(*entry, "status", "tcp.connection_reset"));
  EXPECT_FALSE(HasStringValue(*entry, "quic_error", ""));

  DomainReliabilityUploader::UploadResult result;
  result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  CallUploadCallback(result);

  EXPECT_TRUE(CheckNoBeacons());
}

// Edge cases that a non-QUIC protocol error with granular QUIC error reported,
// probably indicating state machine in http_network_transaction is working
// in a different way.
TEST_F(DomainReliabilityContextTest,
       ReportUploadWithNonQuicProtocolErrorAndQuicError) {
  InitContext(MakeTestConfig());
  context_->OnBeacon(MakeCustomizedBeacon(&time_, "tcp.connection_reset",
                                          "quic.invalid.stream_data", false));

  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());

  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  EXPECT_EQ(0, upload_max_depth());
  EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());

  base::Value::Dict value = base::test::ParseJsonDict(upload_report());
  const Value::Dict* entry = GetEntryFromReport(value, 0);
  ASSERT_TRUE(entry);
  EXPECT_TRUE(HasBooleanValue(*entry, "quic_broken", true));
  EXPECT_TRUE(HasStringValue(*entry, "status", "tcp.connection_reset"));
  EXPECT_TRUE(HasStringValue(*entry, "quic_error", "quic.invalid.stream_data"));

  DomainReliabilityUploader::UploadResult result;
  result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  CallUploadCallback(result);

  EXPECT_TRUE(CheckNoBeacons());
}

TEST_F(DomainReliabilityContextTest, ZeroSampleRate) {
  std::unique_ptr<DomainReliabilityConfig> config(MakeTestConfig());
  config->failure_sample_rate = 0.0;
  InitContext(std::move(config));

  BeaconVector beacons;
  for (int i = 0; i < 100; i++) {
    context_->OnBeacon(MakeBeacon(&time_));
    EXPECT_TRUE(CheckNoBeacons());
  }
}

TEST_F(DomainReliabilityContextTest, FractionalSampleRate) {
  std::unique_ptr<DomainReliabilityConfig> config(MakeTestConfig());
  config->failure_sample_rate = 0.5;
  InitContext(std::move(config));

  BeaconVector beacons;
  do {
    context_->OnBeacon(MakeBeacon(&time_));
    context_->GetQueuedBeaconsForTesting(&beacons);
  } while (beacons.empty());
  EXPECT_EQ(1u, beacons.size());

  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  EXPECT_EQ(0, upload_max_depth());
  EXPECT_EQ(GURL("https://exampleuploader/upload"), upload_url());

  base::Value::Dict value = base::test::ParseJsonDict(upload_report());
  const Value::Dict* entry = GetEntryFromReport(value, 0);
  ASSERT_TRUE(entry);
  EXPECT_TRUE(HasDoubleValue(*entry, "sample_rate", 0.5));

  DomainReliabilityUploader::UploadResult result;
  result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  CallUploadCallback(result);

  EXPECT_TRUE(CheckNoBeacons());
}

TEST_F(DomainReliabilityContextTest, FailureSampleOnly) {
  std::unique_ptr<DomainReliabilityConfig> config(MakeTestConfig());
  config->success_sample_rate = 0.0;
  config->failure_sample_rate = 1.0;
  InitContext(std::move(config));

  BeaconVector beacons;

  context_->OnBeacon(MakeBeacon(&time_));
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());

  std::unique_ptr<DomainReliabilityBeacon> beacon(MakeBeacon(&time_));
  beacon->status = "ok";
  beacon->chrome_error = net::OK;
  context_->OnBeacon(std::move(beacon));
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());
}

TEST_F(DomainReliabilityContextTest, SuccessSampleOnly) {
  std::unique_ptr<DomainReliabilityConfig> config(MakeTestConfig());
  config->success_sample_rate = 1.0;
  config->failure_sample_rate = 0.0;
  InitContext(std::move(config));

  BeaconVector beacons;

  context_->OnBeacon(MakeBeacon(&time_));
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(0u, beacons.size());

  std::unique_ptr<DomainReliabilityBeacon> beacon(MakeBeacon(&time_));
  beacon->status = "ok";
  beacon->chrome_error = net::OK;
  context_->OnBeacon(std::move(beacon));
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());
}

TEST_F(DomainReliabilityContextTest, SampleAllBeacons) {
  std::unique_ptr<DomainReliabilityConfig> config(MakeTestConfig());
  config->success_sample_rate = 1.0;
  config->failure_sample_rate = 1.0;
  InitContext(std::move(config));

  BeaconVector beacons;

  context_->OnBeacon(MakeBeacon(&time_));
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());

  std::unique_ptr<DomainReliabilityBeacon> beacon(MakeBeacon(&time_));
  beacon->status = "ok";
  beacon->chrome_error = net::OK;
  context_->OnBeacon(std::move(beacon));
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(2u, beacons.size());
}

TEST_F(DomainReliabilityContextTest, SampleNoBeacons) {
  std::unique_ptr<DomainReliabilityConfig> config(MakeTestConfig());
  config->success_sample_rate = 0.0;
  config->failure_sample_rate = 0.0;
  InitContext(std::move(config));

  BeaconVector beacons;

  context_->OnBeacon(MakeBeacon(&time_));
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(0u, beacons.size());

  std::unique_ptr<DomainReliabilityBeacon> beacon(MakeBeacon(&time_));
  beacon->status = "ok";
  beacon->chrome_error = net::OK;
  context_->OnBeacon(std::move(beacon));
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(0u, beacons.size());
}

TEST_F(DomainReliabilityContextTest, ExpiredBeaconDoesNotUpload) {
  base::HistogramTester histograms;
  InitContext(MakeTestConfig());
  std::unique_ptr<DomainReliabilityBeacon> beacon = MakeBeacon(&time_);
  time_.Advance(base::Hours(2));
  context_->OnBeacon(std::move(beacon));

  time_.Advance(max_delay());
  EXPECT_FALSE(upload_allowed_callback_pending());
  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_TRUE(beacons.empty());

  histograms.ExpectBucketCount(kBeaconOutcomeHistogram,
                               DomainReliabilityBeacon::Outcome::kExpired, 1);
  histograms.ExpectTotalCount(kBeaconOutcomeHistogram, 1);

  ShutDownContext();
  histograms.ExpectTotalCount(kBeaconOutcomeHistogram, 1);
}

TEST_F(DomainReliabilityContextTest, EvictOldestBeacon) {
  base::HistogramTester histograms;
  InitContext(MakeTestConfig());

  std::unique_ptr<DomainReliabilityBeacon> oldest_beacon = MakeBeacon(&time_);
  const DomainReliabilityBeacon* oldest_beacon_ptr = oldest_beacon.get();
  time_.Advance(base::Seconds(1));
  context_->OnBeacon(std::move(oldest_beacon));

  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    std::unique_ptr<DomainReliabilityBeacon> beacon = MakeBeacon(&time_);
    time_.Advance(base::Seconds(1));
    context_->OnBeacon(std::move(beacon));
  }

  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());

  for (const DomainReliabilityBeacon* beacon : beacons) {
    EXPECT_NE(oldest_beacon_ptr, beacon);
  }

  histograms.ExpectBucketCount(kBeaconOutcomeHistogram,
                               DomainReliabilityBeacon::Outcome::kEvicted, 1);
  histograms.ExpectTotalCount(kBeaconOutcomeHistogram, 1);

  ShutDownContext();
  histograms.ExpectBucketCount(
      kBeaconOutcomeHistogram,
      DomainReliabilityBeacon::Outcome::kContextShutDown,
      DomainReliabilityContext::kMaxQueuedBeacons);
  histograms.ExpectTotalCount(kBeaconOutcomeHistogram,
                              1 + DomainReliabilityContext::kMaxQueuedBeacons);
}

// Test eviction when there's no active upload.
TEST_F(DomainReliabilityContextTest, Eviction) {
  InitContext(MakeTestConfig());

  // Add |DomainReliabilityContext::kMaxQueuedBeacons| beacons.
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    context_->OnBeacon(
        MakeCustomizedBeacon(&time_, StatusFromInt(i), "" /* quic_error */,
                             false /* quic_port_migration_detected */));
  }

  // No beacons should have been evicted.
  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    EXPECT_EQ(beacons[i]->status, StatusFromInt(i));
  }

  // Add one more beacon.
  context_->OnBeacon(MakeCustomizedBeacon(
      &time_, StatusFromInt(DomainReliabilityContext::kMaxQueuedBeacons),
      "" /* quic_error */, false /* quic_port_migration_detected */));

  // The first beacon should have been evicted.
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    EXPECT_EQ(beacons[i]->status, StatusFromInt(i + 1));
  }

  // Wait for the report to start being uploaded.
  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  // All beacons but the first should be in the report.
  EXPECT_EQ(upload_report().find(StatusFromInt(0)), std::string::npos);
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    EXPECT_NE(upload_report().find(StatusFromInt(i + 1)), std::string::npos);
  }

  DomainReliabilityUploader::UploadResult result;
  result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  CallUploadCallback(result);

  EXPECT_TRUE(CheckNoBeacons());
}

// Test eviction when there's an upload that eventually succeeds.
TEST_F(DomainReliabilityContextTest, EvictionDuringSuccessfulUpload) {
  InitContext(MakeTestConfig());

  // Add |DomainReliabilityContext::kMaxQueuedBeacons| beacons.
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    context_->OnBeacon(
        MakeCustomizedBeacon(&time_, StatusFromInt(i), "" /* quic_error */,
                             false /* quic_port_migration_detected */));
  }

  // No beacons should have been evicted.
  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    EXPECT_EQ(beacons[i]->status, StatusFromInt(i));
  }

  // Wait for the report to start being uploaded.
  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  // All beacons should be in the report.
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    EXPECT_NE(upload_report().find(StatusFromInt(i)), std::string::npos);
  }

  // Add one more beacon.
  context_->OnBeacon(MakeCustomizedBeacon(
      &time_, StatusFromInt(DomainReliabilityContext::kMaxQueuedBeacons),
      "" /* quic_error */, false /* quic_port_migration_detected */));

  // The first beacon should have been evicted.
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    EXPECT_EQ(beacons[i]->status, StatusFromInt(i + 1));
  }

  // The upload completes.
  DomainReliabilityUploader::UploadResult successful_result;
  successful_result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  CallUploadCallback(successful_result);

  // The last beacon should still be queued.
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(1u, beacons.size());
  EXPECT_EQ(beacons[0]->status,
            StatusFromInt(DomainReliabilityContext::kMaxQueuedBeacons));

  // Another upload should have still been queued, for the new report. Wait for
  // it to start uploading.
  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  // Only the last beacon should be in the report.
  EXPECT_NE(upload_report().find(
                StatusFromInt(DomainReliabilityContext::kMaxQueuedBeacons)),
            std::string::npos);
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    EXPECT_EQ(upload_report().find(StatusFromInt(i)), std::string::npos);
  }

  // The upload completes.
  CallUploadCallback(successful_result);

  EXPECT_TRUE(CheckNoBeacons());
}

// Test eviction when there's an upload that eventually fails.
TEST_F(DomainReliabilityContextTest, EvictionDuringUnsuccessfulUpload) {
  InitContext(MakeTestConfig());

  // Add |DomainReliabilityContext::kMaxQueuedBeacons| beacons.
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    context_->OnBeacon(
        MakeCustomizedBeacon(&time_, StatusFromInt(i), "" /* quic_error */,
                             false /* quic_port_migration_detected */));
  }

  // No beacons should have been evicted.
  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    EXPECT_EQ(beacons[i]->status, StatusFromInt(i));
  }

  // Wait for the report to start being uploaded.
  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  // All beacons should be in the report.
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    EXPECT_NE(upload_report().find(StatusFromInt(i)), std::string::npos);
  }

  // Add one more beacon.
  context_->OnBeacon(MakeCustomizedBeacon(
      &time_, StatusFromInt(DomainReliabilityContext::kMaxQueuedBeacons),
      "" /* quic_error */, false /* quic_port_migration_detected */));

  // The first beacon should have been evicted.
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    EXPECT_EQ(beacons[i]->status, StatusFromInt(i + 1));
  }

  // The upload fails.
  DomainReliabilityUploader::UploadResult result;
  result.status = DomainReliabilityUploader::UploadResult::FAILURE;
  CallUploadCallback(result);

  // All beacons but the first should still be queued.
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    EXPECT_EQ(beacons[i]->status, StatusFromInt(i + 1));
  }

  // Wait for the report to start being uploaded.
  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  // All beacons but the first should be in the report.
  EXPECT_EQ(upload_report().find(StatusFromInt(0)), std::string::npos);
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    EXPECT_NE(upload_report().find(StatusFromInt(i + 1)), std::string::npos);
  }

  // The upload completes successfully.
  result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  CallUploadCallback(result);

  EXPECT_TRUE(CheckNoBeacons());
}

// Test eviction of all initially pending reports when there's an upload that
// eventually succeeds.
TEST_F(DomainReliabilityContextTest, EvictAllDuringSuccessfulUpload) {
  InitContext(MakeTestConfig());

  // Add |DomainReliabilityContext::kMaxQueuedBeacons| beacons.
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    context_->OnBeacon(
        MakeCustomizedBeacon(&time_, StatusFromInt(i), "" /* quic_error */,
                             false /* quic_port_migration_detected */));
  }

  // No beacons should have been evicted.
  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    EXPECT_EQ(beacons[i]->status, StatusFromInt(i));
  }

  // Wait for the report to start being uploaded.
  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  // All beacons should be in the report.
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    EXPECT_NE(upload_report().find(StatusFromInt(i)), std::string::npos);
  }

  // Evict all beacons, twice. It's important to add a beacon after all beacons
  // from the original report have already been deleted, to make sure that
  // eviction works correctly once |uploading_beacons_size_| reaches 0.
  for (size_t i = 0; i < 2 * DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    context_->OnBeacon(MakeCustomizedBeacon(
        &time_, StatusFromInt(i + DomainReliabilityContext::kMaxQueuedBeacons),
        "" /* quic_error */, false /* quic_port_migration_detected */));
  }

  // All the original beacons should have been evicted, as should the first
  // |DomainReliabilityContext::kMaxQueuedBeacons| beacons from the above loop.
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    EXPECT_EQ(
        beacons[i]->status,
        StatusFromInt(i + 2 * DomainReliabilityContext::kMaxQueuedBeacons));
  }

  // The upload succeeds, but no beacons should be removed, since all the
  // original beacons have already been evicted.
  DomainReliabilityUploader::UploadResult successful_result;
  successful_result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  CallUploadCallback(successful_result);

  // The same beacons as before should be queued.
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    EXPECT_EQ(
        beacons[i]->status,
        StatusFromInt(i + 2 * DomainReliabilityContext::kMaxQueuedBeacons));
  }

  // Wait for the report to start being uploaded.
  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  // Check the expected beacons are in the report.
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons * 3; ++i) {
    if (i < DomainReliabilityContext::kMaxQueuedBeacons * 2) {
      EXPECT_EQ(upload_report().find(StatusFromInt(i)), std::string::npos);
    } else {
      EXPECT_NE(upload_report().find(StatusFromInt(i)), std::string::npos);
    }
  }

  // The upload completes successfully.
  CallUploadCallback(successful_result);

  EXPECT_TRUE(CheckNoBeacons());
}

// Make sure that evictions account for when there are different
// NetworkAnonymizationKeys in use.
TEST_F(DomainReliabilityContextTest,
       EvictionDuringSuccessfulUploadNetworkAnonymizationKey) {
  ASSERT_EQ(0u, DomainReliabilityContext::kMaxQueuedBeacons % 2)
      << "DomainReliabilityContext::kMaxQueuedBeacons must be even.";

  InitContext(MakeTestConfig());

  net::NetworkAnonymizationKey network_anonymization_keys[] = {
      net::NetworkAnonymizationKey::CreateTransient(),
      net::NetworkAnonymizationKey::CreateTransient(),
  };

  // Add |DomainReliabilityContext::kMaxQueuedBeacons| beacons, using a
  // different NetworkAnonymizationKey for every other beacon.
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    context_->OnBeacon(MakeBeaconWithNetworkAnonymizationKey(
        &time_, StatusFromInt(i), network_anonymization_keys[i % 2]));
  }

  // No beacons should have been evicted.
  BeaconVector beacons;
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    EXPECT_EQ(beacons[i]->status, StatusFromInt(i));
    EXPECT_EQ(beacons[i]->network_anonymization_key,
              network_anonymization_keys[i % 2]);
  }

  // Wait for the report to start being uploaded.
  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  EXPECT_EQ(network_anonymization_keys[0], upload_network_anonymization_key());
  // All even-numbered beacons should be in the report.
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    if (i % 2 == 0) {
      EXPECT_NE(upload_report().find(StatusFromInt(i)), std::string::npos);
    } else {
      EXPECT_EQ(upload_report().find(StatusFromInt(i)), std::string::npos);
    }
  }

  // Add two more beacons, using the same pattern as before
  for (size_t i = 0; i < 2; ++i) {
    context_->OnBeacon(MakeBeaconWithNetworkAnonymizationKey(
        &time_, StatusFromInt(i + DomainReliabilityContext::kMaxQueuedBeacons),
        network_anonymization_keys[i % 2]));
  }

  // Only the first two beacons should have been evicted.
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons, beacons.size());
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    EXPECT_EQ(beacons[i]->status, StatusFromInt(i + 2));
    EXPECT_EQ(beacons[i]->network_anonymization_key,
              network_anonymization_keys[i % 2]);
  }

  // The upload succeeds.  Every beacon using the first NetworkAnonymizationKey,
  // except the second to last, should have been evicted.
  DomainReliabilityUploader::UploadResult successful_result;
  successful_result.status = DomainReliabilityUploader::UploadResult::SUCCESS;
  CallUploadCallback(successful_result);

  // Check remaining beacons.
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(DomainReliabilityContext::kMaxQueuedBeacons / 2 + 1,
            beacons.size());
  int beacon_index = 0;
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons; ++i) {
    if (i % 2 == 0 && i < DomainReliabilityContext::kMaxQueuedBeacons - 2)
      continue;
    EXPECT_EQ(beacons[beacon_index]->status, StatusFromInt(i + 2));
    EXPECT_EQ(beacons[beacon_index]->network_anonymization_key,
              network_anonymization_keys[i % 2]);
    beacon_index++;
  }

  // Another report should be queued.  Wait for it to start being uploaded.
  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  EXPECT_EQ(network_anonymization_keys[1], upload_network_anonymization_key());
  // Check the expected beacons are in the report.
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons + 2; ++i) {
    if (i % 2 == 0 || i < 2) {
      EXPECT_EQ(upload_report().find(StatusFromInt(i)), std::string::npos);
    } else {
      EXPECT_NE(upload_report().find(StatusFromInt(i)), std::string::npos);
    }
  }

  // The upload completes successfully.
  CallUploadCallback(successful_result);

  // Check remaining beacons. There should only be one left.
  context_->GetQueuedBeaconsForTesting(&beacons);
  ASSERT_EQ(1u, beacons.size());
  EXPECT_EQ(beacons[0]->status,
            StatusFromInt(DomainReliabilityContext::kMaxQueuedBeacons));
  EXPECT_EQ(beacons[0]->network_anonymization_key,
            network_anonymization_keys[0]);

  // Another report should be queued.  Wait for it to start being uploaded.
  time_.Advance(max_delay());
  EXPECT_TRUE(upload_allowed_callback_pending());
  CallUploadAllowedResultCallback(true);
  EXPECT_TRUE(upload_pending());
  EXPECT_EQ(network_anonymization_keys[0], upload_network_anonymization_key());
  // Check the expected beacons are in the report.
  for (size_t i = 0; i < DomainReliabilityContext::kMaxQueuedBeacons + 2; ++i) {
    if (i == DomainReliabilityContext::kMaxQueuedBeacons) {
      EXPECT_NE(upload_report().find(StatusFromInt(i)), std::string::npos);
    } else {
      EXPECT_EQ(upload_report().find(StatusFromInt(i)), std::string::npos);
    }
  }

  // The upload completes successfully.
  CallUploadCallback(successful_result);

  EXPECT_TRUE(CheckNoBeacons());
}

// TODO(juliatuttle): Add beacon_unittest.cc to test serialization.

}  // namespace
}  // namespace domain_reliability
