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