xref: /aosp_15_r20/external/cronet/net/dns/host_cache_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/dns/host_cache.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <map>
8*6777b538SAndroid Build Coastguard Worker #include <memory>
9*6777b538SAndroid Build Coastguard Worker #include <optional>
10*6777b538SAndroid Build Coastguard Worker #include <string>
11*6777b538SAndroid Build Coastguard Worker #include <string_view>
12*6777b538SAndroid Build Coastguard Worker #include <utility>
13*6777b538SAndroid Build Coastguard Worker #include <vector>
14*6777b538SAndroid Build Coastguard Worker 
15*6777b538SAndroid Build Coastguard Worker #include "base/format_macros.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/json/json_reader.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/json/json_writer.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/ranges/algorithm.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/strings/strcat.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
25*6777b538SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
26*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
27*6777b538SAndroid Build Coastguard Worker #include "base/values.h"
28*6777b538SAndroid Build Coastguard Worker #include "net/base/connection_endpoint_metadata.h"
29*6777b538SAndroid Build Coastguard Worker #include "net/base/host_port_pair.h"
30*6777b538SAndroid Build Coastguard Worker #include "net/base/ip_address.h"
31*6777b538SAndroid Build Coastguard Worker #include "net/base/ip_endpoint.h"
32*6777b538SAndroid Build Coastguard Worker #include "net/base/network_anonymization_key.h"
33*6777b538SAndroid Build Coastguard Worker #include "net/base/schemeful_site.h"
34*6777b538SAndroid Build Coastguard Worker #include "net/dns/host_resolver_internal_result.h"
35*6777b538SAndroid Build Coastguard Worker #include "net/dns/host_resolver_results_test_util.h"
36*6777b538SAndroid Build Coastguard Worker #include "net/dns/https_record_rdata.h"
37*6777b538SAndroid Build Coastguard Worker #include "net/dns/public/host_resolver_results.h"
38*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
39*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
40*6777b538SAndroid Build Coastguard Worker #include "url/gurl.h"
41*6777b538SAndroid Build Coastguard Worker #include "url/scheme_host_port.h"
42*6777b538SAndroid Build Coastguard Worker #include "url/url_constants.h"
43*6777b538SAndroid Build Coastguard Worker 
44*6777b538SAndroid Build Coastguard Worker using ::testing::_;
45*6777b538SAndroid Build Coastguard Worker using ::testing::ElementsAre;
46*6777b538SAndroid Build Coastguard Worker using ::testing::ElementsAreArray;
47*6777b538SAndroid Build Coastguard Worker using ::testing::IsEmpty;
48*6777b538SAndroid Build Coastguard Worker using ::testing::Optional;
49*6777b538SAndroid Build Coastguard Worker using ::testing::Pair;
50*6777b538SAndroid Build Coastguard Worker using ::testing::Pointee;
51*6777b538SAndroid Build Coastguard Worker using ::testing::Property;
52*6777b538SAndroid Build Coastguard Worker using ::testing::UnorderedElementsAre;
53*6777b538SAndroid Build Coastguard Worker 
54*6777b538SAndroid Build Coastguard Worker namespace net {
55*6777b538SAndroid Build Coastguard Worker 
56*6777b538SAndroid Build Coastguard Worker namespace {
57*6777b538SAndroid Build Coastguard Worker 
58*6777b538SAndroid Build Coastguard Worker const int kMaxCacheEntries = 10;
59*6777b538SAndroid Build Coastguard Worker 
60*6777b538SAndroid Build Coastguard Worker // Builds a key for |hostname|, defaulting the query type to unspecified.
Key(const std::string & hostname)61*6777b538SAndroid Build Coastguard Worker HostCache::Key Key(const std::string& hostname) {
62*6777b538SAndroid Build Coastguard Worker   return HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, hostname, 443),
63*6777b538SAndroid Build Coastguard Worker                         DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
64*6777b538SAndroid Build Coastguard Worker                         NetworkAnonymizationKey());
65*6777b538SAndroid Build Coastguard Worker }
66*6777b538SAndroid Build Coastguard Worker 
FoobarIndexIsOdd(const std::string & foobarx_com)67*6777b538SAndroid Build Coastguard Worker bool FoobarIndexIsOdd(const std::string& foobarx_com) {
68*6777b538SAndroid Build Coastguard Worker   return (foobarx_com[6] - '0') % 2 == 1;
69*6777b538SAndroid Build Coastguard Worker }
70*6777b538SAndroid Build Coastguard Worker 
71*6777b538SAndroid Build Coastguard Worker class MockPersistenceDelegate : public HostCache::PersistenceDelegate {
72*6777b538SAndroid Build Coastguard Worker  public:
ScheduleWrite()73*6777b538SAndroid Build Coastguard Worker   void ScheduleWrite() override { ++num_changes_; }
74*6777b538SAndroid Build Coastguard Worker 
num_changes() const75*6777b538SAndroid Build Coastguard Worker   int num_changes() const { return num_changes_; }
76*6777b538SAndroid Build Coastguard Worker 
77*6777b538SAndroid Build Coastguard Worker  private:
78*6777b538SAndroid Build Coastguard Worker   int num_changes_ = 0;
79*6777b538SAndroid Build Coastguard Worker };
80*6777b538SAndroid Build Coastguard Worker 
81*6777b538SAndroid Build Coastguard Worker MATCHER_P(EntryContentsEqual,
82*6777b538SAndroid Build Coastguard Worker           entry,
83*6777b538SAndroid Build Coastguard Worker           base::StrCat({"contents ", negation ? "!=" : "==", " contents of ",
84*6777b538SAndroid Build Coastguard Worker                         testing::PrintToString(entry)})) {
85*6777b538SAndroid Build Coastguard Worker   return arg.ContentsEqual(entry);
86*6777b538SAndroid Build Coastguard Worker }
87*6777b538SAndroid Build Coastguard Worker 
MakeIP(std::string_view literal)88*6777b538SAndroid Build Coastguard Worker IPAddress MakeIP(std::string_view literal) {
89*6777b538SAndroid Build Coastguard Worker   IPAddress ret;
90*6777b538SAndroid Build Coastguard Worker   CHECK(ret.AssignFromIPLiteral(literal));
91*6777b538SAndroid Build Coastguard Worker   return ret;
92*6777b538SAndroid Build Coastguard Worker }
93*6777b538SAndroid Build Coastguard Worker 
MakeEndpoints(std::vector<std::string> my_addresses)94*6777b538SAndroid Build Coastguard Worker std::vector<IPEndPoint> MakeEndpoints(std::vector<std::string> my_addresses) {
95*6777b538SAndroid Build Coastguard Worker   std::vector<IPEndPoint> out(my_addresses.size());
96*6777b538SAndroid Build Coastguard Worker   base::ranges::transform(my_addresses, out.begin(),
97*6777b538SAndroid Build Coastguard Worker                           [](auto& s) { return IPEndPoint(MakeIP(s), 0); });
98*6777b538SAndroid Build Coastguard Worker   return out;
99*6777b538SAndroid Build Coastguard Worker }
100*6777b538SAndroid Build Coastguard Worker 
101*6777b538SAndroid Build Coastguard Worker }  // namespace
102*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,Basic)103*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, Basic) {
104*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kTTL = base::Seconds(10);
105*6777b538SAndroid Build Coastguard Worker 
106*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
107*6777b538SAndroid Build Coastguard Worker 
108*6777b538SAndroid Build Coastguard Worker   // Start at t=0.
109*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
110*6777b538SAndroid Build Coastguard Worker 
111*6777b538SAndroid Build Coastguard Worker   HostCache::Key key1 = Key("foobar.com");
112*6777b538SAndroid Build Coastguard Worker   HostCache::Key key2 = Key("foobar2.com");
113*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry =
114*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{"foobar.com"},
115*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
116*6777b538SAndroid Build Coastguard Worker 
117*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, cache.size());
118*6777b538SAndroid Build Coastguard Worker 
119*6777b538SAndroid Build Coastguard Worker   // Add an entry for "foobar.com" at t=0.
120*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
121*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry, now, kTTL);
122*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
123*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now)->second.error() == entry.error());
124*6777b538SAndroid Build Coastguard Worker 
125*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, cache.size());
126*6777b538SAndroid Build Coastguard Worker 
127*6777b538SAndroid Build Coastguard Worker   // Advance to t=5.
128*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(5);
129*6777b538SAndroid Build Coastguard Worker 
130*6777b538SAndroid Build Coastguard Worker   // Add an entry for "foobar2.com" at t=5.
131*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key2, now));
132*6777b538SAndroid Build Coastguard Worker   cache.Set(key2, entry, now, kTTL);
133*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key2, now));
134*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, cache.size());
135*6777b538SAndroid Build Coastguard Worker 
136*6777b538SAndroid Build Coastguard Worker   // Advance to t=9
137*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(4);
138*6777b538SAndroid Build Coastguard Worker 
139*6777b538SAndroid Build Coastguard Worker   // Verify that the entries we added are still retrievable, and usable.
140*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
141*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key2, now));
142*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(cache.Lookup(key1, now), cache.Lookup(key2, now));
143*6777b538SAndroid Build Coastguard Worker 
144*6777b538SAndroid Build Coastguard Worker   // Advance to t=10; key is now expired.
145*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(1);
146*6777b538SAndroid Build Coastguard Worker 
147*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
148*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key2, now));
149*6777b538SAndroid Build Coastguard Worker 
150*6777b538SAndroid Build Coastguard Worker   // Update key1, so it is no longer expired.
151*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry, now, kTTL);
152*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
153*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, cache.size());
154*6777b538SAndroid Build Coastguard Worker 
155*6777b538SAndroid Build Coastguard Worker   // Both entries should still be retrievable and usable.
156*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
157*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key2, now));
158*6777b538SAndroid Build Coastguard Worker 
159*6777b538SAndroid Build Coastguard Worker   // Advance to t=20; both entries are now expired.
160*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(10);
161*6777b538SAndroid Build Coastguard Worker 
162*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
163*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key2, now));
164*6777b538SAndroid Build Coastguard Worker }
165*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,GetEndpoints)166*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, GetEndpoints) {
167*6777b538SAndroid Build Coastguard Worker   std::vector<IPEndPoint> ip_endpoints = {IPEndPoint(IPAddress(1, 1, 1, 1), 0),
168*6777b538SAndroid Build Coastguard Worker                                           IPEndPoint(IPAddress(2, 2, 2, 2), 0)};
169*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry(OK, ip_endpoints, /*aliases=*/{},
170*6777b538SAndroid Build Coastguard Worker                          HostCache::Entry::SOURCE_DNS);
171*6777b538SAndroid Build Coastguard Worker 
172*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(entry.GetEndpoints(),
173*6777b538SAndroid Build Coastguard Worker               ElementsAre(ExpectEndpointResult(ip_endpoints)));
174*6777b538SAndroid Build Coastguard Worker }
175*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,GetEmptyEndpoints)176*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, GetEmptyEndpoints) {
177*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry(ERR_NAME_NOT_RESOLVED, /*ip_endpoints=*/{},
178*6777b538SAndroid Build Coastguard Worker                          /*aliases=*/{}, HostCache::Entry::SOURCE_DNS);
179*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(entry.GetEndpoints(), IsEmpty());
180*6777b538SAndroid Build Coastguard Worker }
181*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,GetEmptyEndpointsWithMetadata)182*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, GetEmptyEndpointsWithMetadata) {
183*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry(ERR_NAME_NOT_RESOLVED, /*ip_endpoints=*/{},
184*6777b538SAndroid Build Coastguard Worker                          /*aliases=*/{}, HostCache::Entry::SOURCE_DNS);
185*6777b538SAndroid Build Coastguard Worker 
186*6777b538SAndroid Build Coastguard Worker   // Merge in non-empty metadata.
187*6777b538SAndroid Build Coastguard Worker   ConnectionEndpointMetadata metadata;
188*6777b538SAndroid Build Coastguard Worker   metadata.supported_protocol_alpns = {"h3", "h2"};
189*6777b538SAndroid Build Coastguard Worker   HostCache::Entry metadata_entry(
190*6777b538SAndroid Build Coastguard Worker       OK,
191*6777b538SAndroid Build Coastguard Worker       std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>{
192*6777b538SAndroid Build Coastguard Worker           {1u, metadata}},
193*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::SOURCE_DNS);
194*6777b538SAndroid Build Coastguard Worker 
195*6777b538SAndroid Build Coastguard Worker   auto merged_entry = HostCache::Entry::MergeEntries(entry, metadata_entry);
196*6777b538SAndroid Build Coastguard Worker 
197*6777b538SAndroid Build Coastguard Worker   // Result should still be empty.
198*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(merged_entry.GetEndpoints(), IsEmpty());
199*6777b538SAndroid Build Coastguard Worker }
200*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,GetMissingEndpoints)201*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, GetMissingEndpoints) {
202*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_DNS);
203*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(entry.GetEndpoints(), IsEmpty());
204*6777b538SAndroid Build Coastguard Worker }
205*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,GetMissingEndpointsWithMetadata)206*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, GetMissingEndpointsWithMetadata) {
207*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_DNS);
208*6777b538SAndroid Build Coastguard Worker 
209*6777b538SAndroid Build Coastguard Worker   // Merge in non-empty metadata.
210*6777b538SAndroid Build Coastguard Worker   ConnectionEndpointMetadata metadata;
211*6777b538SAndroid Build Coastguard Worker   metadata.supported_protocol_alpns = {"h3", "h2"};
212*6777b538SAndroid Build Coastguard Worker   HostCache::Entry metadata_entry(
213*6777b538SAndroid Build Coastguard Worker       OK,
214*6777b538SAndroid Build Coastguard Worker       std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>{
215*6777b538SAndroid Build Coastguard Worker           {1u, metadata}},
216*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::SOURCE_DNS);
217*6777b538SAndroid Build Coastguard Worker 
218*6777b538SAndroid Build Coastguard Worker   auto merged_entry = HostCache::Entry::MergeEntries(entry, metadata_entry);
219*6777b538SAndroid Build Coastguard Worker 
220*6777b538SAndroid Build Coastguard Worker   // Result should still be empty.
221*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(merged_entry.GetEndpoints(), IsEmpty());
222*6777b538SAndroid Build Coastguard Worker }
223*6777b538SAndroid Build Coastguard Worker 
224*6777b538SAndroid Build Coastguard Worker // Test that Keys without scheme are allowed and treated as completely different
225*6777b538SAndroid Build Coastguard Worker // from similar Keys with scheme.
TEST(HostCacheTest,HandlesKeysWithoutScheme)226*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, HandlesKeysWithoutScheme) {
227*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kTTL = base::Seconds(10);
228*6777b538SAndroid Build Coastguard Worker 
229*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
230*6777b538SAndroid Build Coastguard Worker 
231*6777b538SAndroid Build Coastguard Worker   // t=0.
232*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
233*6777b538SAndroid Build Coastguard Worker 
234*6777b538SAndroid Build Coastguard Worker   HostCache::Key key("host1.test", DnsQueryType::UNSPECIFIED, 0,
235*6777b538SAndroid Build Coastguard Worker                      HostResolverSource::ANY, NetworkAnonymizationKey());
236*6777b538SAndroid Build Coastguard Worker   HostCache::Key key_with_scheme(
237*6777b538SAndroid Build Coastguard Worker       url::SchemeHostPort(url::kHttpsScheme, "host1.test", 443),
238*6777b538SAndroid Build Coastguard Worker       DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
239*6777b538SAndroid Build Coastguard Worker       NetworkAnonymizationKey());
240*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(key, key_with_scheme);
241*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry =
242*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
243*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
244*6777b538SAndroid Build Coastguard Worker 
245*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0U, cache.size());
246*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(cache.Lookup(key, now));
247*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(cache.Lookup(key_with_scheme, now));
248*6777b538SAndroid Build Coastguard Worker 
249*6777b538SAndroid Build Coastguard Worker   // Add entry for `key`.
250*6777b538SAndroid Build Coastguard Worker   cache.Set(key, entry, now, kTTL);
251*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, cache.size());
252*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key, now));
253*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key_with_scheme, now));
254*6777b538SAndroid Build Coastguard Worker 
255*6777b538SAndroid Build Coastguard Worker   // Add entry for `key_with_scheme`.
256*6777b538SAndroid Build Coastguard Worker   cache.Set(key_with_scheme, entry, now, kTTL);
257*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, cache.size());
258*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key, now));
259*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key_with_scheme, now));
260*6777b538SAndroid Build Coastguard Worker 
261*6777b538SAndroid Build Coastguard Worker   // Clear the cache and try adding in reverse order.
262*6777b538SAndroid Build Coastguard Worker   cache.clear();
263*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0U, cache.size());
264*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(cache.Lookup(key, now));
265*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(cache.Lookup(key_with_scheme, now));
266*6777b538SAndroid Build Coastguard Worker 
267*6777b538SAndroid Build Coastguard Worker   // Add entry for `key_with_scheme`.
268*6777b538SAndroid Build Coastguard Worker   cache.Set(key_with_scheme, entry, now, kTTL);
269*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, cache.size());
270*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key, now));
271*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key_with_scheme, now));
272*6777b538SAndroid Build Coastguard Worker 
273*6777b538SAndroid Build Coastguard Worker   // Add entry for `key`.
274*6777b538SAndroid Build Coastguard Worker   cache.Set(key, entry, now, kTTL);
275*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, cache.size());
276*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key, now));
277*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key_with_scheme, now));
278*6777b538SAndroid Build Coastguard Worker }
279*6777b538SAndroid Build Coastguard Worker 
280*6777b538SAndroid Build Coastguard Worker // Make sure NetworkAnonymizationKey is respected.
TEST(HostCacheTest,NetworkAnonymizationKey)281*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, NetworkAnonymizationKey) {
282*6777b538SAndroid Build Coastguard Worker   const url::SchemeHostPort kHost(url::kHttpsScheme, "hostname.test", 443);
283*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kTTL = base::Seconds(10);
284*6777b538SAndroid Build Coastguard Worker 
285*6777b538SAndroid Build Coastguard Worker   const SchemefulSite kSite1(GURL("https://site1.test/"));
286*6777b538SAndroid Build Coastguard Worker   const auto kNetworkAnonymizationKey1 =
287*6777b538SAndroid Build Coastguard Worker       NetworkAnonymizationKey::CreateSameSite(kSite1);
288*6777b538SAndroid Build Coastguard Worker   const SchemefulSite kSite2(GURL("https://site2.test/"));
289*6777b538SAndroid Build Coastguard Worker   const auto kNetworkAnonymizationKey2 =
290*6777b538SAndroid Build Coastguard Worker       NetworkAnonymizationKey::CreateSameSite(kSite2);
291*6777b538SAndroid Build Coastguard Worker 
292*6777b538SAndroid Build Coastguard Worker   HostCache::Key key1(kHost, DnsQueryType::UNSPECIFIED, 0,
293*6777b538SAndroid Build Coastguard Worker                       HostResolverSource::ANY, kNetworkAnonymizationKey1);
294*6777b538SAndroid Build Coastguard Worker   HostCache::Key key2(kHost, DnsQueryType::UNSPECIFIED, 0,
295*6777b538SAndroid Build Coastguard Worker                       HostResolverSource::ANY, kNetworkAnonymizationKey2);
296*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry1 =
297*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
298*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
299*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry2 =
300*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(ERR_FAILED, /*ip_endpoints=*/{}, /*aliases=*/{},
301*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
302*6777b538SAndroid Build Coastguard Worker 
303*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
304*6777b538SAndroid Build Coastguard Worker 
305*6777b538SAndroid Build Coastguard Worker   // Start at t=0.
306*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
307*6777b538SAndroid Build Coastguard Worker 
308*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, cache.size());
309*6777b538SAndroid Build Coastguard Worker 
310*6777b538SAndroid Build Coastguard Worker   // Add an entry for kNetworkAnonymizationKey1.
311*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
312*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry1, now, kTTL);
313*6777b538SAndroid Build Coastguard Worker 
314*6777b538SAndroid Build Coastguard Worker   const std::pair<const HostCache::Key, HostCache::Entry>* result =
315*6777b538SAndroid Build Coastguard Worker       cache.Lookup(key1, now);
316*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(result);
317*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNetworkAnonymizationKey1, result->first.network_anonymization_key);
318*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(OK, result->second.error());
319*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key2, now));
320*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, cache.size());
321*6777b538SAndroid Build Coastguard Worker 
322*6777b538SAndroid Build Coastguard Worker   // Add a different entry for kNetworkAnonymizationKey2.
323*6777b538SAndroid Build Coastguard Worker   cache.Set(key2, entry2, now, 3 * kTTL);
324*6777b538SAndroid Build Coastguard Worker   result = cache.Lookup(key1, now);
325*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(result);
326*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNetworkAnonymizationKey1, result->first.network_anonymization_key);
327*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(OK, result->second.error());
328*6777b538SAndroid Build Coastguard Worker   result = cache.Lookup(key2, now);
329*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(result);
330*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNetworkAnonymizationKey2, result->first.network_anonymization_key);
331*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_FAILED, result->second.error());
332*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, cache.size());
333*6777b538SAndroid Build Coastguard Worker 
334*6777b538SAndroid Build Coastguard Worker   // Advance time so that first entry times out. Second entry should remain.
335*6777b538SAndroid Build Coastguard Worker   now += 2 * kTTL;
336*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
337*6777b538SAndroid Build Coastguard Worker   result = cache.Lookup(key2, now);
338*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(result);
339*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNetworkAnonymizationKey2, result->first.network_anonymization_key);
340*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_FAILED, result->second.error());
341*6777b538SAndroid Build Coastguard Worker }
342*6777b538SAndroid Build Coastguard Worker 
343*6777b538SAndroid Build Coastguard Worker // Try caching entries for a failed resolve attempt -- since we set the TTL of
344*6777b538SAndroid Build Coastguard Worker // such entries to 0 it won't store, but it will kick out the previous result.
TEST(HostCacheTest,NoCacheZeroTTL)345*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, NoCacheZeroTTL) {
346*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kSuccessEntryTTL = base::Seconds(10);
347*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kFailureEntryTTL = base::Seconds(0);
348*6777b538SAndroid Build Coastguard Worker 
349*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
350*6777b538SAndroid Build Coastguard Worker 
351*6777b538SAndroid Build Coastguard Worker   // Set t=0.
352*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
353*6777b538SAndroid Build Coastguard Worker 
354*6777b538SAndroid Build Coastguard Worker   HostCache::Key key1 = Key("foobar.com");
355*6777b538SAndroid Build Coastguard Worker   HostCache::Key key2 = Key("foobar2.com");
356*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry =
357*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
358*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
359*6777b538SAndroid Build Coastguard Worker 
360*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
361*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry, now, kFailureEntryTTL);
362*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, cache.size());
363*6777b538SAndroid Build Coastguard Worker 
364*6777b538SAndroid Build Coastguard Worker   // We disallow use of negative entries.
365*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
366*6777b538SAndroid Build Coastguard Worker 
367*6777b538SAndroid Build Coastguard Worker   // Now overwrite with a valid entry, and then overwrite with negative entry
368*6777b538SAndroid Build Coastguard Worker   // again -- the valid entry should be kicked out.
369*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry, now, kSuccessEntryTTL);
370*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
371*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry, now, kFailureEntryTTL);
372*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
373*6777b538SAndroid Build Coastguard Worker }
374*6777b538SAndroid Build Coastguard Worker 
375*6777b538SAndroid Build Coastguard Worker // Try caching entries for a failed resolves for 10 seconds.
TEST(HostCacheTest,CacheNegativeEntry)376*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, CacheNegativeEntry) {
377*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kFailureEntryTTL = base::Seconds(10);
378*6777b538SAndroid Build Coastguard Worker 
379*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
380*6777b538SAndroid Build Coastguard Worker 
381*6777b538SAndroid Build Coastguard Worker   // Start at t=0.
382*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
383*6777b538SAndroid Build Coastguard Worker 
384*6777b538SAndroid Build Coastguard Worker   HostCache::Key key1 = Key("foobar.com");
385*6777b538SAndroid Build Coastguard Worker   HostCache::Key key2 = Key("foobar2.com");
386*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry =
387*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
388*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
389*6777b538SAndroid Build Coastguard Worker 
390*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, cache.size());
391*6777b538SAndroid Build Coastguard Worker 
392*6777b538SAndroid Build Coastguard Worker   // Add an entry for "foobar.com" at t=0.
393*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
394*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry, now, kFailureEntryTTL);
395*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
396*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, cache.size());
397*6777b538SAndroid Build Coastguard Worker 
398*6777b538SAndroid Build Coastguard Worker   // Advance to t=5.
399*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(5);
400*6777b538SAndroid Build Coastguard Worker 
401*6777b538SAndroid Build Coastguard Worker   // Add an entry for "foobar2.com" at t=5.
402*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key2, now));
403*6777b538SAndroid Build Coastguard Worker   cache.Set(key2, entry, now, kFailureEntryTTL);
404*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key2, now));
405*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, cache.size());
406*6777b538SAndroid Build Coastguard Worker 
407*6777b538SAndroid Build Coastguard Worker   // Advance to t=9
408*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(4);
409*6777b538SAndroid Build Coastguard Worker 
410*6777b538SAndroid Build Coastguard Worker   // Verify that the entries we added are still retrievable, and usable.
411*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
412*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key2, now));
413*6777b538SAndroid Build Coastguard Worker 
414*6777b538SAndroid Build Coastguard Worker   // Advance to t=10; key1 is now expired.
415*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(1);
416*6777b538SAndroid Build Coastguard Worker 
417*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
418*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key2, now));
419*6777b538SAndroid Build Coastguard Worker 
420*6777b538SAndroid Build Coastguard Worker   // Update key1, so it is no longer expired.
421*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry, now, kFailureEntryTTL);
422*6777b538SAndroid Build Coastguard Worker   // Re-uses existing entry storage.
423*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
424*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, cache.size());
425*6777b538SAndroid Build Coastguard Worker 
426*6777b538SAndroid Build Coastguard Worker   // Both entries should still be retrievable and usable.
427*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
428*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key2, now));
429*6777b538SAndroid Build Coastguard Worker 
430*6777b538SAndroid Build Coastguard Worker   // Advance to t=20; both entries are now expired.
431*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(10);
432*6777b538SAndroid Build Coastguard Worker 
433*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
434*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key2, now));
435*6777b538SAndroid Build Coastguard Worker }
436*6777b538SAndroid Build Coastguard Worker 
437*6777b538SAndroid Build Coastguard Worker // Tests that the same hostname can be duplicated in the cache, so long as
438*6777b538SAndroid Build Coastguard Worker // the query type differs.
TEST(HostCacheTest,DnsQueryTypeIsPartOfKey)439*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, DnsQueryTypeIsPartOfKey) {
440*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kSuccessEntryTTL = base::Seconds(10);
441*6777b538SAndroid Build Coastguard Worker 
442*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
443*6777b538SAndroid Build Coastguard Worker 
444*6777b538SAndroid Build Coastguard Worker   // t=0.
445*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
446*6777b538SAndroid Build Coastguard Worker 
447*6777b538SAndroid Build Coastguard Worker   HostCache::Key key1(url::SchemeHostPort(url::kHttpScheme, "foobar.com", 80),
448*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
449*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey());
450*6777b538SAndroid Build Coastguard Worker   HostCache::Key key2(url::SchemeHostPort(url::kHttpScheme, "foobar.com", 80),
451*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::A, 0, HostResolverSource::ANY,
452*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey());
453*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry =
454*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
455*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
456*6777b538SAndroid Build Coastguard Worker 
457*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, cache.size());
458*6777b538SAndroid Build Coastguard Worker 
459*6777b538SAndroid Build Coastguard Worker   // Add an entry for ("foobar.com", UNSPECIFIED) at t=0.
460*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
461*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry, now, kSuccessEntryTTL);
462*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
463*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, cache.size());
464*6777b538SAndroid Build Coastguard Worker 
465*6777b538SAndroid Build Coastguard Worker   // Add an entry for ("foobar.com", IPV4_ONLY) at t=0.
466*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key2, now));
467*6777b538SAndroid Build Coastguard Worker   cache.Set(key2, entry, now, kSuccessEntryTTL);
468*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key2, now));
469*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, cache.size());
470*6777b538SAndroid Build Coastguard Worker 
471*6777b538SAndroid Build Coastguard Worker   // Even though the hostnames were the same, we should have two unique
472*6777b538SAndroid Build Coastguard Worker   // entries (because the address families differ).
473*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(cache.Lookup(key1, now), cache.Lookup(key2, now));
474*6777b538SAndroid Build Coastguard Worker }
475*6777b538SAndroid Build Coastguard Worker 
476*6777b538SAndroid Build Coastguard Worker // Tests that the same hostname can be duplicated in the cache, so long as
477*6777b538SAndroid Build Coastguard Worker // the HostResolverFlags differ.
TEST(HostCacheTest,HostResolverFlagsArePartOfKey)478*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, HostResolverFlagsArePartOfKey) {
479*6777b538SAndroid Build Coastguard Worker   const url::SchemeHostPort kHost(url::kHttpsScheme, "foobar.test", 443);
480*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kTTL = base::Seconds(10);
481*6777b538SAndroid Build Coastguard Worker 
482*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
483*6777b538SAndroid Build Coastguard Worker 
484*6777b538SAndroid Build Coastguard Worker   // t=0.
485*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
486*6777b538SAndroid Build Coastguard Worker 
487*6777b538SAndroid Build Coastguard Worker   HostCache::Key key1(kHost, DnsQueryType::A, 0, HostResolverSource::ANY,
488*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey());
489*6777b538SAndroid Build Coastguard Worker   HostCache::Key key2(kHost, DnsQueryType::A, HOST_RESOLVER_CANONNAME,
490*6777b538SAndroid Build Coastguard Worker                       HostResolverSource::ANY, NetworkAnonymizationKey());
491*6777b538SAndroid Build Coastguard Worker   HostCache::Key key3(kHost, DnsQueryType::A, HOST_RESOLVER_LOOPBACK_ONLY,
492*6777b538SAndroid Build Coastguard Worker                       HostResolverSource::ANY, NetworkAnonymizationKey());
493*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry =
494*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
495*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
496*6777b538SAndroid Build Coastguard Worker 
497*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, cache.size());
498*6777b538SAndroid Build Coastguard Worker 
499*6777b538SAndroid Build Coastguard Worker   // Add an entry for ("foobar.com", IPV4, NONE) at t=0.
500*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
501*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry, now, kTTL);
502*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
503*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, cache.size());
504*6777b538SAndroid Build Coastguard Worker 
505*6777b538SAndroid Build Coastguard Worker   // Add an entry for ("foobar.com", IPV4, CANONNAME) at t=0.
506*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key2, now));
507*6777b538SAndroid Build Coastguard Worker   cache.Set(key2, entry, now, kTTL);
508*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key2, now));
509*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, cache.size());
510*6777b538SAndroid Build Coastguard Worker 
511*6777b538SAndroid Build Coastguard Worker   // Add an entry for ("foobar.com", IPV4, LOOPBACK_ONLY) at t=0.
512*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key3, now));
513*6777b538SAndroid Build Coastguard Worker   cache.Set(key3, entry, now, kTTL);
514*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key3, now));
515*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3U, cache.size());
516*6777b538SAndroid Build Coastguard Worker 
517*6777b538SAndroid Build Coastguard Worker   // Even though the hostnames were the same, we should have two unique
518*6777b538SAndroid Build Coastguard Worker   // entries (because the HostResolverFlags differ).
519*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(cache.Lookup(key1, now), cache.Lookup(key2, now));
520*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(cache.Lookup(key1, now), cache.Lookup(key3, now));
521*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(cache.Lookup(key2, now), cache.Lookup(key3, now));
522*6777b538SAndroid Build Coastguard Worker }
523*6777b538SAndroid Build Coastguard Worker 
524*6777b538SAndroid Build Coastguard Worker // Tests that the same hostname can be duplicated in the cache, so long as
525*6777b538SAndroid Build Coastguard Worker // the HostResolverSource differs.
TEST(HostCacheTest,HostResolverSourceIsPartOfKey)526*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, HostResolverSourceIsPartOfKey) {
527*6777b538SAndroid Build Coastguard Worker   const url::SchemeHostPort kHost(url::kHttpsScheme, "foobar.test", 443);
528*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kSuccessEntryTTL = base::Seconds(10);
529*6777b538SAndroid Build Coastguard Worker 
530*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
531*6777b538SAndroid Build Coastguard Worker 
532*6777b538SAndroid Build Coastguard Worker   // t=0.
533*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
534*6777b538SAndroid Build Coastguard Worker 
535*6777b538SAndroid Build Coastguard Worker   HostCache::Key key1(kHost, DnsQueryType::UNSPECIFIED, 0,
536*6777b538SAndroid Build Coastguard Worker                       HostResolverSource::ANY, NetworkAnonymizationKey());
537*6777b538SAndroid Build Coastguard Worker   HostCache::Key key2(kHost, DnsQueryType::UNSPECIFIED, 0,
538*6777b538SAndroid Build Coastguard Worker                       HostResolverSource::DNS, NetworkAnonymizationKey());
539*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry =
540*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
541*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
542*6777b538SAndroid Build Coastguard Worker 
543*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, cache.size());
544*6777b538SAndroid Build Coastguard Worker 
545*6777b538SAndroid Build Coastguard Worker   // Add an entry for ("foobar.com", UNSPECIFIED, ANY) at t=0.
546*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
547*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry, now, kSuccessEntryTTL);
548*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
549*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, cache.size());
550*6777b538SAndroid Build Coastguard Worker 
551*6777b538SAndroid Build Coastguard Worker   // Add an entry for ("foobar.com", UNSPECIFIED, DNS) at t=0.
552*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key2, now));
553*6777b538SAndroid Build Coastguard Worker   cache.Set(key2, entry, now, kSuccessEntryTTL);
554*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key2, now));
555*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, cache.size());
556*6777b538SAndroid Build Coastguard Worker 
557*6777b538SAndroid Build Coastguard Worker   // Even though the hostnames were the same, we should have two unique
558*6777b538SAndroid Build Coastguard Worker   // entries (because the HostResolverSource differs).
559*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(cache.Lookup(key1, now), cache.Lookup(key2, now));
560*6777b538SAndroid Build Coastguard Worker }
561*6777b538SAndroid Build Coastguard Worker 
562*6777b538SAndroid Build Coastguard Worker // Tests that the same hostname can be duplicated in the cache, so long as
563*6777b538SAndroid Build Coastguard Worker // the secure field in the key differs.
TEST(HostCacheTest,SecureIsPartOfKey)564*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, SecureIsPartOfKey) {
565*6777b538SAndroid Build Coastguard Worker   const url::SchemeHostPort kHost(url::kHttpsScheme, "foobar.test", 443);
566*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kSuccessEntryTTL = base::Seconds(10);
567*6777b538SAndroid Build Coastguard Worker 
568*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
569*6777b538SAndroid Build Coastguard Worker 
570*6777b538SAndroid Build Coastguard Worker   // t=0.
571*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
572*6777b538SAndroid Build Coastguard Worker   HostCache::EntryStaleness stale;
573*6777b538SAndroid Build Coastguard Worker 
574*6777b538SAndroid Build Coastguard Worker   HostCache::Key key1(kHost, DnsQueryType::A, 0, HostResolverSource::ANY,
575*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey());
576*6777b538SAndroid Build Coastguard Worker   key1.secure = true;
577*6777b538SAndroid Build Coastguard Worker   HostCache::Key key2(kHost, DnsQueryType::A, 0, HostResolverSource::ANY,
578*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey());
579*6777b538SAndroid Build Coastguard Worker   key2.secure = false;
580*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry =
581*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
582*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
583*6777b538SAndroid Build Coastguard Worker 
584*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, cache.size());
585*6777b538SAndroid Build Coastguard Worker 
586*6777b538SAndroid Build Coastguard Worker   // Add an entry for ("foobar.com", IPV4, true /* secure */) at t=0.
587*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
588*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry, now, kSuccessEntryTTL);
589*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
590*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, cache.size());
591*6777b538SAndroid Build Coastguard Worker 
592*6777b538SAndroid Build Coastguard Worker   // Lookup a key that is identical to the inserted key except for the secure
593*6777b538SAndroid Build Coastguard Worker   // field.
594*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key2, now));
595*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.LookupStale(key2, now, &stale));
596*6777b538SAndroid Build Coastguard Worker   const std::pair<const HostCache::Key, HostCache::Entry>* result;
597*6777b538SAndroid Build Coastguard Worker   result = cache.Lookup(key2, now, true /* ignore_secure */);
598*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(result);
599*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(result->first.secure);
600*6777b538SAndroid Build Coastguard Worker   result = cache.LookupStale(key2, now, &stale, true /* ignore_secure */);
601*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(result);
602*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(result->first.secure);
603*6777b538SAndroid Build Coastguard Worker 
604*6777b538SAndroid Build Coastguard Worker   // Add an entry for ("foobar.com", IPV4, false */ secure */) at t=0.
605*6777b538SAndroid Build Coastguard Worker   cache.Set(key2, entry, now, kSuccessEntryTTL);
606*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key2, now));
607*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.LookupStale(key2, now, &stale));
608*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, cache.size());
609*6777b538SAndroid Build Coastguard Worker }
610*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,PreferLessStaleMoreSecure)611*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, PreferLessStaleMoreSecure) {
612*6777b538SAndroid Build Coastguard Worker   const url::SchemeHostPort kHost(url::kHttpsScheme, "foobar.test", 443);
613*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kSuccessEntryTTL = base::Seconds(10);
614*6777b538SAndroid Build Coastguard Worker 
615*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
616*6777b538SAndroid Build Coastguard Worker 
617*6777b538SAndroid Build Coastguard Worker   // t=0.
618*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
619*6777b538SAndroid Build Coastguard Worker   HostCache::EntryStaleness stale;
620*6777b538SAndroid Build Coastguard Worker 
621*6777b538SAndroid Build Coastguard Worker   HostCache::Key insecure_key(kHost, DnsQueryType::A, 0,
622*6777b538SAndroid Build Coastguard Worker                               HostResolverSource::ANY,
623*6777b538SAndroid Build Coastguard Worker                               NetworkAnonymizationKey());
624*6777b538SAndroid Build Coastguard Worker   HostCache::Key secure_key(kHost, DnsQueryType::A, 0, HostResolverSource::ANY,
625*6777b538SAndroid Build Coastguard Worker                             NetworkAnonymizationKey());
626*6777b538SAndroid Build Coastguard Worker   secure_key.secure = true;
627*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry =
628*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
629*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
630*6777b538SAndroid Build Coastguard Worker 
631*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, cache.size());
632*6777b538SAndroid Build Coastguard Worker 
633*6777b538SAndroid Build Coastguard Worker   // Add both insecure and secure entries.
634*6777b538SAndroid Build Coastguard Worker   cache.Set(insecure_key, entry, now, kSuccessEntryTTL);
635*6777b538SAndroid Build Coastguard Worker   cache.Set(secure_key, entry, now, kSuccessEntryTTL);
636*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(insecure_key, cache.Lookup(insecure_key, now)->first);
637*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(secure_key, cache.Lookup(secure_key, now)->first);
638*6777b538SAndroid Build Coastguard Worker   // Secure key is preferred when equally stale.
639*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(secure_key,
640*6777b538SAndroid Build Coastguard Worker             cache.Lookup(insecure_key, now, true /* ignore_secure */)->first);
641*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(secure_key,
642*6777b538SAndroid Build Coastguard Worker             cache.Lookup(insecure_key, now, true /* ignore_secure */)->first);
643*6777b538SAndroid Build Coastguard Worker 
644*6777b538SAndroid Build Coastguard Worker   // Simulate network change.
645*6777b538SAndroid Build Coastguard Worker   cache.Invalidate();
646*6777b538SAndroid Build Coastguard Worker 
647*6777b538SAndroid Build Coastguard Worker   // Re-add insecure entry.
648*6777b538SAndroid Build Coastguard Worker   cache.Set(insecure_key, entry, now, kSuccessEntryTTL);
649*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(insecure_key, cache.Lookup(insecure_key, now)->first);
650*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(secure_key, now));
651*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(secure_key, cache.LookupStale(secure_key, now, &stale)->first);
652*6777b538SAndroid Build Coastguard Worker   // Result with fewer network changes is preferred.
653*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
654*6777b538SAndroid Build Coastguard Worker       insecure_key,
655*6777b538SAndroid Build Coastguard Worker       cache.LookupStale(secure_key, now, &stale, true /* ignore-secure */)
656*6777b538SAndroid Build Coastguard Worker           ->first);
657*6777b538SAndroid Build Coastguard Worker 
658*6777b538SAndroid Build Coastguard Worker   // Add both insecure and secure entries to a cleared cache, still at t=0.
659*6777b538SAndroid Build Coastguard Worker   cache.clear();
660*6777b538SAndroid Build Coastguard Worker   cache.Set(insecure_key, entry, now, base::Seconds(20));
661*6777b538SAndroid Build Coastguard Worker   cache.Set(secure_key, entry, now, kSuccessEntryTTL);
662*6777b538SAndroid Build Coastguard Worker 
663*6777b538SAndroid Build Coastguard Worker   // Advance to t=15 to expire the secure entry only.
664*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(15);
665*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(insecure_key, cache.Lookup(insecure_key, now)->first);
666*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(secure_key, now));
667*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(secure_key, cache.LookupStale(secure_key, now, &stale)->first);
668*6777b538SAndroid Build Coastguard Worker   // Non-expired result is preferred.
669*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
670*6777b538SAndroid Build Coastguard Worker       insecure_key,
671*6777b538SAndroid Build Coastguard Worker       cache.LookupStale(secure_key, now, &stale, true /* ignore-secure */)
672*6777b538SAndroid Build Coastguard Worker           ->first);
673*6777b538SAndroid Build Coastguard Worker }
674*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,NoCache)675*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, NoCache) {
676*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kTTL = base::Seconds(10);
677*6777b538SAndroid Build Coastguard Worker 
678*6777b538SAndroid Build Coastguard Worker   // Disable caching.
679*6777b538SAndroid Build Coastguard Worker   HostCache cache(0);
680*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.caching_is_disabled());
681*6777b538SAndroid Build Coastguard Worker 
682*6777b538SAndroid Build Coastguard Worker   // Set t=0.
683*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
684*6777b538SAndroid Build Coastguard Worker 
685*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry =
686*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
687*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
688*6777b538SAndroid Build Coastguard Worker 
689*6777b538SAndroid Build Coastguard Worker   // Lookup and Set should have no effect.
690*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(Key("foobar.com"), now));
691*6777b538SAndroid Build Coastguard Worker   cache.Set(Key("foobar.com"), entry, now, kTTL);
692*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(Key("foobar.com"), now));
693*6777b538SAndroid Build Coastguard Worker 
694*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, cache.size());
695*6777b538SAndroid Build Coastguard Worker }
696*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,Clear)697*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, Clear) {
698*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kTTL = base::Seconds(10);
699*6777b538SAndroid Build Coastguard Worker 
700*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
701*6777b538SAndroid Build Coastguard Worker 
702*6777b538SAndroid Build Coastguard Worker   // Set t=0.
703*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
704*6777b538SAndroid Build Coastguard Worker 
705*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry =
706*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
707*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
708*6777b538SAndroid Build Coastguard Worker 
709*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, cache.size());
710*6777b538SAndroid Build Coastguard Worker 
711*6777b538SAndroid Build Coastguard Worker   // Add three entries.
712*6777b538SAndroid Build Coastguard Worker   cache.Set(Key("foobar1.com"), entry, now, kTTL);
713*6777b538SAndroid Build Coastguard Worker   cache.Set(Key("foobar2.com"), entry, now, kTTL);
714*6777b538SAndroid Build Coastguard Worker   cache.Set(Key("foobar3.com"), entry, now, kTTL);
715*6777b538SAndroid Build Coastguard Worker 
716*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3u, cache.size());
717*6777b538SAndroid Build Coastguard Worker 
718*6777b538SAndroid Build Coastguard Worker   cache.clear();
719*6777b538SAndroid Build Coastguard Worker 
720*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, cache.size());
721*6777b538SAndroid Build Coastguard Worker }
722*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,ClearForHosts)723*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, ClearForHosts) {
724*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kTTL = base::Seconds(10);
725*6777b538SAndroid Build Coastguard Worker 
726*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
727*6777b538SAndroid Build Coastguard Worker 
728*6777b538SAndroid Build Coastguard Worker   // Set t=0.
729*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
730*6777b538SAndroid Build Coastguard Worker 
731*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry =
732*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
733*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
734*6777b538SAndroid Build Coastguard Worker 
735*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, cache.size());
736*6777b538SAndroid Build Coastguard Worker 
737*6777b538SAndroid Build Coastguard Worker   // Add several entries.
738*6777b538SAndroid Build Coastguard Worker   cache.Set(Key("foobar1.com"), entry, now, kTTL);
739*6777b538SAndroid Build Coastguard Worker   cache.Set(Key("foobar2.com"), entry, now, kTTL);
740*6777b538SAndroid Build Coastguard Worker   cache.Set(Key("foobar3.com"), entry, now, kTTL);
741*6777b538SAndroid Build Coastguard Worker   cache.Set(Key("foobar4.com"), entry, now, kTTL);
742*6777b538SAndroid Build Coastguard Worker   cache.Set(Key("foobar5.com"), entry, now, kTTL);
743*6777b538SAndroid Build Coastguard Worker 
744*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5u, cache.size());
745*6777b538SAndroid Build Coastguard Worker 
746*6777b538SAndroid Build Coastguard Worker   // Clear the hosts matching a certain predicate, such as the number being odd.
747*6777b538SAndroid Build Coastguard Worker   cache.ClearForHosts(base::BindRepeating(&FoobarIndexIsOdd));
748*6777b538SAndroid Build Coastguard Worker 
749*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cache.size());
750*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(Key("foobar2.com"), now));
751*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(Key("foobar4.com"), now));
752*6777b538SAndroid Build Coastguard Worker 
753*6777b538SAndroid Build Coastguard Worker   // Passing null callback will delete all hosts.
754*6777b538SAndroid Build Coastguard Worker   cache.ClearForHosts(base::NullCallback());
755*6777b538SAndroid Build Coastguard Worker 
756*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, cache.size());
757*6777b538SAndroid Build Coastguard Worker }
758*6777b538SAndroid Build Coastguard Worker 
759*6777b538SAndroid Build Coastguard Worker // Try to add too many entries to cache; it should evict the one with the oldest
760*6777b538SAndroid Build Coastguard Worker // expiration time.
TEST(HostCacheTest,Evict)761*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, Evict) {
762*6777b538SAndroid Build Coastguard Worker   HostCache cache(2);
763*6777b538SAndroid Build Coastguard Worker 
764*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
765*6777b538SAndroid Build Coastguard Worker 
766*6777b538SAndroid Build Coastguard Worker   HostCache::Key key1 = Key("foobar.com");
767*6777b538SAndroid Build Coastguard Worker   HostCache::Key key2 = Key("foobar2.com");
768*6777b538SAndroid Build Coastguard Worker   HostCache::Key key3 = Key("foobar3.com");
769*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry =
770*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
771*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
772*6777b538SAndroid Build Coastguard Worker 
773*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, cache.size());
774*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
775*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key2, now));
776*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key3, now));
777*6777b538SAndroid Build Coastguard Worker 
778*6777b538SAndroid Build Coastguard Worker   // |key1| expires in 10 seconds, but |key2| in just 5.
779*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry, now, base::Seconds(10));
780*6777b538SAndroid Build Coastguard Worker   cache.Set(key2, entry, now, base::Seconds(5));
781*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cache.size());
782*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
783*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key2, now));
784*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key3, now));
785*6777b538SAndroid Build Coastguard Worker 
786*6777b538SAndroid Build Coastguard Worker   // |key2| should be chosen for eviction, since it expires sooner.
787*6777b538SAndroid Build Coastguard Worker   cache.Set(key3, entry, now, base::Seconds(10));
788*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cache.size());
789*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
790*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key2, now));
791*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key3, now));
792*6777b538SAndroid Build Coastguard Worker }
793*6777b538SAndroid Build Coastguard Worker 
794*6777b538SAndroid Build Coastguard Worker // Try to retrieve stale entries from the cache. They should be returned by
795*6777b538SAndroid Build Coastguard Worker // |LookupStale()| but not |Lookup()|, with correct |EntryStaleness| data.
TEST(HostCacheTest,Stale)796*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, Stale) {
797*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kTTL = base::Seconds(10);
798*6777b538SAndroid Build Coastguard Worker 
799*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
800*6777b538SAndroid Build Coastguard Worker 
801*6777b538SAndroid Build Coastguard Worker   // Start at t=0.
802*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
803*6777b538SAndroid Build Coastguard Worker   HostCache::EntryStaleness stale;
804*6777b538SAndroid Build Coastguard Worker 
805*6777b538SAndroid Build Coastguard Worker   HostCache::Key key = Key("foobar.com");
806*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry =
807*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
808*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
809*6777b538SAndroid Build Coastguard Worker 
810*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, cache.size());
811*6777b538SAndroid Build Coastguard Worker 
812*6777b538SAndroid Build Coastguard Worker   // Add an entry for "foobar.com" at t=0.
813*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key, now));
814*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.LookupStale(key, now, &stale));
815*6777b538SAndroid Build Coastguard Worker   cache.Set(key, entry, now, kTTL);
816*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key, now));
817*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.LookupStale(key, now, &stale));
818*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(stale.is_stale());
819*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, stale.stale_hits);
820*6777b538SAndroid Build Coastguard Worker 
821*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1U, cache.size());
822*6777b538SAndroid Build Coastguard Worker 
823*6777b538SAndroid Build Coastguard Worker   // Advance to t=5.
824*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(5);
825*6777b538SAndroid Build Coastguard Worker 
826*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key, now));
827*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.LookupStale(key, now, &stale));
828*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(stale.is_stale());
829*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, stale.stale_hits);
830*6777b538SAndroid Build Coastguard Worker 
831*6777b538SAndroid Build Coastguard Worker   // Advance to t=15.
832*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(10);
833*6777b538SAndroid Build Coastguard Worker 
834*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key, now));
835*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.LookupStale(key, now, &stale));
836*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(stale.is_stale());
837*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Seconds(5), stale.expired_by);
838*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, stale.network_changes);
839*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, stale.stale_hits);
840*6777b538SAndroid Build Coastguard Worker 
841*6777b538SAndroid Build Coastguard Worker   // Advance to t=20.
842*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(5);
843*6777b538SAndroid Build Coastguard Worker 
844*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key, now));
845*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.LookupStale(key, now, &stale));
846*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(stale.is_stale());
847*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Seconds(10), stale.expired_by);
848*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, stale.network_changes);
849*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, stale.stale_hits);
850*6777b538SAndroid Build Coastguard Worker 
851*6777b538SAndroid Build Coastguard Worker   // Simulate network change.
852*6777b538SAndroid Build Coastguard Worker   cache.Invalidate();
853*6777b538SAndroid Build Coastguard Worker 
854*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key, now));
855*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.LookupStale(key, now, &stale));
856*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(stale.is_stale());
857*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Seconds(10), stale.expired_by);
858*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, stale.network_changes);
859*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, stale.stale_hits);
860*6777b538SAndroid Build Coastguard Worker }
861*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,EvictStale)862*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, EvictStale) {
863*6777b538SAndroid Build Coastguard Worker   HostCache cache(2);
864*6777b538SAndroid Build Coastguard Worker 
865*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
866*6777b538SAndroid Build Coastguard Worker   HostCache::EntryStaleness stale;
867*6777b538SAndroid Build Coastguard Worker 
868*6777b538SAndroid Build Coastguard Worker   HostCache::Key key1 = Key("foobar.com");
869*6777b538SAndroid Build Coastguard Worker   HostCache::Key key2 = Key("foobar2.com");
870*6777b538SAndroid Build Coastguard Worker   HostCache::Key key3 = Key("foobar3.com");
871*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry =
872*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
873*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
874*6777b538SAndroid Build Coastguard Worker 
875*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, cache.size());
876*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
877*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key2, now));
878*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key3, now));
879*6777b538SAndroid Build Coastguard Worker 
880*6777b538SAndroid Build Coastguard Worker   // |key1| expires in 10 seconds.
881*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry, now, base::Seconds(10));
882*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, cache.size());
883*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
884*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key2, now));
885*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key3, now));
886*6777b538SAndroid Build Coastguard Worker 
887*6777b538SAndroid Build Coastguard Worker   // Simulate network change, expiring the cache.
888*6777b538SAndroid Build Coastguard Worker   cache.Invalidate();
889*6777b538SAndroid Build Coastguard Worker 
890*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, cache.size());
891*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
892*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.LookupStale(key1, now, &stale));
893*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, stale.network_changes);
894*6777b538SAndroid Build Coastguard Worker 
895*6777b538SAndroid Build Coastguard Worker   // Advance to t=1.
896*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(1);
897*6777b538SAndroid Build Coastguard Worker 
898*6777b538SAndroid Build Coastguard Worker   // |key2| expires before |key1| would originally have expired.
899*6777b538SAndroid Build Coastguard Worker   cache.Set(key2, entry, now, base::Seconds(5));
900*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cache.size());
901*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
902*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.LookupStale(key1, now, &stale));
903*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key2, now));
904*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key3, now));
905*6777b538SAndroid Build Coastguard Worker 
906*6777b538SAndroid Build Coastguard Worker   // |key1| should be chosen for eviction, since it is stale.
907*6777b538SAndroid Build Coastguard Worker   cache.Set(key3, entry, now, base::Seconds(1));
908*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cache.size());
909*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
910*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.LookupStale(key1, now, &stale));
911*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key2, now));
912*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key3, now));
913*6777b538SAndroid Build Coastguard Worker 
914*6777b538SAndroid Build Coastguard Worker   // Advance to t=6.
915*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(5);
916*6777b538SAndroid Build Coastguard Worker 
917*6777b538SAndroid Build Coastguard Worker   // Insert |key1| again. |key3| should be evicted.
918*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry, now, base::Seconds(10));
919*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cache.size());
920*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
921*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key2, now));
922*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.LookupStale(key2, now, &stale));
923*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key3, now));
924*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.LookupStale(key3, now, &stale));
925*6777b538SAndroid Build Coastguard Worker }
926*6777b538SAndroid Build Coastguard Worker 
927*6777b538SAndroid Build Coastguard Worker // Pinned entries should not be evicted, even if the cache is full and the Entry
928*6777b538SAndroid Build Coastguard Worker // has expired.
TEST(HostCacheTest,NoEvictPinned)929*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, NoEvictPinned) {
930*6777b538SAndroid Build Coastguard Worker   HostCache cache(2);
931*6777b538SAndroid Build Coastguard Worker 
932*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
933*6777b538SAndroid Build Coastguard Worker 
934*6777b538SAndroid Build Coastguard Worker   HostCache::Key key1 = Key("foobar.com");
935*6777b538SAndroid Build Coastguard Worker   HostCache::Key key2 = Key("foobar2.com");
936*6777b538SAndroid Build Coastguard Worker   HostCache::Key key3 = Key("foobar3.com");
937*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry =
938*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
939*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
940*6777b538SAndroid Build Coastguard Worker   entry.set_pinning(true);
941*6777b538SAndroid Build Coastguard Worker 
942*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry, now, base::Seconds(5));
943*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(10);
944*6777b538SAndroid Build Coastguard Worker   cache.Set(key2, entry, now, base::Seconds(5));
945*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(10);
946*6777b538SAndroid Build Coastguard Worker   cache.Set(key3, entry, now, base::Seconds(5));
947*6777b538SAndroid Build Coastguard Worker 
948*6777b538SAndroid Build Coastguard Worker   // There are 3 entries in this cache whose nominal max size is 2.
949*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3u, cache.size());
950*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.LookupStale(key1, now, nullptr));
951*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.LookupStale(key2, now, nullptr));
952*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key3, now));
953*6777b538SAndroid Build Coastguard Worker }
954*6777b538SAndroid Build Coastguard Worker 
955*6777b538SAndroid Build Coastguard Worker // Obsolete pinned entries should be evicted normally.
TEST(HostCacheTest,EvictObsoletePinned)956*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, EvictObsoletePinned) {
957*6777b538SAndroid Build Coastguard Worker   HostCache cache(2);
958*6777b538SAndroid Build Coastguard Worker 
959*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
960*6777b538SAndroid Build Coastguard Worker 
961*6777b538SAndroid Build Coastguard Worker   HostCache::Key key1 = Key("foobar.com");
962*6777b538SAndroid Build Coastguard Worker   HostCache::Key key2 = Key("foobar2.com");
963*6777b538SAndroid Build Coastguard Worker   HostCache::Key key3 = Key("foobar3.com");
964*6777b538SAndroid Build Coastguard Worker   HostCache::Key key4 = Key("foobar4.com");
965*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry =
966*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
967*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
968*6777b538SAndroid Build Coastguard Worker   entry.set_pinning(true);
969*6777b538SAndroid Build Coastguard Worker 
970*6777b538SAndroid Build Coastguard Worker   // |key2| should be preserved, since it expires later.
971*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry, now, base::Seconds(5));
972*6777b538SAndroid Build Coastguard Worker   cache.Set(key2, entry, now, base::Seconds(10));
973*6777b538SAndroid Build Coastguard Worker   cache.Set(key3, entry, now, base::Seconds(5));
974*6777b538SAndroid Build Coastguard Worker   // There are 3 entries in this cache whose nominal max size is 2.
975*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3u, cache.size());
976*6777b538SAndroid Build Coastguard Worker 
977*6777b538SAndroid Build Coastguard Worker   cache.Invalidate();
978*6777b538SAndroid Build Coastguard Worker   // |Invalidate()| does not trigger eviction.
979*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3u, cache.size());
980*6777b538SAndroid Build Coastguard Worker 
981*6777b538SAndroid Build Coastguard Worker   // |Set()| triggers an eviction, leaving only |key2| in cache,
982*6777b538SAndroid Build Coastguard Worker   // before adding |key4|
983*6777b538SAndroid Build Coastguard Worker   cache.Set(key4, entry, now, base::Seconds(2));
984*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cache.size());
985*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.LookupStale(key1, now, nullptr));
986*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.LookupStale(key2, now, nullptr));
987*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.LookupStale(key3, now, nullptr));
988*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.LookupStale(key4, now, nullptr));
989*6777b538SAndroid Build Coastguard Worker }
990*6777b538SAndroid Build Coastguard Worker 
991*6777b538SAndroid Build Coastguard Worker // An active pin is preserved if the record is
992*6777b538SAndroid Build Coastguard Worker // replaced due to a Set() call without the pin.
TEST(HostCacheTest,PreserveActivePin)993*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, PreserveActivePin) {
994*6777b538SAndroid Build Coastguard Worker   HostCache cache(2);
995*6777b538SAndroid Build Coastguard Worker 
996*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
997*6777b538SAndroid Build Coastguard Worker 
998*6777b538SAndroid Build Coastguard Worker   // Make entry1 and entry2, identical except for IP and pinned flag.
999*6777b538SAndroid Build Coastguard Worker   IPEndPoint endpoint1(IPAddress(192, 0, 2, 1), 0);
1000*6777b538SAndroid Build Coastguard Worker   IPEndPoint endpoint2(IPAddress(192, 0, 2, 2), 0);
1001*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry1 = HostCache::Entry(OK, {endpoint1}, /*aliases=*/{},
1002*6777b538SAndroid Build Coastguard Worker                                              HostCache::Entry::SOURCE_UNKNOWN);
1003*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry2 = HostCache::Entry(OK, {endpoint2}, /*aliases=*/{},
1004*6777b538SAndroid Build Coastguard Worker                                              HostCache::Entry::SOURCE_UNKNOWN);
1005*6777b538SAndroid Build Coastguard Worker   entry1.set_pinning(true);
1006*6777b538SAndroid Build Coastguard Worker 
1007*6777b538SAndroid Build Coastguard Worker   HostCache::Key key = Key("foobar.com");
1008*6777b538SAndroid Build Coastguard Worker 
1009*6777b538SAndroid Build Coastguard Worker   // Insert entry1, and verify that it can be retrieved with the
1010*6777b538SAndroid Build Coastguard Worker   // correct IP and |pinning()| == true.
1011*6777b538SAndroid Build Coastguard Worker   cache.Set(key, entry1, now, base::Seconds(10));
1012*6777b538SAndroid Build Coastguard Worker   const auto* pair1 = cache.Lookup(key, now);
1013*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(pair1);
1014*6777b538SAndroid Build Coastguard Worker   const HostCache::Entry& result1 = pair1->second;
1015*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result1.GetEndpoints(),
1016*6777b538SAndroid Build Coastguard Worker               ElementsAre(ExpectEndpointResult(ElementsAre(endpoint1))));
1017*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result1.pinning(), Optional(true));
1018*6777b538SAndroid Build Coastguard Worker 
1019*6777b538SAndroid Build Coastguard Worker   // Insert |entry2|, and verify that it when it is retrieved, it
1020*6777b538SAndroid Build Coastguard Worker   // has the new IP, and the "pinned" flag copied from |entry1|.
1021*6777b538SAndroid Build Coastguard Worker   cache.Set(key, entry2, now, base::Seconds(10));
1022*6777b538SAndroid Build Coastguard Worker   const auto* pair2 = cache.Lookup(key, now);
1023*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(pair2);
1024*6777b538SAndroid Build Coastguard Worker   const HostCache::Entry& result2 = pair2->second;
1025*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result2.GetEndpoints(),
1026*6777b538SAndroid Build Coastguard Worker               ElementsAre(ExpectEndpointResult(ElementsAre(endpoint2))));
1027*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result2.pinning(), Optional(true));
1028*6777b538SAndroid Build Coastguard Worker }
1029*6777b538SAndroid Build Coastguard Worker 
1030*6777b538SAndroid Build Coastguard Worker // An obsolete cache pin is not preserved if the record is replaced.
TEST(HostCacheTest,DontPreserveObsoletePin)1031*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, DontPreserveObsoletePin) {
1032*6777b538SAndroid Build Coastguard Worker   HostCache cache(2);
1033*6777b538SAndroid Build Coastguard Worker 
1034*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
1035*6777b538SAndroid Build Coastguard Worker 
1036*6777b538SAndroid Build Coastguard Worker   // Make entry1 and entry2, identical except for IP and "pinned" flag.
1037*6777b538SAndroid Build Coastguard Worker   IPEndPoint endpoint1(IPAddress(192, 0, 2, 1), 0);
1038*6777b538SAndroid Build Coastguard Worker   IPEndPoint endpoint2(IPAddress(192, 0, 2, 2), 0);
1039*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry1 = HostCache::Entry(OK, {endpoint1}, /*aliases=*/{},
1040*6777b538SAndroid Build Coastguard Worker                                              HostCache::Entry::SOURCE_UNKNOWN);
1041*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry2 = HostCache::Entry(OK, {endpoint2}, /*aliases=*/{},
1042*6777b538SAndroid Build Coastguard Worker                                              HostCache::Entry::SOURCE_UNKNOWN);
1043*6777b538SAndroid Build Coastguard Worker   entry1.set_pinning(true);
1044*6777b538SAndroid Build Coastguard Worker 
1045*6777b538SAndroid Build Coastguard Worker   HostCache::Key key = Key("foobar.com");
1046*6777b538SAndroid Build Coastguard Worker 
1047*6777b538SAndroid Build Coastguard Worker   // Insert entry1, and verify that it can be retrieved with the
1048*6777b538SAndroid Build Coastguard Worker   // correct IP and |pinning()| == true.
1049*6777b538SAndroid Build Coastguard Worker   cache.Set(key, entry1, now, base::Seconds(10));
1050*6777b538SAndroid Build Coastguard Worker   const auto* pair1 = cache.Lookup(key, now);
1051*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(pair1);
1052*6777b538SAndroid Build Coastguard Worker   const HostCache::Entry& result1 = pair1->second;
1053*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result1.GetEndpoints(),
1054*6777b538SAndroid Build Coastguard Worker               ElementsAre(ExpectEndpointResult(ElementsAre(endpoint1))));
1055*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result1.pinning(), Optional(true));
1056*6777b538SAndroid Build Coastguard Worker 
1057*6777b538SAndroid Build Coastguard Worker   // Make entry1 obsolete.
1058*6777b538SAndroid Build Coastguard Worker   cache.Invalidate();
1059*6777b538SAndroid Build Coastguard Worker 
1060*6777b538SAndroid Build Coastguard Worker   // Insert |entry2|, and verify that it when it is retrieved, it
1061*6777b538SAndroid Build Coastguard Worker   // has the new IP, and the "pinned" flag is not copied from |entry1|.
1062*6777b538SAndroid Build Coastguard Worker   cache.Set(key, entry2, now, base::Seconds(10));
1063*6777b538SAndroid Build Coastguard Worker   const auto* pair2 = cache.Lookup(key, now);
1064*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(pair2);
1065*6777b538SAndroid Build Coastguard Worker   const HostCache::Entry& result2 = pair2->second;
1066*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result2.GetEndpoints(),
1067*6777b538SAndroid Build Coastguard Worker               ElementsAre(ExpectEndpointResult(ElementsAre(endpoint2))));
1068*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result2.pinning(), Optional(false));
1069*6777b538SAndroid Build Coastguard Worker }
1070*6777b538SAndroid Build Coastguard Worker 
1071*6777b538SAndroid Build Coastguard Worker // An active pin is removed if the record is replaced by a Set() call
1072*6777b538SAndroid Build Coastguard Worker // with the pin flag set to false.
TEST(HostCacheTest,Unpin)1073*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, Unpin) {
1074*6777b538SAndroid Build Coastguard Worker   HostCache cache(2);
1075*6777b538SAndroid Build Coastguard Worker 
1076*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
1077*6777b538SAndroid Build Coastguard Worker 
1078*6777b538SAndroid Build Coastguard Worker   // Make entry1 and entry2, identical except for IP and pinned flag.
1079*6777b538SAndroid Build Coastguard Worker   IPEndPoint endpoint1(IPAddress(192, 0, 2, 1), 0);
1080*6777b538SAndroid Build Coastguard Worker   IPEndPoint endpoint2(IPAddress(192, 0, 2, 2), 0);
1081*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry1 = HostCache::Entry(OK, {endpoint1}, /*aliases=*/{},
1082*6777b538SAndroid Build Coastguard Worker                                              HostCache::Entry::SOURCE_UNKNOWN);
1083*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry2 = HostCache::Entry(OK, {endpoint2}, /*aliases=*/{},
1084*6777b538SAndroid Build Coastguard Worker                                              HostCache::Entry::SOURCE_UNKNOWN);
1085*6777b538SAndroid Build Coastguard Worker   entry1.set_pinning(true);
1086*6777b538SAndroid Build Coastguard Worker   entry2.set_pinning(false);
1087*6777b538SAndroid Build Coastguard Worker 
1088*6777b538SAndroid Build Coastguard Worker   HostCache::Key key = Key("foobar.com");
1089*6777b538SAndroid Build Coastguard Worker 
1090*6777b538SAndroid Build Coastguard Worker   // Insert entry1, and verify that it can be retrieved with the
1091*6777b538SAndroid Build Coastguard Worker   // correct IP and |pinning()| == true.
1092*6777b538SAndroid Build Coastguard Worker   cache.Set(key, entry1, now, base::Seconds(10));
1093*6777b538SAndroid Build Coastguard Worker   const auto* pair1 = cache.Lookup(key, now);
1094*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(pair1);
1095*6777b538SAndroid Build Coastguard Worker   const HostCache::Entry& result1 = pair1->second;
1096*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result1.GetEndpoints(),
1097*6777b538SAndroid Build Coastguard Worker               ElementsAre(ExpectEndpointResult(ElementsAre(endpoint1))));
1098*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result1.pinning(), Optional(true));
1099*6777b538SAndroid Build Coastguard Worker 
1100*6777b538SAndroid Build Coastguard Worker   // Insert |entry2|, and verify that it when it is retrieved, it
1101*6777b538SAndroid Build Coastguard Worker   // has the new IP, and the "pinned" flag is now false.
1102*6777b538SAndroid Build Coastguard Worker   cache.Set(key, entry2, now, base::Seconds(10));
1103*6777b538SAndroid Build Coastguard Worker   const auto* pair2 = cache.Lookup(key, now);
1104*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(pair2);
1105*6777b538SAndroid Build Coastguard Worker   const HostCache::Entry& result2 = pair2->second;
1106*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result2.GetEndpoints(),
1107*6777b538SAndroid Build Coastguard Worker               ElementsAre(ExpectEndpointResult(ElementsAre(endpoint2))));
1108*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result2.pinning(), Optional(false));
1109*6777b538SAndroid Build Coastguard Worker }
1110*6777b538SAndroid Build Coastguard Worker 
1111*6777b538SAndroid Build Coastguard Worker // Tests the less than and equal operators for HostCache::Key work.
TEST(HostCacheTest,KeyComparators)1112*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, KeyComparators) {
1113*6777b538SAndroid Build Coastguard Worker   struct CacheTestParameters {
1114*6777b538SAndroid Build Coastguard Worker     CacheTestParameters(const HostCache::Key key1,
1115*6777b538SAndroid Build Coastguard Worker                         const HostCache::Key key2,
1116*6777b538SAndroid Build Coastguard Worker                         int expected_comparison)
1117*6777b538SAndroid Build Coastguard Worker         : key1(key1), key2(key2), expected_comparison(expected_comparison) {}
1118*6777b538SAndroid Build Coastguard Worker 
1119*6777b538SAndroid Build Coastguard Worker     // Inputs.
1120*6777b538SAndroid Build Coastguard Worker     HostCache::Key key1;
1121*6777b538SAndroid Build Coastguard Worker     HostCache::Key key2;
1122*6777b538SAndroid Build Coastguard Worker 
1123*6777b538SAndroid Build Coastguard Worker     // Expectation.
1124*6777b538SAndroid Build Coastguard Worker     //   -1 means key1 is less than key2
1125*6777b538SAndroid Build Coastguard Worker     //    0 means key1 equals key2
1126*6777b538SAndroid Build Coastguard Worker     //    1 means key1 is greater than key2
1127*6777b538SAndroid Build Coastguard Worker     int expected_comparison;
1128*6777b538SAndroid Build Coastguard Worker   };
1129*6777b538SAndroid Build Coastguard Worker   std::vector<CacheTestParameters> tests = {
1130*6777b538SAndroid Build Coastguard Worker       {HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1131*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
1132*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1133*6777b538SAndroid Build Coastguard Worker        HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1134*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
1135*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1136*6777b538SAndroid Build Coastguard Worker        0},
1137*6777b538SAndroid Build Coastguard Worker       {HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1138*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::A, 0, HostResolverSource::ANY,
1139*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1140*6777b538SAndroid Build Coastguard Worker        HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1141*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
1142*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1143*6777b538SAndroid Build Coastguard Worker        1},
1144*6777b538SAndroid Build Coastguard Worker       {HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1145*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
1146*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1147*6777b538SAndroid Build Coastguard Worker        HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1148*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::A, 0, HostResolverSource::ANY,
1149*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1150*6777b538SAndroid Build Coastguard Worker        -1},
1151*6777b538SAndroid Build Coastguard Worker       {HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1152*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
1153*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1154*6777b538SAndroid Build Coastguard Worker        HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host2", 443),
1155*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
1156*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1157*6777b538SAndroid Build Coastguard Worker        -1},
1158*6777b538SAndroid Build Coastguard Worker       {HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1159*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::A, 0, HostResolverSource::ANY,
1160*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1161*6777b538SAndroid Build Coastguard Worker        HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host2", 443),
1162*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
1163*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1164*6777b538SAndroid Build Coastguard Worker        1},
1165*6777b538SAndroid Build Coastguard Worker       {HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1166*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
1167*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1168*6777b538SAndroid Build Coastguard Worker        HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host2", 443),
1169*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::A, 0, HostResolverSource::ANY,
1170*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1171*6777b538SAndroid Build Coastguard Worker        -1},
1172*6777b538SAndroid Build Coastguard Worker       {HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1173*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
1174*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1175*6777b538SAndroid Build Coastguard Worker        HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1176*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, HOST_RESOLVER_CANONNAME,
1177*6777b538SAndroid Build Coastguard Worker                       HostResolverSource::ANY, NetworkAnonymizationKey()),
1178*6777b538SAndroid Build Coastguard Worker        -1},
1179*6777b538SAndroid Build Coastguard Worker       {HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1180*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, HOST_RESOLVER_CANONNAME,
1181*6777b538SAndroid Build Coastguard Worker                       HostResolverSource::ANY, NetworkAnonymizationKey()),
1182*6777b538SAndroid Build Coastguard Worker        HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1183*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
1184*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1185*6777b538SAndroid Build Coastguard Worker        1},
1186*6777b538SAndroid Build Coastguard Worker       {HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1187*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, HOST_RESOLVER_CANONNAME,
1188*6777b538SAndroid Build Coastguard Worker                       HostResolverSource::ANY, NetworkAnonymizationKey()),
1189*6777b538SAndroid Build Coastguard Worker        HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host2", 443),
1190*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, HOST_RESOLVER_CANONNAME,
1191*6777b538SAndroid Build Coastguard Worker                       HostResolverSource::ANY, NetworkAnonymizationKey()),
1192*6777b538SAndroid Build Coastguard Worker        -1},
1193*6777b538SAndroid Build Coastguard Worker       // 9: Different host scheme.
1194*6777b538SAndroid Build Coastguard Worker       {HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1195*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
1196*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1197*6777b538SAndroid Build Coastguard Worker        HostCache::Key(url::SchemeHostPort(url::kHttpScheme, "host1", 443),
1198*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
1199*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1200*6777b538SAndroid Build Coastguard Worker        1},
1201*6777b538SAndroid Build Coastguard Worker       // 10: Different host port.
1202*6777b538SAndroid Build Coastguard Worker       {HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1203*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
1204*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1205*6777b538SAndroid Build Coastguard Worker        HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 1544),
1206*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
1207*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1208*6777b538SAndroid Build Coastguard Worker        -1},
1209*6777b538SAndroid Build Coastguard Worker       // 11: Same host name without scheme/port.
1210*6777b538SAndroid Build Coastguard Worker       {HostCache::Key("host1", DnsQueryType::UNSPECIFIED, 0,
1211*6777b538SAndroid Build Coastguard Worker                       HostResolverSource::ANY, NetworkAnonymizationKey()),
1212*6777b538SAndroid Build Coastguard Worker        HostCache::Key("host1", DnsQueryType::UNSPECIFIED, 0,
1213*6777b538SAndroid Build Coastguard Worker                       HostResolverSource::ANY, NetworkAnonymizationKey()),
1214*6777b538SAndroid Build Coastguard Worker        0},
1215*6777b538SAndroid Build Coastguard Worker       // 12: Different host name without scheme/port.
1216*6777b538SAndroid Build Coastguard Worker       {HostCache::Key("host1", DnsQueryType::UNSPECIFIED, 0,
1217*6777b538SAndroid Build Coastguard Worker                       HostResolverSource::ANY, NetworkAnonymizationKey()),
1218*6777b538SAndroid Build Coastguard Worker        HostCache::Key("host2", DnsQueryType::UNSPECIFIED, 0,
1219*6777b538SAndroid Build Coastguard Worker                       HostResolverSource::ANY, NetworkAnonymizationKey()),
1220*6777b538SAndroid Build Coastguard Worker        -1},
1221*6777b538SAndroid Build Coastguard Worker       // 13: Only one with scheme/port.
1222*6777b538SAndroid Build Coastguard Worker       {HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1223*6777b538SAndroid Build Coastguard Worker                       DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
1224*6777b538SAndroid Build Coastguard Worker                       NetworkAnonymizationKey()),
1225*6777b538SAndroid Build Coastguard Worker        HostCache::Key("host1", DnsQueryType::UNSPECIFIED, 0,
1226*6777b538SAndroid Build Coastguard Worker                       HostResolverSource::ANY, NetworkAnonymizationKey()),
1227*6777b538SAndroid Build Coastguard Worker        -1},
1228*6777b538SAndroid Build Coastguard Worker   };
1229*6777b538SAndroid Build Coastguard Worker   HostCache::Key insecure_key =
1230*6777b538SAndroid Build Coastguard Worker       HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1231*6777b538SAndroid Build Coastguard Worker                      DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
1232*6777b538SAndroid Build Coastguard Worker                      NetworkAnonymizationKey());
1233*6777b538SAndroid Build Coastguard Worker   HostCache::Key secure_key =
1234*6777b538SAndroid Build Coastguard Worker       HostCache::Key(url::SchemeHostPort(url::kHttpsScheme, "host1", 443),
1235*6777b538SAndroid Build Coastguard Worker                      DnsQueryType::UNSPECIFIED, 0, HostResolverSource::ANY,
1236*6777b538SAndroid Build Coastguard Worker                      NetworkAnonymizationKey());
1237*6777b538SAndroid Build Coastguard Worker   secure_key.secure = true;
1238*6777b538SAndroid Build Coastguard Worker   tests.emplace_back(insecure_key, secure_key, -1);
1239*6777b538SAndroid Build Coastguard Worker 
1240*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(tests); ++i) {
1241*6777b538SAndroid Build Coastguard Worker     SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]", i));
1242*6777b538SAndroid Build Coastguard Worker 
1243*6777b538SAndroid Build Coastguard Worker     const HostCache::Key& key1 = tests[i].key1;
1244*6777b538SAndroid Build Coastguard Worker     const HostCache::Key& key2 = tests[i].key2;
1245*6777b538SAndroid Build Coastguard Worker 
1246*6777b538SAndroid Build Coastguard Worker     switch (tests[i].expected_comparison) {
1247*6777b538SAndroid Build Coastguard Worker       case -1:
1248*6777b538SAndroid Build Coastguard Worker         EXPECT_TRUE(key1 < key2);
1249*6777b538SAndroid Build Coastguard Worker         EXPECT_FALSE(key2 < key1);
1250*6777b538SAndroid Build Coastguard Worker         break;
1251*6777b538SAndroid Build Coastguard Worker       case 0:
1252*6777b538SAndroid Build Coastguard Worker         EXPECT_FALSE(key1 < key2);
1253*6777b538SAndroid Build Coastguard Worker         EXPECT_FALSE(key2 < key1);
1254*6777b538SAndroid Build Coastguard Worker         break;
1255*6777b538SAndroid Build Coastguard Worker       case 1:
1256*6777b538SAndroid Build Coastguard Worker         EXPECT_FALSE(key1 < key2);
1257*6777b538SAndroid Build Coastguard Worker         EXPECT_TRUE(key2 < key1);
1258*6777b538SAndroid Build Coastguard Worker         break;
1259*6777b538SAndroid Build Coastguard Worker       default:
1260*6777b538SAndroid Build Coastguard Worker         FAIL() << "Invalid expectation. Can be only -1, 0, 1";
1261*6777b538SAndroid Build Coastguard Worker     }
1262*6777b538SAndroid Build Coastguard Worker   }
1263*6777b538SAndroid Build Coastguard Worker }
1264*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,SerializeAndDeserializeWithExpirations)1265*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, SerializeAndDeserializeWithExpirations) {
1266*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kTTL = base::Seconds(10);
1267*6777b538SAndroid Build Coastguard Worker 
1268*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
1269*6777b538SAndroid Build Coastguard Worker 
1270*6777b538SAndroid Build Coastguard Worker   // Start at t=0.
1271*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
1272*6777b538SAndroid Build Coastguard Worker 
1273*6777b538SAndroid Build Coastguard Worker   HostCache::Key expire_by_time_key = Key("expire.by.time.test");
1274*6777b538SAndroid Build Coastguard Worker   HostCache::Key expire_by_changes_key = Key("expire.by.changes.test");
1275*6777b538SAndroid Build Coastguard Worker 
1276*6777b538SAndroid Build Coastguard Worker   IPEndPoint endpoint(IPAddress(1, 2, 3, 4), 0);
1277*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry = HostCache::Entry(OK, {endpoint}, /*aliases=*/{},
1278*6777b538SAndroid Build Coastguard Worker                                             HostCache::Entry::SOURCE_UNKNOWN);
1279*6777b538SAndroid Build Coastguard Worker 
1280*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, cache.size());
1281*6777b538SAndroid Build Coastguard Worker 
1282*6777b538SAndroid Build Coastguard Worker   // Add an entry for `expire_by_time_key` at t=0.
1283*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(expire_by_time_key, now));
1284*6777b538SAndroid Build Coastguard Worker   cache.Set(expire_by_time_key, entry, now, kTTL);
1285*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(cache.Lookup(expire_by_time_key, now),
1286*6777b538SAndroid Build Coastguard Worker               Pointee(Pair(expire_by_time_key, EntryContentsEqual(entry))));
1287*6777b538SAndroid Build Coastguard Worker 
1288*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, cache.size());
1289*6777b538SAndroid Build Coastguard Worker 
1290*6777b538SAndroid Build Coastguard Worker   // Advance to t=5.
1291*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(5);
1292*6777b538SAndroid Build Coastguard Worker 
1293*6777b538SAndroid Build Coastguard Worker   // Add entry for `expire_by_changes_key` at t=5.
1294*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(expire_by_changes_key, now));
1295*6777b538SAndroid Build Coastguard Worker   cache.Set(expire_by_changes_key, entry, now, kTTL);
1296*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(expire_by_changes_key, now));
1297*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cache.size());
1298*6777b538SAndroid Build Coastguard Worker 
1299*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, cache.last_restore_size());
1300*6777b538SAndroid Build Coastguard Worker 
1301*6777b538SAndroid Build Coastguard Worker   // Advance to t=12, and serialize/deserialize the cache.
1302*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(7);
1303*6777b538SAndroid Build Coastguard Worker 
1304*6777b538SAndroid Build Coastguard Worker   base::Value::List serialized_cache;
1305*6777b538SAndroid Build Coastguard Worker   cache.GetList(serialized_cache, false /* include_staleness */,
1306*6777b538SAndroid Build Coastguard Worker                 HostCache::SerializationType::kRestorable);
1307*6777b538SAndroid Build Coastguard Worker   HostCache restored_cache(kMaxCacheEntries);
1308*6777b538SAndroid Build Coastguard Worker 
1309*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(restored_cache.RestoreFromListValue(serialized_cache));
1310*6777b538SAndroid Build Coastguard Worker 
1311*6777b538SAndroid Build Coastguard Worker   HostCache::EntryStaleness stale;
1312*6777b538SAndroid Build Coastguard Worker 
1313*6777b538SAndroid Build Coastguard Worker   // The `expire_by_time_key` entry is stale due to both network changes and
1314*6777b538SAndroid Build Coastguard Worker   // expiration time.
1315*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(restored_cache.Lookup(expire_by_time_key, now));
1316*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(restored_cache.LookupStale(expire_by_time_key, now, &stale),
1317*6777b538SAndroid Build Coastguard Worker               Pointee(Pair(expire_by_time_key, EntryContentsEqual(entry))));
1318*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, stale.network_changes);
1319*6777b538SAndroid Build Coastguard Worker   // Time to TimeTicks conversion is fuzzy, so just check that expected and
1320*6777b538SAndroid Build Coastguard Worker   // actual expiration times are close.
1321*6777b538SAndroid Build Coastguard Worker   EXPECT_GT(base::Milliseconds(100),
1322*6777b538SAndroid Build Coastguard Worker             (base::Seconds(2) - stale.expired_by).magnitude());
1323*6777b538SAndroid Build Coastguard Worker 
1324*6777b538SAndroid Build Coastguard Worker   // The `expire_by_changes_key` entry is stale only due to network changes.
1325*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(restored_cache.Lookup(expire_by_changes_key, now));
1326*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(restored_cache.LookupStale(expire_by_changes_key, now, &stale),
1327*6777b538SAndroid Build Coastguard Worker               Pointee(Pair(expire_by_changes_key, EntryContentsEqual(entry))));
1328*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, stale.network_changes);
1329*6777b538SAndroid Build Coastguard Worker   EXPECT_GT(base::Milliseconds(100),
1330*6777b538SAndroid Build Coastguard Worker             (base::Seconds(-3) - stale.expired_by).magnitude());
1331*6777b538SAndroid Build Coastguard Worker 
1332*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, restored_cache.last_restore_size());
1333*6777b538SAndroid Build Coastguard Worker }
1334*6777b538SAndroid Build Coastguard Worker 
1335*6777b538SAndroid Build Coastguard Worker // Test that any changes between serialization and restore are preferred over
1336*6777b538SAndroid Build Coastguard Worker // old restored entries.
TEST(HostCacheTest,SerializeAndDeserializeWithChanges)1337*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, SerializeAndDeserializeWithChanges) {
1338*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kTTL = base::Seconds(10);
1339*6777b538SAndroid Build Coastguard Worker 
1340*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
1341*6777b538SAndroid Build Coastguard Worker 
1342*6777b538SAndroid Build Coastguard Worker   // Start at t=0.
1343*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
1344*6777b538SAndroid Build Coastguard Worker 
1345*6777b538SAndroid Build Coastguard Worker   HostCache::Key to_serialize_key1 = Key("to.serialize1.test");
1346*6777b538SAndroid Build Coastguard Worker   HostCache::Key to_serialize_key2 = Key("to.serialize2.test");
1347*6777b538SAndroid Build Coastguard Worker   HostCache::Key other_key = Key("other.test");
1348*6777b538SAndroid Build Coastguard Worker 
1349*6777b538SAndroid Build Coastguard Worker   IPEndPoint endpoint(IPAddress(1, 1, 1, 1), 0);
1350*6777b538SAndroid Build Coastguard Worker   HostCache::Entry serialized_entry = HostCache::Entry(
1351*6777b538SAndroid Build Coastguard Worker       OK, {endpoint}, /*aliases=*/{}, HostCache::Entry::SOURCE_UNKNOWN);
1352*6777b538SAndroid Build Coastguard Worker 
1353*6777b538SAndroid Build Coastguard Worker   IPEndPoint replacement_endpoint(IPAddress(2, 2, 2, 2), 0);
1354*6777b538SAndroid Build Coastguard Worker   HostCache::Entry replacement_entry =
1355*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, {replacement_endpoint}, /*aliases=*/{},
1356*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
1357*6777b538SAndroid Build Coastguard Worker 
1358*6777b538SAndroid Build Coastguard Worker   IPEndPoint other_endpoint(IPAddress(3, 3, 3, 3), 0);
1359*6777b538SAndroid Build Coastguard Worker   HostCache::Entry other_entry = HostCache::Entry(
1360*6777b538SAndroid Build Coastguard Worker       OK, {other_endpoint}, /*aliases=*/{}, HostCache::Entry::SOURCE_UNKNOWN);
1361*6777b538SAndroid Build Coastguard Worker 
1362*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, cache.size());
1363*6777b538SAndroid Build Coastguard Worker 
1364*6777b538SAndroid Build Coastguard Worker   // Add `to_serialize_key1` and `to_serialize_key2`
1365*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(to_serialize_key1, now));
1366*6777b538SAndroid Build Coastguard Worker   cache.Set(to_serialize_key1, serialized_entry, now, kTTL);
1367*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
1368*6777b538SAndroid Build Coastguard Worker       cache.Lookup(to_serialize_key1, now),
1369*6777b538SAndroid Build Coastguard Worker       Pointee(Pair(to_serialize_key1, EntryContentsEqual(serialized_entry))));
1370*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(to_serialize_key2, now));
1371*6777b538SAndroid Build Coastguard Worker   cache.Set(to_serialize_key2, serialized_entry, now, kTTL);
1372*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
1373*6777b538SAndroid Build Coastguard Worker       cache.Lookup(to_serialize_key2, now),
1374*6777b538SAndroid Build Coastguard Worker       Pointee(Pair(to_serialize_key2, EntryContentsEqual(serialized_entry))));
1375*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cache.size());
1376*6777b538SAndroid Build Coastguard Worker 
1377*6777b538SAndroid Build Coastguard Worker   // Serialize the cache.
1378*6777b538SAndroid Build Coastguard Worker   base::Value::List serialized_cache;
1379*6777b538SAndroid Build Coastguard Worker   cache.GetList(serialized_cache, false /* include_staleness */,
1380*6777b538SAndroid Build Coastguard Worker                 HostCache::SerializationType::kRestorable);
1381*6777b538SAndroid Build Coastguard Worker   HostCache restored_cache(kMaxCacheEntries);
1382*6777b538SAndroid Build Coastguard Worker 
1383*6777b538SAndroid Build Coastguard Worker   // Add entries for `to_serialize_key1` and `other_key` to the new cache
1384*6777b538SAndroid Build Coastguard Worker   // before restoring the serialized one. The `to_serialize_key1` result is
1385*6777b538SAndroid Build Coastguard Worker   // different from the original.
1386*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(restored_cache.Lookup(to_serialize_key1, now));
1387*6777b538SAndroid Build Coastguard Worker   restored_cache.Set(to_serialize_key1, replacement_entry, now, kTTL);
1388*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
1389*6777b538SAndroid Build Coastguard Worker       restored_cache.Lookup(to_serialize_key1, now),
1390*6777b538SAndroid Build Coastguard Worker       Pointee(Pair(to_serialize_key1, EntryContentsEqual(replacement_entry))));
1391*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, restored_cache.size());
1392*6777b538SAndroid Build Coastguard Worker 
1393*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(restored_cache.Lookup(other_key, now));
1394*6777b538SAndroid Build Coastguard Worker   restored_cache.Set(other_key, other_entry, now, kTTL);
1395*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(restored_cache.Lookup(other_key, now),
1396*6777b538SAndroid Build Coastguard Worker               Pointee(Pair(other_key, EntryContentsEqual(other_entry))));
1397*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, restored_cache.size());
1398*6777b538SAndroid Build Coastguard Worker 
1399*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, restored_cache.last_restore_size());
1400*6777b538SAndroid Build Coastguard Worker 
1401*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(restored_cache.RestoreFromListValue(serialized_cache));
1402*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, restored_cache.last_restore_size());
1403*6777b538SAndroid Build Coastguard Worker 
1404*6777b538SAndroid Build Coastguard Worker   HostCache::EntryStaleness stale;
1405*6777b538SAndroid Build Coastguard Worker 
1406*6777b538SAndroid Build Coastguard Worker   // Expect `to_serialize_key1` has the replacement entry.
1407*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
1408*6777b538SAndroid Build Coastguard Worker       restored_cache.Lookup(to_serialize_key1, now),
1409*6777b538SAndroid Build Coastguard Worker       Pointee(Pair(to_serialize_key1, EntryContentsEqual(replacement_entry))));
1410*6777b538SAndroid Build Coastguard Worker 
1411*6777b538SAndroid Build Coastguard Worker   // Expect `to_serialize_key2` has the original entry.
1412*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
1413*6777b538SAndroid Build Coastguard Worker       restored_cache.LookupStale(to_serialize_key2, now, &stale),
1414*6777b538SAndroid Build Coastguard Worker       Pointee(Pair(to_serialize_key2, EntryContentsEqual(serialized_entry))));
1415*6777b538SAndroid Build Coastguard Worker 
1416*6777b538SAndroid Build Coastguard Worker   // Expect no change for `other_key`.
1417*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(restored_cache.Lookup(other_key, now),
1418*6777b538SAndroid Build Coastguard Worker               Pointee(Pair(other_key, EntryContentsEqual(other_entry))));
1419*6777b538SAndroid Build Coastguard Worker }
1420*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,SerializeAndDeserializeAddresses)1421*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, SerializeAndDeserializeAddresses) {
1422*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kTTL = base::Seconds(10);
1423*6777b538SAndroid Build Coastguard Worker 
1424*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
1425*6777b538SAndroid Build Coastguard Worker 
1426*6777b538SAndroid Build Coastguard Worker   // Start at t=0.
1427*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
1428*6777b538SAndroid Build Coastguard Worker 
1429*6777b538SAndroid Build Coastguard Worker   HostCache::Key key1 = Key("foobar.com");
1430*6777b538SAndroid Build Coastguard Worker   key1.secure = true;
1431*6777b538SAndroid Build Coastguard Worker   HostCache::Key key2 = Key("foobar2.com");
1432*6777b538SAndroid Build Coastguard Worker   HostCache::Key key3 = Key("foobar3.com");
1433*6777b538SAndroid Build Coastguard Worker   HostCache::Key key4 = Key("foobar4.com");
1434*6777b538SAndroid Build Coastguard Worker 
1435*6777b538SAndroid Build Coastguard Worker   IPAddress address_ipv4(1, 2, 3, 4);
1436*6777b538SAndroid Build Coastguard Worker   IPAddress address_ipv6(0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1437*6777b538SAndroid Build Coastguard Worker   IPEndPoint endpoint_ipv4(address_ipv4, 0);
1438*6777b538SAndroid Build Coastguard Worker   IPEndPoint endpoint_ipv6(address_ipv6, 0);
1439*6777b538SAndroid Build Coastguard Worker 
1440*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry1 = HostCache::Entry(
1441*6777b538SAndroid Build Coastguard Worker       OK, {endpoint_ipv4}, /*aliases=*/{}, HostCache::Entry::SOURCE_UNKNOWN);
1442*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry2 =
1443*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, {endpoint_ipv6, endpoint_ipv4}, /*aliases=*/{},
1444*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
1445*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry3 = HostCache::Entry(
1446*6777b538SAndroid Build Coastguard Worker       OK, {endpoint_ipv6}, /*aliases=*/{}, HostCache::Entry::SOURCE_UNKNOWN);
1447*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry4 = HostCache::Entry(
1448*6777b538SAndroid Build Coastguard Worker       OK, {endpoint_ipv4}, /*aliases=*/{}, HostCache::Entry::SOURCE_UNKNOWN);
1449*6777b538SAndroid Build Coastguard Worker 
1450*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, cache.size());
1451*6777b538SAndroid Build Coastguard Worker 
1452*6777b538SAndroid Build Coastguard Worker   // Add an entry for "foobar.com" at t=0.
1453*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
1454*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry1, now, kTTL);
1455*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
1456*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now)->second.error() == entry1.error());
1457*6777b538SAndroid Build Coastguard Worker 
1458*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, cache.size());
1459*6777b538SAndroid Build Coastguard Worker 
1460*6777b538SAndroid Build Coastguard Worker   // Advance to t=5.
1461*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(5);
1462*6777b538SAndroid Build Coastguard Worker 
1463*6777b538SAndroid Build Coastguard Worker   // Add entries for "foobar2.com" and "foobar3.com" at t=5.
1464*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key2, now));
1465*6777b538SAndroid Build Coastguard Worker   cache.Set(key2, entry2, now, kTTL);
1466*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key2, now));
1467*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cache.size());
1468*6777b538SAndroid Build Coastguard Worker 
1469*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key3, now));
1470*6777b538SAndroid Build Coastguard Worker   cache.Set(key3, entry3, now, kTTL);
1471*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key3, now));
1472*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3u, cache.size());
1473*6777b538SAndroid Build Coastguard Worker 
1474*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, cache.last_restore_size());
1475*6777b538SAndroid Build Coastguard Worker 
1476*6777b538SAndroid Build Coastguard Worker   // Advance to t=12, ansd serialize the cache.
1477*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(7);
1478*6777b538SAndroid Build Coastguard Worker 
1479*6777b538SAndroid Build Coastguard Worker   base::Value::List serialized_cache;
1480*6777b538SAndroid Build Coastguard Worker   cache.GetList(serialized_cache, false /* include_staleness */,
1481*6777b538SAndroid Build Coastguard Worker                 HostCache::SerializationType::kRestorable);
1482*6777b538SAndroid Build Coastguard Worker   HostCache restored_cache(kMaxCacheEntries);
1483*6777b538SAndroid Build Coastguard Worker 
1484*6777b538SAndroid Build Coastguard Worker   // Add entries for "foobar3.com" and "foobar4.com" to the cache before
1485*6777b538SAndroid Build Coastguard Worker   // restoring it. The "foobar3.com" result is different from the original.
1486*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(restored_cache.Lookup(key3, now));
1487*6777b538SAndroid Build Coastguard Worker   restored_cache.Set(key3, entry1, now, kTTL);
1488*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(restored_cache.Lookup(key3, now));
1489*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, restored_cache.size());
1490*6777b538SAndroid Build Coastguard Worker 
1491*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(restored_cache.Lookup(key4, now));
1492*6777b538SAndroid Build Coastguard Worker   restored_cache.Set(key4, entry4, now, kTTL);
1493*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(restored_cache.Lookup(key4, now));
1494*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, restored_cache.size());
1495*6777b538SAndroid Build Coastguard Worker 
1496*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, restored_cache.last_restore_size());
1497*6777b538SAndroid Build Coastguard Worker 
1498*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(restored_cache.RestoreFromListValue(serialized_cache));
1499*6777b538SAndroid Build Coastguard Worker 
1500*6777b538SAndroid Build Coastguard Worker   HostCache::EntryStaleness stale;
1501*6777b538SAndroid Build Coastguard Worker 
1502*6777b538SAndroid Build Coastguard Worker   // The "foobar.com" entry is stale due to both network changes and expiration
1503*6777b538SAndroid Build Coastguard Worker   // time.
1504*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(restored_cache.Lookup(key1, now));
1505*6777b538SAndroid Build Coastguard Worker   const std::pair<const HostCache::Key, HostCache::Entry>* result1 =
1506*6777b538SAndroid Build Coastguard Worker       restored_cache.LookupStale(key1, now, &stale);
1507*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(result1);
1508*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(result1->first.secure);
1509*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result1->second.text_records(), IsEmpty());
1510*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result1->second.hostnames(), IsEmpty());
1511*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, result1->second.ip_endpoints().size());
1512*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(endpoint_ipv4, result1->second.ip_endpoints().front());
1513*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, stale.network_changes);
1514*6777b538SAndroid Build Coastguard Worker   // Time to TimeTicks conversion is fuzzy, so just check that expected and
1515*6777b538SAndroid Build Coastguard Worker   // actual expiration times are close.
1516*6777b538SAndroid Build Coastguard Worker   EXPECT_GT(base::Milliseconds(100),
1517*6777b538SAndroid Build Coastguard Worker             (base::Seconds(2) - stale.expired_by).magnitude());
1518*6777b538SAndroid Build Coastguard Worker 
1519*6777b538SAndroid Build Coastguard Worker   // The "foobar2.com" entry is stale only due to network changes.
1520*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(restored_cache.Lookup(key2, now));
1521*6777b538SAndroid Build Coastguard Worker   const std::pair<const HostCache::Key, HostCache::Entry>* result2 =
1522*6777b538SAndroid Build Coastguard Worker       restored_cache.LookupStale(key2, now, &stale);
1523*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(result2);
1524*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(result2->first.secure);
1525*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, result2->second.ip_endpoints().size());
1526*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(endpoint_ipv6, result2->second.ip_endpoints().front());
1527*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(endpoint_ipv4, result2->second.ip_endpoints().back());
1528*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, stale.network_changes);
1529*6777b538SAndroid Build Coastguard Worker   EXPECT_GT(base::Milliseconds(100),
1530*6777b538SAndroid Build Coastguard Worker             (base::Seconds(-3) - stale.expired_by).magnitude());
1531*6777b538SAndroid Build Coastguard Worker 
1532*6777b538SAndroid Build Coastguard Worker   // The "foobar3.com" entry is the new one, not the restored one.
1533*6777b538SAndroid Build Coastguard Worker   const std::pair<const HostCache::Key, HostCache::Entry>* result3 =
1534*6777b538SAndroid Build Coastguard Worker       restored_cache.Lookup(key3, now);
1535*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(result3);
1536*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, result3->second.ip_endpoints().size());
1537*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(endpoint_ipv4, result3->second.ip_endpoints().front());
1538*6777b538SAndroid Build Coastguard Worker 
1539*6777b538SAndroid Build Coastguard Worker   // The "foobar4.com" entry is still present and usable.
1540*6777b538SAndroid Build Coastguard Worker   const std::pair<const HostCache::Key, HostCache::Entry>* result4 =
1541*6777b538SAndroid Build Coastguard Worker       restored_cache.Lookup(key4, now);
1542*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(result4);
1543*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, result4->second.ip_endpoints().size());
1544*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(endpoint_ipv4, result4->second.ip_endpoints().front());
1545*6777b538SAndroid Build Coastguard Worker 
1546*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, restored_cache.last_restore_size());
1547*6777b538SAndroid Build Coastguard Worker }
1548*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,SerializeAndDeserializeEntryWithoutScheme)1549*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, SerializeAndDeserializeEntryWithoutScheme) {
1550*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kTTL = base::Seconds(10);
1551*6777b538SAndroid Build Coastguard Worker 
1552*6777b538SAndroid Build Coastguard Worker   HostCache::Key key("host.test", DnsQueryType::UNSPECIFIED, 0,
1553*6777b538SAndroid Build Coastguard Worker                      HostResolverSource::ANY, NetworkAnonymizationKey());
1554*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry =
1555*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{},
1556*6777b538SAndroid Build Coastguard Worker                        /*aliases=*/{}, HostCache::Entry::SOURCE_UNKNOWN);
1557*6777b538SAndroid Build Coastguard Worker 
1558*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
1559*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
1560*6777b538SAndroid Build Coastguard Worker 
1561*6777b538SAndroid Build Coastguard Worker   cache.Set(key, entry, now, kTTL);
1562*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(cache.Lookup(key, now));
1563*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(cache.size(), 1u);
1564*6777b538SAndroid Build Coastguard Worker 
1565*6777b538SAndroid Build Coastguard Worker   base::Value::List serialized_cache;
1566*6777b538SAndroid Build Coastguard Worker   cache.GetList(serialized_cache, /*include_staleness=*/false,
1567*6777b538SAndroid Build Coastguard Worker                 HostCache::SerializationType::kRestorable);
1568*6777b538SAndroid Build Coastguard Worker   HostCache restored_cache(kMaxCacheEntries);
1569*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(restored_cache.RestoreFromListValue(serialized_cache));
1570*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(restored_cache.size(), 1u);
1571*6777b538SAndroid Build Coastguard Worker 
1572*6777b538SAndroid Build Coastguard Worker   HostCache::EntryStaleness staleness;
1573*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(restored_cache.LookupStale(key, now, &staleness),
1574*6777b538SAndroid Build Coastguard Worker               Pointee(Pair(key, EntryContentsEqual(entry))));
1575*6777b538SAndroid Build Coastguard Worker }
1576*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,SerializeAndDeserializeWithNetworkAnonymizationKey)1577*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, SerializeAndDeserializeWithNetworkAnonymizationKey) {
1578*6777b538SAndroid Build Coastguard Worker   const url::SchemeHostPort kHost =
1579*6777b538SAndroid Build Coastguard Worker       url::SchemeHostPort(url::kHttpsScheme, "hostname.test", 443);
1580*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kTTL = base::Seconds(10);
1581*6777b538SAndroid Build Coastguard Worker   const SchemefulSite kSite(GURL("https://site.test/"));
1582*6777b538SAndroid Build Coastguard Worker   const auto kNetworkAnonymizationKey =
1583*6777b538SAndroid Build Coastguard Worker       NetworkAnonymizationKey::CreateSameSite(kSite);
1584*6777b538SAndroid Build Coastguard Worker   const SchemefulSite kOpaqueSite;
1585*6777b538SAndroid Build Coastguard Worker   const auto kOpaqueNetworkAnonymizationKey =
1586*6777b538SAndroid Build Coastguard Worker       NetworkAnonymizationKey::CreateSameSite(kOpaqueSite);
1587*6777b538SAndroid Build Coastguard Worker 
1588*6777b538SAndroid Build Coastguard Worker   HostCache::Key key1(kHost, DnsQueryType::UNSPECIFIED, 0,
1589*6777b538SAndroid Build Coastguard Worker                       HostResolverSource::ANY, kNetworkAnonymizationKey);
1590*6777b538SAndroid Build Coastguard Worker   HostCache::Key key2(kHost, DnsQueryType::UNSPECIFIED, 0,
1591*6777b538SAndroid Build Coastguard Worker                       HostResolverSource::ANY, kOpaqueNetworkAnonymizationKey);
1592*6777b538SAndroid Build Coastguard Worker 
1593*6777b538SAndroid Build Coastguard Worker   IPEndPoint endpoint(IPAddress(1, 2, 3, 4), 0);
1594*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry = HostCache::Entry(OK, {endpoint}, /*aliases=*/{},
1595*6777b538SAndroid Build Coastguard Worker                                             HostCache::Entry::SOURCE_UNKNOWN);
1596*6777b538SAndroid Build Coastguard Worker 
1597*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
1598*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
1599*6777b538SAndroid Build Coastguard Worker 
1600*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, entry, now, kTTL);
1601*6777b538SAndroid Build Coastguard Worker   cache.Set(key2, entry, now, kTTL);
1602*6777b538SAndroid Build Coastguard Worker 
1603*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
1604*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNetworkAnonymizationKey,
1605*6777b538SAndroid Build Coastguard Worker             cache.Lookup(key1, now)->first.network_anonymization_key);
1606*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key2, now));
1607*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kOpaqueNetworkAnonymizationKey,
1608*6777b538SAndroid Build Coastguard Worker             cache.Lookup(key2, now)->first.network_anonymization_key);
1609*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cache.size());
1610*6777b538SAndroid Build Coastguard Worker 
1611*6777b538SAndroid Build Coastguard Worker   base::Value::List serialized_cache;
1612*6777b538SAndroid Build Coastguard Worker   cache.GetList(serialized_cache, false /* include_staleness */,
1613*6777b538SAndroid Build Coastguard Worker                 HostCache::SerializationType::kRestorable);
1614*6777b538SAndroid Build Coastguard Worker   HostCache restored_cache(kMaxCacheEntries);
1615*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(restored_cache.RestoreFromListValue(serialized_cache));
1616*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, restored_cache.size());
1617*6777b538SAndroid Build Coastguard Worker 
1618*6777b538SAndroid Build Coastguard Worker   HostCache::EntryStaleness stale;
1619*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(restored_cache.LookupStale(key1, now, &stale),
1620*6777b538SAndroid Build Coastguard Worker               Pointee(Pair(key1, EntryContentsEqual(entry))));
1621*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(restored_cache.Lookup(key2, now));
1622*6777b538SAndroid Build Coastguard Worker }
1623*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,SerializeForDebugging)1624*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, SerializeForDebugging) {
1625*6777b538SAndroid Build Coastguard Worker   const url::SchemeHostPort kHost(url::kHttpsScheme, "hostname.test", 443);
1626*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kTTL = base::Seconds(10);
1627*6777b538SAndroid Build Coastguard Worker   const NetworkAnonymizationKey kNetworkAnonymizationKey =
1628*6777b538SAndroid Build Coastguard Worker       NetworkAnonymizationKey::CreateTransient();
1629*6777b538SAndroid Build Coastguard Worker 
1630*6777b538SAndroid Build Coastguard Worker   HostCache::Key key(kHost, DnsQueryType::UNSPECIFIED, 0,
1631*6777b538SAndroid Build Coastguard Worker                      HostResolverSource::ANY, kNetworkAnonymizationKey);
1632*6777b538SAndroid Build Coastguard Worker 
1633*6777b538SAndroid Build Coastguard Worker   IPEndPoint endpoint(IPAddress(1, 2, 3, 4), 0);
1634*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry = HostCache::Entry(OK, {endpoint}, /*aliases=*/{},
1635*6777b538SAndroid Build Coastguard Worker                                             HostCache::Entry::SOURCE_UNKNOWN);
1636*6777b538SAndroid Build Coastguard Worker 
1637*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
1638*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
1639*6777b538SAndroid Build Coastguard Worker 
1640*6777b538SAndroid Build Coastguard Worker   cache.Set(key, entry, now, kTTL);
1641*6777b538SAndroid Build Coastguard Worker 
1642*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key, now));
1643*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNetworkAnonymizationKey,
1644*6777b538SAndroid Build Coastguard Worker             cache.Lookup(key, now)->first.network_anonymization_key);
1645*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, cache.size());
1646*6777b538SAndroid Build Coastguard Worker 
1647*6777b538SAndroid Build Coastguard Worker   base::Value::List serialized_cache;
1648*6777b538SAndroid Build Coastguard Worker   cache.GetList(serialized_cache, false /* include_staleness */,
1649*6777b538SAndroid Build Coastguard Worker                 HostCache::SerializationType::kDebug);
1650*6777b538SAndroid Build Coastguard Worker   HostCache restored_cache(kMaxCacheEntries);
1651*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(restored_cache.RestoreFromListValue(serialized_cache));
1652*6777b538SAndroid Build Coastguard Worker 
1653*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, serialized_cache.size());
1654*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(serialized_cache[0].is_dict());
1655*6777b538SAndroid Build Coastguard Worker   const std::string* nak_string =
1656*6777b538SAndroid Build Coastguard Worker       serialized_cache[0].GetDict().FindString("network_anonymization_key");
1657*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(nak_string);
1658*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(kNetworkAnonymizationKey.ToDebugString(), *nak_string);
1659*6777b538SAndroid Build Coastguard Worker }
1660*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,SerializeAndDeserialize_Text)1661*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, SerializeAndDeserialize_Text) {
1662*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
1663*6777b538SAndroid Build Coastguard Worker 
1664*6777b538SAndroid Build Coastguard Worker   base::TimeDelta ttl = base::Seconds(99);
1665*6777b538SAndroid Build Coastguard Worker   std::vector<std::string> text_records({"foo", "bar"});
1666*6777b538SAndroid Build Coastguard Worker   HostCache::Key key(url::SchemeHostPort(url::kHttpsScheme, "example.com", 443),
1667*6777b538SAndroid Build Coastguard Worker                      DnsQueryType::A, 0, HostResolverSource::DNS,
1668*6777b538SAndroid Build Coastguard Worker                      NetworkAnonymizationKey());
1669*6777b538SAndroid Build Coastguard Worker   key.secure = true;
1670*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry(OK, text_records, HostCache::Entry::SOURCE_DNS, ttl);
1671*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(entry.text_records(), Not(IsEmpty()));
1672*6777b538SAndroid Build Coastguard Worker 
1673*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
1674*6777b538SAndroid Build Coastguard Worker   cache.Set(key, entry, now, ttl);
1675*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, cache.size());
1676*6777b538SAndroid Build Coastguard Worker 
1677*6777b538SAndroid Build Coastguard Worker   base::Value::List serialized_cache;
1678*6777b538SAndroid Build Coastguard Worker   cache.GetList(serialized_cache, false /* include_staleness */,
1679*6777b538SAndroid Build Coastguard Worker                 HostCache::SerializationType::kRestorable);
1680*6777b538SAndroid Build Coastguard Worker   HostCache restored_cache(kMaxCacheEntries);
1681*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(restored_cache.RestoreFromListValue(serialized_cache));
1682*6777b538SAndroid Build Coastguard Worker 
1683*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, serialized_cache.size());
1684*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, restored_cache.size());
1685*6777b538SAndroid Build Coastguard Worker   HostCache::EntryStaleness stale;
1686*6777b538SAndroid Build Coastguard Worker   const std::pair<const HostCache::Key, HostCache::Entry>* result =
1687*6777b538SAndroid Build Coastguard Worker       restored_cache.LookupStale(key, now, &stale);
1688*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result, Pointee(Pair(key, EntryContentsEqual(entry))));
1689*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result->second.text_records(), text_records);
1690*6777b538SAndroid Build Coastguard Worker }
1691*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,SerializeAndDeserialize_Hostname)1692*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, SerializeAndDeserialize_Hostname) {
1693*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
1694*6777b538SAndroid Build Coastguard Worker 
1695*6777b538SAndroid Build Coastguard Worker   base::TimeDelta ttl = base::Seconds(99);
1696*6777b538SAndroid Build Coastguard Worker   std::vector<HostPortPair> hostnames(
1697*6777b538SAndroid Build Coastguard Worker       {HostPortPair("example.com", 95), HostPortPair("chromium.org", 122)});
1698*6777b538SAndroid Build Coastguard Worker   HostCache::Key key(url::SchemeHostPort(url::kHttpsScheme, "example.com", 443),
1699*6777b538SAndroid Build Coastguard Worker                      DnsQueryType::A, 0, HostResolverSource::DNS,
1700*6777b538SAndroid Build Coastguard Worker                      NetworkAnonymizationKey());
1701*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry(OK, hostnames, HostCache::Entry::SOURCE_DNS, ttl);
1702*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(entry.hostnames(), Not(IsEmpty()));
1703*6777b538SAndroid Build Coastguard Worker 
1704*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
1705*6777b538SAndroid Build Coastguard Worker   cache.Set(key, entry, now, ttl);
1706*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, cache.size());
1707*6777b538SAndroid Build Coastguard Worker 
1708*6777b538SAndroid Build Coastguard Worker   base::Value::List serialized_cache;
1709*6777b538SAndroid Build Coastguard Worker   cache.GetList(serialized_cache, false /* include_staleness */,
1710*6777b538SAndroid Build Coastguard Worker                 HostCache::SerializationType::kRestorable);
1711*6777b538SAndroid Build Coastguard Worker   HostCache restored_cache(kMaxCacheEntries);
1712*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(restored_cache.RestoreFromListValue(serialized_cache));
1713*6777b538SAndroid Build Coastguard Worker 
1714*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, restored_cache.size());
1715*6777b538SAndroid Build Coastguard Worker   HostCache::EntryStaleness stale;
1716*6777b538SAndroid Build Coastguard Worker   const std::pair<const HostCache::Key, HostCache::Entry>* result =
1717*6777b538SAndroid Build Coastguard Worker       restored_cache.LookupStale(key, now, &stale);
1718*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result, Pointee(Pair(key, EntryContentsEqual(entry))));
1719*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result->second.hostnames(), hostnames);
1720*6777b538SAndroid Build Coastguard Worker }
1721*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,SerializeAndDeserializeEndpointResult)1722*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, SerializeAndDeserializeEndpointResult) {
1723*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
1724*6777b538SAndroid Build Coastguard Worker 
1725*6777b538SAndroid Build Coastguard Worker   base::TimeDelta ttl = base::Seconds(99);
1726*6777b538SAndroid Build Coastguard Worker   HostCache::Key key(url::SchemeHostPort(url::kHttpsScheme, "example.com", 443),
1727*6777b538SAndroid Build Coastguard Worker                      DnsQueryType::A, 0, HostResolverSource::DNS,
1728*6777b538SAndroid Build Coastguard Worker                      NetworkAnonymizationKey());
1729*6777b538SAndroid Build Coastguard Worker   IPEndPoint ipv6_endpoint(
1730*6777b538SAndroid Build Coastguard Worker       IPAddress(1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4), 110);
1731*6777b538SAndroid Build Coastguard Worker   IPEndPoint ipv4_endpoint1(IPAddress(1, 1, 1, 1), 80);
1732*6777b538SAndroid Build Coastguard Worker   IPEndPoint ipv4_endpoint2(IPAddress(2, 2, 2, 2), 90);
1733*6777b538SAndroid Build Coastguard Worker   IPEndPoint other_ipv4_endpoint(IPAddress(3, 3, 3, 3), 100);
1734*6777b538SAndroid Build Coastguard Worker   std::string ipv6_alias = "ipv6_alias.test";
1735*6777b538SAndroid Build Coastguard Worker   std::string ipv4_alias = "ipv4_alias.test";
1736*6777b538SAndroid Build Coastguard Worker   std::string other_alias = "other_alias.test";
1737*6777b538SAndroid Build Coastguard Worker   std::vector<IPEndPoint> ip_endpoints = {ipv6_endpoint, ipv4_endpoint1,
1738*6777b538SAndroid Build Coastguard Worker                                           ipv4_endpoint2, other_ipv4_endpoint};
1739*6777b538SAndroid Build Coastguard Worker   std::set<std::string> aliases = {ipv6_alias, ipv4_alias, other_alias};
1740*6777b538SAndroid Build Coastguard Worker   HostCache::Entry entry(OK, ip_endpoints, aliases,
1741*6777b538SAndroid Build Coastguard Worker                          HostCache::Entry::SOURCE_DNS, ttl);
1742*6777b538SAndroid Build Coastguard Worker 
1743*6777b538SAndroid Build Coastguard Worker   std::set<std::string> canonical_names = {ipv6_alias, ipv4_alias};
1744*6777b538SAndroid Build Coastguard Worker   entry.set_canonical_names(canonical_names);
1745*6777b538SAndroid Build Coastguard Worker 
1746*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(entry.GetEndpoints(), Not(IsEmpty()));
1747*6777b538SAndroid Build Coastguard Worker 
1748*6777b538SAndroid Build Coastguard Worker   ConnectionEndpointMetadata metadata1;
1749*6777b538SAndroid Build Coastguard Worker   metadata1.supported_protocol_alpns = {"h3", "h2"};
1750*6777b538SAndroid Build Coastguard Worker   metadata1.ech_config_list = {'f', 'o', 'o'};
1751*6777b538SAndroid Build Coastguard Worker   metadata1.target_name = ipv6_alias;
1752*6777b538SAndroid Build Coastguard Worker   ConnectionEndpointMetadata metadata2;
1753*6777b538SAndroid Build Coastguard Worker   metadata2.supported_protocol_alpns = {"h2", "h4"};
1754*6777b538SAndroid Build Coastguard Worker   metadata2.target_name = ipv4_alias;
1755*6777b538SAndroid Build Coastguard Worker   HostCache::Entry metadata_entry(
1756*6777b538SAndroid Build Coastguard Worker       OK,
1757*6777b538SAndroid Build Coastguard Worker       std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>{
1758*6777b538SAndroid Build Coastguard Worker           {1u, metadata1}, {2u, metadata2}},
1759*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::SOURCE_DNS);
1760*6777b538SAndroid Build Coastguard Worker 
1761*6777b538SAndroid Build Coastguard Worker   auto merged_entry = HostCache::Entry::MergeEntries(entry, metadata_entry);
1762*6777b538SAndroid Build Coastguard Worker 
1763*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(merged_entry.GetEndpoints(),
1764*6777b538SAndroid Build Coastguard Worker               ElementsAre(ExpectEndpointResult(ip_endpoints)));
1765*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
1766*6777b538SAndroid Build Coastguard Worker       merged_entry.GetMetadatas(),
1767*6777b538SAndroid Build Coastguard Worker       testing::ElementsAre(
1768*6777b538SAndroid Build Coastguard Worker           ExpectConnectionEndpointMetadata(testing::ElementsAre("h3", "h2"),
1769*6777b538SAndroid Build Coastguard Worker                                            testing::ElementsAre('f', 'o', 'o'),
1770*6777b538SAndroid Build Coastguard Worker                                            ipv6_alias),
1771*6777b538SAndroid Build Coastguard Worker           ExpectConnectionEndpointMetadata(testing::ElementsAre("h2", "h4"),
1772*6777b538SAndroid Build Coastguard Worker                                            IsEmpty(), ipv4_alias)));
1773*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(merged_entry.canonical_names(),
1774*6777b538SAndroid Build Coastguard Worker               UnorderedElementsAre(ipv4_alias, ipv6_alias));
1775*6777b538SAndroid Build Coastguard Worker 
1776*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
1777*6777b538SAndroid Build Coastguard Worker   cache.Set(key, merged_entry, now, ttl);
1778*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, cache.size());
1779*6777b538SAndroid Build Coastguard Worker 
1780*6777b538SAndroid Build Coastguard Worker   base::Value::List serialized_cache;
1781*6777b538SAndroid Build Coastguard Worker   cache.GetList(serialized_cache, false /* include_staleness */,
1782*6777b538SAndroid Build Coastguard Worker                 HostCache::SerializationType::kRestorable);
1783*6777b538SAndroid Build Coastguard Worker   HostCache restored_cache(kMaxCacheEntries);
1784*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(restored_cache.RestoreFromListValue(serialized_cache));
1785*6777b538SAndroid Build Coastguard Worker 
1786*6777b538SAndroid Build Coastguard Worker   // Check `serialized_cache` can be encoded as JSON. This ensures it has no
1787*6777b538SAndroid Build Coastguard Worker   // binary values.
1788*6777b538SAndroid Build Coastguard Worker   std::string json;
1789*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::JSONWriter::Write(serialized_cache, &json));
1790*6777b538SAndroid Build Coastguard Worker 
1791*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, restored_cache.size());
1792*6777b538SAndroid Build Coastguard Worker   HostCache::EntryStaleness stale;
1793*6777b538SAndroid Build Coastguard Worker   const std::pair<const HostCache::Key, HostCache::Entry>* result =
1794*6777b538SAndroid Build Coastguard Worker       restored_cache.LookupStale(key, now, &stale);
1795*6777b538SAndroid Build Coastguard Worker 
1796*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(result);
1797*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result, Pointee(Pair(key, EntryContentsEqual(merged_entry))));
1798*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result->second.GetEndpoints(),
1799*6777b538SAndroid Build Coastguard Worker               ElementsAre(ExpectEndpointResult(ip_endpoints)));
1800*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
1801*6777b538SAndroid Build Coastguard Worker       result->second.GetMetadatas(),
1802*6777b538SAndroid Build Coastguard Worker       testing::ElementsAre(
1803*6777b538SAndroid Build Coastguard Worker           ExpectConnectionEndpointMetadata(testing::ElementsAre("h3", "h2"),
1804*6777b538SAndroid Build Coastguard Worker                                            testing::ElementsAre('f', 'o', 'o'),
1805*6777b538SAndroid Build Coastguard Worker                                            ipv6_alias),
1806*6777b538SAndroid Build Coastguard Worker           ExpectConnectionEndpointMetadata(testing::ElementsAre("h2", "h4"),
1807*6777b538SAndroid Build Coastguard Worker                                            IsEmpty(), ipv4_alias)));
1808*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result->second.canonical_names(),
1809*6777b538SAndroid Build Coastguard Worker               UnorderedElementsAre(ipv4_alias, ipv6_alias));
1810*6777b538SAndroid Build Coastguard Worker 
1811*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(result->second.aliases(), aliases);
1812*6777b538SAndroid Build Coastguard Worker }
1813*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,DeserializeNoEndpointNoAliase)1814*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, DeserializeNoEndpointNoAliase) {
1815*6777b538SAndroid Build Coastguard Worker   base::TimeDelta ttl = base::Seconds(99);
1816*6777b538SAndroid Build Coastguard Worker   std::string expiration_time_str = base::NumberToString(
1817*6777b538SAndroid Build Coastguard Worker       (base::Time::Now() + ttl).since_origin().InMicroseconds());
1818*6777b538SAndroid Build Coastguard Worker 
1819*6777b538SAndroid Build Coastguard Worker   auto dict = base::JSONReader::Read(base::StringPrintf(
1820*6777b538SAndroid Build Coastguard Worker       R"(
1821*6777b538SAndroid Build Coastguard Worker  [ {
1822*6777b538SAndroid Build Coastguard Worker    "dns_query_type": 1,
1823*6777b538SAndroid Build Coastguard Worker    "expiration": "%s",
1824*6777b538SAndroid Build Coastguard Worker    "flags": 0,
1825*6777b538SAndroid Build Coastguard Worker    "host_resolver_source": 2,
1826*6777b538SAndroid Build Coastguard Worker    "hostname": "example.com",
1827*6777b538SAndroid Build Coastguard Worker    "network_anonymization_key": [  ],
1828*6777b538SAndroid Build Coastguard Worker    "port": 443,
1829*6777b538SAndroid Build Coastguard Worker    "scheme": "https",
1830*6777b538SAndroid Build Coastguard Worker    "secure": false
1831*6777b538SAndroid Build Coastguard Worker } ]
1832*6777b538SAndroid Build Coastguard Worker )",
1833*6777b538SAndroid Build Coastguard Worker       expiration_time_str.c_str()));
1834*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(dict);
1835*6777b538SAndroid Build Coastguard Worker 
1836*6777b538SAndroid Build Coastguard Worker   HostCache restored_cache(kMaxCacheEntries);
1837*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(dict->is_list());
1838*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(restored_cache.RestoreFromListValue(dict->GetList()));
1839*6777b538SAndroid Build Coastguard Worker 
1840*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, restored_cache.size());
1841*6777b538SAndroid Build Coastguard Worker 
1842*6777b538SAndroid Build Coastguard Worker   HostCache::Key key(url::SchemeHostPort(url::kHttpsScheme, "example.com", 443),
1843*6777b538SAndroid Build Coastguard Worker                      DnsQueryType::A, 0, HostResolverSource::DNS,
1844*6777b538SAndroid Build Coastguard Worker                      NetworkAnonymizationKey());
1845*6777b538SAndroid Build Coastguard Worker 
1846*6777b538SAndroid Build Coastguard Worker   HostCache::EntryStaleness stale;
1847*6777b538SAndroid Build Coastguard Worker   const std::pair<const HostCache::Key, HostCache::Entry>* result =
1848*6777b538SAndroid Build Coastguard Worker       restored_cache.LookupStale(key, base::TimeTicks::Now(), &stale);
1849*6777b538SAndroid Build Coastguard Worker 
1850*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(result);
1851*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result->second.aliases(), ElementsAre());
1852*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result->second.ip_endpoints(), ElementsAre());
1853*6777b538SAndroid Build Coastguard Worker }
1854*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,DeserializeLegacyAddresses)1855*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, DeserializeLegacyAddresses) {
1856*6777b538SAndroid Build Coastguard Worker   base::TimeDelta ttl = base::Seconds(99);
1857*6777b538SAndroid Build Coastguard Worker   std::string expiration_time_str = base::NumberToString(
1858*6777b538SAndroid Build Coastguard Worker       (base::Time::Now() + ttl).since_origin().InMicroseconds());
1859*6777b538SAndroid Build Coastguard Worker 
1860*6777b538SAndroid Build Coastguard Worker   auto dict = base::JSONReader::Read(base::StringPrintf(
1861*6777b538SAndroid Build Coastguard Worker       R"(
1862*6777b538SAndroid Build Coastguard Worker  [ {
1863*6777b538SAndroid Build Coastguard Worker    "addresses": [ "2000::", "1.2.3.4" ],
1864*6777b538SAndroid Build Coastguard Worker    "dns_query_type": 1,
1865*6777b538SAndroid Build Coastguard Worker    "expiration": "%s",
1866*6777b538SAndroid Build Coastguard Worker    "flags": 0,
1867*6777b538SAndroid Build Coastguard Worker    "host_resolver_source": 2,
1868*6777b538SAndroid Build Coastguard Worker    "hostname": "example.com",
1869*6777b538SAndroid Build Coastguard Worker    "network_anonymization_key": [  ],
1870*6777b538SAndroid Build Coastguard Worker    "port": 443,
1871*6777b538SAndroid Build Coastguard Worker    "scheme": "https",
1872*6777b538SAndroid Build Coastguard Worker    "secure": false
1873*6777b538SAndroid Build Coastguard Worker } ]
1874*6777b538SAndroid Build Coastguard Worker )",
1875*6777b538SAndroid Build Coastguard Worker       expiration_time_str.c_str()));
1876*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(dict);
1877*6777b538SAndroid Build Coastguard Worker 
1878*6777b538SAndroid Build Coastguard Worker   HostCache restored_cache(kMaxCacheEntries);
1879*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(dict->is_list());
1880*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(restored_cache.RestoreFromListValue(dict->GetList()));
1881*6777b538SAndroid Build Coastguard Worker 
1882*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(1u, restored_cache.size());
1883*6777b538SAndroid Build Coastguard Worker 
1884*6777b538SAndroid Build Coastguard Worker   HostCache::Key key(url::SchemeHostPort(url::kHttpsScheme, "example.com", 443),
1885*6777b538SAndroid Build Coastguard Worker                      DnsQueryType::A, 0, HostResolverSource::DNS,
1886*6777b538SAndroid Build Coastguard Worker                      NetworkAnonymizationKey());
1887*6777b538SAndroid Build Coastguard Worker 
1888*6777b538SAndroid Build Coastguard Worker   HostCache::EntryStaleness stale;
1889*6777b538SAndroid Build Coastguard Worker   const std::pair<const HostCache::Key, HostCache::Entry>* result =
1890*6777b538SAndroid Build Coastguard Worker       restored_cache.LookupStale(key, base::TimeTicks::Now(), &stale);
1891*6777b538SAndroid Build Coastguard Worker 
1892*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(result);
1893*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result->second.ip_endpoints(),
1894*6777b538SAndroid Build Coastguard Worker               ElementsAreArray(MakeEndpoints({"2000::", "1.2.3.4"})));
1895*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result->second.aliases(), ElementsAre());
1896*6777b538SAndroid Build Coastguard Worker }
1897*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,DeserializeInvalidQueryTypeIntegrity)1898*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, DeserializeInvalidQueryTypeIntegrity) {
1899*6777b538SAndroid Build Coastguard Worker   base::TimeDelta ttl = base::Seconds(99);
1900*6777b538SAndroid Build Coastguard Worker   std::string expiration_time_str = base::NumberToString(
1901*6777b538SAndroid Build Coastguard Worker       (base::Time::Now() + ttl).since_origin().InMicroseconds());
1902*6777b538SAndroid Build Coastguard Worker 
1903*6777b538SAndroid Build Coastguard Worker   // RestoreFromListValue doesn't support dns_query_type=6 (INTEGRITY).
1904*6777b538SAndroid Build Coastguard Worker   auto dict = base::JSONReader::Read(base::StringPrintf(
1905*6777b538SAndroid Build Coastguard Worker       R"(
1906*6777b538SAndroid Build Coastguard Worker  [ {
1907*6777b538SAndroid Build Coastguard Worker    "addresses": [ "2000::", "1.2.3.4" ],
1908*6777b538SAndroid Build Coastguard Worker    "dns_query_type": 6,
1909*6777b538SAndroid Build Coastguard Worker    "expiration": "%s",
1910*6777b538SAndroid Build Coastguard Worker    "flags": 0,
1911*6777b538SAndroid Build Coastguard Worker    "host_resolver_source": 2,
1912*6777b538SAndroid Build Coastguard Worker    "hostname": "example.com",
1913*6777b538SAndroid Build Coastguard Worker    "network_anonymization_key": [  ],
1914*6777b538SAndroid Build Coastguard Worker    "port": 443,
1915*6777b538SAndroid Build Coastguard Worker    "scheme": "https",
1916*6777b538SAndroid Build Coastguard Worker    "secure": false
1917*6777b538SAndroid Build Coastguard Worker } ]
1918*6777b538SAndroid Build Coastguard Worker )",
1919*6777b538SAndroid Build Coastguard Worker       expiration_time_str.c_str()));
1920*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(dict);
1921*6777b538SAndroid Build Coastguard Worker 
1922*6777b538SAndroid Build Coastguard Worker   HostCache restored_cache(kMaxCacheEntries);
1923*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(dict->is_list());
1924*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(restored_cache.RestoreFromListValue(dict->GetList()));
1925*6777b538SAndroid Build Coastguard Worker 
1926*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, restored_cache.size());
1927*6777b538SAndroid Build Coastguard Worker }
1928*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,DeserializeInvalidQueryTypeHttpsExperimental)1929*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, DeserializeInvalidQueryTypeHttpsExperimental) {
1930*6777b538SAndroid Build Coastguard Worker   base::TimeDelta ttl = base::Seconds(99);
1931*6777b538SAndroid Build Coastguard Worker   std::string expiration_time_str = base::NumberToString(
1932*6777b538SAndroid Build Coastguard Worker       (base::Time::Now() + ttl).since_origin().InMicroseconds());
1933*6777b538SAndroid Build Coastguard Worker 
1934*6777b538SAndroid Build Coastguard Worker   // RestoreFromListValue doesn't support dns_query_type=8 (HTTPS_EXPERIMENTAL).
1935*6777b538SAndroid Build Coastguard Worker   auto dict = base::JSONReader::Read(base::StringPrintf(
1936*6777b538SAndroid Build Coastguard Worker       R"(
1937*6777b538SAndroid Build Coastguard Worker  [ {
1938*6777b538SAndroid Build Coastguard Worker    "addresses": [ "2000::", "1.2.3.4" ],
1939*6777b538SAndroid Build Coastguard Worker    "dns_query_type": 8,
1940*6777b538SAndroid Build Coastguard Worker    "expiration": "%s",
1941*6777b538SAndroid Build Coastguard Worker    "flags": 0,
1942*6777b538SAndroid Build Coastguard Worker    "host_resolver_source": 2,
1943*6777b538SAndroid Build Coastguard Worker    "hostname": "example.com",
1944*6777b538SAndroid Build Coastguard Worker    "network_anonymization_key": [  ],
1945*6777b538SAndroid Build Coastguard Worker    "port": 443,
1946*6777b538SAndroid Build Coastguard Worker    "scheme": "https",
1947*6777b538SAndroid Build Coastguard Worker    "secure": false
1948*6777b538SAndroid Build Coastguard Worker } ]
1949*6777b538SAndroid Build Coastguard Worker )",
1950*6777b538SAndroid Build Coastguard Worker       expiration_time_str.c_str()));
1951*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(dict);
1952*6777b538SAndroid Build Coastguard Worker 
1953*6777b538SAndroid Build Coastguard Worker   HostCache restored_cache(kMaxCacheEntries);
1954*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(dict->is_list());
1955*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(restored_cache.RestoreFromListValue(dict->GetList()));
1956*6777b538SAndroid Build Coastguard Worker 
1957*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, restored_cache.size());
1958*6777b538SAndroid Build Coastguard Worker }
1959*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,PersistenceDelegate)1960*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, PersistenceDelegate) {
1961*6777b538SAndroid Build Coastguard Worker   const base::TimeDelta kTTL = base::Seconds(10);
1962*6777b538SAndroid Build Coastguard Worker   HostCache cache(kMaxCacheEntries);
1963*6777b538SAndroid Build Coastguard Worker   MockPersistenceDelegate delegate;
1964*6777b538SAndroid Build Coastguard Worker   cache.set_persistence_delegate(&delegate);
1965*6777b538SAndroid Build Coastguard Worker 
1966*6777b538SAndroid Build Coastguard Worker   HostCache::Key key1 = Key("foobar.com");
1967*6777b538SAndroid Build Coastguard Worker   HostCache::Key key2 = Key("foobar2.com");
1968*6777b538SAndroid Build Coastguard Worker 
1969*6777b538SAndroid Build Coastguard Worker   HostCache::Entry ok_entry =
1970*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
1971*6777b538SAndroid Build Coastguard Worker                        HostCache::Entry::SOURCE_UNKNOWN);
1972*6777b538SAndroid Build Coastguard Worker   std::vector<IPEndPoint> other_endpoints = {
1973*6777b538SAndroid Build Coastguard Worker       IPEndPoint(IPAddress(1, 1, 1, 1), 300)};
1974*6777b538SAndroid Build Coastguard Worker   HostCache::Entry other_entry(OK, std::move(other_endpoints), /*aliases=*/{},
1975*6777b538SAndroid Build Coastguard Worker                                HostCache::Entry::SOURCE_UNKNOWN);
1976*6777b538SAndroid Build Coastguard Worker   HostCache::Entry error_entry =
1977*6777b538SAndroid Build Coastguard Worker       HostCache::Entry(ERR_NAME_NOT_RESOLVED, /*ip_endpoints=*/{},
1978*6777b538SAndroid Build Coastguard Worker                        /*aliases=*/{}, HostCache::Entry::SOURCE_UNKNOWN);
1979*6777b538SAndroid Build Coastguard Worker 
1980*6777b538SAndroid Build Coastguard Worker   // Start at t=0.
1981*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now;
1982*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, cache.size());
1983*6777b538SAndroid Build Coastguard Worker 
1984*6777b538SAndroid Build Coastguard Worker   // Add two entries at t=0.
1985*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key1, now));
1986*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, ok_entry, now, kTTL);
1987*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
1988*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1u, cache.size());
1989*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1, delegate.num_changes());
1990*6777b538SAndroid Build Coastguard Worker 
1991*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(cache.Lookup(key2, now));
1992*6777b538SAndroid Build Coastguard Worker   cache.Set(key2, error_entry, now, kTTL);
1993*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key2, now));
1994*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cache.size());
1995*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, delegate.num_changes());
1996*6777b538SAndroid Build Coastguard Worker 
1997*6777b538SAndroid Build Coastguard Worker   // Advance to t=5.
1998*6777b538SAndroid Build Coastguard Worker   now += base::Seconds(5);
1999*6777b538SAndroid Build Coastguard Worker 
2000*6777b538SAndroid Build Coastguard Worker   // Changes that shouldn't trigger a write:
2001*6777b538SAndroid Build Coastguard Worker   // Add an entry for "foobar.com" with different expiration time.
2002*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
2003*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, ok_entry, now, kTTL);
2004*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
2005*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cache.size());
2006*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, delegate.num_changes());
2007*6777b538SAndroid Build Coastguard Worker 
2008*6777b538SAndroid Build Coastguard Worker   // Add an entry for "foobar.com" with different TTL.
2009*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
2010*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, ok_entry, now, kTTL - base::Seconds(5));
2011*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
2012*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cache.size());
2013*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2, delegate.num_changes());
2014*6777b538SAndroid Build Coastguard Worker 
2015*6777b538SAndroid Build Coastguard Worker   // Changes that should trigger a write:
2016*6777b538SAndroid Build Coastguard Worker   // Add an entry for "foobar.com" with different address list.
2017*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
2018*6777b538SAndroid Build Coastguard Worker   cache.Set(key1, other_entry, now, kTTL);
2019*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
2020*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cache.size());
2021*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3, delegate.num_changes());
2022*6777b538SAndroid Build Coastguard Worker 
2023*6777b538SAndroid Build Coastguard Worker   // Add an entry for "foobar2.com" with different error.
2024*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
2025*6777b538SAndroid Build Coastguard Worker   cache.Set(key2, ok_entry, now, kTTL);
2026*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(cache.Lookup(key1, now));
2027*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2u, cache.size());
2028*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(4, delegate.num_changes());
2029*6777b538SAndroid Build Coastguard Worker }
2030*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,MergeEndpointsWithAliases)2031*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, MergeEndpointsWithAliases) {
2032*6777b538SAndroid Build Coastguard Worker   const IPAddress kAddressFront(1, 2, 3, 4);
2033*6777b538SAndroid Build Coastguard Worker   const IPEndPoint kEndpointFront(kAddressFront, 0);
2034*6777b538SAndroid Build Coastguard Worker   HostCache::Entry front(OK, {kEndpointFront}, {"alias1", "alias2", "alias3"},
2035*6777b538SAndroid Build Coastguard Worker                          HostCache::Entry::SOURCE_DNS);
2036*6777b538SAndroid Build Coastguard Worker   front.set_text_records(std::vector<std::string>{"text1"});
2037*6777b538SAndroid Build Coastguard Worker   const HostPortPair kHostnameFront("host", 1);
2038*6777b538SAndroid Build Coastguard Worker   front.set_hostnames(std::vector<HostPortPair>{kHostnameFront});
2039*6777b538SAndroid Build Coastguard Worker 
2040*6777b538SAndroid Build Coastguard Worker   const IPAddress kAddressBack(0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2041*6777b538SAndroid Build Coastguard Worker                                0);
2042*6777b538SAndroid Build Coastguard Worker   const IPEndPoint kEndpointBack(kAddressBack, 0);
2043*6777b538SAndroid Build Coastguard Worker   HostCache::Entry back(OK, {kEndpointBack}, {"alias2", "alias4", "alias5"},
2044*6777b538SAndroid Build Coastguard Worker                         HostCache::Entry::SOURCE_DNS);
2045*6777b538SAndroid Build Coastguard Worker   back.set_text_records(std::vector<std::string>{"text2"});
2046*6777b538SAndroid Build Coastguard Worker   const HostPortPair kHostnameBack("host", 2);
2047*6777b538SAndroid Build Coastguard Worker   back.set_hostnames(std::vector<HostPortPair>{kHostnameBack});
2048*6777b538SAndroid Build Coastguard Worker 
2049*6777b538SAndroid Build Coastguard Worker   HostCache::Entry result =
2050*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::MergeEntries(std::move(front), std::move(back));
2051*6777b538SAndroid Build Coastguard Worker 
2052*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(OK, result.error());
2053*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(HostCache::Entry::SOURCE_DNS, result.source());
2054*6777b538SAndroid Build Coastguard Worker 
2055*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.ip_endpoints(),
2056*6777b538SAndroid Build Coastguard Worker               ElementsAre(kEndpointFront, kEndpointBack));
2057*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.text_records(), ElementsAre("text1", "text2"));
2058*6777b538SAndroid Build Coastguard Worker 
2059*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.hostnames(), ElementsAre(kHostnameFront, kHostnameBack));
2060*6777b538SAndroid Build Coastguard Worker 
2061*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
2062*6777b538SAndroid Build Coastguard Worker       result.aliases(),
2063*6777b538SAndroid Build Coastguard Worker       UnorderedElementsAre("alias1", "alias2", "alias3", "alias4", "alias5"));
2064*6777b538SAndroid Build Coastguard Worker }
2065*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,MergeEndpointsKeepEndpointsOrder)2066*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, MergeEndpointsKeepEndpointsOrder) {
2067*6777b538SAndroid Build Coastguard Worker   std::vector<IPEndPoint> front_addresses =
2068*6777b538SAndroid Build Coastguard Worker       MakeEndpoints({"::1", "0.0.0.2", "0.0.0.4"});
2069*6777b538SAndroid Build Coastguard Worker   std::vector<IPEndPoint> back_addresses =
2070*6777b538SAndroid Build Coastguard Worker       MakeEndpoints({"0.0.0.2", "0.0.0.2", "::3", "::3", "0.0.0.4"});
2071*6777b538SAndroid Build Coastguard Worker 
2072*6777b538SAndroid Build Coastguard Worker   HostCache::Entry front(OK, front_addresses, /*aliases=*/{"front"},
2073*6777b538SAndroid Build Coastguard Worker                          HostCache::Entry::SOURCE_DNS);
2074*6777b538SAndroid Build Coastguard Worker   HostCache::Entry back(OK, back_addresses, /*aliases=*/{"back"},
2075*6777b538SAndroid Build Coastguard Worker                         HostCache::Entry::SOURCE_DNS);
2076*6777b538SAndroid Build Coastguard Worker 
2077*6777b538SAndroid Build Coastguard Worker   HostCache::Entry result =
2078*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::MergeEntries(std::move(front), std::move(back));
2079*6777b538SAndroid Build Coastguard Worker 
2080*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
2081*6777b538SAndroid Build Coastguard Worker       result.ip_endpoints(),
2082*6777b538SAndroid Build Coastguard Worker       ElementsAreArray(MakeEndpoints({"::1", "0.0.0.2", "0.0.0.4", "0.0.0.2",
2083*6777b538SAndroid Build Coastguard Worker                                       "0.0.0.2", "::3", "::3", "0.0.0.4"})));
2084*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.aliases(), UnorderedElementsAre("front", "back"));
2085*6777b538SAndroid Build Coastguard Worker }
2086*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,MergeMetadatas)2087*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, MergeMetadatas) {
2088*6777b538SAndroid Build Coastguard Worker   ConnectionEndpointMetadata front_metadata;
2089*6777b538SAndroid Build Coastguard Worker   front_metadata.supported_protocol_alpns = {"h5", "h6", "monster truck rally"};
2090*6777b538SAndroid Build Coastguard Worker   front_metadata.ech_config_list = {'h', 'i'};
2091*6777b538SAndroid Build Coastguard Worker   std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>
2092*6777b538SAndroid Build Coastguard Worker       front_metadata_map{{4u, front_metadata}};
2093*6777b538SAndroid Build Coastguard Worker   HostCache::Entry front(OK, front_metadata_map, HostCache::Entry::SOURCE_DNS);
2094*6777b538SAndroid Build Coastguard Worker 
2095*6777b538SAndroid Build Coastguard Worker   ConnectionEndpointMetadata back_metadata;
2096*6777b538SAndroid Build Coastguard Worker   back_metadata.supported_protocol_alpns = {"h5"};
2097*6777b538SAndroid Build Coastguard Worker   std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>
2098*6777b538SAndroid Build Coastguard Worker       back_metadata_map{{2u, back_metadata}};
2099*6777b538SAndroid Build Coastguard Worker   HostCache::Entry back(OK, back_metadata_map, HostCache::Entry::SOURCE_DNS);
2100*6777b538SAndroid Build Coastguard Worker 
2101*6777b538SAndroid Build Coastguard Worker   HostCache::Entry result = HostCache::Entry::MergeEntries(front, back);
2102*6777b538SAndroid Build Coastguard Worker 
2103*6777b538SAndroid Build Coastguard Worker   // Expect `GetEndpoints()` to ignore metadatas if no `IPEndPoint`s.
2104*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.GetEndpoints(), IsEmpty());
2105*6777b538SAndroid Build Coastguard Worker 
2106*6777b538SAndroid Build Coastguard Worker   // Expect order irrelevant for endpoint metadata merging.
2107*6777b538SAndroid Build Coastguard Worker   result = HostCache::Entry::MergeEntries(back, front);
2108*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.GetEndpoints(), IsEmpty());
2109*6777b538SAndroid Build Coastguard Worker }
2110*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,MergeMetadatasWithIpEndpointsDifferentCanonicalName)2111*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, MergeMetadatasWithIpEndpointsDifferentCanonicalName) {
2112*6777b538SAndroid Build Coastguard Worker   std::string target_name = "example.com";
2113*6777b538SAndroid Build Coastguard Worker   std::string other_target_name = "other.example.com";
2114*6777b538SAndroid Build Coastguard Worker   ConnectionEndpointMetadata metadata;
2115*6777b538SAndroid Build Coastguard Worker   metadata.supported_protocol_alpns = {"h5", "h6", "monster truck rally"};
2116*6777b538SAndroid Build Coastguard Worker   metadata.ech_config_list = {'h', 'i'};
2117*6777b538SAndroid Build Coastguard Worker   metadata.target_name = target_name;
2118*6777b538SAndroid Build Coastguard Worker 
2119*6777b538SAndroid Build Coastguard Worker   std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> metadata_map{
2120*6777b538SAndroid Build Coastguard Worker       {4u, metadata}};
2121*6777b538SAndroid Build Coastguard Worker   HostCache::Entry metadata_entry(OK, metadata_map,
2122*6777b538SAndroid Build Coastguard Worker                                   HostCache::Entry::SOURCE_DNS);
2123*6777b538SAndroid Build Coastguard Worker 
2124*6777b538SAndroid Build Coastguard Worker   // Expect `GetEndpoints()` to always ignore metadatas with no `IPEndPoint`s.
2125*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(metadata_entry.GetEndpoints(), IsEmpty());
2126*6777b538SAndroid Build Coastguard Worker 
2127*6777b538SAndroid Build Coastguard Worker   // Merge in an `IPEndPoint` with different canonical name.
2128*6777b538SAndroid Build Coastguard Worker   IPEndPoint ip_endpoint(IPAddress(1, 1, 1, 1), 0);
2129*6777b538SAndroid Build Coastguard Worker   HostCache::Entry with_ip_endpoint(OK, {ip_endpoint}, /*aliases=*/{},
2130*6777b538SAndroid Build Coastguard Worker                                     HostCache::Entry::SOURCE_DNS);
2131*6777b538SAndroid Build Coastguard Worker   with_ip_endpoint.set_canonical_names(
2132*6777b538SAndroid Build Coastguard Worker       std::set<std::string>{other_target_name});
2133*6777b538SAndroid Build Coastguard Worker   HostCache::Entry result =
2134*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::MergeEntries(metadata_entry, with_ip_endpoint);
2135*6777b538SAndroid Build Coastguard Worker 
2136*6777b538SAndroid Build Coastguard Worker   // Expect `GetEndpoints()` not to return the metadata.
2137*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
2138*6777b538SAndroid Build Coastguard Worker       result.GetEndpoints(),
2139*6777b538SAndroid Build Coastguard Worker       ElementsAre(ExpectEndpointResult(std::vector<IPEndPoint>{ip_endpoint})));
2140*6777b538SAndroid Build Coastguard Worker 
2141*6777b538SAndroid Build Coastguard Worker   // Expect merge order irrelevant.
2142*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(result,
2143*6777b538SAndroid Build Coastguard Worker             HostCache::Entry::MergeEntries(with_ip_endpoint, metadata_entry));
2144*6777b538SAndroid Build Coastguard Worker }
2145*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,MergeMetadatasWithIpEndpointsMatchingCanonicalName)2146*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, MergeMetadatasWithIpEndpointsMatchingCanonicalName) {
2147*6777b538SAndroid Build Coastguard Worker   std::string target_name = "example.com";
2148*6777b538SAndroid Build Coastguard Worker   ConnectionEndpointMetadata metadata;
2149*6777b538SAndroid Build Coastguard Worker   metadata.supported_protocol_alpns = {"h5", "h6", "monster truck rally"};
2150*6777b538SAndroid Build Coastguard Worker   metadata.ech_config_list = {'h', 'i'};
2151*6777b538SAndroid Build Coastguard Worker   metadata.target_name = target_name;
2152*6777b538SAndroid Build Coastguard Worker 
2153*6777b538SAndroid Build Coastguard Worker   std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> metadata_map{
2154*6777b538SAndroid Build Coastguard Worker       {4u, metadata}};
2155*6777b538SAndroid Build Coastguard Worker   HostCache::Entry metadata_entry(OK, metadata_map,
2156*6777b538SAndroid Build Coastguard Worker                                   HostCache::Entry::SOURCE_DNS);
2157*6777b538SAndroid Build Coastguard Worker 
2158*6777b538SAndroid Build Coastguard Worker   // Expect `GetEndpoints()` to always ignore metadatas with no `IPEndPoint`s.
2159*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(metadata_entry.GetEndpoints(), IsEmpty());
2160*6777b538SAndroid Build Coastguard Worker 
2161*6777b538SAndroid Build Coastguard Worker   // Merge in an `IPEndPoint` with different canonical name.
2162*6777b538SAndroid Build Coastguard Worker   IPEndPoint ip_endpoint(IPAddress(1, 1, 1, 1), 0);
2163*6777b538SAndroid Build Coastguard Worker   HostCache::Entry with_ip_endpoint(OK, {ip_endpoint}, /*aliases=*/{},
2164*6777b538SAndroid Build Coastguard Worker                                     HostCache::Entry::SOURCE_DNS);
2165*6777b538SAndroid Build Coastguard Worker   with_ip_endpoint.set_canonical_names(std::set<std::string>{target_name});
2166*6777b538SAndroid Build Coastguard Worker   HostCache::Entry result =
2167*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::MergeEntries(metadata_entry, with_ip_endpoint);
2168*6777b538SAndroid Build Coastguard Worker 
2169*6777b538SAndroid Build Coastguard Worker   // Expect `GetEndpoints()` to return the metadata.
2170*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
2171*6777b538SAndroid Build Coastguard Worker       result.GetEndpoints(),
2172*6777b538SAndroid Build Coastguard Worker       ElementsAre(ExpectEndpointResult(ElementsAre(ip_endpoint), metadata),
2173*6777b538SAndroid Build Coastguard Worker                   ExpectEndpointResult(ElementsAre(ip_endpoint))));
2174*6777b538SAndroid Build Coastguard Worker 
2175*6777b538SAndroid Build Coastguard Worker   // Expect merge order irrelevant.
2176*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(result,
2177*6777b538SAndroid Build Coastguard Worker             HostCache::Entry::MergeEntries(with_ip_endpoint, metadata_entry));
2178*6777b538SAndroid Build Coastguard Worker }
2179*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,MergeMultipleMetadatasWithIpEndpoints)2180*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, MergeMultipleMetadatasWithIpEndpoints) {
2181*6777b538SAndroid Build Coastguard Worker   std::string target_name = "example.com";
2182*6777b538SAndroid Build Coastguard Worker   ConnectionEndpointMetadata front_metadata;
2183*6777b538SAndroid Build Coastguard Worker   front_metadata.supported_protocol_alpns = {"h5", "h6", "monster truck rally"};
2184*6777b538SAndroid Build Coastguard Worker   front_metadata.ech_config_list = {'h', 'i'};
2185*6777b538SAndroid Build Coastguard Worker   front_metadata.target_name = target_name;
2186*6777b538SAndroid Build Coastguard Worker 
2187*6777b538SAndroid Build Coastguard Worker   std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>
2188*6777b538SAndroid Build Coastguard Worker       front_metadata_map{{4u, front_metadata}};
2189*6777b538SAndroid Build Coastguard Worker   HostCache::Entry front(OK, front_metadata_map, HostCache::Entry::SOURCE_DNS);
2190*6777b538SAndroid Build Coastguard Worker 
2191*6777b538SAndroid Build Coastguard Worker   ConnectionEndpointMetadata back_metadata;
2192*6777b538SAndroid Build Coastguard Worker   back_metadata.supported_protocol_alpns = {"h5"};
2193*6777b538SAndroid Build Coastguard Worker   back_metadata.target_name = target_name;
2194*6777b538SAndroid Build Coastguard Worker   std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>
2195*6777b538SAndroid Build Coastguard Worker       back_metadata_map{{2u, back_metadata}};
2196*6777b538SAndroid Build Coastguard Worker   HostCache::Entry back(OK, back_metadata_map, HostCache::Entry::SOURCE_DNS);
2197*6777b538SAndroid Build Coastguard Worker 
2198*6777b538SAndroid Build Coastguard Worker   HostCache::Entry merged_metadatas =
2199*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::MergeEntries(front, back);
2200*6777b538SAndroid Build Coastguard Worker   HostCache::Entry reversed_merged_metadatas =
2201*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::MergeEntries(back, front);
2202*6777b538SAndroid Build Coastguard Worker 
2203*6777b538SAndroid Build Coastguard Worker   // Expect `GetEndpoints()` to always ignore metadatas with no `IPEndPoint`s.
2204*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(merged_metadatas.GetEndpoints(), IsEmpty());
2205*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(reversed_merged_metadatas.GetEndpoints(), IsEmpty());
2206*6777b538SAndroid Build Coastguard Worker 
2207*6777b538SAndroid Build Coastguard Worker   // Merge in an `IPEndPoint`.
2208*6777b538SAndroid Build Coastguard Worker   IPEndPoint ip_endpoint(IPAddress(1, 1, 1, 1), 0);
2209*6777b538SAndroid Build Coastguard Worker   HostCache::Entry with_ip_endpoint(OK, {ip_endpoint}, /*aliases=*/{},
2210*6777b538SAndroid Build Coastguard Worker                                     HostCache::Entry::SOURCE_DNS);
2211*6777b538SAndroid Build Coastguard Worker   with_ip_endpoint.set_canonical_names(std::set<std::string>{target_name});
2212*6777b538SAndroid Build Coastguard Worker 
2213*6777b538SAndroid Build Coastguard Worker   HostCache::Entry result =
2214*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::MergeEntries(merged_metadatas, with_ip_endpoint);
2215*6777b538SAndroid Build Coastguard Worker 
2216*6777b538SAndroid Build Coastguard Worker   // Expect `back_metadata` before `front_metadata` because it has lower
2217*6777b538SAndroid Build Coastguard Worker   // priority number.
2218*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
2219*6777b538SAndroid Build Coastguard Worker       result.GetEndpoints(),
2220*6777b538SAndroid Build Coastguard Worker       ElementsAre(
2221*6777b538SAndroid Build Coastguard Worker           ExpectEndpointResult(ElementsAre(ip_endpoint), back_metadata),
2222*6777b538SAndroid Build Coastguard Worker           ExpectEndpointResult(ElementsAre(ip_endpoint), front_metadata),
2223*6777b538SAndroid Build Coastguard Worker           ExpectEndpointResult(ElementsAre(ip_endpoint))));
2224*6777b538SAndroid Build Coastguard Worker 
2225*6777b538SAndroid Build Coastguard Worker   // Expect merge order irrelevant.
2226*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(result, HostCache::Entry::MergeEntries(reversed_merged_metadatas,
2227*6777b538SAndroid Build Coastguard Worker                                                    with_ip_endpoint));
2228*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(result,
2229*6777b538SAndroid Build Coastguard Worker             HostCache::Entry::MergeEntries(with_ip_endpoint, merged_metadatas));
2230*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(result, HostCache::Entry::MergeEntries(with_ip_endpoint,
2231*6777b538SAndroid Build Coastguard Worker                                                    reversed_merged_metadatas));
2232*6777b538SAndroid Build Coastguard Worker }
2233*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,MergeAliases)2234*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, MergeAliases) {
2235*6777b538SAndroid Build Coastguard Worker   HostCache::Entry front(OK, /*ip_endpoints=*/{},
2236*6777b538SAndroid Build Coastguard Worker                          /*aliases=*/{"foo1.test", "foo2.test", "foo3.test"},
2237*6777b538SAndroid Build Coastguard Worker                          HostCache::Entry::SOURCE_DNS);
2238*6777b538SAndroid Build Coastguard Worker 
2239*6777b538SAndroid Build Coastguard Worker   HostCache::Entry back(OK, /*ip_endpoints=*/{},
2240*6777b538SAndroid Build Coastguard Worker                         /*aliases=*/{"foo2.test", "foo4.test"},
2241*6777b538SAndroid Build Coastguard Worker                         HostCache::Entry::SOURCE_DNS);
2242*6777b538SAndroid Build Coastguard Worker 
2243*6777b538SAndroid Build Coastguard Worker   HostCache::Entry expected(
2244*6777b538SAndroid Build Coastguard Worker       OK, /*ip_endpoints=*/{},
2245*6777b538SAndroid Build Coastguard Worker       /*aliases=*/{"foo1.test", "foo2.test", "foo3.test", "foo4.test"},
2246*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::SOURCE_DNS);
2247*6777b538SAndroid Build Coastguard Worker 
2248*6777b538SAndroid Build Coastguard Worker   HostCache::Entry result = HostCache::Entry::MergeEntries(front, back);
2249*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(result, expected);
2250*6777b538SAndroid Build Coastguard Worker 
2251*6777b538SAndroid Build Coastguard Worker   // Expect order irrelevant for alias merging.
2252*6777b538SAndroid Build Coastguard Worker   result = HostCache::Entry::MergeEntries(back, front);
2253*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(result, expected);
2254*6777b538SAndroid Build Coastguard Worker }
2255*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,MergeEntries_frontEmpty)2256*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, MergeEntries_frontEmpty) {
2257*6777b538SAndroid Build Coastguard Worker   HostCache::Entry front(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_DNS);
2258*6777b538SAndroid Build Coastguard Worker 
2259*6777b538SAndroid Build Coastguard Worker   const IPAddress kAddressBack(0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2260*6777b538SAndroid Build Coastguard Worker                                0);
2261*6777b538SAndroid Build Coastguard Worker   const IPEndPoint kEndpointBack(kAddressBack, 0);
2262*6777b538SAndroid Build Coastguard Worker   HostCache::Entry back(OK, {kEndpointBack}, {"alias1", "alias2", "alias3"},
2263*6777b538SAndroid Build Coastguard Worker                         HostCache::Entry::SOURCE_DNS, base::Hours(4));
2264*6777b538SAndroid Build Coastguard Worker   back.set_text_records(std::vector<std::string>{"text2"});
2265*6777b538SAndroid Build Coastguard Worker   const HostPortPair kHostnameBack("host", 2);
2266*6777b538SAndroid Build Coastguard Worker   back.set_hostnames(std::vector<HostPortPair>{kHostnameBack});
2267*6777b538SAndroid Build Coastguard Worker 
2268*6777b538SAndroid Build Coastguard Worker   HostCache::Entry result =
2269*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::MergeEntries(std::move(front), std::move(back));
2270*6777b538SAndroid Build Coastguard Worker 
2271*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(OK, result.error());
2272*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(HostCache::Entry::SOURCE_DNS, result.source());
2273*6777b538SAndroid Build Coastguard Worker 
2274*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.ip_endpoints(), ElementsAre(kEndpointBack));
2275*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.text_records(), ElementsAre("text2"));
2276*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.hostnames(), ElementsAre(kHostnameBack));
2277*6777b538SAndroid Build Coastguard Worker 
2278*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Hours(4), result.ttl());
2279*6777b538SAndroid Build Coastguard Worker 
2280*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.aliases(),
2281*6777b538SAndroid Build Coastguard Worker               UnorderedElementsAre("alias1", "alias2", "alias3"));
2282*6777b538SAndroid Build Coastguard Worker }
2283*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,MergeEntries_backEmpty)2284*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, MergeEntries_backEmpty) {
2285*6777b538SAndroid Build Coastguard Worker   const IPAddress kAddressFront(1, 2, 3, 4);
2286*6777b538SAndroid Build Coastguard Worker   const IPEndPoint kEndpointFront(kAddressFront, 0);
2287*6777b538SAndroid Build Coastguard Worker   HostCache::Entry front(OK, {kEndpointFront}, {"alias1", "alias2", "alias3"},
2288*6777b538SAndroid Build Coastguard Worker                          HostCache::Entry::SOURCE_DNS, base::Minutes(5));
2289*6777b538SAndroid Build Coastguard Worker   front.set_text_records(std::vector<std::string>{"text1"});
2290*6777b538SAndroid Build Coastguard Worker   const HostPortPair kHostnameFront("host", 1);
2291*6777b538SAndroid Build Coastguard Worker   front.set_hostnames(std::vector<HostPortPair>{kHostnameFront});
2292*6777b538SAndroid Build Coastguard Worker 
2293*6777b538SAndroid Build Coastguard Worker   HostCache::Entry back(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_DNS);
2294*6777b538SAndroid Build Coastguard Worker 
2295*6777b538SAndroid Build Coastguard Worker   HostCache::Entry result =
2296*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::MergeEntries(std::move(front), std::move(back));
2297*6777b538SAndroid Build Coastguard Worker 
2298*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(OK, result.error());
2299*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(HostCache::Entry::SOURCE_DNS, result.source());
2300*6777b538SAndroid Build Coastguard Worker 
2301*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.ip_endpoints(), ElementsAre(kEndpointFront));
2302*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.text_records(), ElementsAre("text1"));
2303*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.hostnames(), ElementsAre(kHostnameFront));
2304*6777b538SAndroid Build Coastguard Worker 
2305*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Minutes(5), result.ttl());
2306*6777b538SAndroid Build Coastguard Worker 
2307*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.aliases(),
2308*6777b538SAndroid Build Coastguard Worker               UnorderedElementsAre("alias1", "alias2", "alias3"));
2309*6777b538SAndroid Build Coastguard Worker }
2310*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,MergeEntries_bothEmpty)2311*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, MergeEntries_bothEmpty) {
2312*6777b538SAndroid Build Coastguard Worker   HostCache::Entry front(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_DNS);
2313*6777b538SAndroid Build Coastguard Worker   HostCache::Entry back(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_DNS);
2314*6777b538SAndroid Build Coastguard Worker 
2315*6777b538SAndroid Build Coastguard Worker   HostCache::Entry result =
2316*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::MergeEntries(std::move(front), std::move(back));
2317*6777b538SAndroid Build Coastguard Worker 
2318*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ERR_NAME_NOT_RESOLVED, result.error());
2319*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(HostCache::Entry::SOURCE_DNS, result.source());
2320*6777b538SAndroid Build Coastguard Worker 
2321*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.ip_endpoints(), IsEmpty());
2322*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.text_records(), IsEmpty());
2323*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.hostnames(), IsEmpty());
2324*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(result.has_ttl());
2325*6777b538SAndroid Build Coastguard Worker }
2326*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,MergeEntries_frontWithAliasesNoAddressesBackWithBoth)2327*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, MergeEntries_frontWithAliasesNoAddressesBackWithBoth) {
2328*6777b538SAndroid Build Coastguard Worker   HostCache::Entry front(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_DNS);
2329*6777b538SAndroid Build Coastguard Worker   std::set<std::string> aliases_front({"alias0", "alias1", "alias2"});
2330*6777b538SAndroid Build Coastguard Worker   front.set_aliases(aliases_front);
2331*6777b538SAndroid Build Coastguard Worker 
2332*6777b538SAndroid Build Coastguard Worker   const IPAddress kAddressBack(0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2333*6777b538SAndroid Build Coastguard Worker                                0);
2334*6777b538SAndroid Build Coastguard Worker   const IPEndPoint kEndpointBack(kAddressBack, 0);
2335*6777b538SAndroid Build Coastguard Worker   HostCache::Entry back(OK, {kEndpointBack}, {"alias1", "alias2", "alias3"},
2336*6777b538SAndroid Build Coastguard Worker                         HostCache::Entry::SOURCE_DNS, base::Hours(4));
2337*6777b538SAndroid Build Coastguard Worker 
2338*6777b538SAndroid Build Coastguard Worker   HostCache::Entry result =
2339*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::MergeEntries(std::move(front), std::move(back));
2340*6777b538SAndroid Build Coastguard Worker 
2341*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(OK, result.error());
2342*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(HostCache::Entry::SOURCE_DNS, result.source());
2343*6777b538SAndroid Build Coastguard Worker 
2344*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.ip_endpoints(), ElementsAre(kEndpointBack));
2345*6777b538SAndroid Build Coastguard Worker 
2346*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Hours(4), result.ttl());
2347*6777b538SAndroid Build Coastguard Worker 
2348*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.aliases(),
2349*6777b538SAndroid Build Coastguard Worker               UnorderedElementsAre("alias0", "alias1", "alias2", "alias3"));
2350*6777b538SAndroid Build Coastguard Worker }
2351*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,MergeEntries_backWithAliasesNoAddressesFrontWithBoth)2352*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, MergeEntries_backWithAliasesNoAddressesFrontWithBoth) {
2353*6777b538SAndroid Build Coastguard Worker   HostCache::Entry back(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_DNS);
2354*6777b538SAndroid Build Coastguard Worker   std::set<std::string> aliases_back({"alias1", "alias2", "alias3"});
2355*6777b538SAndroid Build Coastguard Worker   back.set_aliases(aliases_back);
2356*6777b538SAndroid Build Coastguard Worker 
2357*6777b538SAndroid Build Coastguard Worker   const IPAddress kAddressFront(0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2358*6777b538SAndroid Build Coastguard Worker                                 0);
2359*6777b538SAndroid Build Coastguard Worker   const IPEndPoint kEndpointFront(kAddressFront, 0);
2360*6777b538SAndroid Build Coastguard Worker   HostCache::Entry front(OK, {kEndpointFront}, {"alias0", "alias1", "alias2"},
2361*6777b538SAndroid Build Coastguard Worker                          HostCache::Entry::SOURCE_DNS, base::Hours(4));
2362*6777b538SAndroid Build Coastguard Worker 
2363*6777b538SAndroid Build Coastguard Worker   HostCache::Entry result =
2364*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::MergeEntries(std::move(front), std::move(back));
2365*6777b538SAndroid Build Coastguard Worker 
2366*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(OK, result.error());
2367*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(HostCache::Entry::SOURCE_DNS, result.source());
2368*6777b538SAndroid Build Coastguard Worker 
2369*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.ip_endpoints(), ElementsAre(kEndpointFront));
2370*6777b538SAndroid Build Coastguard Worker 
2371*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Hours(4), result.ttl());
2372*6777b538SAndroid Build Coastguard Worker 
2373*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.aliases(),
2374*6777b538SAndroid Build Coastguard Worker               UnorderedElementsAre("alias0", "alias1", "alias2", "alias3"));
2375*6777b538SAndroid Build Coastguard Worker }
2376*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,MergeEntries_frontWithAddressesNoAliasesBackWithBoth)2377*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, MergeEntries_frontWithAddressesNoAliasesBackWithBoth) {
2378*6777b538SAndroid Build Coastguard Worker   const IPAddress kAddressFront(1, 2, 3, 4);
2379*6777b538SAndroid Build Coastguard Worker   const IPEndPoint kEndpointFront(kAddressFront, 0);
2380*6777b538SAndroid Build Coastguard Worker   HostCache::Entry front(OK, {kEndpointFront}, /*aliases=*/{},
2381*6777b538SAndroid Build Coastguard Worker                          HostCache::Entry::SOURCE_DNS, base::Hours(4));
2382*6777b538SAndroid Build Coastguard Worker 
2383*6777b538SAndroid Build Coastguard Worker   const IPAddress kAddressBack(0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2384*6777b538SAndroid Build Coastguard Worker                                0);
2385*6777b538SAndroid Build Coastguard Worker   const IPEndPoint kEndpointBack(kAddressBack, 0);
2386*6777b538SAndroid Build Coastguard Worker   HostCache::Entry back(OK, {kEndpointBack}, {"alias1", "alias2", "alias3"},
2387*6777b538SAndroid Build Coastguard Worker                         HostCache::Entry::SOURCE_DNS, base::Hours(4));
2388*6777b538SAndroid Build Coastguard Worker   HostCache::Entry result =
2389*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::MergeEntries(std::move(front), std::move(back));
2390*6777b538SAndroid Build Coastguard Worker 
2391*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(OK, result.error());
2392*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(HostCache::Entry::SOURCE_DNS, result.source());
2393*6777b538SAndroid Build Coastguard Worker 
2394*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.ip_endpoints(),
2395*6777b538SAndroid Build Coastguard Worker               ElementsAre(kEndpointFront, kEndpointBack));
2396*6777b538SAndroid Build Coastguard Worker 
2397*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Hours(4), result.ttl());
2398*6777b538SAndroid Build Coastguard Worker 
2399*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.aliases(),
2400*6777b538SAndroid Build Coastguard Worker               UnorderedElementsAre("alias1", "alias2", "alias3"));
2401*6777b538SAndroid Build Coastguard Worker }
2402*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,MergeEntries_backWithAddressesNoAliasesFrontWithBoth)2403*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, MergeEntries_backWithAddressesNoAliasesFrontWithBoth) {
2404*6777b538SAndroid Build Coastguard Worker   const IPAddress kAddressFront(1, 2, 3, 4);
2405*6777b538SAndroid Build Coastguard Worker   const IPEndPoint kEndpointFront(kAddressFront, 0);
2406*6777b538SAndroid Build Coastguard Worker   HostCache::Entry front(OK, {kEndpointFront}, {"alias1", "alias2", "alias3"},
2407*6777b538SAndroid Build Coastguard Worker                          HostCache::Entry::SOURCE_DNS, base::Hours(4));
2408*6777b538SAndroid Build Coastguard Worker   const IPAddress kAddressBack(0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2409*6777b538SAndroid Build Coastguard Worker                                0);
2410*6777b538SAndroid Build Coastguard Worker   const IPEndPoint kEndpointBack(kAddressBack, 0);
2411*6777b538SAndroid Build Coastguard Worker   HostCache::Entry back(OK, {kEndpointBack}, /*aliases=*/{},
2412*6777b538SAndroid Build Coastguard Worker                         HostCache::Entry::SOURCE_DNS, base::Hours(4));
2413*6777b538SAndroid Build Coastguard Worker 
2414*6777b538SAndroid Build Coastguard Worker   HostCache::Entry result =
2415*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::MergeEntries(std::move(front), std::move(back));
2416*6777b538SAndroid Build Coastguard Worker 
2417*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(OK, result.error());
2418*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(HostCache::Entry::SOURCE_DNS, result.source());
2419*6777b538SAndroid Build Coastguard Worker 
2420*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.ip_endpoints(),
2421*6777b538SAndroid Build Coastguard Worker               ElementsAre(kEndpointFront, kEndpointBack));
2422*6777b538SAndroid Build Coastguard Worker 
2423*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Hours(4), result.ttl());
2424*6777b538SAndroid Build Coastguard Worker 
2425*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.aliases(),
2426*6777b538SAndroid Build Coastguard Worker               UnorderedElementsAre("alias1", "alias2", "alias3"));
2427*6777b538SAndroid Build Coastguard Worker }
2428*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,MergeEntries_differentTtl)2429*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, MergeEntries_differentTtl) {
2430*6777b538SAndroid Build Coastguard Worker   HostCache::Entry front(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_DNS,
2431*6777b538SAndroid Build Coastguard Worker                          base::Days(12));
2432*6777b538SAndroid Build Coastguard Worker   HostCache::Entry back(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_DNS,
2433*6777b538SAndroid Build Coastguard Worker                         base::Seconds(42));
2434*6777b538SAndroid Build Coastguard Worker 
2435*6777b538SAndroid Build Coastguard Worker   HostCache::Entry result =
2436*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::MergeEntries(std::move(front), std::move(back));
2437*6777b538SAndroid Build Coastguard Worker 
2438*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(base::Seconds(42), result.ttl());
2439*6777b538SAndroid Build Coastguard Worker }
2440*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,MergeEntries_FrontCannonnamePreserved)2441*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, MergeEntries_FrontCannonnamePreserved) {
2442*6777b538SAndroid Build Coastguard Worker   HostCache::Entry front(OK, /*ip_endpoints=*/{}, /*aliases=*/{"name1"},
2443*6777b538SAndroid Build Coastguard Worker                          HostCache::Entry::SOURCE_DNS);
2444*6777b538SAndroid Build Coastguard Worker 
2445*6777b538SAndroid Build Coastguard Worker   HostCache::Entry back(OK, /*ip_endpoints=*/{}, /*aliases=*/{"name2"},
2446*6777b538SAndroid Build Coastguard Worker                         HostCache::Entry::SOURCE_DNS);
2447*6777b538SAndroid Build Coastguard Worker 
2448*6777b538SAndroid Build Coastguard Worker   HostCache::Entry result =
2449*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::MergeEntries(std::move(front), std::move(back));
2450*6777b538SAndroid Build Coastguard Worker 
2451*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.aliases(), UnorderedElementsAre("name1", "name2"));
2452*6777b538SAndroid Build Coastguard Worker }
2453*6777b538SAndroid Build Coastguard Worker 
2454*6777b538SAndroid Build Coastguard Worker // Test that the back canonname can be used if there is no front cannonname.
TEST(HostCacheTest,MergeEntries_BackCannonnameUsable)2455*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, MergeEntries_BackCannonnameUsable) {
2456*6777b538SAndroid Build Coastguard Worker   HostCache::Entry front(OK, /*ip_endpoints=*/{}, /*aliases=*/{},
2457*6777b538SAndroid Build Coastguard Worker                          HostCache::Entry::SOURCE_DNS);
2458*6777b538SAndroid Build Coastguard Worker 
2459*6777b538SAndroid Build Coastguard Worker   HostCache::Entry back(OK, /*ip_endpoints=*/{}, /*aliases=*/{"name2"},
2460*6777b538SAndroid Build Coastguard Worker                         HostCache::Entry::SOURCE_DNS);
2461*6777b538SAndroid Build Coastguard Worker 
2462*6777b538SAndroid Build Coastguard Worker   HostCache::Entry result =
2463*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::MergeEntries(std::move(front), std::move(back));
2464*6777b538SAndroid Build Coastguard Worker 
2465*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(result.aliases(), UnorderedElementsAre("name2"));
2466*6777b538SAndroid Build Coastguard Worker }
2467*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,ConvertFromInternalAddressResult)2468*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, ConvertFromInternalAddressResult) {
2469*6777b538SAndroid Build Coastguard Worker   const std::vector<IPEndPoint> kEndpoints{
2470*6777b538SAndroid Build Coastguard Worker       IPEndPoint(IPAddress(2, 2, 2, 2), 46)};
2471*6777b538SAndroid Build Coastguard Worker   constexpr base::TimeDelta kTtl1 = base::Minutes(45);
2472*6777b538SAndroid Build Coastguard Worker   constexpr base::TimeDelta kTtl2 = base::Minutes(40);
2473*6777b538SAndroid Build Coastguard Worker   constexpr base::TimeDelta kTtl3 = base::Minutes(55);
2474*6777b538SAndroid Build Coastguard Worker 
2475*6777b538SAndroid Build Coastguard Worker   std::set<std::unique_ptr<HostResolverInternalResult>> results;
2476*6777b538SAndroid Build Coastguard Worker   results.insert(std::make_unique<HostResolverInternalDataResult>(
2477*6777b538SAndroid Build Coastguard Worker       "endpoint.test", DnsQueryType::AAAA, base::TimeTicks() + kTtl1,
2478*6777b538SAndroid Build Coastguard Worker       base::Time() + kTtl1, HostResolverInternalResult::Source::kDns,
2479*6777b538SAndroid Build Coastguard Worker       kEndpoints, std::vector<std::string>{}, std::vector<HostPortPair>{}));
2480*6777b538SAndroid Build Coastguard Worker   results.insert(std::make_unique<HostResolverInternalAliasResult>(
2481*6777b538SAndroid Build Coastguard Worker       "domain1.test", DnsQueryType::AAAA, base::TimeTicks() + kTtl2,
2482*6777b538SAndroid Build Coastguard Worker       base::Time() + kTtl2, HostResolverInternalResult::Source::kDns,
2483*6777b538SAndroid Build Coastguard Worker       "domain2.test"));
2484*6777b538SAndroid Build Coastguard Worker   results.insert(std::make_unique<HostResolverInternalAliasResult>(
2485*6777b538SAndroid Build Coastguard Worker       "domain2.test", DnsQueryType::AAAA, base::TimeTicks() + kTtl3,
2486*6777b538SAndroid Build Coastguard Worker       base::Time() + kTtl3, HostResolverInternalResult::Source::kDns,
2487*6777b538SAndroid Build Coastguard Worker       "endpoint.test"));
2488*6777b538SAndroid Build Coastguard Worker 
2489*6777b538SAndroid Build Coastguard Worker   HostCache::Entry converted(std::move(results), base::Time(),
2490*6777b538SAndroid Build Coastguard Worker                              base::TimeTicks());
2491*6777b538SAndroid Build Coastguard Worker 
2492*6777b538SAndroid Build Coastguard Worker   // Expect kTtl2 because it is the min TTL.
2493*6777b538SAndroid Build Coastguard Worker   HostCache::Entry expected(
2494*6777b538SAndroid Build Coastguard Worker       OK, kEndpoints,
2495*6777b538SAndroid Build Coastguard Worker       /*aliases=*/{"domain1.test", "domain2.test", "endpoint.test"},
2496*6777b538SAndroid Build Coastguard Worker       HostCache::Entry::SOURCE_DNS, kTtl2);
2497*6777b538SAndroid Build Coastguard Worker   expected.set_canonical_names(std::set<std::string>{"endpoint.test"});
2498*6777b538SAndroid Build Coastguard Worker 
2499*6777b538SAndroid Build Coastguard Worker   // Entries converted from HostResolverInternalDataResults do not differentiate
2500*6777b538SAndroid Build Coastguard Worker   // between empty and no-data for the various data types, so need to set empty
2501*6777b538SAndroid Build Coastguard Worker   // strings and hostname entries into `expected`.
2502*6777b538SAndroid Build Coastguard Worker   expected.set_text_records(std::vector<std::string>());
2503*6777b538SAndroid Build Coastguard Worker   expected.set_hostnames(std::vector<HostPortPair>());
2504*6777b538SAndroid Build Coastguard Worker 
2505*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(converted, expected);
2506*6777b538SAndroid Build Coastguard Worker }
2507*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,ConvertFromInternalMetadataResult)2508*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, ConvertFromInternalMetadataResult) {
2509*6777b538SAndroid Build Coastguard Worker   const std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>
2510*6777b538SAndroid Build Coastguard Worker       kMetadatas{{1, ConnectionEndpointMetadata({"h2", "h3"},
2511*6777b538SAndroid Build Coastguard Worker                                                 /*ech_config_list=*/{},
2512*6777b538SAndroid Build Coastguard Worker                                                 "target.test")}};
2513*6777b538SAndroid Build Coastguard Worker   constexpr base::TimeDelta kTtl1 = base::Minutes(45);
2514*6777b538SAndroid Build Coastguard Worker   constexpr base::TimeDelta kTtl2 = base::Minutes(40);
2515*6777b538SAndroid Build Coastguard Worker   constexpr base::TimeDelta kTtl3 = base::Minutes(55);
2516*6777b538SAndroid Build Coastguard Worker 
2517*6777b538SAndroid Build Coastguard Worker   std::set<std::unique_ptr<HostResolverInternalResult>> results;
2518*6777b538SAndroid Build Coastguard Worker   results.insert(std::make_unique<HostResolverInternalMetadataResult>(
2519*6777b538SAndroid Build Coastguard Worker       "endpoint.test", DnsQueryType::HTTPS, base::TimeTicks() + kTtl1,
2520*6777b538SAndroid Build Coastguard Worker       base::Time() + kTtl1, HostResolverInternalResult::Source::kDns,
2521*6777b538SAndroid Build Coastguard Worker       kMetadatas));
2522*6777b538SAndroid Build Coastguard Worker   results.insert(std::make_unique<HostResolverInternalAliasResult>(
2523*6777b538SAndroid Build Coastguard Worker       "domain1.test", DnsQueryType::HTTPS, base::TimeTicks() + kTtl2,
2524*6777b538SAndroid Build Coastguard Worker       base::Time() + kTtl2, HostResolverInternalResult::Source::kDns,
2525*6777b538SAndroid Build Coastguard Worker       "domain2.test"));
2526*6777b538SAndroid Build Coastguard Worker   results.insert(std::make_unique<HostResolverInternalAliasResult>(
2527*6777b538SAndroid Build Coastguard Worker       "domain2.test", DnsQueryType::HTTPS, base::TimeTicks() + kTtl3,
2528*6777b538SAndroid Build Coastguard Worker       base::Time() + kTtl3, HostResolverInternalResult::Source::kDns,
2529*6777b538SAndroid Build Coastguard Worker       "endpoint.test"));
2530*6777b538SAndroid Build Coastguard Worker 
2531*6777b538SAndroid Build Coastguard Worker   HostCache::Entry converted(std::move(results), base::Time(),
2532*6777b538SAndroid Build Coastguard Worker                              base::TimeTicks());
2533*6777b538SAndroid Build Coastguard Worker 
2534*6777b538SAndroid Build Coastguard Worker   // Expect kTtl2 because it is the min TTL.
2535*6777b538SAndroid Build Coastguard Worker   HostCache::Entry expected(OK, kMetadatas, HostCache::Entry::SOURCE_DNS,
2536*6777b538SAndroid Build Coastguard Worker                             kTtl2);
2537*6777b538SAndroid Build Coastguard Worker   expected.set_https_record_compatibility(std::vector<bool>{true});
2538*6777b538SAndroid Build Coastguard Worker 
2539*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(converted, expected);
2540*6777b538SAndroid Build Coastguard Worker }
2541*6777b538SAndroid Build Coastguard Worker 
2542*6777b538SAndroid Build Coastguard Worker // Test the case of compatible HTTPS records but no metadata of use to Chrome.
2543*6777b538SAndroid Build Coastguard Worker // Represented in internal result type as an empty metadata result. Represented
2544*6777b538SAndroid Build Coastguard Worker // in HostCache::Entry as empty metadata with at least one true in
2545*6777b538SAndroid Build Coastguard Worker // `https_record_compatibility_`.
TEST(HostCacheTest,ConvertFromCompatibleOnlyInternalMetadataResult)2546*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, ConvertFromCompatibleOnlyInternalMetadataResult) {
2547*6777b538SAndroid Build Coastguard Worker   const std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>
2548*6777b538SAndroid Build Coastguard Worker       kMetadatas;
2549*6777b538SAndroid Build Coastguard Worker   constexpr base::TimeDelta kTtl1 = base::Minutes(45);
2550*6777b538SAndroid Build Coastguard Worker   constexpr base::TimeDelta kTtl2 = base::Minutes(40);
2551*6777b538SAndroid Build Coastguard Worker   constexpr base::TimeDelta kTtl3 = base::Minutes(55);
2552*6777b538SAndroid Build Coastguard Worker 
2553*6777b538SAndroid Build Coastguard Worker   std::set<std::unique_ptr<HostResolverInternalResult>> results;
2554*6777b538SAndroid Build Coastguard Worker   results.insert(std::make_unique<HostResolverInternalMetadataResult>(
2555*6777b538SAndroid Build Coastguard Worker       "endpoint.test", DnsQueryType::HTTPS, base::TimeTicks() + kTtl1,
2556*6777b538SAndroid Build Coastguard Worker       base::Time() + kTtl1, HostResolverInternalResult::Source::kDns,
2557*6777b538SAndroid Build Coastguard Worker       kMetadatas));
2558*6777b538SAndroid Build Coastguard Worker   results.insert(std::make_unique<HostResolverInternalAliasResult>(
2559*6777b538SAndroid Build Coastguard Worker       "domain1.test", DnsQueryType::HTTPS, base::TimeTicks() + kTtl2,
2560*6777b538SAndroid Build Coastguard Worker       base::Time() + kTtl2, HostResolverInternalResult::Source::kDns,
2561*6777b538SAndroid Build Coastguard Worker       "domain2.test"));
2562*6777b538SAndroid Build Coastguard Worker   results.insert(std::make_unique<HostResolverInternalAliasResult>(
2563*6777b538SAndroid Build Coastguard Worker       "domain2.test", DnsQueryType::HTTPS, base::TimeTicks() + kTtl3,
2564*6777b538SAndroid Build Coastguard Worker       base::Time() + kTtl3, HostResolverInternalResult::Source::kDns,
2565*6777b538SAndroid Build Coastguard Worker       "endpoint.test"));
2566*6777b538SAndroid Build Coastguard Worker 
2567*6777b538SAndroid Build Coastguard Worker   HostCache::Entry converted(std::move(results), base::Time(),
2568*6777b538SAndroid Build Coastguard Worker                              base::TimeTicks());
2569*6777b538SAndroid Build Coastguard Worker 
2570*6777b538SAndroid Build Coastguard Worker   // Expect kTtl2 because it is the min TTL.
2571*6777b538SAndroid Build Coastguard Worker   HostCache::Entry expected(ERR_NAME_NOT_RESOLVED, kMetadatas,
2572*6777b538SAndroid Build Coastguard Worker                             HostCache::Entry::SOURCE_DNS, kTtl2);
2573*6777b538SAndroid Build Coastguard Worker   expected.set_https_record_compatibility(std::vector<bool>{true});
2574*6777b538SAndroid Build Coastguard Worker 
2575*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(converted, expected);
2576*6777b538SAndroid Build Coastguard Worker }
2577*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,ConvertFromInternalErrorResult)2578*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, ConvertFromInternalErrorResult) {
2579*6777b538SAndroid Build Coastguard Worker   constexpr base::TimeDelta kTtl1 = base::Minutes(45);
2580*6777b538SAndroid Build Coastguard Worker   constexpr base::TimeDelta kTtl2 = base::Minutes(40);
2581*6777b538SAndroid Build Coastguard Worker   constexpr base::TimeDelta kTtl3 = base::Minutes(55);
2582*6777b538SAndroid Build Coastguard Worker 
2583*6777b538SAndroid Build Coastguard Worker   std::set<std::unique_ptr<HostResolverInternalResult>> results;
2584*6777b538SAndroid Build Coastguard Worker   results.insert(std::make_unique<HostResolverInternalErrorResult>(
2585*6777b538SAndroid Build Coastguard Worker       "endpoint.test", DnsQueryType::A, base::TimeTicks() + kTtl1,
2586*6777b538SAndroid Build Coastguard Worker       base::Time() + kTtl1, HostResolverInternalResult::Source::kDns,
2587*6777b538SAndroid Build Coastguard Worker       ERR_NAME_NOT_RESOLVED));
2588*6777b538SAndroid Build Coastguard Worker   results.insert(std::make_unique<HostResolverInternalAliasResult>(
2589*6777b538SAndroid Build Coastguard Worker       "domain1.test", DnsQueryType::A, base::TimeTicks() + kTtl2,
2590*6777b538SAndroid Build Coastguard Worker       base::Time() + kTtl2, HostResolverInternalResult::Source::kDns,
2591*6777b538SAndroid Build Coastguard Worker       "domain2.test"));
2592*6777b538SAndroid Build Coastguard Worker   results.insert(std::make_unique<HostResolverInternalAliasResult>(
2593*6777b538SAndroid Build Coastguard Worker       "domain2.test", DnsQueryType::A, base::TimeTicks() + kTtl3,
2594*6777b538SAndroid Build Coastguard Worker       base::Time() + kTtl3, HostResolverInternalResult::Source::kDns,
2595*6777b538SAndroid Build Coastguard Worker       "endpoint.test"));
2596*6777b538SAndroid Build Coastguard Worker 
2597*6777b538SAndroid Build Coastguard Worker   HostCache::Entry converted(std::move(results), base::Time(),
2598*6777b538SAndroid Build Coastguard Worker                              base::TimeTicks());
2599*6777b538SAndroid Build Coastguard Worker 
2600*6777b538SAndroid Build Coastguard Worker   // Expect kTtl2 because it is the min TTL.
2601*6777b538SAndroid Build Coastguard Worker   HostCache::Entry expected(ERR_NAME_NOT_RESOLVED, HostCache::Entry::SOURCE_DNS,
2602*6777b538SAndroid Build Coastguard Worker                             kTtl2);
2603*6777b538SAndroid Build Coastguard Worker 
2604*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(converted, expected);
2605*6777b538SAndroid Build Coastguard Worker }
2606*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,ConvertFromNonCachableInternalErrorResult)2607*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, ConvertFromNonCachableInternalErrorResult) {
2608*6777b538SAndroid Build Coastguard Worker   constexpr base::TimeDelta kTtl1 = base::Minutes(45);
2609*6777b538SAndroid Build Coastguard Worker   constexpr base::TimeDelta kTtl2 = base::Minutes(40);
2610*6777b538SAndroid Build Coastguard Worker 
2611*6777b538SAndroid Build Coastguard Worker   std::set<std::unique_ptr<HostResolverInternalResult>> results;
2612*6777b538SAndroid Build Coastguard Worker   results.insert(std::make_unique<HostResolverInternalErrorResult>(
2613*6777b538SAndroid Build Coastguard Worker       "endpoint.test", DnsQueryType::AAAA, /*expiration=*/std::nullopt,
2614*6777b538SAndroid Build Coastguard Worker       /*timed_expiration=*/std::nullopt,
2615*6777b538SAndroid Build Coastguard Worker       HostResolverInternalResult::Source::kDns, ERR_NAME_NOT_RESOLVED));
2616*6777b538SAndroid Build Coastguard Worker   results.insert(std::make_unique<HostResolverInternalAliasResult>(
2617*6777b538SAndroid Build Coastguard Worker       "domain1.test", DnsQueryType::AAAA, base::TimeTicks() + kTtl1,
2618*6777b538SAndroid Build Coastguard Worker       base::Time() + kTtl1, HostResolverInternalResult::Source::kDns,
2619*6777b538SAndroid Build Coastguard Worker       "domain2.test"));
2620*6777b538SAndroid Build Coastguard Worker   results.insert(std::make_unique<HostResolverInternalAliasResult>(
2621*6777b538SAndroid Build Coastguard Worker       "domain2.test", DnsQueryType::AAAA, base::TimeTicks() + kTtl2,
2622*6777b538SAndroid Build Coastguard Worker       base::Time() + kTtl2, HostResolverInternalResult::Source::kDns,
2623*6777b538SAndroid Build Coastguard Worker       "endpoint.test"));
2624*6777b538SAndroid Build Coastguard Worker 
2625*6777b538SAndroid Build Coastguard Worker   HostCache::Entry converted(std::move(results), base::Time(),
2626*6777b538SAndroid Build Coastguard Worker                              base::TimeTicks());
2627*6777b538SAndroid Build Coastguard Worker 
2628*6777b538SAndroid Build Coastguard Worker   // Expect no TTL because error is non-cachable (has no TTL itself).
2629*6777b538SAndroid Build Coastguard Worker   HostCache::Entry expected(ERR_NAME_NOT_RESOLVED,
2630*6777b538SAndroid Build Coastguard Worker                             HostCache::Entry::SOURCE_DNS);
2631*6777b538SAndroid Build Coastguard Worker 
2632*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(converted, expected);
2633*6777b538SAndroid Build Coastguard Worker }
2634*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,ConvertFromInternalAliasOnlyResult)2635*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, ConvertFromInternalAliasOnlyResult) {
2636*6777b538SAndroid Build Coastguard Worker   constexpr base::TimeDelta kTtl1 = base::Minutes(45);
2637*6777b538SAndroid Build Coastguard Worker   constexpr base::TimeDelta kTtl2 = base::Minutes(40);
2638*6777b538SAndroid Build Coastguard Worker 
2639*6777b538SAndroid Build Coastguard Worker   std::set<std::unique_ptr<HostResolverInternalResult>> results;
2640*6777b538SAndroid Build Coastguard Worker   results.insert(std::make_unique<HostResolverInternalAliasResult>(
2641*6777b538SAndroid Build Coastguard Worker       "domain1.test", DnsQueryType::A, base::TimeTicks() + kTtl1,
2642*6777b538SAndroid Build Coastguard Worker       base::Time() + kTtl1, HostResolverInternalResult::Source::kDns,
2643*6777b538SAndroid Build Coastguard Worker       "domain2.test"));
2644*6777b538SAndroid Build Coastguard Worker   results.insert(std::make_unique<HostResolverInternalAliasResult>(
2645*6777b538SAndroid Build Coastguard Worker       "domain2.test", DnsQueryType::A, base::TimeTicks() + kTtl2,
2646*6777b538SAndroid Build Coastguard Worker       base::Time() + kTtl2, HostResolverInternalResult::Source::kDns,
2647*6777b538SAndroid Build Coastguard Worker       "endpoint.test"));
2648*6777b538SAndroid Build Coastguard Worker 
2649*6777b538SAndroid Build Coastguard Worker   HostCache::Entry converted(std::move(results), base::Time(),
2650*6777b538SAndroid Build Coastguard Worker                              base::TimeTicks());
2651*6777b538SAndroid Build Coastguard Worker 
2652*6777b538SAndroid Build Coastguard Worker   // Expect no TTL because alias-only results are not cacheable.
2653*6777b538SAndroid Build Coastguard Worker   HostCache::Entry expected(ERR_NAME_NOT_RESOLVED,
2654*6777b538SAndroid Build Coastguard Worker                             HostCache::Entry::SOURCE_DNS);
2655*6777b538SAndroid Build Coastguard Worker 
2656*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(converted, expected);
2657*6777b538SAndroid Build Coastguard Worker }
2658*6777b538SAndroid Build Coastguard Worker 
TEST(HostCacheTest,ConvertFromEmptyInternalResult)2659*6777b538SAndroid Build Coastguard Worker TEST(HostCacheTest, ConvertFromEmptyInternalResult) {
2660*6777b538SAndroid Build Coastguard Worker   HostCache::Entry converted({}, base::Time(), base::TimeTicks());
2661*6777b538SAndroid Build Coastguard Worker   HostCache::Entry expected(ERR_NAME_NOT_RESOLVED,
2662*6777b538SAndroid Build Coastguard Worker                             HostCache::Entry::SOURCE_UNKNOWN);
2663*6777b538SAndroid Build Coastguard Worker 
2664*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(converted, expected);
2665*6777b538SAndroid Build Coastguard Worker }
2666*6777b538SAndroid Build Coastguard Worker 
2667*6777b538SAndroid Build Coastguard Worker }  // namespace net
2668