// Copyright 2017 The Chromium 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 "net/reporting/reporting_endpoint_manager.h"

#include <string>

#include "base/strings/stringprintf.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/time/time.h"
#include "net/base/backoff_entry.h"
#include "net/base/network_isolation_key.h"
#include "net/reporting/reporting_cache.h"
#include "net/reporting/reporting_endpoint.h"
#include "net/reporting/reporting_policy.h"
#include "net/reporting/reporting_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"

namespace net {
namespace {

class TestReportingCache : public ReportingCache {
 public:
  class PersistentReportingStore;

  // Tests using this class only use one origin/group.
  TestReportingCache(const url::Origin& expected_origin,
                     const std::string& expected_group)
      : expected_origin_(expected_origin), expected_group_(expected_group) {}
  ~TestReportingCache() override = default;

  void SetEndpoint(const ReportingEndpoint& reporting_endpoint) {
    reporting_endpoints_[reporting_endpoint.group_key.network_isolation_key]
        .push_back(reporting_endpoint);
  }

  // ReportingCache implementation:

  std::vector<ReportingEndpoint> GetCandidateEndpointsForDelivery(
      const ReportingEndpointGroupKey& group_key) override {
    EXPECT_EQ(expected_origin_, group_key.origin);
    EXPECT_EQ(expected_group_, group_key.group_name);
    return reporting_endpoints_[group_key.network_isolation_key];
  }

  // Everything below is NOTREACHED.
  void AddReport(const NetworkIsolationKey& network_isolation_key,
                 const GURL& url,
                 const std::string& user_agent,
                 const std::string& group_name,
                 const std::string& type,
                 std::unique_ptr<const base::Value> body,
                 int depth,
                 base::TimeTicks queued,
                 int attempts) override {
    NOTREACHED();
  }
  void GetReports(
      std::vector<const ReportingReport*>* reports_out) const override {
    NOTREACHED();
  }
  base::Value GetReportsAsValue() const override {
    NOTREACHED();
    return base::Value();
  }
  std::vector<const ReportingReport*> GetReportsToDeliver() override {
    NOTREACHED();
    return {};
  }
  void ClearReportsPending(
      const std::vector<const ReportingReport*>& reports) override {
    NOTREACHED();
  }
  void IncrementReportsAttempts(
      const std::vector<const ReportingReport*>& reports) override {
    NOTREACHED();
  }
  void IncrementEndpointDeliveries(const ReportingEndpointGroupKey& group_key,
                                   const GURL& url,
                                   int reports_delivered,
                                   bool successful) override {
    NOTREACHED();
  }
  void RemoveReports(const std::vector<const ReportingReport*>& reports,
                     ReportingReport::Outcome outcome) override {
    NOTREACHED();
  }
  void RemoveAllReports(ReportingReport::Outcome outcome) override {
    NOTREACHED();
  }
  size_t GetFullReportCountForTesting() const override {
    NOTREACHED();
    return 0;
  }
  bool IsReportPendingForTesting(const ReportingReport* report) const override {
    NOTREACHED();
    return false;
  }
  bool IsReportDoomedForTesting(const ReportingReport* report) const override {
    NOTREACHED();
    return false;
  }
  void OnParsedHeader(
      const NetworkIsolationKey& network_isolation_key,
      const url::Origin& origin,
      std::vector<ReportingEndpointGroup> parsed_header) override {
    NOTREACHED();
  }
  std::set<url::Origin> GetAllOrigins() const override {
    NOTREACHED();
    return std::set<url::Origin>();
  }
  void RemoveClient(const NetworkIsolationKey& network_isolation_key,
                    const url::Origin& origin) override {
    NOTREACHED();
  }
  void RemoveClientsForOrigin(const url::Origin& origin) override {
    NOTREACHED();
  }
  void RemoveAllClients() override { NOTREACHED(); }
  void RemoveEndpointGroup(
      const ReportingEndpointGroupKey& group_key) override {
    NOTREACHED();
  }
  void RemoveEndpointsForUrl(const GURL& url) override { NOTREACHED(); }
  void AddClientsLoadedFromStore(
      std::vector<ReportingEndpoint> loaded_endpoints,
      std::vector<CachedReportingEndpointGroup> loaded_endpoint_groups)
      override {
    NOTREACHED();
  }
  base::Value GetClientsAsValue() const override {
    NOTREACHED();
    return base::Value();
  }
  size_t GetEndpointCount() const override {
    NOTREACHED();
    return 0;
  }
  void Flush() override { NOTREACHED(); }
  ReportingEndpoint GetEndpointForTesting(
      const ReportingEndpointGroupKey& group_key,
      const GURL& url) const override {
    NOTREACHED();
    return ReportingEndpoint();
  }
  bool EndpointGroupExistsForTesting(const ReportingEndpointGroupKey& group_key,
                                     OriginSubdomains include_subdomains,
                                     base::Time expires) const override {
    NOTREACHED();
    return false;
  }
  bool ClientExistsForTesting(const NetworkIsolationKey& network_isolation_key,
                              const url::Origin& origin) const override {
    NOTREACHED();
    return false;
  }
  size_t GetEndpointGroupCountForTesting() const override {
    NOTREACHED();
    return 0;
  }
  size_t GetClientCountForTesting() const override {
    NOTREACHED();
    return 0;
  }
  void SetEndpointForTesting(const ReportingEndpointGroupKey& group_key,
                             const GURL& url,
                             OriginSubdomains include_subdomains,
                             base::Time expires,
                             int priority,
                             int weight) override {
    NOTREACHED();
  }

 private:
  const url::Origin expected_origin_;
  const std::string expected_group_;

  std::map<NetworkIsolationKey, std::vector<ReportingEndpoint>>
      reporting_endpoints_;

  DISALLOW_COPY_AND_ASSIGN(TestReportingCache);
};

class ReportingEndpointManagerTest : public testing::Test {
 public:
  ReportingEndpointManagerTest() : cache_(kOrigin, kGroup) {
    policy_.endpoint_backoff_policy.num_errors_to_ignore = 0;
    policy_.endpoint_backoff_policy.initial_delay_ms = 60000;
    policy_.endpoint_backoff_policy.multiply_factor = 2.0;
    policy_.endpoint_backoff_policy.jitter_factor = 0.0;
    policy_.endpoint_backoff_policy.maximum_backoff_ms = -1;
    policy_.endpoint_backoff_policy.entry_lifetime_ms = 0;
    policy_.endpoint_backoff_policy.always_use_initial_delay = false;

    clock_.SetNowTicks(base::TimeTicks());

    endpoint_manager_ = ReportingEndpointManager::Create(
        &policy_, &clock_, &delegate_, &cache_, TestReportingRandIntCallback());
  }

 protected:
  void SetEndpoint(
      const GURL& endpoint,
      int priority = ReportingEndpoint::EndpointInfo::kDefaultPriority,
      int weight = ReportingEndpoint::EndpointInfo::kDefaultWeight,
      const NetworkIsolationKey& network_isolation_key =
          NetworkIsolationKey()) {
    ReportingEndpointGroupKey group_key(kGroupKey);
    group_key.network_isolation_key = network_isolation_key;
    cache_.SetEndpoint(ReportingEndpoint(
        group_key,
        ReportingEndpoint::EndpointInfo{endpoint, priority, weight}));
  }

  const NetworkIsolationKey kNik;
  const url::Origin kOrigin = url::Origin::Create(GURL("https://origin/"));
  const std::string kGroup = "group";
  const ReportingEndpointGroupKey kGroupKey =
      ReportingEndpointGroupKey(kNik, kOrigin, kGroup);
  const GURL kEndpoint = GURL("https://endpoint/");

  ReportingPolicy policy_;
  base::SimpleTestTickClock clock_;
  TestReportingDelegate delegate_;
  TestReportingCache cache_;
  std::unique_ptr<ReportingEndpointManager> endpoint_manager_;
};

TEST_F(ReportingEndpointManagerTest, NoEndpoint) {
  ReportingEndpoint endpoint =
      endpoint_manager_->FindEndpointForDelivery(kGroupKey);
  EXPECT_FALSE(endpoint);
}

TEST_F(ReportingEndpointManagerTest, Endpoint) {
  SetEndpoint(kEndpoint);

  ReportingEndpoint endpoint =
      endpoint_manager_->FindEndpointForDelivery(kGroupKey);
  ASSERT_TRUE(endpoint);
  EXPECT_EQ(kEndpoint, endpoint.info.url);
}

TEST_F(ReportingEndpointManagerTest, BackedOffEndpoint) {
  ASSERT_EQ(2.0, policy_.endpoint_backoff_policy.multiply_factor);

  base::TimeDelta initial_delay = base::TimeDelta::FromMilliseconds(
      policy_.endpoint_backoff_policy.initial_delay_ms);

  SetEndpoint(kEndpoint);

  endpoint_manager_->InformOfEndpointRequest(NetworkIsolationKey(), kEndpoint,
                                             false);

  // After one failure, endpoint is in exponential backoff.
  ReportingEndpoint endpoint =
      endpoint_manager_->FindEndpointForDelivery(kGroupKey);
  EXPECT_FALSE(endpoint);

  // After initial delay, endpoint is usable again.
  clock_.Advance(initial_delay);

  ReportingEndpoint endpoint2 =
      endpoint_manager_->FindEndpointForDelivery(kGroupKey);
  ASSERT_TRUE(endpoint2);
  EXPECT_EQ(kEndpoint, endpoint2.info.url);

  endpoint_manager_->InformOfEndpointRequest(NetworkIsolationKey(), kEndpoint,
                                             false);

  // After a second failure, endpoint is backed off again.
  ReportingEndpoint endpoint3 =
      endpoint_manager_->FindEndpointForDelivery(kGroupKey);
  EXPECT_FALSE(endpoint3);

  clock_.Advance(initial_delay);

  // Next backoff is longer -- 2x the first -- so endpoint isn't usable yet.
  ReportingEndpoint endpoint4 =
      endpoint_manager_->FindEndpointForDelivery(kGroupKey);
  EXPECT_FALSE(endpoint4);

  clock_.Advance(initial_delay);

  // After 2x the initial delay, the endpoint is usable again.
  ReportingEndpoint endpoint5 =
      endpoint_manager_->FindEndpointForDelivery(kGroupKey);
  ASSERT_TRUE(endpoint5);
  EXPECT_EQ(kEndpoint, endpoint5.info.url);

  endpoint_manager_->InformOfEndpointRequest(NetworkIsolationKey(), kEndpoint,
                                             true);
  endpoint_manager_->InformOfEndpointRequest(NetworkIsolationKey(), kEndpoint,
                                             true);

  // Two more successful requests should reset the backoff to the initial delay
  // again.
  endpoint_manager_->InformOfEndpointRequest(NetworkIsolationKey(), kEndpoint,
                                             false);

  ReportingEndpoint endpoint6 =
      endpoint_manager_->FindEndpointForDelivery(kGroupKey);
  EXPECT_FALSE(endpoint6);

  clock_.Advance(initial_delay);

  ReportingEndpoint endpoint7 =
      endpoint_manager_->FindEndpointForDelivery(kGroupKey);
  EXPECT_TRUE(endpoint7);
}

// Make sure that multiple endpoints will all be returned at some point, to
// avoid accidentally or intentionally implementing any priority ordering.
TEST_F(ReportingEndpointManagerTest, RandomEndpoint) {
  static const GURL kEndpoint1("https://endpoint1/");
  static const GURL kEndpoint2("https://endpoint2/");
  static const int kMaxAttempts = 20;

  SetEndpoint(kEndpoint1);
  SetEndpoint(kEndpoint2);

  bool endpoint1_seen = false;
  bool endpoint2_seen = false;

  for (int i = 0; i < kMaxAttempts; ++i) {
    ReportingEndpoint endpoint =
        endpoint_manager_->FindEndpointForDelivery(kGroupKey);
    ASSERT_TRUE(endpoint);
    ASSERT_TRUE(endpoint.info.url == kEndpoint1 ||
                endpoint.info.url == kEndpoint2);

    if (endpoint.info.url == kEndpoint1)
      endpoint1_seen = true;
    else if (endpoint.info.url == kEndpoint2)
      endpoint2_seen = true;

    if (endpoint1_seen && endpoint2_seen)
      break;
  }

  EXPECT_TRUE(endpoint1_seen);
  EXPECT_TRUE(endpoint2_seen);
}

TEST_F(ReportingEndpointManagerTest, Priority) {
  static const GURL kPrimaryEndpoint("https://endpoint1/");
  static const GURL kBackupEndpoint("https://endpoint2/");

  SetEndpoint(kPrimaryEndpoint, 10 /* priority */,
              ReportingEndpoint::EndpointInfo::kDefaultWeight);
  SetEndpoint(kBackupEndpoint, 20 /* priority */,
              ReportingEndpoint::EndpointInfo::kDefaultWeight);

  ReportingEndpoint endpoint =
      endpoint_manager_->FindEndpointForDelivery(kGroupKey);
  ASSERT_TRUE(endpoint);
  EXPECT_EQ(kPrimaryEndpoint, endpoint.info.url);

  // The backoff policy we set up in the constructor means that a single failed
  // upload will take the primary endpoint out of contention.  This should cause
  // us to choose the backend endpoint.
  endpoint_manager_->InformOfEndpointRequest(NetworkIsolationKey(),
                                             kPrimaryEndpoint, false);
  ReportingEndpoint endpoint2 =
      endpoint_manager_->FindEndpointForDelivery(kGroupKey);
  ASSERT_TRUE(endpoint2);
  EXPECT_EQ(kBackupEndpoint, endpoint2.info.url);

  // Advance the current time far enough to clear out the primary endpoint's
  // backoff clock.  This should bring the primary endpoint back into play.
  clock_.Advance(base::TimeDelta::FromMinutes(2));
  ReportingEndpoint endpoint3 =
      endpoint_manager_->FindEndpointForDelivery(kGroupKey);
  ASSERT_TRUE(endpoint3);
  EXPECT_EQ(kPrimaryEndpoint, endpoint3.info.url);
}

// Note: This test depends on the deterministic mock RandIntCallback set up in
// TestReportingContext, which returns consecutive integers starting at 0
// (modulo the requested range, plus the requested minimum).
TEST_F(ReportingEndpointManagerTest, Weight) {
  static const GURL kEndpoint1("https://endpoint1/");
  static const GURL kEndpoint2("https://endpoint2/");

  static const int kEndpoint1Weight = 5;
  static const int kEndpoint2Weight = 2;
  static const int kTotalEndpointWeight = kEndpoint1Weight + kEndpoint2Weight;

  SetEndpoint(kEndpoint1, ReportingEndpoint::EndpointInfo::kDefaultPriority,
              kEndpoint1Weight);
  SetEndpoint(kEndpoint2, ReportingEndpoint::EndpointInfo::kDefaultPriority,
              kEndpoint2Weight);

  int endpoint1_count = 0;
  int endpoint2_count = 0;

  for (int i = 0; i < kTotalEndpointWeight; ++i) {
    ReportingEndpoint endpoint =
        endpoint_manager_->FindEndpointForDelivery(kGroupKey);
    ASSERT_TRUE(endpoint);
    ASSERT_TRUE(endpoint.info.url == kEndpoint1 ||
                endpoint.info.url == kEndpoint2);

    if (endpoint.info.url == kEndpoint1)
      ++endpoint1_count;
    else if (endpoint.info.url == kEndpoint2)
      ++endpoint2_count;
  }

  EXPECT_EQ(kEndpoint1Weight, endpoint1_count);
  EXPECT_EQ(kEndpoint2Weight, endpoint2_count);
}

TEST_F(ReportingEndpointManagerTest, ZeroWeights) {
  static const GURL kEndpoint1("https://endpoint1/");
  static const GURL kEndpoint2("https://endpoint2/");

  SetEndpoint(kEndpoint1, ReportingEndpoint::EndpointInfo::kDefaultPriority,
              0 /* weight */);
  SetEndpoint(kEndpoint2, ReportingEndpoint::EndpointInfo::kDefaultPriority,
              0 /* weight */);

  int endpoint1_count = 0;
  int endpoint2_count = 0;

  for (int i = 0; i < 10; ++i) {
    ReportingEndpoint endpoint =
        endpoint_manager_->FindEndpointForDelivery(kGroupKey);
    ASSERT_TRUE(endpoint);
    ASSERT_TRUE(endpoint.info.url == kEndpoint1 ||
                endpoint.info.url == kEndpoint2);

    if (endpoint.info.url == kEndpoint1)
      ++endpoint1_count;
    else if (endpoint.info.url == kEndpoint2)
      ++endpoint2_count;
  }

  EXPECT_EQ(5, endpoint1_count);
  EXPECT_EQ(5, endpoint2_count);
}

// Check that ReportingEndpointManager distinguishes NetworkIsolationKeys.
TEST_F(ReportingEndpointManagerTest, NetworkIsolationKey) {
  const url::Origin kOrigin2 = url::Origin::Create(GURL("https://origin2/"));

  const NetworkIsolationKey kNetworkIsolationKey1(kOrigin, kOrigin);
  const NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
  const ReportingEndpointGroupKey kGroupKey1(kNetworkIsolationKey1, kOrigin,
                                             kGroup);
  const ReportingEndpointGroupKey kGroupKey2(kNetworkIsolationKey2, kOrigin,
                                             kGroup);

  // An Endpoint set for kNetworkIsolationKey1 should not affect
  // kNetworkIsolationKey2.
  SetEndpoint(kEndpoint, ReportingEndpoint::EndpointInfo::kDefaultPriority,
              0 /* weight */, kNetworkIsolationKey1);
  ReportingEndpoint endpoint =
      endpoint_manager_->FindEndpointForDelivery(kGroupKey1);
  ASSERT_TRUE(endpoint);
  EXPECT_EQ(kEndpoint, endpoint.info.url);
  EXPECT_FALSE(endpoint_manager_->FindEndpointForDelivery(kGroupKey2));
  EXPECT_FALSE(endpoint_manager_->FindEndpointForDelivery(kGroupKey));

  // Set the same Endpoint for kNetworkIsolationKey2, so both should be
  // reporting to the same URL.
  SetEndpoint(kEndpoint, ReportingEndpoint::EndpointInfo::kDefaultPriority,
              0 /* weight */, kNetworkIsolationKey2);
  endpoint = endpoint_manager_->FindEndpointForDelivery(kGroupKey1);
  ASSERT_TRUE(endpoint);
  EXPECT_EQ(kEndpoint, endpoint.info.url);
  endpoint = endpoint_manager_->FindEndpointForDelivery(kGroupKey2);
  ASSERT_TRUE(endpoint);
  EXPECT_EQ(kEndpoint, endpoint.info.url);
  EXPECT_FALSE(endpoint_manager_->FindEndpointForDelivery(kGroupKey));

  // An error reporting to that URL in the context of kNetworkIsolationKey1
  // should only affect the Endpoint retrieved in the context of
  // kNetworkIsolationKey1.
  endpoint_manager_->InformOfEndpointRequest(kNetworkIsolationKey1, kEndpoint,
                                             false);
  EXPECT_FALSE(endpoint_manager_->FindEndpointForDelivery(kGroupKey1));
  endpoint = endpoint_manager_->FindEndpointForDelivery(kGroupKey2);
  ASSERT_TRUE(endpoint);
  EXPECT_EQ(kEndpoint, endpoint.info.url);
  EXPECT_FALSE(endpoint_manager_->FindEndpointForDelivery(kGroupKey));
}

TEST_F(ReportingEndpointManagerTest, NetworkIsolationKeyWithMultipleEndpoints) {
  const url::Origin kOrigin2 = url::Origin::Create(GURL("https://origin2/"));

  const NetworkIsolationKey kNetworkIsolationKey1(kOrigin, kOrigin);
  const NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
  const ReportingEndpointGroupKey kGroupKey1(kNetworkIsolationKey1, kOrigin,
                                             kGroup);
  const ReportingEndpointGroupKey kGroupKey2(kNetworkIsolationKey2, kOrigin,
                                             kGroup);

  const GURL kEndpoint1("https://endpoint1/");
  const GURL kEndpoint2("https://endpoint2/");
  const GURL kEndpoint3("https://endpoint3/");
  const int kMaxAttempts = 20;

  // Add two Endpoints for kNetworkIsolationKey1, and a different one for
  // kNetworkIsolationKey2.
  SetEndpoint(kEndpoint1, ReportingEndpoint::EndpointInfo::kDefaultPriority,
              ReportingEndpoint::EndpointInfo::kDefaultWeight,
              kNetworkIsolationKey1);
  SetEndpoint(kEndpoint2, ReportingEndpoint::EndpointInfo::kDefaultPriority,
              ReportingEndpoint::EndpointInfo::kDefaultWeight,
              kNetworkIsolationKey1);
  SetEndpoint(kEndpoint3, ReportingEndpoint::EndpointInfo::kDefaultPriority,
              ReportingEndpoint::EndpointInfo::kDefaultWeight,
              kNetworkIsolationKey2);

  bool endpoint1_seen = false;
  bool endpoint2_seen = false;

  // Make sure that calling FindEndpointForDelivery() with kNetworkIsolationKey1
  // can return both of its endpoints, but not kNetworkIsolationKey2's endpoint.
  for (int i = 0; i < kMaxAttempts; ++i) {
    ReportingEndpoint endpoint =
        endpoint_manager_->FindEndpointForDelivery(kGroupKey1);
    ASSERT_TRUE(endpoint);
    ASSERT_TRUE(endpoint.info.url == kEndpoint1 ||
                endpoint.info.url == kEndpoint2);

    if (endpoint.info.url == kEndpoint1) {
      endpoint1_seen = true;
    } else if (endpoint.info.url == kEndpoint2) {
      endpoint2_seen = true;
    }
  }

  EXPECT_TRUE(endpoint1_seen);
  EXPECT_TRUE(endpoint2_seen);

  ReportingEndpoint endpoint =
      endpoint_manager_->FindEndpointForDelivery(kGroupKey2);
  ASSERT_TRUE(endpoint);
  EXPECT_EQ(kEndpoint3, endpoint.info.url);
}

TEST_F(ReportingEndpointManagerTest, CacheEviction) {
  // Add |kMaxEndpointBackoffCacheSize| endpoints.
  for (int i = 0; i < ReportingEndpointManager::kMaxEndpointBackoffCacheSize;
       ++i) {
    SetEndpoint(GURL(base::StringPrintf("https://endpoint%i/", i)));
  }

  // Mark each endpoint as bad, one-at-a-time. Use FindEndpointForDelivery() to
  // pick which one to mark as bad, both to exercise the code walking through
  // all endpoints, and as a sanity check.
  std::set<GURL> seen_endpoints;
  for (int i = 0; i < ReportingEndpointManager::kMaxEndpointBackoffCacheSize;
       ++i) {
    ReportingEndpoint endpoint =
        endpoint_manager_->FindEndpointForDelivery(kGroupKey);
    EXPECT_TRUE(endpoint);
    EXPECT_FALSE(seen_endpoints.count(endpoint.info.url));
    seen_endpoints.insert(endpoint.info.url);
    endpoint_manager_->InformOfEndpointRequest(NetworkIsolationKey(),
                                               endpoint.info.url, false);
  }
  // All endpoints should now be marked as bad.
  EXPECT_FALSE(endpoint_manager_->FindEndpointForDelivery(kGroupKey));

  // Add another endpoint with a different NetworkIsolationKey;
  const NetworkIsolationKey kDifferentNetworkIsolationKey(kOrigin, kOrigin);
  const ReportingEndpointGroupKey kDifferentGroupKey(
      kDifferentNetworkIsolationKey, kOrigin, kGroup);
  SetEndpoint(kEndpoint, ReportingEndpoint::EndpointInfo::kDefaultPriority,
              ReportingEndpoint::EndpointInfo::kDefaultWeight,
              kDifferentNetworkIsolationKey);
  // All endpoints associated with the empty NetworkIsolationKey should still be
  // marked as bad.
  EXPECT_FALSE(endpoint_manager_->FindEndpointForDelivery(kGroupKey));

  // Make the endpoint added for the kDifferentNetworkIsolationKey as bad.
  endpoint_manager_->InformOfEndpointRequest(kDifferentNetworkIsolationKey,
                                             kEndpoint, false);
  // The only endpoint for kDifferentNetworkIsolationKey should still be marked
  // as bad.
  EXPECT_FALSE(endpoint_manager_->FindEndpointForDelivery(kDifferentGroupKey));
  // One of the endpoints for the empty NetworkIsolationKey should no longer be
  // marked as bad, due to eviction.
  ReportingEndpoint endpoint =
      endpoint_manager_->FindEndpointForDelivery(kGroupKey);
  EXPECT_TRUE(endpoint);

  // Reporting a success for the (only) good endpoint for the empty
  // NetworkIsolationKey should evict the entry for kNetworkIsolationKey, since
  // the most recent FindEndpointForDelivery() call visited all of the empty
  // NetworkIsolationKey's cached bad entries.
  endpoint_manager_->InformOfEndpointRequest(NetworkIsolationKey(),
                                             endpoint.info.url, true);

  EXPECT_TRUE(endpoint_manager_->FindEndpointForDelivery(kDifferentGroupKey));
}

}  // namespace
}  // namespace net
