xref: /aosp_15_r20/external/cronet/net/dns/host_resolver_cache_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2023 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/dns/host_resolver_cache.h"
6 
7 #include <memory>
8 #include <optional>
9 #include <string>
10 #include <vector>
11 
12 #include "base/test/simple_test_clock.h"
13 #include "base/test/simple_test_tick_clock.h"
14 #include "base/time/time.h"
15 #include "net/base/connection_endpoint_metadata.h"
16 #include "net/base/connection_endpoint_metadata_test_util.h"
17 #include "net/base/ip_address.h"
18 #include "net/base/ip_endpoint.h"
19 #include "net/base/net_errors.h"
20 #include "net/base/network_anonymization_key.h"
21 #include "net/base/schemeful_site.h"
22 #include "net/dns/host_resolver_internal_result.h"
23 #include "net/dns/host_resolver_internal_result_test_util.h"
24 #include "net/dns/public/dns_query_type.h"
25 #include "net/dns/public/host_resolver_source.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "url/gurl.h"
29 
30 namespace net {
31 
32 namespace {
33 
34 using ::testing::ElementsAre;
35 using ::testing::Eq;
36 using ::testing::IsEmpty;
37 using ::testing::Ne;
38 using ::testing::Optional;
39 using ::testing::Pair;
40 using ::testing::Pointee;
41 
42 MATCHER(IsNotStale, "") {
43   return !arg.IsStale() && !arg.expired_by.has_value() &&
44          !arg.stale_by_generation;
45 }
46 
47 MATCHER_P(IsNotStale, result_matcher, "") {
48   return !arg.IsStale() && !arg.expired_by.has_value() &&
49          !arg.stale_by_generation &&
50          ExplainMatchResult(result_matcher, arg.result.get(), result_listener);
51 }
52 
53 // Fudge TimeDelta matching by a couple milliseconds because it is not important
54 // whether something is considered expired at or just after expiration because
55 // TTLs come at second-wide precision anyway.
56 MATCHER_P(TimeDeltaIsApproximately, approximate_expectation, "") {
57   return arg - base::Milliseconds(3) <= approximate_expectation &&
58          arg + base::Milliseconds(3) >= approximate_expectation;
59 }
60 
61 MATCHER_P2(IsStale, expired_by_matcher, expected_stale_by_generation, "") {
62   return arg.IsStale() &&
63          ExplainMatchResult(expired_by_matcher, arg.expired_by,
64                             result_listener) &&
65          arg.stale_by_generation == expected_stale_by_generation;
66 }
67 
68 MATCHER_P3(IsStale,
69            result_matcher,
70            expired_by_matcher,
71            expected_stale_by_generation,
72            "") {
73   return arg.IsStale() &&
74          ExplainMatchResult(result_matcher, arg.result.get(),
75                             result_listener) &&
76          ExplainMatchResult(expired_by_matcher, arg.expired_by,
77                             result_listener) &&
78          arg.stale_by_generation == expected_stale_by_generation;
79 }
80 
81 class HostResolverCacheTest : public ::testing::Test {
82  protected:
83   const size_t kMaxResults = 10;
84 
85   base::SimpleTestClock clock_;
86   base::SimpleTestTickClock tick_clock_;
87 };
88 
TEST_F(HostResolverCacheTest,CacheAResult)89 TEST_F(HostResolverCacheTest, CacheAResult) {
90   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
91 
92   const std::string kName = "foo.test";
93   const base::TimeDelta kTtl = base::Minutes(2);
94   const std::vector<IPEndPoint> kEndpoints = {
95       IPEndPoint(IPAddress(1, 2, 3, 4), /*port=*/0),
96       IPEndPoint(IPAddress(2, 3, 4, 5), /*port=*/0)};
97   auto result = std::make_unique<HostResolverInternalDataResult>(
98       kName, DnsQueryType::A, tick_clock_.NowTicks() + kTtl,
99       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, kEndpoints,
100       /*strings=*/std::vector<std::string>{},
101       /*hosts=*/std::vector<HostPortPair>{});
102 
103   const NetworkAnonymizationKey anonymization_key;
104   cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS,
105             /*secure=*/false);
106 
107   auto matcher = Pointee(ExpectHostResolverInternalDataResult(
108       kName, DnsQueryType::A, HostResolverInternalResult::Source::kDns,
109       Optional(tick_clock_.NowTicks() + kTtl), Optional(clock_.Now() + kTtl),
110       kEndpoints));
111   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::A,
112                            HostResolverSource::DNS, /*secure=*/false),
113               matcher);
114   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::UNSPECIFIED,
115                            HostResolverSource::DNS, /*secure=*/false),
116               matcher);
117   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::A,
118                            HostResolverSource::ANY, /*secure=*/false),
119               matcher);
120   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::A,
121                            HostResolverSource::DNS, /*secure=*/std::nullopt),
122               matcher);
123   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
124                          HostResolverSource::DNS, /*secure=*/false),
125             nullptr);
126   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::A,
127                          HostResolverSource::SYSTEM, /*secure=*/false),
128             nullptr);
129   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::A,
130                          HostResolverSource::DNS, /*secure=*/true),
131             nullptr);
132 
133   auto stale_result_matcher =
134       Optional(IsNotStale(ExpectHostResolverInternalDataResult(
135           kName, DnsQueryType::A, HostResolverInternalResult::Source::kDns,
136           Optional(tick_clock_.NowTicks() + kTtl),
137           Optional(clock_.Now() + kTtl), kEndpoints)));
138   EXPECT_THAT(cache.LookupStale(kName, anonymization_key, DnsQueryType::A,
139                                 HostResolverSource::DNS, /*secure=*/false),
140               stale_result_matcher);
141   EXPECT_THAT(
142       cache.LookupStale(kName, anonymization_key, DnsQueryType::UNSPECIFIED,
143                         HostResolverSource::DNS, /*secure=*/false),
144       stale_result_matcher);
145   EXPECT_THAT(cache.LookupStale(kName, anonymization_key, DnsQueryType::A,
146                                 HostResolverSource::ANY, /*secure=*/false),
147               stale_result_matcher);
148   EXPECT_THAT(
149       cache.LookupStale(kName, anonymization_key, DnsQueryType::A,
150                         HostResolverSource::DNS, /*secure=*/std::nullopt),
151       stale_result_matcher);
152   EXPECT_EQ(cache.LookupStale(kName, anonymization_key, DnsQueryType::AAAA,
153                               HostResolverSource::DNS, /*secure=*/false),
154             std::nullopt);
155   EXPECT_EQ(cache.LookupStale(kName, anonymization_key, DnsQueryType::A,
156                               HostResolverSource::SYSTEM, /*secure=*/false),
157             std::nullopt);
158   EXPECT_EQ(cache.LookupStale(kName, anonymization_key, DnsQueryType::A,
159                               HostResolverSource::DNS, /*secure=*/true),
160             std::nullopt);
161 }
162 
TEST_F(HostResolverCacheTest,CacheAaaaResult)163 TEST_F(HostResolverCacheTest, CacheAaaaResult) {
164   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
165 
166   const std::string kName = "foo.test";
167   const base::TimeDelta kTtl = base::Minutes(2);
168   const std::vector<IPEndPoint> kEndpoints = {
169       IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0),
170       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::4").value(),
171                  /*port=*/0)};
172   auto result = std::make_unique<HostResolverInternalDataResult>(
173       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
174       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, kEndpoints,
175       /*strings=*/std::vector<std::string>{},
176       /*hosts=*/std::vector<HostPortPair>{});
177 
178   const NetworkAnonymizationKey anonymization_key;
179   cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS,
180             /*secure=*/false);
181 
182   auto matcher = Pointee(ExpectHostResolverInternalDataResult(
183       kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
184       Optional(tick_clock_.NowTicks() + kTtl), Optional(clock_.Now() + kTtl),
185       kEndpoints));
186   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
187                            HostResolverSource::DNS, /*secure=*/false),
188               matcher);
189   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::UNSPECIFIED,
190                            HostResolverSource::DNS, /*secure=*/false),
191               matcher);
192   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
193                            HostResolverSource::ANY, /*secure=*/false),
194               matcher);
195   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
196                            HostResolverSource::DNS, /*secure=*/std::nullopt),
197               matcher);
198 
199   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::A,
200                          HostResolverSource::DNS, /*secure=*/false),
201             nullptr);
202   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
203                          HostResolverSource::SYSTEM, /*secure=*/false),
204             nullptr);
205   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
206                          HostResolverSource::DNS, /*secure=*/true),
207             nullptr);
208 
209   auto stale_result_matcher =
210       Optional(IsNotStale(ExpectHostResolverInternalDataResult(
211           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
212           Optional(tick_clock_.NowTicks() + kTtl),
213           Optional(clock_.Now() + kTtl), kEndpoints)));
214   EXPECT_THAT(cache.LookupStale(kName, anonymization_key, DnsQueryType::AAAA,
215                                 HostResolverSource::DNS, /*secure=*/false),
216               stale_result_matcher);
217   EXPECT_THAT(
218       cache.LookupStale(kName, anonymization_key, DnsQueryType::UNSPECIFIED,
219                         HostResolverSource::DNS, /*secure=*/false),
220       stale_result_matcher);
221   EXPECT_THAT(cache.LookupStale(kName, anonymization_key, DnsQueryType::AAAA,
222                                 HostResolverSource::ANY, /*secure=*/false),
223               stale_result_matcher);
224   EXPECT_THAT(
225       cache.LookupStale(kName, anonymization_key, DnsQueryType::AAAA,
226                         HostResolverSource::DNS, /*secure=*/std::nullopt),
227       stale_result_matcher);
228 
229   EXPECT_EQ(cache.LookupStale(kName, anonymization_key, DnsQueryType::A,
230                               HostResolverSource::DNS, /*secure=*/false),
231             std::nullopt);
232   EXPECT_EQ(cache.LookupStale(kName, anonymization_key, DnsQueryType::AAAA,
233                               HostResolverSource::SYSTEM, /*secure=*/false),
234             std::nullopt);
235   EXPECT_EQ(cache.LookupStale(kName, anonymization_key, DnsQueryType::AAAA,
236                               HostResolverSource::DNS, /*secure=*/true),
237             std::nullopt);
238 }
239 
TEST_F(HostResolverCacheTest,CacheHttpsResult)240 TEST_F(HostResolverCacheTest, CacheHttpsResult) {
241   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
242 
243   const std::string kName = "foo.test";
244   const base::TimeDelta kTtl = base::Minutes(2);
245   const std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>
246       kMetadatas = {
247           {2, ConnectionEndpointMetadata({"h2", "h3"},
248                                          /*ech_config_list=*/{}, kName)},
249           {1,
250            ConnectionEndpointMetadata({"h2"}, /*ech_config_list=*/{}, kName)}};
251   auto result = std::make_unique<HostResolverInternalMetadataResult>(
252       kName, DnsQueryType::HTTPS, tick_clock_.NowTicks() + kTtl,
253       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
254       kMetadatas);
255 
256   const NetworkAnonymizationKey anonymization_key;
257   cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS,
258             /*secure=*/false);
259 
260   auto matcher = Pointee(ExpectHostResolverInternalMetadataResult(
261       kName, DnsQueryType::HTTPS, HostResolverInternalResult::Source::kDns,
262       Optional(tick_clock_.NowTicks() + kTtl), Optional(clock_.Now() + kTtl),
263       kMetadatas));
264   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS,
265                            HostResolverSource::DNS, /*secure=*/false),
266               matcher);
267   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::UNSPECIFIED,
268                            HostResolverSource::DNS, /*secure=*/false),
269               matcher);
270   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS,
271                            HostResolverSource::ANY, /*secure=*/false),
272               matcher);
273   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS,
274                            HostResolverSource::DNS, /*secure=*/std::nullopt),
275               matcher);
276   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::A,
277                          HostResolverSource::DNS, /*secure=*/false),
278             nullptr);
279   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS,
280                          HostResolverSource::SYSTEM, /*secure=*/false),
281             nullptr);
282   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS,
283                          HostResolverSource::DNS, /*secure=*/true),
284             nullptr);
285 
286   auto stale_result_matcher =
287       Optional(IsNotStale(ExpectHostResolverInternalMetadataResult(
288           kName, DnsQueryType::HTTPS, HostResolverInternalResult::Source::kDns,
289           Optional(tick_clock_.NowTicks() + kTtl),
290           Optional(clock_.Now() + kTtl), kMetadatas)));
291   EXPECT_THAT(cache.LookupStale(kName, anonymization_key, DnsQueryType::HTTPS,
292                                 HostResolverSource::DNS, /*secure=*/false),
293               stale_result_matcher);
294   EXPECT_THAT(
295       cache.LookupStale(kName, anonymization_key, DnsQueryType::UNSPECIFIED,
296                         HostResolverSource::DNS, /*secure=*/false),
297       stale_result_matcher);
298   EXPECT_THAT(cache.LookupStale(kName, anonymization_key, DnsQueryType::HTTPS,
299                                 HostResolverSource::ANY, /*secure=*/false),
300               stale_result_matcher);
301   EXPECT_THAT(
302       cache.LookupStale(kName, anonymization_key, DnsQueryType::HTTPS,
303                         HostResolverSource::DNS, /*secure=*/std::nullopt),
304       stale_result_matcher);
305   EXPECT_EQ(cache.LookupStale(kName, anonymization_key, DnsQueryType::A,
306                               HostResolverSource::DNS, /*secure=*/false),
307             std::nullopt);
308   EXPECT_EQ(cache.LookupStale(kName, anonymization_key, DnsQueryType::HTTPS,
309                               HostResolverSource::SYSTEM, /*secure=*/false),
310             std::nullopt);
311   EXPECT_EQ(cache.LookupStale(kName, anonymization_key, DnsQueryType::HTTPS,
312                               HostResolverSource::DNS, /*secure=*/true),
313             std::nullopt);
314 }
315 
316 // Domain names containing scheme/port are not expected to be handled any
317 // differently from other domain names. That is, if an entry is cached with
318 // a domain name containing scheme or port, it can only be looked up using the
319 // exact same domain name containing scheme and port. Testing the case simply
320 // because such things were handled differently in a previous version of the
321 // cache.
TEST_F(HostResolverCacheTest,RespectsSchemeAndPortInName)322 TEST_F(HostResolverCacheTest, RespectsSchemeAndPortInName) {
323   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
324 
325   const std::string kNameWithScheme = "_411._https.foo.test";
326   const base::TimeDelta kTtl = base::Minutes(2);
327   const std::string kAlpn1 = "foo";
328   auto result1 = std::make_unique<HostResolverInternalMetadataResult>(
329       kNameWithScheme, DnsQueryType::HTTPS, tick_clock_.NowTicks() + kTtl,
330       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
331       std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>{
332           {4, ConnectionEndpointMetadata({kAlpn1}, /*ech_config_list=*/{},
333                                          kNameWithScheme)}});
334 
335   const std::string kNameWithoutScheme = "foo.test";
336   const std::string kAlpn2 = "bar";
337   auto result2 = std::make_unique<HostResolverInternalMetadataResult>(
338       kNameWithoutScheme, DnsQueryType::HTTPS, tick_clock_.NowTicks() + kTtl,
339       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
340       std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>{
341           {7, ConnectionEndpointMetadata({kAlpn2}, /*ech_config_list=*/{},
342                                          kNameWithoutScheme)}});
343 
344   const NetworkAnonymizationKey anonymization_key;
345   cache.Set(std::move(result1), anonymization_key, HostResolverSource::DNS,
346             /*secure=*/false);
347   cache.Set(std::move(result2), anonymization_key, HostResolverSource::DNS,
348             /*secure=*/false);
349 
350   EXPECT_THAT(cache.Lookup(kNameWithScheme, anonymization_key),
351               Pointee(ExpectHostResolverInternalMetadataResult(
352                   kNameWithScheme, DnsQueryType::HTTPS,
353                   HostResolverInternalResult::Source::kDns,
354                   /*expiration_matcher=*/Ne(std::nullopt),
355                   /*timed_expiration_matcher=*/Ne(std::nullopt),
356                   ElementsAre(Pair(4, ExpectConnectionEndpointMetadata(
357                                           ElementsAre(kAlpn1), IsEmpty(),
358                                           kNameWithScheme))))));
359   EXPECT_THAT(cache.Lookup(kNameWithoutScheme, anonymization_key),
360               Pointee(ExpectHostResolverInternalMetadataResult(
361                   kNameWithoutScheme, DnsQueryType::HTTPS,
362                   HostResolverInternalResult::Source::kDns,
363                   /*expiration_matcher=*/Ne(std::nullopt),
364                   /*timed_expiration_matcher=*/Ne(std::nullopt),
365                   ElementsAre(Pair(7, ExpectConnectionEndpointMetadata(
366                                           ElementsAre(kAlpn2), IsEmpty(),
367                                           kNameWithoutScheme))))));
368 }
369 
TEST_F(HostResolverCacheTest,CacheHttpsAliasResult)370 TEST_F(HostResolverCacheTest, CacheHttpsAliasResult) {
371   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
372 
373   const std::string kName = "foo.test";
374   const base::TimeDelta kTtl = base::Minutes(2);
375   const std::string kTarget = "target.test";
376   auto result = std::make_unique<HostResolverInternalAliasResult>(
377       kName, DnsQueryType::HTTPS, tick_clock_.NowTicks() + kTtl,
378       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, kTarget);
379 
380   const NetworkAnonymizationKey anonymization_key;
381   cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS,
382             /*secure=*/false);
383 
384   auto matcher = Pointee(ExpectHostResolverInternalAliasResult(
385       kName, DnsQueryType::HTTPS, HostResolverInternalResult::Source::kDns,
386       Optional(tick_clock_.NowTicks() + kTtl), Optional(clock_.Now() + kTtl),
387       kTarget));
388   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS,
389                            HostResolverSource::DNS, /*secure=*/false),
390               matcher);
391   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::UNSPECIFIED,
392                            HostResolverSource::DNS, /*secure=*/false),
393               matcher);
394   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS,
395                            HostResolverSource::ANY, /*secure=*/false),
396               matcher);
397   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS,
398                            HostResolverSource::DNS, /*secure=*/std::nullopt),
399               matcher);
400 
401   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::A,
402                          HostResolverSource::DNS, /*secure=*/false),
403             nullptr);
404   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS,
405                          HostResolverSource::SYSTEM, /*secure=*/false),
406             nullptr);
407   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS,
408                          HostResolverSource::DNS, /*secure=*/true),
409             nullptr);
410 }
411 
TEST_F(HostResolverCacheTest,CacheCnameAliasResult)412 TEST_F(HostResolverCacheTest, CacheCnameAliasResult) {
413   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
414 
415   const std::string kName = "foo.test";
416   const base::TimeDelta kTtl = base::Minutes(2);
417   const std::string kTarget = "target.test";
418 
419   // CNAME results are not typically queried directly, but received as part of
420   // the results for queries for other query types. Thus except in the weird
421   // cases where it is queried directly, CNAME results should be cached for the
422   // queried type (or as a wildcard UNSPECIFIED type), rather than type CNAME.
423   // Here, test the case where it is cached under the AAAA query type.
424   auto result = std::make_unique<HostResolverInternalAliasResult>(
425       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
426       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, kTarget);
427 
428   const NetworkAnonymizationKey anonymization_key;
429   cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS,
430             /*secure=*/false);
431 
432   auto matcher = Pointee(ExpectHostResolverInternalAliasResult(
433       kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
434       Optional(tick_clock_.NowTicks() + kTtl), Optional(clock_.Now() + kTtl),
435       kTarget));
436   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
437                            HostResolverSource::DNS, /*secure=*/false),
438               matcher);
439   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::UNSPECIFIED,
440                            HostResolverSource::DNS, /*secure=*/false),
441               matcher);
442   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
443                            HostResolverSource::ANY, /*secure=*/false),
444               matcher);
445   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
446                            HostResolverSource::DNS, /*secure=*/std::nullopt),
447               matcher);
448 
449   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::A,
450                          HostResolverSource::DNS, /*secure=*/false),
451             nullptr);
452   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
453                          HostResolverSource::SYSTEM, /*secure=*/false),
454             nullptr);
455   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
456                          HostResolverSource::DNS, /*secure=*/true),
457             nullptr);
458 }
459 
TEST_F(HostResolverCacheTest,CacheWildcardAlias)460 TEST_F(HostResolverCacheTest, CacheWildcardAlias) {
461   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
462 
463   const std::string kName = "foo.test";
464   const std::string kAliasTarget = "target.test";
465   const base::TimeDelta kTtl = base::Minutes(2);
466   auto result = std::make_unique<HostResolverInternalAliasResult>(
467       kName, DnsQueryType::UNSPECIFIED, tick_clock_.NowTicks() + kTtl,
468       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
469       kAliasTarget);
470 
471   const NetworkAnonymizationKey anonymization_key;
472   cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS,
473             /*secure=*/false);
474 
475   auto matcher = Pointee(ExpectHostResolverInternalAliasResult(
476       kName, DnsQueryType::UNSPECIFIED,
477       HostResolverInternalResult::Source::kDns,
478       Optional(tick_clock_.NowTicks() + kTtl), Optional(clock_.Now() + kTtl),
479       kAliasTarget));
480   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::UNSPECIFIED),
481               matcher);
482   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::A), matcher);
483   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA),
484               matcher);
485   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS),
486               matcher);
487   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::TXT),
488               matcher);
489 }
490 
TEST_F(HostResolverCacheTest,CacheErrorResult)491 TEST_F(HostResolverCacheTest, CacheErrorResult) {
492   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
493 
494   const std::string kName = "foo.test";
495   const base::TimeDelta kTtl = base::Minutes(2);
496   auto result = std::make_unique<HostResolverInternalErrorResult>(
497       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
498       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
499       ERR_NAME_NOT_RESOLVED);
500 
501   const NetworkAnonymizationKey anonymization_key;
502   cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS,
503             /*secure=*/false);
504 
505   auto matcher = Pointee(ExpectHostResolverInternalErrorResult(
506       kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
507       Optional(tick_clock_.NowTicks() + kTtl), Optional(clock_.Now() + kTtl),
508       ERR_NAME_NOT_RESOLVED));
509   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
510                            HostResolverSource::DNS, /*secure=*/false),
511               matcher);
512   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::UNSPECIFIED,
513                            HostResolverSource::DNS, /*secure=*/false),
514               matcher);
515   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
516                            HostResolverSource::ANY, /*secure=*/false),
517               matcher);
518   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
519                            HostResolverSource::DNS, /*secure=*/std::nullopt),
520               matcher);
521 
522   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::A,
523                          HostResolverSource::DNS, /*secure=*/false),
524             nullptr);
525   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
526                          HostResolverSource::SYSTEM, /*secure=*/false),
527             nullptr);
528   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
529                          HostResolverSource::DNS, /*secure=*/true),
530             nullptr);
531 }
532 
TEST_F(HostResolverCacheTest,ResultsCanBeUpdated)533 TEST_F(HostResolverCacheTest, ResultsCanBeUpdated) {
534   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
535 
536   const std::string kName = "foo.test";
537   const base::TimeDelta kTtl = base::Minutes(2);
538   const std::vector<IPEndPoint> kEndpoints1 = {
539       IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)};
540   auto result1 = std::make_unique<HostResolverInternalDataResult>(
541       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
542       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
543       kEndpoints1,
544       /*strings=*/std::vector<std::string>{},
545       /*hosts=*/std::vector<HostPortPair>{});
546   const std::string kName2 = "goo.test";
547   auto result2 = std::make_unique<HostResolverInternalDataResult>(
548       kName2, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
549       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
550       kEndpoints1,
551       /*strings=*/std::vector<std::string>{},
552       /*hosts=*/std::vector<HostPortPair>{});
553 
554   const NetworkAnonymizationKey anonymization_key;
555   cache.Set(std::move(result1), anonymization_key, HostResolverSource::DNS,
556             /*secure=*/false);
557   cache.Set(std::move(result2), anonymization_key, HostResolverSource::DNS,
558             /*secure=*/false);
559 
560   EXPECT_THAT(
561       cache.Lookup(kName, anonymization_key),
562       Pointee(ExpectHostResolverInternalDataResult(
563           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
564           Optional(tick_clock_.NowTicks() + kTtl),
565           Optional(clock_.Now() + kTtl), kEndpoints1)));
566   EXPECT_THAT(
567       cache.Lookup(kName2, anonymization_key),
568       Pointee(ExpectHostResolverInternalDataResult(
569           kName2, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
570           Optional(tick_clock_.NowTicks() + kTtl),
571           Optional(clock_.Now() + kTtl), kEndpoints1)));
572 
573   const std::vector<IPEndPoint> kEndpoints2 = {
574       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::4").value(),
575                  /*port=*/0)};
576   auto result3 = std::make_unique<HostResolverInternalDataResult>(
577       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
578       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
579       kEndpoints2,
580       /*strings=*/std::vector<std::string>{},
581       /*hosts=*/std::vector<HostPortPair>{});
582 
583   cache.Set(std::move(result3), anonymization_key, HostResolverSource::DNS,
584             /*secure=*/false);
585 
586   EXPECT_THAT(
587       cache.Lookup(kName, anonymization_key),
588       Pointee(ExpectHostResolverInternalDataResult(
589           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
590           Optional(tick_clock_.NowTicks() + kTtl),
591           Optional(clock_.Now() + kTtl), kEndpoints2)));
592   EXPECT_THAT(
593       cache.Lookup(kName2, anonymization_key),
594       Pointee(ExpectHostResolverInternalDataResult(
595           kName2, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
596           Optional(tick_clock_.NowTicks() + kTtl),
597           Optional(clock_.Now() + kTtl), kEndpoints1)));
598 }
599 
TEST_F(HostResolverCacheTest,UpdateCanReplaceWildcard)600 TEST_F(HostResolverCacheTest, UpdateCanReplaceWildcard) {
601   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
602 
603   const std::string kName = "foo.test";
604   const std::string kAliasTarget1 = "target1.test";
605   const base::TimeDelta kTtl = base::Minutes(2);
606   auto result1 = std::make_unique<HostResolverInternalAliasResult>(
607       kName, DnsQueryType::UNSPECIFIED, tick_clock_.NowTicks() + kTtl,
608       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
609       kAliasTarget1);
610 
611   const NetworkAnonymizationKey anonymization_key;
612   cache.Set(std::move(result1), anonymization_key, HostResolverSource::DNS,
613             /*secure=*/false);
614 
615   EXPECT_NE(cache.Lookup(kName, anonymization_key, DnsQueryType::A), nullptr);
616   EXPECT_NE(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA),
617             nullptr);
618 
619   const std::string kAliasTarget2 = "target2.test";
620   auto result2 = std::make_unique<HostResolverInternalAliasResult>(
621       kName, DnsQueryType::A, tick_clock_.NowTicks() + kTtl,
622       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
623       kAliasTarget2);
624 
625   cache.Set(std::move(result2), anonymization_key, HostResolverSource::DNS,
626             /*secure=*/false);
627 
628   // After update, because most recent entry is not wildcard, expect lookup to
629   // only succeed for the specific type.
630   EXPECT_THAT(
631       cache.Lookup(kName, anonymization_key, DnsQueryType::A),
632       Pointee(ExpectHostResolverInternalAliasResult(
633           kName, DnsQueryType::A, HostResolverInternalResult::Source::kDns,
634           Optional(tick_clock_.NowTicks() + kTtl),
635           Optional(clock_.Now() + kTtl), kAliasTarget2)));
636   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA),
637             nullptr);
638 }
639 
TEST_F(HostResolverCacheTest,WildcardUpdateCanReplaceSpecifics)640 TEST_F(HostResolverCacheTest, WildcardUpdateCanReplaceSpecifics) {
641   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
642 
643   const std::string kName = "foo.test";
644   const std::string kAliasTarget1 = "target1.test";
645   const base::TimeDelta kTtl = base::Minutes(2);
646   auto result1 = std::make_unique<HostResolverInternalAliasResult>(
647       kName, DnsQueryType::A, tick_clock_.NowTicks() + kTtl,
648       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
649       kAliasTarget1);
650   const std::string kAliasTarget2 = "target2.test";
651   auto result2 = std::make_unique<HostResolverInternalAliasResult>(
652       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
653       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
654       kAliasTarget2);
655 
656   const NetworkAnonymizationKey anonymization_key;
657   cache.Set(std::move(result1), anonymization_key, HostResolverSource::DNS,
658             /*secure=*/false);
659   cache.Set(std::move(result2), anonymization_key, HostResolverSource::DNS,
660             /*secure=*/false);
661 
662   EXPECT_THAT(
663       cache.Lookup(kName, anonymization_key, DnsQueryType::A),
664       Pointee(ExpectHostResolverInternalAliasResult(
665           kName, DnsQueryType::A, HostResolverInternalResult::Source::kDns,
666           Optional(tick_clock_.NowTicks() + kTtl),
667           Optional(clock_.Now() + kTtl), kAliasTarget1)));
668   EXPECT_THAT(
669       cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA),
670       Pointee(ExpectHostResolverInternalAliasResult(
671           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
672           Optional(tick_clock_.NowTicks() + kTtl),
673           Optional(clock_.Now() + kTtl), kAliasTarget2)));
674   EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS),
675             nullptr);
676 
677   const std::string kAliasTarget3 = "target3.test";
678   auto result3 = std::make_unique<HostResolverInternalAliasResult>(
679       kName, DnsQueryType::UNSPECIFIED, tick_clock_.NowTicks() + kTtl,
680       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
681       kAliasTarget3);
682 
683   cache.Set(std::move(result3), anonymization_key, HostResolverSource::DNS,
684             /*secure=*/false);
685 
686   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::A),
687               Pointee(ExpectHostResolverInternalAliasResult(
688                   kName, DnsQueryType::UNSPECIFIED,
689                   HostResolverInternalResult::Source::kDns,
690                   Optional(tick_clock_.NowTicks() + kTtl),
691                   Optional(clock_.Now() + kTtl), kAliasTarget3)));
692   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA),
693               Pointee(ExpectHostResolverInternalAliasResult(
694                   kName, DnsQueryType::UNSPECIFIED,
695                   HostResolverInternalResult::Source::kDns,
696                   Optional(tick_clock_.NowTicks() + kTtl),
697                   Optional(clock_.Now() + kTtl), kAliasTarget3)));
698   EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS),
699               Pointee(ExpectHostResolverInternalAliasResult(
700                   kName, DnsQueryType::UNSPECIFIED,
701                   HostResolverInternalResult::Source::kDns,
702                   Optional(tick_clock_.NowTicks() + kTtl),
703                   Optional(clock_.Now() + kTtl), kAliasTarget3)));
704 }
705 
TEST_F(HostResolverCacheTest,LookupNameIsCanonicalized)706 TEST_F(HostResolverCacheTest, LookupNameIsCanonicalized) {
707   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
708 
709   const std::string kName = "fOO.test";
710   const base::TimeDelta kTtl = base::Minutes(2);
711   const std::vector<IPEndPoint> kEndpoints = {
712       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::4").value(),
713                  /*port=*/0)};
714   auto result = std::make_unique<HostResolverInternalDataResult>(
715       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
716       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, kEndpoints,
717       /*strings=*/std::vector<std::string>{},
718       /*hosts=*/std::vector<HostPortPair>{});
719 
720   const NetworkAnonymizationKey anonymization_key;
721   cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS,
722             /*secure=*/false);
723 
724   EXPECT_NE(cache.Lookup("FOO.TEST", anonymization_key), nullptr);
725 }
726 
TEST_F(HostResolverCacheTest,LookupIgnoresExpiredResults)727 TEST_F(HostResolverCacheTest, LookupIgnoresExpiredResults) {
728   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
729 
730   const std::string kName1 = "foo.test";
731   const base::TimeDelta kTtl1 = base::Minutes(2);
732   const std::vector<IPEndPoint> kEndpoints1 = {
733       IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)};
734   auto result1 = std::make_unique<HostResolverInternalDataResult>(
735       kName1, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl1,
736       clock_.Now() + kTtl1, HostResolverInternalResult::Source::kDns,
737       kEndpoints1,
738       /*strings=*/std::vector<std::string>{},
739       /*hosts=*/std::vector<HostPortPair>{});
740 
741   const std::string kName2 = "bar.test";
742   const base::TimeDelta kTtl2 = base::Minutes(4);
743   const std::vector<IPEndPoint> kEndpoints2 = {
744       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::4").value(),
745                  /*port=*/0)};
746   auto result2 = std::make_unique<HostResolverInternalDataResult>(
747       kName2, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl2,
748       clock_.Now() + kTtl2, HostResolverInternalResult::Source::kDns,
749       kEndpoints2,
750       /*strings=*/std::vector<std::string>{},
751       /*hosts=*/std::vector<HostPortPair>{});
752 
753   const NetworkAnonymizationKey anonymization_key;
754   cache.Set(std::move(result1), anonymization_key, HostResolverSource::DNS,
755             /*secure=*/false);
756   cache.Set(std::move(result2), anonymization_key, HostResolverSource::DNS,
757             /*secure=*/false);
758 
759   EXPECT_THAT(
760       cache.Lookup(kName1, anonymization_key),
761       Pointee(ExpectHostResolverInternalDataResult(
762           kName1, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
763           Optional(tick_clock_.NowTicks() + kTtl1),
764           Optional(clock_.Now() + kTtl1), kEndpoints1)));
765   EXPECT_THAT(cache.LookupStale(kName1, anonymization_key),
766               Optional(IsNotStale()));
767   EXPECT_THAT(
768       cache.Lookup(kName2, anonymization_key),
769       Pointee(ExpectHostResolverInternalDataResult(
770           kName2, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
771           Optional(tick_clock_.NowTicks() + kTtl2),
772           Optional(clock_.Now() + kTtl2), kEndpoints2)));
773   EXPECT_THAT(cache.LookupStale(kName2, anonymization_key),
774               Optional(IsNotStale()));
775 
776   // Advance time until just before first expiration. Expect both results still
777   // active.
778   clock_.Advance(kTtl1 - base::Milliseconds(1));
779   tick_clock_.Advance(kTtl1 - base::Milliseconds(1));
780   EXPECT_NE(cache.Lookup(kName1, anonymization_key), nullptr);
781   EXPECT_THAT(cache.LookupStale(kName1, anonymization_key),
782               Optional(IsNotStale()));
783   EXPECT_NE(cache.Lookup(kName2, anonymization_key), nullptr);
784   EXPECT_THAT(cache.LookupStale(kName2, anonymization_key),
785               Optional(IsNotStale()));
786 
787   // Advance time until just after first expiration. Expect first result now
788   // stale, but second result still valid.
789   clock_.Advance(base::Milliseconds(2));
790   tick_clock_.Advance(base::Milliseconds(2));
791   EXPECT_EQ(cache.Lookup(kName1, anonymization_key), nullptr);
792   EXPECT_THAT(
793       cache.LookupStale(kName1, anonymization_key),
794       Optional(IsStale(
795           ExpectHostResolverInternalDataResult(
796               kName1, DnsQueryType::AAAA,
797               HostResolverInternalResult::Source::kDns, Ne(std::nullopt),
798               Ne(std::nullopt), kEndpoints1),
799           Optional(TimeDeltaIsApproximately(base::Milliseconds(1))), false)));
800   EXPECT_NE(cache.Lookup(kName2, anonymization_key), nullptr);
801   EXPECT_THAT(cache.LookupStale(kName2, anonymization_key),
802               Optional(IsNotStale()));
803 
804   // Advance time util just before second expiration. Expect first still stale
805   // and second still valid.
806   clock_.Advance(kTtl2 - kTtl1 - base::Milliseconds(2));
807   tick_clock_.Advance(kTtl2 - kTtl1 - base::Milliseconds(2));
808   EXPECT_EQ(cache.Lookup(kName1, anonymization_key), nullptr);
809   EXPECT_THAT(cache.LookupStale(kName1, anonymization_key),
810               Optional(IsStale(Optional(TimeDeltaIsApproximately(
811                                    base::Minutes(2) - base::Milliseconds(1))),
812                                false)));
813   EXPECT_NE(cache.Lookup(kName2, anonymization_key), nullptr);
814   EXPECT_THAT(cache.LookupStale(kName2, anonymization_key),
815               Optional(IsNotStale()));
816 
817   // Advance time to after second expiration. Expect both results now stale.
818   clock_.Advance(base::Milliseconds(2));
819   tick_clock_.Advance(base::Milliseconds(2));
820   EXPECT_EQ(cache.Lookup(kName1, anonymization_key), nullptr);
821   EXPECT_THAT(cache.LookupStale(kName1, anonymization_key),
822               Optional(IsStale(Optional(TimeDeltaIsApproximately(
823                                    base::Minutes(2) + base::Milliseconds(1))),
824                                false)));
825   EXPECT_EQ(cache.Lookup(kName2, anonymization_key), nullptr);
826   EXPECT_THAT(
827       cache.LookupStale(kName2, anonymization_key),
828       Optional(IsStale(
829           ExpectHostResolverInternalDataResult(
830               kName2, DnsQueryType::AAAA,
831               HostResolverInternalResult::Source::kDns, Ne(std::nullopt),
832               Ne(std::nullopt), kEndpoints2),
833           Optional(TimeDeltaIsApproximately(base::Milliseconds(1))), false)));
834 }
835 
TEST_F(HostResolverCacheTest,ExpiredResultsCanBeUpdated)836 TEST_F(HostResolverCacheTest, ExpiredResultsCanBeUpdated) {
837   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
838 
839   const std::string kName = "foo.test";
840   const std::vector<IPEndPoint> kEndpoints = {
841       IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)};
842   auto result = std::make_unique<HostResolverInternalDataResult>(
843       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() - base::Milliseconds(1),
844       clock_.Now() - base::Milliseconds(1),
845       HostResolverInternalResult::Source::kDns, kEndpoints,
846       /*strings=*/std::vector<std::string>{},
847       /*hosts=*/std::vector<HostPortPair>{});
848 
849   const NetworkAnonymizationKey anonymization_key;
850   cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS,
851             /*secure=*/false);
852 
853   // Expiration before Now, so expect entry to start expired.
854   EXPECT_EQ(cache.Lookup(kName, anonymization_key), nullptr);
855   EXPECT_THAT(
856       cache.LookupStale(kName, anonymization_key),
857       Optional(IsStale(
858           Optional(TimeDeltaIsApproximately(base::Milliseconds(1))), false)));
859 
860   const base::TimeDelta kTtl = base::Seconds(45);
861   auto update_result = std::make_unique<HostResolverInternalDataResult>(
862       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
863       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, kEndpoints,
864       /*strings=*/std::vector<std::string>{},
865       /*hosts=*/std::vector<HostPortPair>{});
866   cache.Set(std::move(update_result), anonymization_key,
867             HostResolverSource::DNS,
868             /*secure=*/false);
869 
870   EXPECT_NE(cache.Lookup(kName, anonymization_key), nullptr);
871   EXPECT_THAT(cache.LookupStale(kName, anonymization_key),
872               Optional(IsNotStale()));
873 
874   // Expect entry to still be expirable for new TTL.
875   clock_.Advance(kTtl + base::Milliseconds(1));
876   tick_clock_.Advance(kTtl + base::Milliseconds(1));
877   EXPECT_EQ(cache.Lookup(kName, anonymization_key), nullptr);
878   EXPECT_THAT(
879       cache.LookupStale(kName, anonymization_key),
880       Optional(IsStale(
881           Optional(TimeDeltaIsApproximately(base::Milliseconds(1))), false)));
882 }
883 
TEST_F(HostResolverCacheTest,LookupIgnoresResultsMarkedStale)884 TEST_F(HostResolverCacheTest, LookupIgnoresResultsMarkedStale) {
885   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
886 
887   const std::string kName1 = "foo.test";
888   const base::TimeDelta kTtl = base::Minutes(2);
889   const std::vector<IPEndPoint> kEndpoints1 = {
890       IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)};
891   auto result1 = std::make_unique<HostResolverInternalDataResult>(
892       kName1, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
893       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
894       kEndpoints1,
895       /*strings=*/std::vector<std::string>{},
896       /*hosts=*/std::vector<HostPortPair>{});
897 
898   const std::string kName2 = "bar.test";
899   const std::vector<IPEndPoint> kEndpoints2 = {
900       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::4").value(),
901                  /*port=*/0)};
902   auto result2 = std::make_unique<HostResolverInternalDataResult>(
903       kName2, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
904       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
905       kEndpoints2,
906       /*strings=*/std::vector<std::string>{},
907       /*hosts=*/std::vector<HostPortPair>{});
908 
909   const NetworkAnonymizationKey anonymization_key;
910   cache.Set(std::move(result1), anonymization_key, HostResolverSource::DNS,
911             /*secure=*/false);
912   cache.Set(std::move(result2), anonymization_key, HostResolverSource::DNS,
913             /*secure=*/false);
914 
915   EXPECT_NE(cache.Lookup(kName1, anonymization_key), nullptr);
916   EXPECT_THAT(cache.LookupStale(kName1, anonymization_key),
917               Optional(IsNotStale()));
918   EXPECT_NE(cache.Lookup(kName2, anonymization_key), nullptr);
919   EXPECT_THAT(cache.LookupStale(kName2, anonymization_key),
920               Optional(IsNotStale()));
921 
922   cache.MakeAllResultsStale();
923 
924   // Expect both entries to now be stale.
925   EXPECT_EQ(cache.Lookup(kName1, anonymization_key), nullptr);
926   EXPECT_THAT(cache.LookupStale(kName1, anonymization_key),
927               Optional(IsStale(std::nullopt, true)));
928   EXPECT_EQ(cache.Lookup(kName2, anonymization_key), nullptr);
929   EXPECT_THAT(cache.LookupStale(kName2, anonymization_key),
930               Optional(IsStale(std::nullopt, true)));
931 
932   const std::string kName3 = "foo3.test";
933   const std::vector<IPEndPoint> kEndpoints3 = {
934       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::2").value(),
935                  /*port=*/0)};
936   auto result3 = std::make_unique<HostResolverInternalDataResult>(
937       kName3, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
938       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
939       kEndpoints3,
940       /*strings=*/std::vector<std::string>{},
941       /*hosts=*/std::vector<HostPortPair>{});
942   cache.Set(std::move(result3), anonymization_key, HostResolverSource::DNS,
943             /*secure=*/false);
944 
945   EXPECT_EQ(cache.Lookup(kName1, anonymization_key), nullptr);
946   EXPECT_THAT(cache.LookupStale(kName1, anonymization_key),
947               Optional(IsStale(std::nullopt, true)));
948   EXPECT_EQ(cache.Lookup(kName2, anonymization_key), nullptr);
949   EXPECT_THAT(cache.LookupStale(kName2, anonymization_key),
950               Optional(IsStale(std::nullopt, true)));
951   EXPECT_THAT(
952       cache.Lookup(kName3, anonymization_key),
953       Pointee(ExpectHostResolverInternalDataResult(
954           kName3, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
955           Optional(tick_clock_.NowTicks() + kTtl),
956           Optional(clock_.Now() + kTtl), kEndpoints3)));
957   EXPECT_THAT(cache.LookupStale(kName3, anonymization_key),
958               Optional(IsNotStale()));
959 }
960 
TEST_F(HostResolverCacheTest,MarkedStaleResultsCanBeUpdated)961 TEST_F(HostResolverCacheTest, MarkedStaleResultsCanBeUpdated) {
962   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
963 
964   const std::string kName = "foo.test";
965   const base::TimeDelta kTtl = base::Minutes(6);
966   const std::vector<IPEndPoint> kEndpoints = {
967       IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)};
968   auto result = std::make_unique<HostResolverInternalDataResult>(
969       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
970       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, kEndpoints,
971       /*strings=*/std::vector<std::string>{},
972       /*hosts=*/std::vector<HostPortPair>{});
973 
974   const NetworkAnonymizationKey anonymization_key;
975   cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS,
976             /*secure=*/false);
977 
978   cache.MakeAllResultsStale();
979 
980   EXPECT_EQ(cache.Lookup(kName, anonymization_key), nullptr);
981   EXPECT_THAT(cache.LookupStale(kName, anonymization_key),
982               Optional(IsStale(std::nullopt, true)));
983 
984   auto update_result = std::make_unique<HostResolverInternalDataResult>(
985       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
986       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, kEndpoints,
987       /*strings=*/std::vector<std::string>{},
988       /*hosts=*/std::vector<HostPortPair>{});
989   cache.Set(std::move(update_result), anonymization_key,
990             HostResolverSource::DNS,
991             /*secure=*/false);
992 
993   EXPECT_NE(cache.Lookup(kName, anonymization_key), nullptr);
994   EXPECT_THAT(cache.LookupStale(kName, anonymization_key),
995               Optional(IsNotStale()));
996 }
997 
TEST_F(HostResolverCacheTest,RespectsNetworkAnonymizationKey)998 TEST_F(HostResolverCacheTest, RespectsNetworkAnonymizationKey) {
999   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
1000 
1001   const std::string kName = "foo.test";
1002   const base::TimeDelta kTtl = base::Minutes(5);
1003   const std::vector<IPEndPoint> kEndpoints1 = {
1004       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::4").value(), /*port=*/0)};
1005   auto result1 = std::make_unique<HostResolverInternalDataResult>(
1006       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
1007       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
1008       kEndpoints1,
1009       /*strings=*/std::vector<std::string>{},
1010       /*hosts=*/std::vector<HostPortPair>{});
1011   const std::vector<IPEndPoint> kEndpoints2 = {
1012       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::10").value(), /*port=*/0)};
1013   auto result2 = std::make_unique<HostResolverInternalDataResult>(
1014       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
1015       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
1016       kEndpoints2,
1017       /*strings=*/std::vector<std::string>{},
1018       /*hosts=*/std::vector<HostPortPair>{});
1019 
1020   const SchemefulSite kSite1(GURL("https://site1.test/"));
1021   const auto kNetworkAnonymizationKey1 =
1022       NetworkAnonymizationKey::CreateSameSite(kSite1);
1023   const SchemefulSite kSite2(GURL("https://site2.test/"));
1024   const auto kNetworkAnonymizationKey2 =
1025       NetworkAnonymizationKey::CreateSameSite(kSite2);
1026 
1027   cache.Set(std::move(result1), kNetworkAnonymizationKey1,
1028             HostResolverSource::DNS,
1029             /*secure=*/false);
1030 
1031   EXPECT_NE(cache.Lookup(kName, kNetworkAnonymizationKey1), nullptr);
1032   EXPECT_NE(cache.LookupStale(kName, kNetworkAnonymizationKey1), std::nullopt);
1033   EXPECT_EQ(cache.Lookup(kName, kNetworkAnonymizationKey2), nullptr);
1034   EXPECT_EQ(cache.LookupStale(kName, kNetworkAnonymizationKey2), std::nullopt);
1035 
1036   cache.Set(std::move(result2), kNetworkAnonymizationKey2,
1037             HostResolverSource::DNS,
1038             /*secure=*/false);
1039 
1040   EXPECT_THAT(
1041       cache.Lookup(kName, kNetworkAnonymizationKey1),
1042       Pointee(ExpectHostResolverInternalDataResult(
1043           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
1044           Optional(tick_clock_.NowTicks() + kTtl),
1045           Optional(clock_.Now() + kTtl), kEndpoints1)));
1046   EXPECT_THAT(
1047       cache.LookupStale(kName, kNetworkAnonymizationKey1),
1048       Optional(IsNotStale(ExpectHostResolverInternalDataResult(
1049           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
1050           Optional(tick_clock_.NowTicks() + kTtl),
1051           Optional(clock_.Now() + kTtl), kEndpoints1))));
1052   EXPECT_THAT(
1053       cache.Lookup(kName, kNetworkAnonymizationKey2),
1054       Pointee(ExpectHostResolverInternalDataResult(
1055           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
1056           Optional(tick_clock_.NowTicks() + kTtl),
1057           Optional(clock_.Now() + kTtl), kEndpoints2)));
1058   EXPECT_THAT(
1059       cache.LookupStale(kName, kNetworkAnonymizationKey2),
1060       Optional(IsNotStale(ExpectHostResolverInternalDataResult(
1061           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
1062           Optional(tick_clock_.NowTicks() + kTtl),
1063           Optional(clock_.Now() + kTtl), kEndpoints2))));
1064 }
1065 
1066 // Newly added entries are always considered to be the most up-to-date
1067 // information, so if an unexpired entry is updated with an expired entry, the
1068 // entry should now be expired.
TEST_F(HostResolverCacheTest,UpdateToStale)1069 TEST_F(HostResolverCacheTest, UpdateToStale) {
1070   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
1071 
1072   const std::string kName = "foo.test";
1073   const std::vector<IPEndPoint> kEndpoints = {
1074       IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)};
1075   auto result = std::make_unique<HostResolverInternalDataResult>(
1076       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Hours(2),
1077       clock_.Now() + base::Hours(2), HostResolverInternalResult::Source::kDns,
1078       kEndpoints,
1079       /*strings=*/std::vector<std::string>{},
1080       /*hosts=*/std::vector<HostPortPair>{});
1081 
1082   const NetworkAnonymizationKey anonymization_key;
1083   cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS,
1084             /*secure=*/false);
1085 
1086   // Expect initial entry to be unexpired.
1087   EXPECT_NE(cache.Lookup(kName, anonymization_key), nullptr);
1088   EXPECT_THAT(cache.LookupStale(kName, anonymization_key),
1089               Optional(IsNotStale()));
1090 
1091   auto update_result = std::make_unique<HostResolverInternalDataResult>(
1092       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() - base::Seconds(1),
1093       clock_.Now() - base::Seconds(1), HostResolverInternalResult::Source::kDns,
1094       kEndpoints,
1095       /*strings=*/std::vector<std::string>{},
1096       /*hosts=*/std::vector<HostPortPair>{});
1097   cache.Set(std::move(update_result), anonymization_key,
1098             HostResolverSource::DNS,
1099             /*secure=*/false);
1100 
1101   // Expect entry to be expired.
1102   EXPECT_EQ(cache.Lookup(kName, anonymization_key), nullptr);
1103   EXPECT_THAT(
1104       cache.LookupStale(kName, anonymization_key),
1105       Optional(IsStale(Optional(TimeDeltaIsApproximately(base::Seconds(1))),
1106                        false)));
1107 }
1108 
1109 // If a wildcard lookup matches multiple result entries, all insecure, expect
1110 // lookup to return the most recently set result.
TEST_F(HostResolverCacheTest,PreferMoreRecentInsecureResult)1111 TEST_F(HostResolverCacheTest, PreferMoreRecentInsecureResult) {
1112   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
1113 
1114   const std::string kName = "foo.test";
1115   const base::TimeDelta kTtl = base::Minutes(2);
1116   const std::vector<IPEndPoint> kNewEndpoints = {
1117       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::8").value(),
1118                  /*port=*/0)};
1119   auto new_result = std::make_unique<HostResolverInternalDataResult>(
1120       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
1121       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
1122       kNewEndpoints,
1123       /*strings=*/std::vector<std::string>{},
1124       /*hosts=*/std::vector<HostPortPair>{});
1125   const std::vector<IPEndPoint> kOldEndpoints = {
1126       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::7").value(),
1127                  /*port=*/0)};
1128   auto old_result = std::make_unique<HostResolverInternalDataResult>(
1129       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
1130       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
1131       kOldEndpoints,
1132       /*strings=*/std::vector<std::string>{},
1133       /*hosts=*/std::vector<HostPortPair>{});
1134 
1135   const NetworkAnonymizationKey anonymization_key;
1136 
1137   cache.Set(std::move(old_result), anonymization_key,
1138             HostResolverSource::SYSTEM,
1139             /*secure=*/false);
1140   cache.Set(std::move(new_result), anonymization_key, HostResolverSource::DNS,
1141             /*secure=*/false);
1142 
1143   EXPECT_THAT(
1144       cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
1145                    HostResolverSource::ANY, /*secure=*/false),
1146       Pointee(ExpectHostResolverInternalDataResult(
1147           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
1148           Optional(tick_clock_.NowTicks() + kTtl),
1149           Optional(clock_.Now() + kTtl), kNewEndpoints)));
1150 
1151   // Other result still available for more specific lookups.
1152   EXPECT_THAT(
1153       cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
1154                    HostResolverSource::SYSTEM, /*secure=*/false),
1155       Pointee(ExpectHostResolverInternalDataResult(
1156           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
1157           Optional(tick_clock_.NowTicks() + kTtl),
1158           Optional(clock_.Now() + kTtl), kOldEndpoints)));
1159 }
1160 
1161 // If a wildcard lookup matches multiple result entries, all secure, expect
1162 // lookup to return the most recently set result.
TEST_F(HostResolverCacheTest,PreferMoreRecentSecureResult)1163 TEST_F(HostResolverCacheTest, PreferMoreRecentSecureResult) {
1164   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
1165 
1166   const std::string kName = "foo.test";
1167   const base::TimeDelta kTtl = base::Minutes(2);
1168   const std::vector<IPEndPoint> kNewEndpoints = {
1169       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::8").value(),
1170                  /*port=*/0)};
1171   auto new_result = std::make_unique<HostResolverInternalDataResult>(
1172       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
1173       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
1174       kNewEndpoints,
1175       /*strings=*/std::vector<std::string>{},
1176       /*hosts=*/std::vector<HostPortPair>{});
1177   const std::vector<IPEndPoint> kOldEndpoints = {
1178       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::7").value(),
1179                  /*port=*/0)};
1180   auto old_result = std::make_unique<HostResolverInternalDataResult>(
1181       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
1182       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
1183       kOldEndpoints,
1184       /*strings=*/std::vector<std::string>{},
1185       /*hosts=*/std::vector<HostPortPair>{});
1186 
1187   const NetworkAnonymizationKey anonymization_key;
1188 
1189   cache.Set(std::move(old_result), anonymization_key,
1190             HostResolverSource::SYSTEM,
1191             /*secure=*/true);
1192   cache.Set(std::move(new_result), anonymization_key, HostResolverSource::DNS,
1193             /*secure=*/true);
1194 
1195   EXPECT_THAT(
1196       cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
1197                    HostResolverSource::ANY, /*secure=*/true),
1198       Pointee(ExpectHostResolverInternalDataResult(
1199           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
1200           Optional(tick_clock_.NowTicks() + kTtl),
1201           Optional(clock_.Now() + kTtl), kNewEndpoints)));
1202 
1203   // Other result still available for more specific lookups.
1204   EXPECT_THAT(
1205       cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
1206                    HostResolverSource::SYSTEM, /*secure=*/true),
1207       Pointee(ExpectHostResolverInternalDataResult(
1208           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
1209           Optional(tick_clock_.NowTicks() + kTtl),
1210           Optional(clock_.Now() + kTtl), kOldEndpoints)));
1211 }
1212 
1213 // If a wildcard lookup matches multiple result entries of mixed secureness,
1214 // expect lookup to return the most recently set secure result.
TEST_F(HostResolverCacheTest,PreferMoreSecureResult)1215 TEST_F(HostResolverCacheTest, PreferMoreSecureResult) {
1216   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
1217 
1218   const std::string kName = "foo.test";
1219   const base::TimeDelta kTtl = base::Minutes(2);
1220   const std::vector<IPEndPoint> kInsecureEndpoints = {
1221       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::4").value(),
1222                  /*port=*/0)};
1223   auto insecure_result = std::make_unique<HostResolverInternalDataResult>(
1224       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
1225       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
1226       kInsecureEndpoints,
1227       /*strings=*/std::vector<std::string>{},
1228       /*hosts=*/std::vector<HostPortPair>{});
1229   const std::vector<IPEndPoint> kSecureEndpoints = {
1230       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::8").value(),
1231                  /*port=*/0)};
1232   auto secure_result = std::make_unique<HostResolverInternalDataResult>(
1233       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
1234       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
1235       kSecureEndpoints,
1236       /*strings=*/std::vector<std::string>{},
1237       /*hosts=*/std::vector<HostPortPair>{});
1238   const std::vector<IPEndPoint> kOldSecureEndpoints = {
1239       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::7").value(),
1240                  /*port=*/0)};
1241   auto old_secure_result = std::make_unique<HostResolverInternalDataResult>(
1242       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
1243       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
1244       kOldSecureEndpoints,
1245       /*strings=*/std::vector<std::string>{},
1246       /*hosts=*/std::vector<HostPortPair>{});
1247 
1248   const NetworkAnonymizationKey anonymization_key;
1249 
1250   // Add in the secure results first to ensure they're not being selected by
1251   // being the most recently added result.
1252   cache.Set(std::move(old_secure_result), anonymization_key,
1253             HostResolverSource::SYSTEM,
1254             /*secure=*/true);
1255   cache.Set(std::move(secure_result), anonymization_key,
1256             HostResolverSource::DNS,
1257             /*secure=*/true);
1258   cache.Set(std::move(insecure_result), anonymization_key,
1259             HostResolverSource::DNS,
1260             /*secure=*/false);
1261 
1262   EXPECT_THAT(
1263       cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
1264                    HostResolverSource::ANY, /*secure=*/std::nullopt),
1265       Pointee(ExpectHostResolverInternalDataResult(
1266           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
1267           Optional(tick_clock_.NowTicks() + kTtl),
1268           Optional(clock_.Now() + kTtl), kSecureEndpoints)));
1269 
1270   // Other results still available for more specific lookups.
1271   EXPECT_THAT(
1272       cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
1273                    HostResolverSource::ANY, /*secure=*/false),
1274       Pointee(ExpectHostResolverInternalDataResult(
1275           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
1276           Optional(tick_clock_.NowTicks() + kTtl),
1277           Optional(clock_.Now() + kTtl), kInsecureEndpoints)));
1278   EXPECT_THAT(
1279       cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA,
1280                    HostResolverSource::SYSTEM, /*secure=*/std::nullopt),
1281       Pointee(ExpectHostResolverInternalDataResult(
1282           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
1283           Optional(tick_clock_.NowTicks() + kTtl),
1284           Optional(clock_.Now() + kTtl), kOldSecureEndpoints)));
1285 }
1286 
1287 // Even though LookupStale() can return stale results, if a wildcard lookup
1288 // matches multiple result entries, expect the lookup to prefer a non-stale
1289 // result.
TEST_F(HostResolverCacheTest,LookupStalePrefersNonStaleResult)1290 TEST_F(HostResolverCacheTest, LookupStalePrefersNonStaleResult) {
1291   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
1292 
1293   const std::string kName = "foo.test";
1294   const std::vector<IPEndPoint> kStaleEndpoints = {
1295       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::7").value(),
1296                  /*port=*/0)};
1297   auto stale_result = std::make_unique<HostResolverInternalDataResult>(
1298       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() - base::Seconds(4),
1299       clock_.Now() - base::Seconds(4), HostResolverInternalResult::Source::kDns,
1300       kStaleEndpoints,
1301       /*strings=*/std::vector<std::string>{},
1302       /*hosts=*/std::vector<HostPortPair>{});
1303   const std::vector<IPEndPoint> kActiveEndpoints = {
1304       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::8").value(),
1305                  /*port=*/0)};
1306   auto active_result = std::make_unique<HostResolverInternalDataResult>(
1307       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Minutes(3),
1308       clock_.Now() + base::Minutes(3), HostResolverInternalResult::Source::kDns,
1309       kActiveEndpoints,
1310       /*strings=*/std::vector<std::string>{},
1311       /*hosts=*/std::vector<HostPortPair>{});
1312 
1313   const NetworkAnonymizationKey anonymization_key;
1314 
1315   cache.Set(std::move(active_result), anonymization_key,
1316             HostResolverSource::DNS,
1317             /*secure=*/false);
1318   cache.Set(std::move(stale_result), anonymization_key,
1319             HostResolverSource::SYSTEM,
1320             /*secure=*/true);
1321 
1322   EXPECT_THAT(
1323       cache.LookupStale(kName, anonymization_key, DnsQueryType::AAAA,
1324                         HostResolverSource::ANY, /*secure=*/std::nullopt),
1325       Optional(IsNotStale(ExpectHostResolverInternalDataResult(
1326           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
1327           Optional(tick_clock_.NowTicks() + base::Minutes(3)),
1328           Optional(clock_.Now() + base::Minutes(3)), kActiveEndpoints))));
1329 
1330   // Other result still available for more specific lookups.
1331   EXPECT_THAT(
1332       cache.LookupStale(kName, anonymization_key, DnsQueryType::AAAA,
1333                         HostResolverSource::SYSTEM, /*secure=*/std::nullopt),
1334       Optional(IsStale(
1335           ExpectHostResolverInternalDataResult(
1336               kName, DnsQueryType::AAAA,
1337               HostResolverInternalResult::Source::kDns,
1338               Optional(tick_clock_.NowTicks() - base::Seconds(4)),
1339               Optional(clock_.Now() - base::Seconds(4)), kStaleEndpoints),
1340           Ne(std::nullopt), false)));
1341 }
1342 
1343 // Same as LookupStalePrefersNonStaleResult except lookup criteria specifies
1344 // insecure. Expect same general behavior (prefers non-stale result) but
1345 // exercises slightly different logic because, if no secure results exist, no
1346 // other results need to be considered once a non-stale result is found
TEST_F(HostResolverCacheTest,InsecureLookupStalePrefersNonStaleResult)1347 TEST_F(HostResolverCacheTest, InsecureLookupStalePrefersNonStaleResult) {
1348   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
1349 
1350   const std::string kName = "foo.test";
1351   const std::vector<IPEndPoint> kStaleEndpoints = {
1352       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::7").value(),
1353                  /*port=*/0)};
1354   auto stale_result = std::make_unique<HostResolverInternalDataResult>(
1355       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() - base::Seconds(4),
1356       clock_.Now() - base::Seconds(4), HostResolverInternalResult::Source::kDns,
1357       kStaleEndpoints,
1358       /*strings=*/std::vector<std::string>{},
1359       /*hosts=*/std::vector<HostPortPair>{});
1360   const std::vector<IPEndPoint> kActiveEndpoints = {
1361       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::8").value(),
1362                  /*port=*/0)};
1363   auto active_result = std::make_unique<HostResolverInternalDataResult>(
1364       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Minutes(3),
1365       clock_.Now() + base::Minutes(3), HostResolverInternalResult::Source::kDns,
1366       kActiveEndpoints,
1367       /*strings=*/std::vector<std::string>{},
1368       /*hosts=*/std::vector<HostPortPair>{});
1369 
1370   const NetworkAnonymizationKey anonymization_key;
1371 
1372   cache.Set(std::move(stale_result), anonymization_key, HostResolverSource::DNS,
1373             /*secure=*/false);
1374   cache.Set(std::move(active_result), anonymization_key,
1375             HostResolverSource::SYSTEM,
1376             /*secure=*/false);
1377 
1378   EXPECT_THAT(
1379       cache.LookupStale(kName, anonymization_key, DnsQueryType::AAAA,
1380                         HostResolverSource::ANY, /*secure=*/false),
1381       Optional(IsNotStale(ExpectHostResolverInternalDataResult(
1382           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
1383           Optional(tick_clock_.NowTicks() + base::Minutes(3)),
1384           Optional(clock_.Now() + base::Minutes(3)), kActiveEndpoints))));
1385 }
1386 
TEST_F(HostResolverCacheTest,LookupStalePrefersLeastStaleByGeneration)1387 TEST_F(HostResolverCacheTest, LookupStalePrefersLeastStaleByGeneration) {
1388   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
1389 
1390   const std::string kName = "foo.test";
1391   const std::vector<IPEndPoint> kMoreStaleEndpoints = {
1392       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::7").value(),
1393                  /*port=*/0)};
1394   auto more_stale_result = std::make_unique<HostResolverInternalDataResult>(
1395       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Seconds(4),
1396       clock_.Now() + base::Seconds(4), HostResolverInternalResult::Source::kDns,
1397       kMoreStaleEndpoints,
1398       /*strings=*/std::vector<std::string>{},
1399       /*hosts=*/std::vector<HostPortPair>{});
1400   const std::vector<IPEndPoint> kLessStaleEndpoints = {
1401       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::8").value(),
1402                  /*port=*/0)};
1403   auto less_stale_result = std::make_unique<HostResolverInternalDataResult>(
1404       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() - base::Minutes(3),
1405       clock_.Now() - base::Minutes(3), HostResolverInternalResult::Source::kDns,
1406       kLessStaleEndpoints,
1407       /*strings=*/std::vector<std::string>{},
1408       /*hosts=*/std::vector<HostPortPair>{});
1409 
1410   const NetworkAnonymizationKey anonymization_key;
1411 
1412   cache.Set(std::move(more_stale_result), anonymization_key,
1413             HostResolverSource::DNS,
1414             /*secure=*/true);
1415   cache.MakeAllResultsStale();
1416   cache.Set(std::move(less_stale_result), anonymization_key,
1417             HostResolverSource::SYSTEM,
1418             /*secure=*/false);
1419 
1420   EXPECT_THAT(
1421       cache.LookupStale(kName, anonymization_key, DnsQueryType::AAAA,
1422                         HostResolverSource::ANY, /*secure=*/std::nullopt),
1423       Optional(IsStale(
1424           ExpectHostResolverInternalDataResult(
1425               kName, DnsQueryType::AAAA,
1426               HostResolverInternalResult::Source::kDns,
1427               Optional(tick_clock_.NowTicks() - base::Minutes(3)),
1428               Optional(clock_.Now() - base::Minutes(3)), kLessStaleEndpoints),
1429           Ne(std::nullopt), false)));
1430 
1431   // Other result still available for more specific lookups.
1432   EXPECT_THAT(
1433       cache.LookupStale(kName, anonymization_key, DnsQueryType::AAAA,
1434                         HostResolverSource::DNS, /*secure=*/std::nullopt),
1435       Optional(IsStale(
1436           ExpectHostResolverInternalDataResult(
1437               kName, DnsQueryType::AAAA,
1438               HostResolverInternalResult::Source::kDns,
1439               Optional(tick_clock_.NowTicks() + base::Seconds(4)),
1440               Optional(clock_.Now() + base::Seconds(4)), kMoreStaleEndpoints),
1441           std::nullopt, true)));
1442 }
1443 
TEST_F(HostResolverCacheTest,LookupStalePrefersLeastStaleByExpiration)1444 TEST_F(HostResolverCacheTest, LookupStalePrefersLeastStaleByExpiration) {
1445   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
1446 
1447   const std::string kName = "foo.test";
1448   const std::vector<IPEndPoint> kLessStaleEndpoints = {
1449       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::8").value(),
1450                  /*port=*/0)};
1451   auto less_stale_result = std::make_unique<HostResolverInternalDataResult>(
1452       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() - base::Minutes(3),
1453       clock_.Now() - base::Minutes(3), HostResolverInternalResult::Source::kDns,
1454       kLessStaleEndpoints,
1455       /*strings=*/std::vector<std::string>{},
1456       /*hosts=*/std::vector<HostPortPair>{});
1457   const std::vector<IPEndPoint> kMoreStaleEndpoints = {
1458       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::7").value(),
1459                  /*port=*/0)};
1460   auto more_stale_result = std::make_unique<HostResolverInternalDataResult>(
1461       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() - base::Hours(1),
1462       clock_.Now() - base::Hours(1), HostResolverInternalResult::Source::kDns,
1463       kMoreStaleEndpoints,
1464       /*strings=*/std::vector<std::string>{},
1465       /*hosts=*/std::vector<HostPortPair>{});
1466 
1467   const NetworkAnonymizationKey anonymization_key;
1468 
1469   cache.Set(std::move(less_stale_result), anonymization_key,
1470             HostResolverSource::SYSTEM,
1471             /*secure=*/false);
1472   cache.Set(std::move(more_stale_result), anonymization_key,
1473             HostResolverSource::DNS,
1474             /*secure=*/true);
1475 
1476   EXPECT_THAT(
1477       cache.LookupStale(kName, anonymization_key, DnsQueryType::AAAA,
1478                         HostResolverSource::ANY, /*secure=*/std::nullopt),
1479       Optional(IsStale(
1480           ExpectHostResolverInternalDataResult(
1481               kName, DnsQueryType::AAAA,
1482               HostResolverInternalResult::Source::kDns, Ne(std::nullopt),
1483               Ne(std::nullopt), kLessStaleEndpoints),
1484           Optional(TimeDeltaIsApproximately(base::Minutes(3))), false)));
1485 
1486   // Other result still available for more specific lookups.
1487   EXPECT_THAT(
1488       cache.LookupStale(kName, anonymization_key, DnsQueryType::AAAA,
1489                         HostResolverSource::DNS, /*secure=*/std::nullopt),
1490       Optional(
1491           IsStale(ExpectHostResolverInternalDataResult(
1492                       kName, DnsQueryType::AAAA,
1493                       HostResolverInternalResult::Source::kDns,
1494                       Ne(std::nullopt), Ne(std::nullopt), kMoreStaleEndpoints),
1495                   Optional(TimeDeltaIsApproximately(base::Hours(1))), false)));
1496 }
1497 
TEST_F(HostResolverCacheTest,LookupStalePrefersMostSecure)1498 TEST_F(HostResolverCacheTest, LookupStalePrefersMostSecure) {
1499   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
1500 
1501   const std::string kName = "foo.test";
1502   const std::vector<IPEndPoint> kSecureEndpoints = {
1503       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::8").value(),
1504                  /*port=*/0)};
1505   auto secure_result = std::make_unique<HostResolverInternalDataResult>(
1506       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() - base::Minutes(3),
1507       clock_.Now() - base::Minutes(3), HostResolverInternalResult::Source::kDns,
1508       kSecureEndpoints,
1509       /*strings=*/std::vector<std::string>{},
1510       /*hosts=*/std::vector<HostPortPair>{});
1511   const std::vector<IPEndPoint> kInsecureEndpoints = {
1512       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::7").value(),
1513                  /*port=*/0)};
1514   auto insecure_result = std::make_unique<HostResolverInternalDataResult>(
1515       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() - base::Minutes(3),
1516       clock_.Now() - base::Minutes(3), HostResolverInternalResult::Source::kDns,
1517       kInsecureEndpoints,
1518       /*strings=*/std::vector<std::string>{},
1519       /*hosts=*/std::vector<HostPortPair>{});
1520 
1521   const NetworkAnonymizationKey anonymization_key;
1522 
1523   cache.Set(std::move(secure_result), anonymization_key,
1524             HostResolverSource::SYSTEM,
1525             /*secure=*/true);
1526   cache.Set(std::move(insecure_result), anonymization_key,
1527             HostResolverSource::DNS,
1528             /*secure=*/false);
1529 
1530   EXPECT_THAT(
1531       cache.LookupStale(kName, anonymization_key, DnsQueryType::AAAA,
1532                         HostResolverSource::ANY, /*secure=*/std::nullopt),
1533       Optional(
1534           IsStale(ExpectHostResolverInternalDataResult(
1535                       kName, DnsQueryType::AAAA,
1536                       HostResolverInternalResult::Source::kDns,
1537                       Ne(std::nullopt), Ne(std::nullopt), kSecureEndpoints),
1538                   Ne(std::nullopt), false)));
1539 
1540   // Other result still available for more specific lookups.
1541   EXPECT_THAT(
1542       cache.LookupStale(kName, anonymization_key, DnsQueryType::AAAA,
1543                         HostResolverSource::DNS, /*secure=*/std::nullopt),
1544       Optional(
1545           IsStale(ExpectHostResolverInternalDataResult(
1546                       kName, DnsQueryType::AAAA,
1547                       HostResolverInternalResult::Source::kDns,
1548                       Ne(std::nullopt), Ne(std::nullopt), kInsecureEndpoints),
1549                   Ne(std::nullopt), false)));
1550 }
1551 
1552 // Same as LookupStalePrefersMostSecure except results are not stale. Expect
1553 // same general behavior (secure result preferred) but exercises slightly
1554 // different logic because no other results need to be considered once a
1555 // non-stale secure result is found.
TEST_F(HostResolverCacheTest,LookupStalePrefersMostSecureNonStale)1556 TEST_F(HostResolverCacheTest, LookupStalePrefersMostSecureNonStale) {
1557   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
1558 
1559   const std::string kName = "foo.test";
1560   const std::vector<IPEndPoint> kInsecureEndpoints = {
1561       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::7").value(),
1562                  /*port=*/0)};
1563   auto insecure_result = std::make_unique<HostResolverInternalDataResult>(
1564       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Minutes(3),
1565       clock_.Now() + base::Minutes(3), HostResolverInternalResult::Source::kDns,
1566       kInsecureEndpoints,
1567       /*strings=*/std::vector<std::string>{},
1568       /*hosts=*/std::vector<HostPortPair>{});
1569   const std::vector<IPEndPoint> kSecureEndpoints = {
1570       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::8").value(),
1571                  /*port=*/0)};
1572   auto secure_result = std::make_unique<HostResolverInternalDataResult>(
1573       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Minutes(3),
1574       clock_.Now() + base::Minutes(3), HostResolverInternalResult::Source::kDns,
1575       kSecureEndpoints,
1576       /*strings=*/std::vector<std::string>{},
1577       /*hosts=*/std::vector<HostPortPair>{});
1578 
1579   const NetworkAnonymizationKey anonymization_key;
1580 
1581   cache.Set(std::move(insecure_result), anonymization_key,
1582             HostResolverSource::DNS,
1583             /*secure=*/false);
1584   cache.Set(std::move(secure_result), anonymization_key,
1585             HostResolverSource::SYSTEM,
1586             /*secure=*/true);
1587 
1588   EXPECT_THAT(
1589       cache.LookupStale(kName, anonymization_key, DnsQueryType::AAAA,
1590                         HostResolverSource::ANY, /*secure=*/std::nullopt),
1591       Optional(IsNotStale(ExpectHostResolverInternalDataResult(
1592           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
1593           Ne(std::nullopt), Ne(std::nullopt), kSecureEndpoints))));
1594 }
1595 
TEST_F(HostResolverCacheTest,LookupStalePrefersMoreRecent)1596 TEST_F(HostResolverCacheTest, LookupStalePrefersMoreRecent) {
1597   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
1598 
1599   const std::string kName = "foo.test";
1600   const std::vector<IPEndPoint> kOldEndpoints = {
1601       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::8").value(),
1602                  /*port=*/0)};
1603   auto old_result = std::make_unique<HostResolverInternalDataResult>(
1604       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() - base::Minutes(3),
1605       clock_.Now() - base::Minutes(3), HostResolverInternalResult::Source::kDns,
1606       kOldEndpoints,
1607       /*strings=*/std::vector<std::string>{},
1608       /*hosts=*/std::vector<HostPortPair>{});
1609   const std::vector<IPEndPoint> kNewEndpoints = {
1610       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::7").value(),
1611                  /*port=*/0)};
1612   auto new_result = std::make_unique<HostResolverInternalDataResult>(
1613       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() - base::Minutes(3),
1614       clock_.Now() - base::Minutes(3), HostResolverInternalResult::Source::kDns,
1615       kNewEndpoints,
1616       /*strings=*/std::vector<std::string>{},
1617       /*hosts=*/std::vector<HostPortPair>{});
1618 
1619   const NetworkAnonymizationKey anonymization_key;
1620 
1621   cache.Set(std::move(old_result), anonymization_key,
1622             HostResolverSource::SYSTEM,
1623             /*secure=*/false);
1624   cache.Set(std::move(new_result), anonymization_key, HostResolverSource::DNS,
1625             /*secure=*/false);
1626 
1627   EXPECT_THAT(
1628       cache.LookupStale(kName, anonymization_key, DnsQueryType::AAAA,
1629                         HostResolverSource::ANY, /*secure=*/std::nullopt),
1630       Optional(IsStale(ExpectHostResolverInternalDataResult(
1631                            kName, DnsQueryType::AAAA,
1632                            HostResolverInternalResult::Source::kDns,
1633                            Ne(std::nullopt), Ne(std::nullopt), kNewEndpoints),
1634                        Ne(std::nullopt), false)));
1635 
1636   // Other result still available for more specific lookups.
1637   EXPECT_THAT(
1638       cache.LookupStale(kName, anonymization_key, DnsQueryType::AAAA,
1639                         HostResolverSource::SYSTEM, /*secure=*/std::nullopt),
1640       Optional(IsStale(ExpectHostResolverInternalDataResult(
1641                            kName, DnsQueryType::AAAA,
1642                            HostResolverInternalResult::Source::kDns,
1643                            Ne(std::nullopt), Ne(std::nullopt), kOldEndpoints),
1644                        Ne(std::nullopt), false)));
1645 }
1646 
TEST_F(HostResolverCacheTest,EvictStaleResults)1647 TEST_F(HostResolverCacheTest, EvictStaleResults) {
1648   HostResolverCache cache(/*max_results=*/2, clock_, tick_clock_);
1649 
1650   const std::string kName1 = "foo1.test";
1651   const std::vector<IPEndPoint> kEndpoints1 = {
1652       IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)};
1653   auto result1 = std::make_unique<HostResolverInternalDataResult>(
1654       kName1, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Minutes(11),
1655       clock_.Now() + base::Minutes(11),
1656       HostResolverInternalResult::Source::kDns, kEndpoints1,
1657       /*strings=*/std::vector<std::string>{},
1658       /*hosts=*/std::vector<HostPortPair>{});
1659 
1660   const NetworkAnonymizationKey anonymization_key;
1661   cache.Set(std::move(result1), anonymization_key, HostResolverSource::DNS,
1662             /*secure=*/false);
1663   cache.MakeAllResultsStale();
1664 
1665   const std::string kName2 = "foo2.test";
1666   const std::vector<IPEndPoint> kEndpoints2 = {
1667       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::4").value(),
1668                  /*port=*/0)};
1669   auto result2 = std::make_unique<HostResolverInternalDataResult>(
1670       kName2, DnsQueryType::AAAA, tick_clock_.NowTicks() - base::Minutes(4),
1671       clock_.Now() - base::Minutes(4), HostResolverInternalResult::Source::kDns,
1672       kEndpoints2,
1673       /*strings=*/std::vector<std::string>{},
1674       /*hosts=*/std::vector<HostPortPair>{});
1675   cache.Set(std::move(result2), anonymization_key, HostResolverSource::DNS,
1676             /*secure=*/false);
1677 
1678   // Expect `result1` to be stale via generation and `result2` to be stale via
1679   // expiration.
1680   EXPECT_THAT(cache.LookupStale(kName1, anonymization_key),
1681               Optional(IsStale(std::nullopt, true)));
1682   EXPECT_THAT(cache.LookupStale(kName2, anonymization_key),
1683               Optional(IsStale(Ne(std::nullopt), false)));
1684 
1685   const std::string kName3 = "foo3.test";
1686   const std::vector<IPEndPoint> kEndpoints3 = {
1687       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::5").value(),
1688                  /*port=*/0)};
1689   auto result3 = std::make_unique<HostResolverInternalDataResult>(
1690       kName3, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Minutes(8),
1691       clock_.Now() + base::Minutes(8), HostResolverInternalResult::Source::kDns,
1692       kEndpoints3,
1693       /*strings=*/std::vector<std::string>{},
1694       /*hosts=*/std::vector<HostPortPair>{});
1695   cache.Set(std::move(result3), anonymization_key, HostResolverSource::DNS,
1696             /*secure=*/false);
1697 
1698   // Expect `result1` and `result2` to be evicted and `result3` to still be
1699   // active.
1700   EXPECT_EQ(cache.LookupStale(kName1, anonymization_key), std::nullopt);
1701   EXPECT_EQ(cache.LookupStale(kName2, anonymization_key), std::nullopt);
1702   EXPECT_NE(cache.Lookup(kName3, anonymization_key), nullptr);
1703 }
1704 
TEST_F(HostResolverCacheTest,EvictSoonestToExpireResult)1705 TEST_F(HostResolverCacheTest, EvictSoonestToExpireResult) {
1706   HostResolverCache cache(/*max_results=*/2, clock_, tick_clock_);
1707 
1708   const std::string kName1 = "foo1.test";
1709   const std::vector<IPEndPoint> kEndpoints1 = {
1710       IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)};
1711   auto result1 = std::make_unique<HostResolverInternalDataResult>(
1712       kName1, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Minutes(11),
1713       clock_.Now() + base::Minutes(11),
1714       HostResolverInternalResult::Source::kDns, kEndpoints1,
1715       /*strings=*/std::vector<std::string>{},
1716       /*hosts=*/std::vector<HostPortPair>{});
1717 
1718   const NetworkAnonymizationKey anonymization_key;
1719   cache.Set(std::move(result1), anonymization_key, HostResolverSource::DNS,
1720             /*secure=*/false);
1721 
1722   const std::string kName2 = "foo2.test";
1723   const std::vector<IPEndPoint> kEndpoints2 = {
1724       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::4").value(),
1725                  /*port=*/0)};
1726   auto result2 = std::make_unique<HostResolverInternalDataResult>(
1727       kName2, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Minutes(4),
1728       clock_.Now() + base::Minutes(4), HostResolverInternalResult::Source::kDns,
1729       kEndpoints2,
1730       /*strings=*/std::vector<std::string>{},
1731       /*hosts=*/std::vector<HostPortPair>{});
1732   cache.Set(std::move(result2), anonymization_key, HostResolverSource::DNS,
1733             /*secure=*/false);
1734 
1735   // Expect both results to be active.
1736   EXPECT_NE(cache.Lookup(kName1, anonymization_key), nullptr);
1737   EXPECT_NE(cache.Lookup(kName2, anonymization_key), nullptr);
1738 
1739   const std::string kName3 = "foo3.test";
1740   const std::vector<IPEndPoint> kEndpoints3 = {
1741       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::5").value(),
1742                  /*port=*/0)};
1743   auto result3 = std::make_unique<HostResolverInternalDataResult>(
1744       kName3, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Minutes(8),
1745       clock_.Now() + base::Minutes(8), HostResolverInternalResult::Source::kDns,
1746       kEndpoints3,
1747       /*strings=*/std::vector<std::string>{},
1748       /*hosts=*/std::vector<HostPortPair>{});
1749   cache.Set(std::move(result3), anonymization_key, HostResolverSource::DNS,
1750             /*secure=*/false);
1751 
1752   // Expect `result2` to be evicted because it expires soonest.
1753   EXPECT_NE(cache.Lookup(kName1, anonymization_key), nullptr);
1754   EXPECT_EQ(cache.LookupStale(kName2, anonymization_key), std::nullopt);
1755   EXPECT_NE(cache.Lookup(kName3, anonymization_key), nullptr);
1756 }
1757 
1758 // If multiple results are equally soon-to-expire, expect least secure option to
1759 // be evicted.
TEST_F(HostResolverCacheTest,EvictLeastSecureResult)1760 TEST_F(HostResolverCacheTest, EvictLeastSecureResult) {
1761   HostResolverCache cache(/*max_results=*/2, clock_, tick_clock_);
1762 
1763   const std::string kName1 = "foo1.test";
1764   const base::TimeDelta kTtl = base::Minutes(2);
1765   const std::vector<IPEndPoint> kEndpoints1 = {
1766       IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)};
1767   auto result1 = std::make_unique<HostResolverInternalDataResult>(
1768       kName1, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
1769       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
1770       kEndpoints1,
1771       /*strings=*/std::vector<std::string>{},
1772       /*hosts=*/std::vector<HostPortPair>{});
1773 
1774   const NetworkAnonymizationKey anonymization_key;
1775   cache.Set(std::move(result1), anonymization_key, HostResolverSource::DNS,
1776             /*secure=*/true);
1777 
1778   const std::string kName2 = "foo2.test";
1779   const std::vector<IPEndPoint> kEndpoints2 = {
1780       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::4").value(),
1781                  /*port=*/0)};
1782   auto result2 = std::make_unique<HostResolverInternalDataResult>(
1783       kName2, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
1784       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
1785       kEndpoints2,
1786       /*strings=*/std::vector<std::string>{},
1787       /*hosts=*/std::vector<HostPortPair>{});
1788   cache.Set(std::move(result2), anonymization_key, HostResolverSource::DNS,
1789             /*secure=*/false);
1790 
1791   // Expect both results to be active.
1792   EXPECT_NE(cache.Lookup(kName1, anonymization_key), nullptr);
1793   EXPECT_NE(cache.Lookup(kName2, anonymization_key), nullptr);
1794 
1795   const std::string kName3 = "foo3.test";
1796   const std::vector<IPEndPoint> kEndpoints3 = {
1797       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::5").value(),
1798                  /*port=*/0)};
1799   auto result3 = std::make_unique<HostResolverInternalDataResult>(
1800       kName3, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Minutes(8),
1801       clock_.Now() + base::Minutes(8), HostResolverInternalResult::Source::kDns,
1802       kEndpoints3,
1803       /*strings=*/std::vector<std::string>{},
1804       /*hosts=*/std::vector<HostPortPair>{});
1805   cache.Set(std::move(result3), anonymization_key, HostResolverSource::DNS,
1806             /*secure=*/false);
1807 
1808   // Expect `result2` to be evicted because, while it will expire at the same
1809   // time as `result1`, it is less secure.
1810   EXPECT_NE(cache.Lookup(kName1, anonymization_key), nullptr);
1811   EXPECT_EQ(cache.LookupStale(kName2, anonymization_key), std::nullopt);
1812   EXPECT_NE(cache.Lookup(kName3, anonymization_key), nullptr);
1813 }
1814 
1815 // If multiple results are equally soon-to-expire and equally (in)secure, expect
1816 // oldest option to be evicted.
TEST_F(HostResolverCacheTest,EvictOldestResult)1817 TEST_F(HostResolverCacheTest, EvictOldestResult) {
1818   HostResolverCache cache(/*max_results=*/2, clock_, tick_clock_);
1819 
1820   const std::string kName1 = "foo1.test";
1821   const base::TimeDelta kTtl = base::Minutes(2);
1822   const std::vector<IPEndPoint> kEndpoints1 = {
1823       IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)};
1824   auto result1 = std::make_unique<HostResolverInternalDataResult>(
1825       kName1, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
1826       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
1827       kEndpoints1,
1828       /*strings=*/std::vector<std::string>{},
1829       /*hosts=*/std::vector<HostPortPair>{});
1830 
1831   const NetworkAnonymizationKey anonymization_key;
1832   cache.Set(std::move(result1), anonymization_key, HostResolverSource::DNS,
1833             /*secure=*/false);
1834 
1835   const std::string kName2 = "foo2.test";
1836   const std::vector<IPEndPoint> kEndpoints2 = {
1837       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::4").value(),
1838                  /*port=*/0)};
1839   auto result2 = std::make_unique<HostResolverInternalDataResult>(
1840       kName2, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
1841       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
1842       kEndpoints2,
1843       /*strings=*/std::vector<std::string>{},
1844       /*hosts=*/std::vector<HostPortPair>{});
1845   cache.Set(std::move(result2), anonymization_key, HostResolverSource::DNS,
1846             /*secure=*/false);
1847 
1848   // Expect both results to be active.
1849   EXPECT_NE(cache.Lookup(kName1, anonymization_key), nullptr);
1850   EXPECT_NE(cache.Lookup(kName2, anonymization_key), nullptr);
1851 
1852   const std::string kName3 = "foo3.test";
1853   const std::vector<IPEndPoint> kEndpoints3 = {
1854       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::5").value(),
1855                  /*port=*/0)};
1856   auto result3 = std::make_unique<HostResolverInternalDataResult>(
1857       kName3, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Minutes(8),
1858       clock_.Now() + base::Minutes(8), HostResolverInternalResult::Source::kDns,
1859       kEndpoints3,
1860       /*strings=*/std::vector<std::string>{},
1861       /*hosts=*/std::vector<HostPortPair>{});
1862   cache.Set(std::move(result3), anonymization_key, HostResolverSource::DNS,
1863             /*secure=*/false);
1864 
1865   // Expect `result1` to be evicted because, while it will expire at the same
1866   // time as `result2` and both are insecure, it is older.
1867   EXPECT_EQ(cache.LookupStale(kName1, anonymization_key), std::nullopt);
1868   EXPECT_NE(cache.Lookup(kName2, anonymization_key), nullptr);
1869   EXPECT_NE(cache.Lookup(kName3, anonymization_key), nullptr);
1870 }
1871 
1872 // Even newly-added results that trigger eviction are themselves eligible for
1873 // eviction if best candidate.
TEST_F(HostResolverCacheTest,EvictLatestResult)1874 TEST_F(HostResolverCacheTest, EvictLatestResult) {
1875   HostResolverCache cache(/*max_results=*/2, clock_, tick_clock_);
1876 
1877   const std::string kName1 = "foo1.test";
1878   const base::TimeDelta kTtl = base::Minutes(2);
1879   const std::vector<IPEndPoint> kEndpoints1 = {
1880       IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)};
1881   auto result1 = std::make_unique<HostResolverInternalDataResult>(
1882       kName1, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
1883       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
1884       kEndpoints1,
1885       /*strings=*/std::vector<std::string>{},
1886       /*hosts=*/std::vector<HostPortPair>{});
1887 
1888   const NetworkAnonymizationKey anonymization_key;
1889   cache.Set(std::move(result1), anonymization_key, HostResolverSource::DNS,
1890             /*secure=*/false);
1891 
1892   const std::string kName2 = "foo2.test";
1893   const std::vector<IPEndPoint> kEndpoints2 = {
1894       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::4").value(),
1895                  /*port=*/0)};
1896   auto result2 = std::make_unique<HostResolverInternalDataResult>(
1897       kName2, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl,
1898       clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns,
1899       kEndpoints2,
1900       /*strings=*/std::vector<std::string>{},
1901       /*hosts=*/std::vector<HostPortPair>{});
1902   cache.Set(std::move(result2), anonymization_key, HostResolverSource::DNS,
1903             /*secure=*/false);
1904 
1905   // Expect both results to be active.
1906   EXPECT_NE(cache.Lookup(kName1, anonymization_key), nullptr);
1907   EXPECT_NE(cache.Lookup(kName2, anonymization_key), nullptr);
1908 
1909   const std::string kName3 = "foo3.test";
1910   const std::vector<IPEndPoint> kEndpoints3 = {
1911       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::5").value(),
1912                  /*port=*/0)};
1913   auto result3 = std::make_unique<HostResolverInternalDataResult>(
1914       kName3, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Minutes(1),
1915       clock_.Now() + base::Minutes(8), HostResolverInternalResult::Source::kDns,
1916       kEndpoints3,
1917       /*strings=*/std::vector<std::string>{},
1918       /*hosts=*/std::vector<HostPortPair>{});
1919   cache.Set(std::move(result3), anonymization_key, HostResolverSource::DNS,
1920             /*secure=*/false);
1921 
1922   // Expect `result3` to be evicted because it is soonest to expire.
1923   EXPECT_NE(cache.Lookup(kName1, anonymization_key), nullptr);
1924   EXPECT_NE(cache.Lookup(kName2, anonymization_key), nullptr);
1925   EXPECT_EQ(cache.LookupStale(kName3, anonymization_key), std::nullopt);
1926 }
1927 
TEST_F(HostResolverCacheTest,SerializeAndDeserialize)1928 TEST_F(HostResolverCacheTest, SerializeAndDeserialize) {
1929   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
1930   const std::string kName = "foo.test";
1931   const std::vector<IPEndPoint> kEndpoints = {
1932       IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)};
1933   const base::Time kExpiration = clock_.Now() + base::Hours(2);
1934   auto result = std::make_unique<HostResolverInternalDataResult>(
1935       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Hours(2),
1936       kExpiration, HostResolverInternalResult::Source::kDns, kEndpoints,
1937       /*strings=*/std::vector<std::string>{},
1938       /*hosts=*/std::vector<HostPortPair>{});
1939   const NetworkAnonymizationKey anonymization_key;
1940   cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS,
1941             /*secure=*/false);
1942 
1943   base::Value value = cache.Serialize();
1944   EXPECT_EQ(value.GetList().size(), 1u);
1945 
1946   HostResolverCache restored_cache(kMaxResults, clock_, tick_clock_);
1947   EXPECT_TRUE(restored_cache.RestoreFromValue(value));
1948 
1949   // Expect restored result to be stale by generation.
1950   EXPECT_THAT(
1951       restored_cache.LookupStale(kName, anonymization_key),
1952       Optional(IsStale(ExpectHostResolverInternalDataResult(
1953                            kName, DnsQueryType::AAAA,
1954                            HostResolverInternalResult::Source::kDns,
1955                            Eq(std::nullopt), Optional(kExpiration), kEndpoints),
1956                        std::nullopt, true)));
1957 }
1958 
TEST_F(HostResolverCacheTest,TransientAnonymizationKeyNotSerialized)1959 TEST_F(HostResolverCacheTest, TransientAnonymizationKeyNotSerialized) {
1960   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
1961   const std::string kName = "foo.test";
1962   const std::vector<IPEndPoint> kEndpoints = {
1963       IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)};
1964   const base::Time kExpiration = clock_.Now() + base::Hours(2);
1965   auto result = std::make_unique<HostResolverInternalDataResult>(
1966       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Hours(2),
1967       kExpiration, HostResolverInternalResult::Source::kDns, kEndpoints,
1968       /*strings=*/std::vector<std::string>{},
1969       /*hosts=*/std::vector<HostPortPair>{});
1970   const auto anonymization_key = NetworkAnonymizationKey::CreateTransient();
1971   cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS,
1972             /*secure=*/false);
1973 
1974   base::Value value = cache.Serialize();
1975   EXPECT_TRUE(value.GetList().empty());
1976 }
1977 
TEST_F(HostResolverCacheTest,DeserializePrefersExistingResults)1978 TEST_F(HostResolverCacheTest, DeserializePrefersExistingResults) {
1979   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
1980   const std::string kName = "foo.test";
1981   const std::vector<IPEndPoint> kRestoredEndpoints = {
1982       IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)};
1983   const base::Time kExpiration = clock_.Now() + base::Hours(2);
1984   auto result = std::make_unique<HostResolverInternalDataResult>(
1985       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Hours(2),
1986       kExpiration, HostResolverInternalResult::Source::kDns, kRestoredEndpoints,
1987       /*strings=*/std::vector<std::string>{},
1988       /*hosts=*/std::vector<HostPortPair>{});
1989   const NetworkAnonymizationKey anonymization_key;
1990   cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS,
1991             /*secure=*/false);
1992 
1993   base::Value value = cache.Serialize();
1994   EXPECT_EQ(value.GetList().size(), 1u);
1995 
1996   HostResolverCache restored_cache(kMaxResults, clock_, tick_clock_);
1997 
1998   const std::vector<IPEndPoint> kEndpoints = {
1999       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::3").value(), /*port=*/0)};
2000   result = std::make_unique<HostResolverInternalDataResult>(
2001       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Hours(2),
2002       kExpiration, HostResolverInternalResult::Source::kDns, kEndpoints,
2003       /*strings=*/std::vector<std::string>{},
2004       /*hosts=*/std::vector<HostPortPair>{});
2005   restored_cache.Set(std::move(result), anonymization_key,
2006                      HostResolverSource::DNS,
2007                      /*secure=*/false);
2008 
2009   EXPECT_TRUE(restored_cache.RestoreFromValue(value));
2010 
2011   // Expect pre-restoration result.
2012   EXPECT_THAT(
2013       restored_cache.LookupStale(kName, anonymization_key),
2014       Optional(IsNotStale(ExpectHostResolverInternalDataResult(
2015           kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
2016           Ne(std::nullopt), Optional(kExpiration), kEndpoints))));
2017 }
2018 
TEST_F(HostResolverCacheTest,DeserializeStopsBeforeEviction)2019 TEST_F(HostResolverCacheTest, DeserializeStopsBeforeEviction) {
2020   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
2021   const std::string kName1 = "foo1.test";
2022   const std::vector<IPEndPoint> kRestoredEndpoints = {
2023       IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)};
2024   const base::Time kExpiration = clock_.Now() + base::Hours(2);
2025   auto result = std::make_unique<HostResolverInternalDataResult>(
2026       kName1, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Hours(2),
2027       kExpiration, HostResolverInternalResult::Source::kDns, kRestoredEndpoints,
2028       /*strings=*/std::vector<std::string>{},
2029       /*hosts=*/std::vector<HostPortPair>{});
2030   const NetworkAnonymizationKey anonymization_key;
2031   cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS,
2032             /*secure=*/false);
2033 
2034   base::Value value = cache.Serialize();
2035   EXPECT_EQ(value.GetList().size(), 1u);
2036 
2037   HostResolverCache restored_cache(1, clock_, tick_clock_);
2038 
2039   const std::string kName2 = "foo2.test";
2040   const std::vector<IPEndPoint> kEndpoints = {
2041       IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::3").value(), /*port=*/0)};
2042   result = std::make_unique<HostResolverInternalDataResult>(
2043       kName2, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Hours(2),
2044       kExpiration, HostResolverInternalResult::Source::kDns, kEndpoints,
2045       /*strings=*/std::vector<std::string>{},
2046       /*hosts=*/std::vector<HostPortPair>{});
2047   restored_cache.Set(std::move(result), anonymization_key,
2048                      HostResolverSource::DNS,
2049                      /*secure=*/false);
2050 
2051   EXPECT_TRUE(restored_cache.RestoreFromValue(value));
2052 
2053   // Expect only pre-restoration result.
2054   EXPECT_EQ(restored_cache.LookupStale(kName1, anonymization_key),
2055             std::nullopt);
2056   EXPECT_THAT(
2057       restored_cache.LookupStale(kName2, anonymization_key),
2058       Optional(IsNotStale(ExpectHostResolverInternalDataResult(
2059           kName2, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns,
2060           Ne(std::nullopt), Optional(kExpiration), kEndpoints))));
2061 }
2062 
TEST_F(HostResolverCacheTest,SerializeForLogging)2063 TEST_F(HostResolverCacheTest, SerializeForLogging) {
2064   HostResolverCache cache(kMaxResults, clock_, tick_clock_);
2065   const std::string kName = "foo.test";
2066   const std::vector<IPEndPoint> kEndpoints = {
2067       IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)};
2068   const base::Time kExpiration = clock_.Now() + base::Hours(2);
2069   auto result = std::make_unique<HostResolverInternalDataResult>(
2070       kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Hours(2),
2071       kExpiration, HostResolverInternalResult::Source::kDns, kEndpoints,
2072       /*strings=*/std::vector<std::string>{},
2073       /*hosts=*/std::vector<HostPortPair>{});
2074   const NetworkAnonymizationKey anonymization_key;
2075   cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS,
2076             /*secure=*/false);
2077 
2078   base::Value value = cache.SerializeForLogging();
2079   EXPECT_TRUE(value.is_dict());
2080 
2081   EXPECT_FALSE(cache.RestoreFromValue(value));
2082 }
2083 
2084 }  // namespace
2085 }  // namespace net
2086