1 // Copyright 2018 The Chromium Authors. All rights reserved.
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 "services/network/host_resolver.h"
6 
7 #include <map>
8 #include <utility>
9 #include <vector>
10 
11 #include "base/check.h"
12 #include "base/optional.h"
13 #include "base/run_loop.h"
14 #include "base/test/bind.h"
15 #include "base/test/task_environment.h"
16 #include "base/time/time.h"
17 #include "mojo/public/cpp/bindings/pending_remote.h"
18 #include "mojo/public/cpp/bindings/receiver.h"
19 #include "mojo/public/cpp/bindings/remote.h"
20 #include "net/base/address_list.h"
21 #include "net/base/host_port_pair.h"
22 #include "net/base/ip_address.h"
23 #include "net/base/ip_endpoint.h"
24 #include "net/base/net_errors.h"
25 #include "net/base/network_isolation_key.h"
26 #include "net/dns/context_host_resolver.h"
27 #include "net/dns/dns_config.h"
28 #include "net/dns/dns_test_util.h"
29 #include "net/dns/host_resolver.h"
30 #include "net/dns/host_resolver_manager.h"
31 #include "net/dns/mock_host_resolver.h"
32 #include "net/dns/public/dns_protocol.h"
33 #include "net/dns/public/secure_dns_mode.h"
34 #include "net/log/net_log.h"
35 #include "net/net_buildflags.h"
36 #include "testing/gmock/include/gmock/gmock.h"
37 #include "testing/gtest/include/gtest/gtest.h"
38 
39 namespace network {
40 namespace {
41 
42 class HostResolverTest : public testing::Test {
43  public:
44   HostResolverTest() = default;
45 
46  protected:
47   base::test::TaskEnvironment task_environment_{
48       base::test::TaskEnvironment::TimeSource::MOCK_TIME,
49       base::test::TaskEnvironment::MainThreadType::IO};
50 };
51 
CreateExpectedEndPoint(const std::string & address,uint16_t port)52 net::IPEndPoint CreateExpectedEndPoint(const std::string& address,
53                                        uint16_t port) {
54   net::IPAddress ip_address;
55   CHECK(ip_address.AssignFromIPLiteral(address));
56   return net::IPEndPoint(ip_address, port);
57 }
58 
59 class TestResolveHostClient : public mojom::ResolveHostClient {
60  public:
61   // If |run_loop| is non-null, will call RunLoop::Quit() on completion.
TestResolveHostClient(mojo::PendingRemote<mojom::ResolveHostClient> * remote,base::RunLoop * run_loop)62   TestResolveHostClient(mojo::PendingRemote<mojom::ResolveHostClient>* remote,
63                         base::RunLoop* run_loop)
64       : receiver_(this, remote->InitWithNewPipeAndPassReceiver()),
65         complete_(false),
66         top_level_result_error_(net::ERR_IO_PENDING),
67         result_error_(net::ERR_UNEXPECTED),
68         run_loop_(run_loop) {}
69 
CloseReceiver()70   void CloseReceiver() { receiver_.reset(); }
71 
OnComplete(int error,const net::ResolveErrorInfo & resolve_error_info,const base::Optional<net::AddressList> & addresses)72   void OnComplete(int error,
73                   const net::ResolveErrorInfo& resolve_error_info,
74                   const base::Optional<net::AddressList>& addresses) override {
75     DCHECK(!complete_);
76 
77     complete_ = true;
78     top_level_result_error_ = error;
79     result_error_ = resolve_error_info.error;
80     result_addresses_ = addresses;
81     if (run_loop_)
82       run_loop_->Quit();
83   }
84 
OnTextResults(const std::vector<std::string> & text_results)85   void OnTextResults(const std::vector<std::string>& text_results) override {
86     DCHECK(!complete_);
87     result_text_ = text_results;
88   }
89 
OnHostnameResults(const std::vector<net::HostPortPair> & hosts)90   void OnHostnameResults(const std::vector<net::HostPortPair>& hosts) override {
91     DCHECK(!complete_);
92     result_hosts_ = hosts;
93   }
94 
complete() const95   bool complete() const { return complete_; }
96 
top_level_result_error() const97   int top_level_result_error() const {
98     DCHECK(complete_);
99     return top_level_result_error_;
100   }
101 
result_error() const102   int result_error() const {
103     DCHECK(complete_);
104     return result_error_;
105   }
106 
result_addresses() const107   const base::Optional<net::AddressList>& result_addresses() const {
108     DCHECK(complete_);
109     return result_addresses_;
110   }
111 
result_text() const112   const base::Optional<std::vector<std::string>>& result_text() const {
113     DCHECK(complete_);
114     return result_text_;
115   }
116 
result_hosts() const117   const base::Optional<std::vector<net::HostPortPair>>& result_hosts() const {
118     DCHECK(complete_);
119     return result_hosts_;
120   }
121 
122  private:
123   mojo::Receiver<mojom::ResolveHostClient> receiver_{this};
124 
125   bool complete_;
126   int top_level_result_error_;
127   int result_error_;
128   base::Optional<net::AddressList> result_addresses_;
129   base::Optional<std::vector<std::string>> result_text_;
130   base::Optional<std::vector<net::HostPortPair>> result_hosts_;
131   base::RunLoop* const run_loop_;
132 };
133 
134 class TestMdnsListenClient : public mojom::MdnsListenClient {
135  public:
136   using UpdateType = net::HostResolver::MdnsListener::Delegate::UpdateType;
137   using UpdateKey = std::pair<UpdateType, net::DnsQueryType>;
138 
TestMdnsListenClient(mojo::PendingRemote<mojom::MdnsListenClient> * remote)139   explicit TestMdnsListenClient(
140       mojo::PendingRemote<mojom::MdnsListenClient>* remote)
141       : receiver_(this, remote->InitWithNewPipeAndPassReceiver()) {}
142 
OnAddressResult(UpdateType update_type,net::DnsQueryType result_type,const net::IPEndPoint & address)143   void OnAddressResult(UpdateType update_type,
144                        net::DnsQueryType result_type,
145                        const net::IPEndPoint& address) override {
146     address_results_.insert({{update_type, result_type}, address});
147   }
148 
OnTextResult(UpdateType update_type,net::DnsQueryType result_type,const std::vector<std::string> & text_records)149   void OnTextResult(UpdateType update_type,
150                     net::DnsQueryType result_type,
151                     const std::vector<std::string>& text_records) override {
152     for (auto& text_record : text_records) {
153       text_results_.insert({{update_type, result_type}, text_record});
154     }
155   }
156 
OnHostnameResult(UpdateType update_type,net::DnsQueryType result_type,const net::HostPortPair & host)157   void OnHostnameResult(UpdateType update_type,
158                         net::DnsQueryType result_type,
159                         const net::HostPortPair& host) override {
160     hostname_results_.insert({{update_type, result_type}, host});
161   }
162 
OnUnhandledResult(UpdateType update_type,net::DnsQueryType result_type)163   void OnUnhandledResult(UpdateType update_type,
164                          net::DnsQueryType result_type) override {
165     unhandled_results_.insert({update_type, result_type});
166   }
167 
address_results()168   const std::multimap<UpdateKey, net::IPEndPoint>& address_results() {
169     return address_results_;
170   }
171 
text_results()172   const std::multimap<UpdateKey, std::string>& text_results() {
173     return text_results_;
174   }
175 
hostname_results()176   const std::multimap<UpdateKey, net::HostPortPair>& hostname_results() {
177     return hostname_results_;
178   }
179 
unhandled_results()180   const std::multiset<UpdateKey>& unhandled_results() {
181     return unhandled_results_;
182   }
183 
184   template <typename T>
CreateExpectedResult(UpdateType update_type,net::DnsQueryType query_type,T result)185   static std::pair<UpdateKey, T> CreateExpectedResult(
186       UpdateType update_type,
187       net::DnsQueryType query_type,
188       T result) {
189     return std::make_pair(std::make_pair(update_type, query_type), result);
190   }
191 
192  private:
193   mojo::Receiver<mojom::MdnsListenClient> receiver_;
194 
195   std::multimap<UpdateKey, net::IPEndPoint> address_results_;
196   std::multimap<UpdateKey, std::string> text_results_;
197   std::multimap<UpdateKey, net::HostPortPair> hostname_results_;
198   std::multiset<UpdateKey> unhandled_results_;
199 };
200 
TEST_F(HostResolverTest,Sync)201 TEST_F(HostResolverTest, Sync) {
202   auto inner_resolver = std::make_unique<net::MockHostResolver>();
203   inner_resolver->set_synchronous_mode(true);
204 
205   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
206 
207   base::RunLoop run_loop;
208   mojo::Remote<mojom::ResolveHostHandle> control_handle;
209   mojom::ResolveHostParametersPtr optional_parameters =
210       mojom::ResolveHostParameters::New();
211   optional_parameters->control_handle =
212       control_handle.BindNewPipeAndPassReceiver();
213   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
214   TestResolveHostClient response_client(&pending_response_client, &run_loop);
215 
216   resolver.ResolveHost(
217       net::HostPortPair("localhost", 160), net::NetworkIsolationKey(),
218       std::move(optional_parameters), std::move(pending_response_client));
219   run_loop.Run();
220 
221   EXPECT_EQ(net::OK, response_client.top_level_result_error());
222   EXPECT_EQ(net::OK, response_client.result_error());
223   EXPECT_THAT(response_client.result_addresses().value().endpoints(),
224               testing::ElementsAre(CreateExpectedEndPoint("127.0.0.1", 160)));
225   EXPECT_FALSE(response_client.result_text());
226   EXPECT_FALSE(response_client.result_hosts());
227   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
228   EXPECT_EQ(net::DEFAULT_PRIORITY, inner_resolver->last_request_priority());
229 }
230 
TEST_F(HostResolverTest,Async)231 TEST_F(HostResolverTest, Async) {
232   auto inner_resolver = std::make_unique<net::MockHostResolver>();
233   inner_resolver->set_synchronous_mode(false);
234 
235   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
236 
237   base::RunLoop run_loop;
238   mojo::Remote<mojom::ResolveHostHandle> control_handle;
239   mojom::ResolveHostParametersPtr optional_parameters =
240       mojom::ResolveHostParameters::New();
241   optional_parameters->control_handle =
242       control_handle.BindNewPipeAndPassReceiver();
243   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
244   TestResolveHostClient response_client(&pending_response_client, &run_loop);
245 
246   resolver.ResolveHost(
247       net::HostPortPair("localhost", 160), net::NetworkIsolationKey(),
248       std::move(optional_parameters), std::move(pending_response_client));
249 
250   bool control_handle_closed = false;
251   auto connection_error_callback =
252       base::BindLambdaForTesting([&]() { control_handle_closed = true; });
253   control_handle.set_disconnect_handler(connection_error_callback);
254   run_loop.Run();
255 
256   EXPECT_EQ(net::OK, response_client.result_error());
257   EXPECT_THAT(response_client.result_addresses().value().endpoints(),
258               testing::ElementsAre(CreateExpectedEndPoint("127.0.0.1", 160)));
259   EXPECT_FALSE(response_client.result_text());
260   EXPECT_FALSE(response_client.result_hosts());
261   EXPECT_TRUE(control_handle_closed);
262   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
263   EXPECT_EQ(net::DEFAULT_PRIORITY, inner_resolver->last_request_priority());
264 }
265 
TEST_F(HostResolverTest,DnsQueryType)266 TEST_F(HostResolverTest, DnsQueryType) {
267   std::unique_ptr<net::HostResolver> inner_resolver =
268       net::HostResolver::CreateStandaloneResolver(net::NetLog::Get());
269 
270   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
271 
272   mojom::ResolveHostParametersPtr optional_parameters =
273       mojom::ResolveHostParameters::New();
274   optional_parameters->dns_query_type = net::DnsQueryType::AAAA;
275 
276   base::RunLoop run_loop;
277   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
278   TestResolveHostClient response_client(&pending_response_client, &run_loop);
279 
280   resolver.ResolveHost(
281       net::HostPortPair("localhost", 160), net::NetworkIsolationKey(),
282       std::move(optional_parameters), std::move(pending_response_client));
283   run_loop.Run();
284 
285   EXPECT_EQ(net::OK, response_client.result_error());
286   EXPECT_THAT(response_client.result_addresses().value().endpoints(),
287               testing::ElementsAre(CreateExpectedEndPoint("::1", 160)));
288 }
289 
TEST_F(HostResolverTest,InitialPriority)290 TEST_F(HostResolverTest, InitialPriority) {
291   auto inner_resolver = std::make_unique<net::MockHostResolver>();
292 
293   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
294 
295   mojom::ResolveHostParametersPtr optional_parameters =
296       mojom::ResolveHostParameters::New();
297   optional_parameters->initial_priority = net::HIGHEST;
298 
299   base::RunLoop run_loop;
300   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
301   TestResolveHostClient response_client(&pending_response_client, &run_loop);
302 
303   resolver.ResolveHost(
304       net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
305       std::move(optional_parameters), std::move(pending_response_client));
306   run_loop.Run();
307 
308   EXPECT_EQ(net::OK, response_client.result_error());
309   EXPECT_THAT(response_client.result_addresses().value().endpoints(),
310               testing::ElementsAre(CreateExpectedEndPoint("127.0.0.1", 80)));
311   EXPECT_EQ(net::HIGHEST, inner_resolver->last_request_priority());
312 }
313 
314 // Make requests specifying a source for host resolution and ensure the correct
315 // source is requested from the inner resolver.
TEST_F(HostResolverTest,Source)316 TEST_F(HostResolverTest, Source) {
317   constexpr char kDomain[] = "example.com";
318   constexpr char kAnyResult[] = "1.2.3.4";
319   constexpr char kSystemResult[] = "127.0.0.1";
320   constexpr char kDnsResult[] = "168.100.12.23";
321   constexpr char kMdnsResult[] = "200.1.2.3";
322   auto inner_resolver = std::make_unique<net::MockHostResolver>();
323   inner_resolver->rules_map()[net::HostResolverSource::ANY]->AddRule(
324       kDomain, kAnyResult);
325   inner_resolver->rules_map()[net::HostResolverSource::SYSTEM]->AddRule(
326       kDomain, kSystemResult);
327   inner_resolver->rules_map()[net::HostResolverSource::DNS]->AddRule(
328       kDomain, kDnsResult);
329   inner_resolver->rules_map()[net::HostResolverSource::MULTICAST_DNS]->AddRule(
330       kDomain, kMdnsResult);
331 
332   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
333 
334   base::RunLoop any_run_loop;
335   mojo::PendingRemote<mojom::ResolveHostClient> pending_any_client;
336   TestResolveHostClient any_client(&pending_any_client, &any_run_loop);
337   mojom::ResolveHostParametersPtr any_parameters =
338       mojom::ResolveHostParameters::New();
339   any_parameters->source = net::HostResolverSource::ANY;
340   resolver.ResolveHost(net::HostPortPair(kDomain, 80),
341                        net::NetworkIsolationKey(), std::move(any_parameters),
342                        std::move(pending_any_client));
343 
344   base::RunLoop system_run_loop;
345   mojo::PendingRemote<mojom::ResolveHostClient> pending_system_client;
346   TestResolveHostClient system_client(&pending_system_client, &system_run_loop);
347   mojom::ResolveHostParametersPtr system_parameters =
348       mojom::ResolveHostParameters::New();
349   system_parameters->source = net::HostResolverSource::SYSTEM;
350   resolver.ResolveHost(net::HostPortPair(kDomain, 80),
351                        net::NetworkIsolationKey(), std::move(system_parameters),
352                        std::move(pending_system_client));
353 
354   base::RunLoop dns_run_loop;
355   mojo::PendingRemote<mojom::ResolveHostClient> pending_dns_client;
356   TestResolveHostClient dns_client(&pending_dns_client, &dns_run_loop);
357   mojom::ResolveHostParametersPtr dns_parameters =
358       mojom::ResolveHostParameters::New();
359   dns_parameters->source = net::HostResolverSource::DNS;
360   resolver.ResolveHost(net::HostPortPair(kDomain, 80),
361                        net::NetworkIsolationKey(), std::move(dns_parameters),
362                        std::move(pending_dns_client));
363 
364   any_run_loop.Run();
365   system_run_loop.Run();
366   dns_run_loop.Run();
367 
368   EXPECT_EQ(net::OK, any_client.result_error());
369   EXPECT_THAT(any_client.result_addresses().value().endpoints(),
370               testing::ElementsAre(CreateExpectedEndPoint(kAnyResult, 80)));
371   EXPECT_EQ(net::OK, system_client.result_error());
372   EXPECT_THAT(system_client.result_addresses().value().endpoints(),
373               testing::ElementsAre(CreateExpectedEndPoint(kSystemResult, 80)));
374   EXPECT_EQ(net::OK, dns_client.result_error());
375   EXPECT_THAT(dns_client.result_addresses().value().endpoints(),
376               testing::ElementsAre(CreateExpectedEndPoint(kDnsResult, 80)));
377 
378 #if BUILDFLAG(ENABLE_MDNS)
379   base::RunLoop mdns_run_loop;
380   mojo::PendingRemote<mojom::ResolveHostClient> pending_mdns_client;
381   TestResolveHostClient mdns_client(&pending_mdns_client, &mdns_run_loop);
382   mojom::ResolveHostParametersPtr mdns_parameters =
383       mojom::ResolveHostParameters::New();
384   mdns_parameters->source = net::HostResolverSource::MULTICAST_DNS;
385   resolver.ResolveHost(net::HostPortPair(kDomain, 80),
386                        net::NetworkIsolationKey(), std::move(mdns_parameters),
387                        std::move(pending_mdns_client));
388 
389   mdns_run_loop.Run();
390 
391   EXPECT_EQ(net::OK, mdns_client.result_error());
392   EXPECT_THAT(mdns_client.result_addresses().value().endpoints(),
393               testing::ElementsAre(CreateExpectedEndPoint(kMdnsResult, 80)));
394 #endif  // BUILDFLAG(ENABLE_MDNS)
395 }
396 
397 // Test that cached results are properly keyed by requested source.
TEST_F(HostResolverTest,SeparateCacheBySource)398 TEST_F(HostResolverTest, SeparateCacheBySource) {
399   constexpr char kDomain[] = "example.com";
400   constexpr char kAnyResultOriginal[] = "1.2.3.4";
401   constexpr char kSystemResultOriginal[] = "127.0.0.1";
402   auto inner_resolver = std::make_unique<net::MockCachingHostResolver>();
403   inner_resolver->rules_map()[net::HostResolverSource::ANY]->AddRule(
404       kDomain, kAnyResultOriginal);
405   inner_resolver->rules_map()[net::HostResolverSource::SYSTEM]->AddRule(
406       kDomain, kSystemResultOriginal);
407 
408   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
409 
410   // Load SYSTEM result into cache.
411   base::RunLoop system_run_loop;
412   mojo::PendingRemote<mojom::ResolveHostClient> pending_system_client_ptr;
413   TestResolveHostClient system_client(&pending_system_client_ptr,
414                                       &system_run_loop);
415   mojom::ResolveHostParametersPtr system_parameters =
416       mojom::ResolveHostParameters::New();
417   system_parameters->source = net::HostResolverSource::SYSTEM;
418   resolver.ResolveHost(net::HostPortPair(kDomain, 80),
419                        net::NetworkIsolationKey(), std::move(system_parameters),
420                        std::move(pending_system_client_ptr));
421   system_run_loop.Run();
422   ASSERT_EQ(net::OK, system_client.result_error());
423   EXPECT_THAT(
424       system_client.result_addresses().value().endpoints(),
425       testing::ElementsAre(CreateExpectedEndPoint(kSystemResultOriginal, 80)));
426 
427   // Change |inner_resolver| rules to ensure results are coming from cache or
428   // not based on whether they resolve to the old or new value.
429   constexpr char kAnyResultFresh[] = "111.222.1.1";
430   constexpr char kSystemResultFresh[] = "111.222.1.2";
431   inner_resolver->rules_map()[net::HostResolverSource::ANY]->ClearRules();
432   inner_resolver->rules_map()[net::HostResolverSource::ANY]->AddRule(
433       kDomain, kAnyResultFresh);
434   inner_resolver->rules_map()[net::HostResolverSource::SYSTEM]->ClearRules();
435   inner_resolver->rules_map()[net::HostResolverSource::SYSTEM]->AddRule(
436       kDomain, kSystemResultFresh);
437 
438   base::RunLoop cached_run_loop;
439   mojo::PendingRemote<mojom::ResolveHostClient> pending_cached_client;
440   TestResolveHostClient cached_client(&pending_cached_client, &cached_run_loop);
441   mojom::ResolveHostParametersPtr cached_parameters =
442       mojom::ResolveHostParameters::New();
443   cached_parameters->source = net::HostResolverSource::SYSTEM;
444   resolver.ResolveHost(net::HostPortPair(kDomain, 80),
445                        net::NetworkIsolationKey(), std::move(cached_parameters),
446                        std::move(pending_cached_client));
447 
448   base::RunLoop uncached_run_loop;
449   mojo::PendingRemote<mojom::ResolveHostClient> pending_uncached_client;
450   TestResolveHostClient uncached_client(&pending_uncached_client,
451                                         &uncached_run_loop);
452   mojom::ResolveHostParametersPtr uncached_parameters =
453       mojom::ResolveHostParameters::New();
454   uncached_parameters->source = net::HostResolverSource::ANY;
455   resolver.ResolveHost(
456       net::HostPortPair(kDomain, 80), net::NetworkIsolationKey(),
457       std::move(uncached_parameters), std::move(pending_uncached_client));
458 
459   cached_run_loop.Run();
460   uncached_run_loop.Run();
461 
462   EXPECT_EQ(net::OK, cached_client.result_error());
463   EXPECT_THAT(
464       cached_client.result_addresses().value().endpoints(),
465       testing::ElementsAre(CreateExpectedEndPoint(kSystemResultOriginal, 80)));
466   EXPECT_EQ(net::OK, uncached_client.result_error());
467   EXPECT_THAT(
468       uncached_client.result_addresses().value().endpoints(),
469       testing::ElementsAre(CreateExpectedEndPoint(kAnyResultFresh, 80)));
470 }
471 
TEST_F(HostResolverTest,CacheDisabled)472 TEST_F(HostResolverTest, CacheDisabled) {
473   constexpr char kDomain[] = "example.com";
474   constexpr char kResultOriginal[] = "1.2.3.4";
475   auto inner_resolver = std::make_unique<net::MockCachingHostResolver>();
476   inner_resolver->rules()->AddRule(kDomain, kResultOriginal);
477 
478   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
479 
480   // Load result into cache.
481   base::RunLoop run_loop;
482   mojo::PendingRemote<mojom::ResolveHostClient> pending_client;
483   TestResolveHostClient client(&pending_client, &run_loop);
484   resolver.ResolveHost(net::HostPortPair(kDomain, 80),
485                        net::NetworkIsolationKey(), nullptr,
486                        std::move(pending_client));
487   run_loop.Run();
488   ASSERT_EQ(net::OK, client.result_error());
489   EXPECT_THAT(
490       client.result_addresses().value().endpoints(),
491       testing::ElementsAre(CreateExpectedEndPoint(kResultOriginal, 80)));
492 
493   // Change |inner_resolver| rules to ensure results are coming from cache or
494   // not based on whether they resolve to the old or new value.
495   constexpr char kResultFresh[] = "111.222.1.1";
496   inner_resolver->rules()->ClearRules();
497   inner_resolver->rules()->AddRule(kDomain, kResultFresh);
498 
499   base::RunLoop cached_run_loop;
500   mojo::PendingRemote<mojom::ResolveHostClient> pending_cached_client;
501   TestResolveHostClient cached_client(&pending_cached_client, &cached_run_loop);
502   mojom::ResolveHostParametersPtr cached_parameters =
503       mojom::ResolveHostParameters::New();
504   cached_parameters->cache_usage =
505       mojom::ResolveHostParameters::CacheUsage::ALLOWED;
506   resolver.ResolveHost(net::HostPortPair(kDomain, 80),
507                        net::NetworkIsolationKey(), std::move(cached_parameters),
508                        std::move(pending_cached_client));
509   cached_run_loop.Run();
510 
511   EXPECT_EQ(net::OK, cached_client.result_error());
512   EXPECT_THAT(
513       cached_client.result_addresses().value().endpoints(),
514       testing::ElementsAre(CreateExpectedEndPoint(kResultOriginal, 80)));
515 
516   base::RunLoop uncached_run_loop;
517   mojo::PendingRemote<mojom::ResolveHostClient> pending_uncached_client;
518   TestResolveHostClient uncached_client(&pending_uncached_client,
519                                         &uncached_run_loop);
520   mojom::ResolveHostParametersPtr uncached_parameters =
521       mojom::ResolveHostParameters::New();
522   uncached_parameters->cache_usage =
523       mojom::ResolveHostParameters::CacheUsage::DISALLOWED;
524   resolver.ResolveHost(
525       net::HostPortPair(kDomain, 80), net::NetworkIsolationKey(),
526       std::move(uncached_parameters), std::move(pending_uncached_client));
527   uncached_run_loop.Run();
528 
529   EXPECT_EQ(net::OK, uncached_client.result_error());
530   EXPECT_THAT(uncached_client.result_addresses().value().endpoints(),
531               testing::ElementsAre(CreateExpectedEndPoint(kResultFresh, 80)));
532 }
533 
TEST_F(HostResolverTest,CacheStaleAllowed)534 TEST_F(HostResolverTest, CacheStaleAllowed) {
535   constexpr char kDomain[] = "example.com";
536   constexpr char kResultOriginal[] = "1.2.3.4";
537   auto inner_resolver = std::make_unique<net::MockCachingHostResolver>();
538   inner_resolver->rules()->AddRule(kDomain, kResultOriginal);
539 
540   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
541 
542   // Load result into cache.
543   base::RunLoop run_loop;
544   mojo::PendingRemote<mojom::ResolveHostClient> pending_client;
545   TestResolveHostClient client(&pending_client, &run_loop);
546   resolver.ResolveHost(net::HostPortPair(kDomain, 80),
547                        net::NetworkIsolationKey(), nullptr,
548                        std::move(pending_client));
549   run_loop.Run();
550   ASSERT_EQ(net::OK, client.result_error());
551   EXPECT_THAT(
552       client.result_addresses().value().endpoints(),
553       testing::ElementsAre(CreateExpectedEndPoint(kResultOriginal, 80)));
554 
555   // Change |inner_resolver| rules to ensure results are coming from cache or
556   // not based on whether they resolve to the old or new value.
557   constexpr char kResultFresh[] = "111.222.1.1";
558   inner_resolver->rules()->ClearRules();
559   inner_resolver->rules()->AddRule(kDomain, kResultFresh);
560 
561   // MockHostResolver gives cache entries a 1 min TTL, so simulate a day
562   // passing, which is more than long enough for the cached results to become
563   // stale.
564   task_environment_.FastForwardBy(base::TimeDelta::FromDays(1));
565 
566   // Fetching stale results returns the original cached value.
567   base::RunLoop cached_run_loop;
568   mojo::PendingRemote<mojom::ResolveHostClient> pending_cached_client;
569   TestResolveHostClient cached_client(&pending_cached_client, &cached_run_loop);
570   mojom::ResolveHostParametersPtr cached_parameters =
571       mojom::ResolveHostParameters::New();
572   cached_parameters->cache_usage =
573       mojom::ResolveHostParameters::CacheUsage::STALE_ALLOWED;
574   resolver.ResolveHost(net::HostPortPair(kDomain, 80),
575                        net::NetworkIsolationKey(), std::move(cached_parameters),
576                        std::move(pending_cached_client));
577   cached_run_loop.Run();
578 
579   EXPECT_EQ(net::OK, cached_client.result_error());
580   EXPECT_THAT(
581       cached_client.result_addresses().value().endpoints(),
582       testing::ElementsAre(CreateExpectedEndPoint(kResultOriginal, 80)));
583 
584   // Resolution where only non-stale cache usage is allowed returns the new
585   // value.
586   base::RunLoop uncached_run_loop;
587   mojo::PendingRemote<mojom::ResolveHostClient> pending_uncached_client;
588   TestResolveHostClient uncached_client(&pending_uncached_client,
589                                         &uncached_run_loop);
590   mojom::ResolveHostParametersPtr uncached_parameters =
591       mojom::ResolveHostParameters::New();
592   uncached_parameters->cache_usage =
593       mojom::ResolveHostParameters::CacheUsage::ALLOWED;
594   resolver.ResolveHost(
595       net::HostPortPair(kDomain, 80), net::NetworkIsolationKey(),
596       std::move(uncached_parameters), std::move(pending_uncached_client));
597   uncached_run_loop.Run();
598 
599   EXPECT_EQ(net::OK, uncached_client.result_error());
600   EXPECT_THAT(uncached_client.result_addresses().value().endpoints(),
601               testing::ElementsAre(CreateExpectedEndPoint(kResultFresh, 80)));
602 }
603 
604 // Test for a resolve with a result only in the cache and error if the cache is
605 // disabled.
TEST_F(HostResolverTest,CacheDisabled_ErrorResults)606 TEST_F(HostResolverTest, CacheDisabled_ErrorResults) {
607   constexpr char kDomain[] = "example.com";
608   constexpr char kResult[] = "1.2.3.4";
609   auto inner_resolver = std::make_unique<net::MockCachingHostResolver>();
610   inner_resolver->rules()->AddRule(kDomain, kResult);
611 
612   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
613 
614   // Load initial result into cache.
615   base::RunLoop run_loop;
616   mojo::PendingRemote<mojom::ResolveHostClient> pending_client;
617   TestResolveHostClient client(&pending_client, &run_loop);
618   resolver.ResolveHost(net::HostPortPair(kDomain, 80),
619                        net::NetworkIsolationKey(), nullptr,
620                        std::move(pending_client));
621   run_loop.Run();
622   ASSERT_EQ(net::OK, client.result_error());
623 
624   // Change |inner_resolver| rules to an error.
625   inner_resolver->rules()->ClearRules();
626   inner_resolver->rules()->AddSimulatedFailure(kDomain);
627 
628   // Resolves for |kFreshErrorDomain| should result in error only when cache is
629   // disabled because success was cached.
630   base::RunLoop cached_run_loop;
631   mojo::PendingRemote<mojom::ResolveHostClient> pending_cached_client;
632   TestResolveHostClient cached_client(&pending_cached_client, &cached_run_loop);
633   mojom::ResolveHostParametersPtr cached_parameters =
634       mojom::ResolveHostParameters::New();
635   cached_parameters->cache_usage =
636       mojom::ResolveHostParameters::CacheUsage::ALLOWED;
637   resolver.ResolveHost(net::HostPortPair(kDomain, 80),
638                        net::NetworkIsolationKey(), std::move(cached_parameters),
639                        std::move(pending_cached_client));
640   cached_run_loop.Run();
641   EXPECT_EQ(net::OK, cached_client.result_error());
642 
643   base::RunLoop uncached_run_loop;
644   mojo::PendingRemote<mojom::ResolveHostClient> pending_uncached_client;
645   TestResolveHostClient uncached_client(&pending_uncached_client,
646                                         &uncached_run_loop);
647   mojom::ResolveHostParametersPtr uncached_parameters =
648       mojom::ResolveHostParameters::New();
649   uncached_parameters->cache_usage =
650       mojom::ResolveHostParameters::CacheUsage::DISALLOWED;
651   resolver.ResolveHost(
652       net::HostPortPair(kDomain, 80), net::NetworkIsolationKey(),
653       std::move(uncached_parameters), std::move(pending_uncached_client));
654   uncached_run_loop.Run();
655   EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, uncached_client.result_error());
656 }
657 
TEST_F(HostResolverTest,IncludeCanonicalName)658 TEST_F(HostResolverTest, IncludeCanonicalName) {
659   auto inner_resolver = std::make_unique<net::MockHostResolver>();
660   inner_resolver->rules()->AddRuleWithFlags("example.com", "123.0.12.24",
661                                             net::HOST_RESOLVER_CANONNAME,
662                                             "canonicalexample.com");
663 
664   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
665 
666   mojom::ResolveHostParametersPtr optional_parameters =
667       mojom::ResolveHostParameters::New();
668   optional_parameters->include_canonical_name = true;
669 
670   base::RunLoop run_loop;
671   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
672   TestResolveHostClient response_client(&pending_response_client, &run_loop);
673 
674   resolver.ResolveHost(
675       net::HostPortPair("example.com", 80), net::NetworkIsolationKey(),
676       std::move(optional_parameters), std::move(pending_response_client));
677   run_loop.Run();
678 
679   EXPECT_EQ(net::OK, response_client.result_error());
680   EXPECT_THAT(response_client.result_addresses().value().endpoints(),
681               testing::ElementsAre(CreateExpectedEndPoint("123.0.12.24", 80)));
682   EXPECT_EQ("canonicalexample.com",
683             response_client.result_addresses().value().canonical_name());
684 }
685 
TEST_F(HostResolverTest,LoopbackOnly)686 TEST_F(HostResolverTest, LoopbackOnly) {
687   auto inner_resolver = std::make_unique<net::MockHostResolver>();
688   inner_resolver->rules()->AddRuleWithFlags("example.com", "127.0.12.24",
689                                             net::HOST_RESOLVER_LOOPBACK_ONLY);
690 
691   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
692 
693   mojom::ResolveHostParametersPtr optional_parameters =
694       mojom::ResolveHostParameters::New();
695   optional_parameters->loopback_only = true;
696 
697   base::RunLoop run_loop;
698   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
699   TestResolveHostClient response_client(&pending_response_client, &run_loop);
700 
701   resolver.ResolveHost(
702       net::HostPortPair("example.com", 80), net::NetworkIsolationKey(),
703       std::move(optional_parameters), std::move(pending_response_client));
704   run_loop.Run();
705 
706   EXPECT_EQ(net::OK, response_client.result_error());
707   EXPECT_THAT(response_client.result_addresses().value().endpoints(),
708               testing::ElementsAre(CreateExpectedEndPoint("127.0.12.24", 80)));
709 }
710 
TEST_F(HostResolverTest,SecureDnsModeOverride)711 TEST_F(HostResolverTest, SecureDnsModeOverride) {
712   auto inner_resolver = std::make_unique<net::MockHostResolver>();
713 
714   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
715 
716   mojom::ResolveHostParametersPtr optional_parameters =
717       mojom::ResolveHostParameters::New();
718   optional_parameters->secure_dns_mode_override =
719       network::mojom::OptionalSecureDnsMode::SECURE;
720 
721   base::RunLoop run_loop;
722   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
723   TestResolveHostClient response_client(&pending_response_client, &run_loop);
724 
725   resolver.ResolveHost(
726       net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
727       std::move(optional_parameters), std::move(pending_response_client));
728   run_loop.Run();
729 
730   EXPECT_EQ(net::OK, response_client.result_error());
731   EXPECT_THAT(response_client.result_addresses().value().endpoints(),
732               testing::ElementsAre(CreateExpectedEndPoint("127.0.0.1", 80)));
733   EXPECT_EQ(net::SecureDnsMode::kSecure,
734             inner_resolver->last_secure_dns_mode_override().value());
735 }
736 
TEST_F(HostResolverTest,Failure_Sync)737 TEST_F(HostResolverTest, Failure_Sync) {
738   auto inner_resolver = std::make_unique<net::MockHostResolver>();
739   inner_resolver->rules()->AddSimulatedFailure("example.com");
740   inner_resolver->set_synchronous_mode(true);
741 
742   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
743 
744   base::RunLoop run_loop;
745   mojo::Remote<mojom::ResolveHostHandle> control_handle;
746   mojom::ResolveHostParametersPtr optional_parameters =
747       mojom::ResolveHostParameters::New();
748   optional_parameters->control_handle =
749       control_handle.BindNewPipeAndPassReceiver();
750   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
751   TestResolveHostClient response_client(&pending_response_client, &run_loop);
752 
753   resolver.ResolveHost(
754       net::HostPortPair("example.com", 160), net::NetworkIsolationKey(),
755       std::move(optional_parameters), std::move(pending_response_client));
756   run_loop.Run();
757 
758   EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED,
759             response_client.top_level_result_error());
760   EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, response_client.result_error());
761   EXPECT_FALSE(response_client.result_addresses());
762   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
763 }
764 
TEST_F(HostResolverTest,Failure_Async)765 TEST_F(HostResolverTest, Failure_Async) {
766   auto inner_resolver = std::make_unique<net::MockHostResolver>();
767   inner_resolver->rules()->AddSimulatedFailure("example.com");
768   inner_resolver->set_synchronous_mode(false);
769 
770   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
771 
772   base::RunLoop run_loop;
773   mojo::Remote<mojom::ResolveHostHandle> control_handle;
774   mojom::ResolveHostParametersPtr optional_parameters =
775       mojom::ResolveHostParameters::New();
776   optional_parameters->control_handle =
777       control_handle.BindNewPipeAndPassReceiver();
778   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
779   TestResolveHostClient response_client(&pending_response_client, &run_loop);
780 
781   resolver.ResolveHost(
782       net::HostPortPair("example.com", 160), net::NetworkIsolationKey(),
783       std::move(optional_parameters), std::move(pending_response_client));
784 
785   bool control_handle_closed = false;
786   auto connection_error_callback =
787       base::BindLambdaForTesting([&]() { control_handle_closed = true; });
788   control_handle.set_disconnect_handler(connection_error_callback);
789   run_loop.Run();
790 
791   EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, response_client.result_error());
792   EXPECT_FALSE(response_client.result_addresses());
793   EXPECT_TRUE(control_handle_closed);
794   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
795 }
796 
TEST_F(HostResolverTest,NetworkIsolationKey)797 TEST_F(HostResolverTest, NetworkIsolationKey) {
798   const url::Origin kOrigin = url::Origin::Create(GURL("https://foo.test/"));
799   const net::NetworkIsolationKey kNetworkIsolationKey(kOrigin, kOrigin);
800 
801   auto inner_resolver = std::make_unique<net::MockHostResolver>();
802 
803   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
804 
805   base::RunLoop run_loop;
806   mojo::Remote<mojom::ResolveHostHandle> control_handle;
807   mojom::ResolveHostParametersPtr optional_parameters =
808       mojom::ResolveHostParameters::New();
809   optional_parameters->control_handle =
810       control_handle.BindNewPipeAndPassReceiver();
811   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
812   TestResolveHostClient response_client(&pending_response_client, &run_loop);
813 
814   resolver.ResolveHost(net::HostPortPair("localhost", 160),
815                        kNetworkIsolationKey, std::move(optional_parameters),
816                        std::move(pending_response_client));
817   run_loop.Run();
818 
819   EXPECT_EQ(net::OK, response_client.result_error());
820   EXPECT_THAT(response_client.result_addresses().value().endpoints(),
821               testing::ElementsAre(CreateExpectedEndPoint("127.0.0.1", 160)));
822   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
823   EXPECT_EQ(kNetworkIsolationKey,
824             inner_resolver->last_request_network_isolation_key());
825 }
826 
TEST_F(HostResolverTest,NoOptionalParameters)827 TEST_F(HostResolverTest, NoOptionalParameters) {
828   std::unique_ptr<net::HostResolver> inner_resolver =
829       net::HostResolver::CreateStandaloneResolver(net::NetLog::Get());
830 
831   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
832 
833   base::RunLoop run_loop;
834   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
835   TestResolveHostClient response_client(&pending_response_client, &run_loop);
836 
837   // Resolve "localhost" because it should always resolve fast and locally, even
838   // when using a real HostResolver.
839   resolver.ResolveHost(net::HostPortPair("localhost", 80),
840                        net::NetworkIsolationKey(), nullptr,
841                        std::move(pending_response_client));
842   run_loop.Run();
843 
844   EXPECT_EQ(net::OK, response_client.result_error());
845   EXPECT_THAT(
846       response_client.result_addresses().value().endpoints(),
847       testing::UnorderedElementsAre(CreateExpectedEndPoint("127.0.0.1", 80),
848                                     CreateExpectedEndPoint("::1", 80)));
849   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
850 }
851 
TEST_F(HostResolverTest,NoControlHandle)852 TEST_F(HostResolverTest, NoControlHandle) {
853   std::unique_ptr<net::HostResolver> inner_resolver =
854       net::HostResolver::CreateStandaloneResolver(net::NetLog::Get());
855 
856   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
857 
858   base::RunLoop run_loop;
859   mojom::ResolveHostParametersPtr optional_parameters =
860       mojom::ResolveHostParameters::New();
861   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
862   TestResolveHostClient response_client(&pending_response_client, &run_loop);
863 
864   // Resolve "localhost" because it should always resolve fast and locally, even
865   // when using a real HostResolver.
866   resolver.ResolveHost(
867       net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
868       std::move(optional_parameters), std::move(pending_response_client));
869   run_loop.Run();
870 
871   EXPECT_EQ(net::OK, response_client.result_error());
872   EXPECT_THAT(
873       response_client.result_addresses().value().endpoints(),
874       testing::UnorderedElementsAre(CreateExpectedEndPoint("127.0.0.1", 80),
875                                     CreateExpectedEndPoint("::1", 80)));
876   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
877 }
878 
TEST_F(HostResolverTest,CloseControlHandle)879 TEST_F(HostResolverTest, CloseControlHandle) {
880   std::unique_ptr<net::HostResolver> inner_resolver =
881       net::HostResolver::CreateStandaloneResolver(net::NetLog::Get());
882 
883   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
884 
885   base::RunLoop run_loop;
886   mojo::Remote<mojom::ResolveHostHandle> control_handle;
887   mojom::ResolveHostParametersPtr optional_parameters =
888       mojom::ResolveHostParameters::New();
889   optional_parameters->control_handle =
890       control_handle.BindNewPipeAndPassReceiver();
891   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
892   TestResolveHostClient response_client(&pending_response_client, &run_loop);
893 
894   // Resolve "localhost" because it should always resolve fast and locally, even
895   // when using a real HostResolver.
896   resolver.ResolveHost(
897       net::HostPortPair("localhost", 160), net::NetworkIsolationKey(),
898       std::move(optional_parameters), std::move(pending_response_client));
899   control_handle.reset();
900   run_loop.Run();
901 
902   EXPECT_EQ(net::OK, response_client.result_error());
903   EXPECT_THAT(
904       response_client.result_addresses().value().endpoints(),
905       testing::UnorderedElementsAre(CreateExpectedEndPoint("127.0.0.1", 160),
906                                     CreateExpectedEndPoint("::1", 160)));
907   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
908 }
909 
TEST_F(HostResolverTest,Cancellation)910 TEST_F(HostResolverTest, Cancellation) {
911   // Use a HangingHostResolver, so the test can ensure the request won't be
912   // completed before the cancellation arrives.
913   auto inner_resolver = std::make_unique<net::HangingHostResolver>();
914 
915   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
916 
917   ASSERT_EQ(0, inner_resolver->num_cancellations());
918 
919   base::RunLoop run_loop;
920   mojo::Remote<mojom::ResolveHostHandle> control_handle;
921   mojom::ResolveHostParametersPtr optional_parameters =
922       mojom::ResolveHostParameters::New();
923   optional_parameters->control_handle =
924       control_handle.BindNewPipeAndPassReceiver();
925   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
926   TestResolveHostClient response_client(&pending_response_client, &run_loop);
927 
928   resolver.ResolveHost(
929       net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
930       std::move(optional_parameters), std::move(pending_response_client));
931   bool control_handle_closed = false;
932   auto connection_error_callback =
933       base::BindLambdaForTesting([&]() { control_handle_closed = true; });
934   control_handle.set_disconnect_handler(connection_error_callback);
935 
936   control_handle->Cancel(net::ERR_ABORTED);
937   run_loop.Run();
938 
939   // On cancellation, should receive an ERR_FAILED result, and the internal
940   // resolver request should have been cancelled.
941   EXPECT_EQ(net::ERR_ABORTED, response_client.result_error());
942   EXPECT_FALSE(response_client.result_addresses());
943   EXPECT_EQ(1, inner_resolver->num_cancellations());
944   EXPECT_TRUE(control_handle_closed);
945   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
946 }
947 
TEST_F(HostResolverTest,Cancellation_SubsequentRequest)948 TEST_F(HostResolverTest, Cancellation_SubsequentRequest) {
949   std::unique_ptr<net::HostResolver> inner_resolver =
950       net::HostResolver::CreateStandaloneResolver(net::NetLog::Get());
951 
952   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
953 
954   base::RunLoop run_loop;
955   mojo::Remote<mojom::ResolveHostHandle> control_handle;
956   mojom::ResolveHostParametersPtr optional_parameters =
957       mojom::ResolveHostParameters::New();
958   optional_parameters->control_handle =
959       control_handle.BindNewPipeAndPassReceiver();
960   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
961   TestResolveHostClient response_client(&pending_response_client, nullptr);
962 
963   resolver.ResolveHost(
964       net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
965       std::move(optional_parameters), std::move(pending_response_client));
966 
967   control_handle->Cancel(net::ERR_ABORTED);
968   run_loop.RunUntilIdle();
969 
970   // Not using a hanging resolver, so could be ERR_ABORTED or OK depending on
971   // timing of the cancellation.
972   EXPECT_TRUE(response_client.result_error() == net::ERR_ABORTED ||
973               response_client.result_error() == net::OK);
974   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
975 
976   // Subsequent requests should be unaffected by the cancellation.
977   base::RunLoop run_loop2;
978   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client2;
979   TestResolveHostClient response_client2(&pending_response_client2, &run_loop2);
980   resolver.ResolveHost(net::HostPortPair("localhost", 80),
981                        net::NetworkIsolationKey(), nullptr,
982                        std::move(pending_response_client2));
983   run_loop2.Run();
984 
985   EXPECT_EQ(net::OK, response_client2.result_error());
986   EXPECT_THAT(
987       response_client2.result_addresses().value().endpoints(),
988       testing::UnorderedElementsAre(CreateExpectedEndPoint("127.0.0.1", 80),
989                                     CreateExpectedEndPoint("::1", 80)));
990   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
991 }
992 
TEST_F(HostResolverTest,DestroyResolver)993 TEST_F(HostResolverTest, DestroyResolver) {
994   // Use a HangingHostResolver, so the test can ensure the request won't be
995   // completed before the cancellation arrives.
996   auto inner_resolver = std::make_unique<net::HangingHostResolver>();
997 
998   auto resolver =
999       std::make_unique<HostResolver>(inner_resolver.get(), net::NetLog::Get());
1000 
1001   ASSERT_EQ(0, inner_resolver->num_cancellations());
1002 
1003   base::RunLoop run_loop;
1004   mojo::Remote<mojom::ResolveHostHandle> control_handle;
1005   mojom::ResolveHostParametersPtr optional_parameters =
1006       mojom::ResolveHostParameters::New();
1007   optional_parameters->control_handle =
1008       control_handle.BindNewPipeAndPassReceiver();
1009   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
1010   TestResolveHostClient response_client(&pending_response_client, &run_loop);
1011 
1012   resolver->ResolveHost(
1013       net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
1014       std::move(optional_parameters), std::move(pending_response_client));
1015   bool control_handle_closed = false;
1016   auto connection_error_callback =
1017       base::BindLambdaForTesting([&]() { control_handle_closed = true; });
1018   control_handle.set_disconnect_handler(connection_error_callback);
1019 
1020   resolver = nullptr;
1021   run_loop.Run();
1022 
1023   // On context destruction, should receive an ERR_FAILED result, and the
1024   // internal resolver request should have been cancelled.
1025   EXPECT_EQ(net::ERR_FAILED, response_client.result_error());
1026   EXPECT_FALSE(response_client.result_addresses());
1027   EXPECT_EQ(1, inner_resolver->num_cancellations());
1028   EXPECT_TRUE(control_handle_closed);
1029 }
1030 
TEST_F(HostResolverTest,CloseClient)1031 TEST_F(HostResolverTest, CloseClient) {
1032   // Use a HangingHostResolver, so the test can ensure the request won't be
1033   // completed before the cancellation arrives.
1034   auto inner_resolver = std::make_unique<net::HangingHostResolver>();
1035 
1036   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
1037 
1038   ASSERT_EQ(0, inner_resolver->num_cancellations());
1039 
1040   base::RunLoop run_loop;
1041   mojo::Remote<mojom::ResolveHostHandle> control_handle;
1042   mojom::ResolveHostParametersPtr optional_parameters =
1043       mojom::ResolveHostParameters::New();
1044   optional_parameters->control_handle =
1045       control_handle.BindNewPipeAndPassReceiver();
1046   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
1047   TestResolveHostClient response_client(&pending_response_client, &run_loop);
1048 
1049   resolver.ResolveHost(
1050       net::HostPortPair("localhost", 80), net::NetworkIsolationKey(),
1051       std::move(optional_parameters), std::move(pending_response_client));
1052   bool control_handle_closed = false;
1053   auto connection_error_callback =
1054       base::BindLambdaForTesting([&]() { control_handle_closed = true; });
1055   control_handle.set_disconnect_handler(connection_error_callback);
1056 
1057   response_client.CloseReceiver();
1058   run_loop.RunUntilIdle();
1059 
1060   // Response pipe is closed, so no results to check. Internal request should be
1061   // cancelled.
1062   EXPECT_FALSE(response_client.complete());
1063   EXPECT_EQ(1, inner_resolver->num_cancellations());
1064   EXPECT_TRUE(control_handle_closed);
1065   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
1066 }
1067 
TEST_F(HostResolverTest,CloseClient_SubsequentRequest)1068 TEST_F(HostResolverTest, CloseClient_SubsequentRequest) {
1069   std::unique_ptr<net::HostResolver> inner_resolver =
1070       net::HostResolver::CreateStandaloneResolver(net::NetLog::Get());
1071 
1072   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
1073 
1074   base::RunLoop run_loop;
1075   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
1076   TestResolveHostClient response_client(&pending_response_client, nullptr);
1077 
1078   resolver.ResolveHost(net::HostPortPair("localhost", 80),
1079                        net::NetworkIsolationKey(), nullptr,
1080                        std::move(pending_response_client));
1081 
1082   response_client.CloseReceiver();
1083   run_loop.RunUntilIdle();
1084 
1085   // Not using a hanging resolver, so could be incomplete or OK depending on
1086   // timing of the cancellation.
1087   EXPECT_TRUE(!response_client.complete() ||
1088               response_client.result_error() == net::OK);
1089   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
1090 
1091   // Subsequent requests should be unaffected by the cancellation.
1092   base::RunLoop run_loop2;
1093   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client2;
1094   TestResolveHostClient response_client2(&pending_response_client2, &run_loop2);
1095   resolver.ResolveHost(net::HostPortPair("localhost", 80),
1096                        net::NetworkIsolationKey(), nullptr,
1097                        std::move(pending_response_client2));
1098   run_loop2.Run();
1099 
1100   EXPECT_EQ(net::OK, response_client2.result_error());
1101   EXPECT_THAT(
1102       response_client2.result_addresses().value().endpoints(),
1103       testing::UnorderedElementsAre(CreateExpectedEndPoint("127.0.0.1", 80),
1104                                     CreateExpectedEndPoint("::1", 80)));
1105   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
1106 }
1107 
TEST_F(HostResolverTest,Binding)1108 TEST_F(HostResolverTest, Binding) {
1109   mojo::Remote<mojom::HostResolver> resolver_remote;
1110   HostResolver* shutdown_resolver = nullptr;
1111   HostResolver::ConnectionShutdownCallback shutdown_callback =
1112       base::BindLambdaForTesting(
1113           [&](HostResolver* resolver) { shutdown_resolver = resolver; });
1114 
1115   std::unique_ptr<net::HostResolver> inner_resolver =
1116       net::HostResolver::CreateStandaloneResolver(net::NetLog::Get());
1117 
1118   HostResolver resolver(resolver_remote.BindNewPipeAndPassReceiver(),
1119                         std::move(shutdown_callback), inner_resolver.get(),
1120                         net::NetLog::Get());
1121 
1122   base::RunLoop run_loop;
1123   mojo::Remote<mojom::ResolveHostHandle> control_handle;
1124   mojom::ResolveHostParametersPtr optional_parameters =
1125       mojom::ResolveHostParameters::New();
1126   optional_parameters->control_handle =
1127       control_handle.BindNewPipeAndPassReceiver();
1128   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
1129   TestResolveHostClient response_client(&pending_response_client, &run_loop);
1130 
1131   // Resolve "localhost" because it should always resolve fast and locally, even
1132   // when using a real HostResolver.
1133   resolver_remote->ResolveHost(
1134       net::HostPortPair("localhost", 160), net::NetworkIsolationKey(),
1135       std::move(optional_parameters), std::move(pending_response_client));
1136   run_loop.Run();
1137 
1138   EXPECT_EQ(net::OK, response_client.result_error());
1139   EXPECT_THAT(
1140       response_client.result_addresses().value().endpoints(),
1141       testing::UnorderedElementsAre(CreateExpectedEndPoint("127.0.0.1", 160),
1142                                     CreateExpectedEndPoint("::1", 160)));
1143   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
1144   EXPECT_FALSE(shutdown_resolver);
1145 }
1146 
TEST_F(HostResolverTest,CloseBinding)1147 TEST_F(HostResolverTest, CloseBinding) {
1148   mojo::Remote<mojom::HostResolver> resolver_remote;
1149   HostResolver* shutdown_resolver = nullptr;
1150   HostResolver::ConnectionShutdownCallback shutdown_callback =
1151       base::BindLambdaForTesting(
1152           [&](HostResolver* resolver) { shutdown_resolver = resolver; });
1153 
1154   // Use a HangingHostResolver, so the test can ensure the request won't be
1155   // completed before the cancellation arrives.
1156   auto inner_resolver = std::make_unique<net::HangingHostResolver>();
1157 
1158   HostResolver resolver(resolver_remote.BindNewPipeAndPassReceiver(),
1159                         std::move(shutdown_callback), inner_resolver.get(),
1160                         net::NetLog::Get());
1161 
1162   ASSERT_EQ(0, inner_resolver->num_cancellations());
1163 
1164   base::RunLoop run_loop;
1165   mojo::Remote<mojom::ResolveHostHandle> control_handle;
1166   mojom::ResolveHostParametersPtr optional_parameters =
1167       mojom::ResolveHostParameters::New();
1168   optional_parameters->control_handle =
1169       control_handle.BindNewPipeAndPassReceiver();
1170   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
1171   TestResolveHostClient response_client(&pending_response_client, &run_loop);
1172   resolver_remote->ResolveHost(
1173       net::HostPortPair("localhost", 160), net::NetworkIsolationKey(),
1174       std::move(optional_parameters), std::move(pending_response_client));
1175   bool control_handle_closed = false;
1176   auto connection_error_callback =
1177       base::BindLambdaForTesting([&]() { control_handle_closed = true; });
1178   control_handle.set_disconnect_handler(connection_error_callback);
1179 
1180   resolver_remote.reset();
1181   run_loop.Run();
1182 
1183   // Request should be cancelled.
1184   EXPECT_EQ(net::ERR_FAILED, response_client.result_error());
1185   EXPECT_FALSE(response_client.result_addresses());
1186   EXPECT_TRUE(control_handle_closed);
1187   EXPECT_EQ(1, inner_resolver->num_cancellations());
1188   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
1189 
1190   // Callback should have been called.
1191   EXPECT_EQ(&resolver, shutdown_resolver);
1192 }
1193 
TEST_F(HostResolverTest,CloseBinding_SubsequentRequest)1194 TEST_F(HostResolverTest, CloseBinding_SubsequentRequest) {
1195   mojo::Remote<mojom::HostResolver> resolver_remote;
1196   HostResolver* shutdown_resolver = nullptr;
1197   HostResolver::ConnectionShutdownCallback shutdown_callback =
1198       base::BindLambdaForTesting(
1199           [&](HostResolver* resolver) { shutdown_resolver = resolver; });
1200 
1201   std::unique_ptr<net::HostResolver> inner_resolver =
1202       net::HostResolver::CreateStandaloneResolver(net::NetLog::Get());
1203 
1204   HostResolver resolver(resolver_remote.BindNewPipeAndPassReceiver(),
1205                         std::move(shutdown_callback), inner_resolver.get(),
1206                         net::NetLog::Get());
1207 
1208   base::RunLoop run_loop;
1209   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
1210   TestResolveHostClient response_client(&pending_response_client, nullptr);
1211   resolver_remote->ResolveHost(net::HostPortPair("localhost", 160),
1212                                net::NetworkIsolationKey(), nullptr,
1213                                std::move(pending_response_client));
1214 
1215   resolver_remote.reset();
1216   run_loop.RunUntilIdle();
1217 
1218   // Not using a hanging resolver, so could be ERR_FAILED or OK depending on
1219   // timing of the cancellation.
1220   EXPECT_TRUE(response_client.result_error() == net::ERR_FAILED ||
1221               response_client.result_error() == net::OK);
1222   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
1223 
1224   // Callback should have been called.
1225   EXPECT_EQ(&resolver, shutdown_resolver);
1226 
1227   // Subsequent requests should be unaffected by the cancellation.
1228   base::RunLoop run_loop2;
1229   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client2;
1230   TestResolveHostClient response_client2(&pending_response_client2, &run_loop2);
1231   resolver.ResolveHost(net::HostPortPair("localhost", 80),
1232                        net::NetworkIsolationKey(), nullptr,
1233                        std::move(pending_response_client2));
1234   run_loop2.Run();
1235 
1236   EXPECT_EQ(net::OK, response_client2.result_error());
1237   EXPECT_THAT(
1238       response_client2.result_addresses().value().endpoints(),
1239       testing::UnorderedElementsAre(CreateExpectedEndPoint("127.0.0.1", 80),
1240                                     CreateExpectedEndPoint("::1", 80)));
1241   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
1242 }
1243 
TEST_F(HostResolverTest,IsSpeculative)1244 TEST_F(HostResolverTest, IsSpeculative) {
1245   std::unique_ptr<net::HostResolver> inner_resolver =
1246       net::HostResolver::CreateStandaloneResolver(net::NetLog::Get());
1247 
1248   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
1249 
1250   base::RunLoop run_loop;
1251   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
1252   TestResolveHostClient response_client(&pending_response_client, &run_loop);
1253   mojom::ResolveHostParametersPtr parameters =
1254       mojom::ResolveHostParameters::New();
1255   parameters->is_speculative = true;
1256 
1257   // Resolve "localhost" because it should always resolve fast and locally, even
1258   // when using a real HostResolver.
1259   resolver.ResolveHost(net::HostPortPair("localhost", 80),
1260                        net::NetworkIsolationKey(), std::move(parameters),
1261                        std::move(pending_response_client));
1262   run_loop.Run();
1263 
1264   EXPECT_EQ(net::OK, response_client.result_error());
1265   EXPECT_FALSE(response_client.result_addresses());
1266   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
1267 }
1268 
CreateValidDnsConfig()1269 net::DnsConfig CreateValidDnsConfig() {
1270   net::IPAddress dns_ip(192, 168, 1, 0);
1271   net::DnsConfig config;
1272   config.nameservers.push_back(
1273       net::IPEndPoint(dns_ip, net::dns_protocol::kDefaultPort));
1274   EXPECT_TRUE(config.IsValid());
1275   return config;
1276 }
1277 
TEST_F(HostResolverTest,TextResults)1278 TEST_F(HostResolverTest, TextResults) {
1279   static const char* kTextRecords[] = {"foo", "bar", "more text"};
1280   net::MockDnsClientRuleList rules;
1281   rules.emplace_back(
1282       "example.com", net::dns_protocol::kTypeTXT, false /* secure */,
1283       net::MockDnsClientRule::Result(net::BuildTestDnsTextResponse(
1284           "example.com", {std::vector<std::string>(std::begin(kTextRecords),
1285                                                    std::end(kTextRecords))})),
1286       false /* delay */);
1287   auto dns_client = std::make_unique<net::MockDnsClient>(CreateValidDnsConfig(),
1288                                                          std::move(rules));
1289   dns_client->set_ignore_system_config_changes(true);
1290 
1291   std::unique_ptr<net::ContextHostResolver> inner_resolver =
1292       net::HostResolver::CreateStandaloneContextResolver(net::NetLog::Get());
1293   inner_resolver->GetManagerForTesting()->SetDnsClientForTesting(
1294       std::move(dns_client));
1295   inner_resolver->GetManagerForTesting()->SetInsecureDnsClientEnabled(true);
1296 
1297   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
1298 
1299   base::RunLoop run_loop;
1300   mojom::ResolveHostParametersPtr optional_parameters =
1301       mojom::ResolveHostParameters::New();
1302   optional_parameters->dns_query_type = net::DnsQueryType::TXT;
1303   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
1304   TestResolveHostClient response_client(&pending_response_client, &run_loop);
1305 
1306   resolver.ResolveHost(
1307       net::HostPortPair("example.com", 160), net::NetworkIsolationKey(),
1308       std::move(optional_parameters), std::move(pending_response_client));
1309   run_loop.Run();
1310 
1311   EXPECT_EQ(net::OK, response_client.result_error());
1312   EXPECT_FALSE(response_client.result_addresses());
1313   EXPECT_THAT(response_client.result_text(),
1314               testing::Optional(testing::ElementsAreArray(kTextRecords)));
1315   EXPECT_FALSE(response_client.result_hosts());
1316   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
1317 }
1318 
TEST_F(HostResolverTest,HostResults)1319 TEST_F(HostResolverTest, HostResults) {
1320   net::MockDnsClientRuleList rules;
1321   rules.emplace_back(
1322       "example.com", net::dns_protocol::kTypePTR, false /*secure */,
1323       net::MockDnsClientRule::Result(net::BuildTestDnsPointerResponse(
1324           "example.com", {"google.com", "chromium.org"})),
1325       false /* delay */);
1326   auto dns_client = std::make_unique<net::MockDnsClient>(CreateValidDnsConfig(),
1327                                                          std::move(rules));
1328   dns_client->set_ignore_system_config_changes(true);
1329 
1330   std::unique_ptr<net::ContextHostResolver> inner_resolver =
1331       net::HostResolver::CreateStandaloneContextResolver(net::NetLog::Get());
1332   inner_resolver->GetManagerForTesting()->SetDnsClientForTesting(
1333       std::move(dns_client));
1334   inner_resolver->GetManagerForTesting()->SetInsecureDnsClientEnabled(true);
1335 
1336   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
1337 
1338   base::RunLoop run_loop;
1339   mojom::ResolveHostParametersPtr optional_parameters =
1340       mojom::ResolveHostParameters::New();
1341   optional_parameters->dns_query_type = net::DnsQueryType::PTR;
1342   mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client;
1343   TestResolveHostClient response_client(&pending_response_client, &run_loop);
1344 
1345   resolver.ResolveHost(
1346       net::HostPortPair("example.com", 160), net::NetworkIsolationKey(),
1347       std::move(optional_parameters), std::move(pending_response_client));
1348   run_loop.Run();
1349 
1350   EXPECT_EQ(net::OK, response_client.result_error());
1351   EXPECT_FALSE(response_client.result_addresses());
1352   EXPECT_FALSE(response_client.result_text());
1353   EXPECT_THAT(response_client.result_hosts(),
1354               testing::Optional(testing::UnorderedElementsAre(
1355                   net::HostPortPair("google.com", 160),
1356                   net::HostPortPair("chromium.org", 160))));
1357   EXPECT_EQ(0u, resolver.GetNumOutstandingRequestsForTesting());
1358 }
1359 
1360 #if BUILDFLAG(ENABLE_MDNS)
TEST_F(HostResolverTest,MdnsListener_AddressResult)1361 TEST_F(HostResolverTest, MdnsListener_AddressResult) {
1362   auto inner_resolver = std::make_unique<net::MockHostResolver>();
1363   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
1364 
1365   mojo::PendingRemote<mojom::MdnsListenClient> pending_response_client;
1366   TestMdnsListenClient response_client(&pending_response_client);
1367 
1368   int error = net::ERR_FAILED;
1369   base::RunLoop run_loop;
1370   net::HostPortPair host("host.local", 41);
1371   resolver.MdnsListen(host, net::DnsQueryType::A,
1372                       std::move(pending_response_client),
1373                       base::BindLambdaForTesting([&](int error_val) {
1374                         error = error_val;
1375                         run_loop.Quit();
1376                       }));
1377 
1378   run_loop.Run();
1379   ASSERT_EQ(net::OK, error);
1380 
1381   net::IPAddress result_address(1, 2, 3, 4);
1382   net::IPEndPoint result(result_address, 41);
1383   inner_resolver->TriggerMdnsListeners(
1384       host, net::DnsQueryType::A,
1385       net::HostResolver::MdnsListener::Delegate::UpdateType::ADDED, result);
1386   base::RunLoop().RunUntilIdle();
1387 
1388   EXPECT_THAT(response_client.address_results(),
1389               testing::ElementsAre(TestMdnsListenClient::CreateExpectedResult(
1390                   net::HostResolver::MdnsListener::Delegate::UpdateType::ADDED,
1391                   net::DnsQueryType::A, result)));
1392 
1393   EXPECT_THAT(response_client.text_results(), testing::IsEmpty());
1394   EXPECT_THAT(response_client.hostname_results(), testing::IsEmpty());
1395   EXPECT_THAT(response_client.unhandled_results(), testing::IsEmpty());
1396 }
1397 
TEST_F(HostResolverTest,MdnsListener_TextResult)1398 TEST_F(HostResolverTest, MdnsListener_TextResult) {
1399   auto inner_resolver = std::make_unique<net::MockHostResolver>();
1400   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
1401 
1402   mojo::PendingRemote<mojom::MdnsListenClient> pending_response_client;
1403   TestMdnsListenClient response_client(&pending_response_client);
1404 
1405   int error = net::ERR_FAILED;
1406   base::RunLoop run_loop;
1407   net::HostPortPair host("host.local", 42);
1408   resolver.MdnsListen(host, net::DnsQueryType::TXT,
1409                       std::move(pending_response_client),
1410                       base::BindLambdaForTesting([&](int error_val) {
1411                         error = error_val;
1412                         run_loop.Quit();
1413                       }));
1414 
1415   run_loop.Run();
1416   ASSERT_EQ(net::OK, error);
1417 
1418   inner_resolver->TriggerMdnsListeners(
1419       host, net::DnsQueryType::TXT,
1420       net::HostResolver::MdnsListener::Delegate::UpdateType::CHANGED,
1421       {"foo", "bar"});
1422   base::RunLoop().RunUntilIdle();
1423 
1424   EXPECT_THAT(
1425       response_client.text_results(),
1426       testing::UnorderedElementsAre(
1427           TestMdnsListenClient::CreateExpectedResult(
1428               net::HostResolver::MdnsListener::Delegate::UpdateType::CHANGED,
1429               net::DnsQueryType::TXT, "foo"),
1430           TestMdnsListenClient::CreateExpectedResult(
1431               net::HostResolver::MdnsListener::Delegate::UpdateType::CHANGED,
1432               net::DnsQueryType::TXT, "bar")));
1433 
1434   EXPECT_THAT(response_client.address_results(), testing::IsEmpty());
1435   EXPECT_THAT(response_client.hostname_results(), testing::IsEmpty());
1436   EXPECT_THAT(response_client.unhandled_results(), testing::IsEmpty());
1437 }
1438 
TEST_F(HostResolverTest,MdnsListener_HostnameResult)1439 TEST_F(HostResolverTest, MdnsListener_HostnameResult) {
1440   auto inner_resolver = std::make_unique<net::MockHostResolver>();
1441   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
1442 
1443   mojo::PendingRemote<mojom::MdnsListenClient> pending_response_client;
1444   TestMdnsListenClient response_client(&pending_response_client);
1445 
1446   int error = net::ERR_FAILED;
1447   base::RunLoop run_loop;
1448   net::HostPortPair host("host.local", 43);
1449   resolver.MdnsListen(host, net::DnsQueryType::PTR,
1450                       std::move(pending_response_client),
1451                       base::BindLambdaForTesting([&](int error_val) {
1452                         error = error_val;
1453                         run_loop.Quit();
1454                       }));
1455 
1456   run_loop.Run();
1457   ASSERT_EQ(net::OK, error);
1458 
1459   net::HostPortPair result("example.com", 43);
1460   inner_resolver->TriggerMdnsListeners(
1461       host, net::DnsQueryType::PTR,
1462       net::HostResolver::MdnsListener::Delegate::UpdateType::REMOVED, result);
1463   base::RunLoop().RunUntilIdle();
1464 
1465   EXPECT_THAT(
1466       response_client.hostname_results(),
1467       testing::ElementsAre(TestMdnsListenClient::CreateExpectedResult(
1468           net::HostResolver::MdnsListener::Delegate::UpdateType::REMOVED,
1469           net::DnsQueryType::PTR, result)));
1470 
1471   EXPECT_THAT(response_client.address_results(), testing::IsEmpty());
1472   EXPECT_THAT(response_client.text_results(), testing::IsEmpty());
1473   EXPECT_THAT(response_client.unhandled_results(), testing::IsEmpty());
1474 }
1475 
TEST_F(HostResolverTest,MdnsListener_UnhandledResult)1476 TEST_F(HostResolverTest, MdnsListener_UnhandledResult) {
1477   auto inner_resolver = std::make_unique<net::MockHostResolver>();
1478   HostResolver resolver(inner_resolver.get(), net::NetLog::Get());
1479 
1480   mojo::PendingRemote<mojom::MdnsListenClient> pending_response_client;
1481   TestMdnsListenClient response_client(&pending_response_client);
1482 
1483   int error = net::ERR_FAILED;
1484   base::RunLoop run_loop;
1485   net::HostPortPair host("host.local", 44);
1486   resolver.MdnsListen(host, net::DnsQueryType::PTR,
1487                       std::move(pending_response_client),
1488                       base::BindLambdaForTesting([&](int error_val) {
1489                         error = error_val;
1490                         run_loop.Quit();
1491                       }));
1492 
1493   run_loop.Run();
1494   ASSERT_EQ(net::OK, error);
1495 
1496   inner_resolver->TriggerMdnsListeners(
1497       host, net::DnsQueryType::PTR,
1498       net::HostResolver::MdnsListener::Delegate::UpdateType::ADDED);
1499   base::RunLoop().RunUntilIdle();
1500 
1501   EXPECT_THAT(response_client.unhandled_results(),
1502               testing::ElementsAre(std::make_pair(
1503                   net::HostResolver::MdnsListener::Delegate::UpdateType::ADDED,
1504                   net::DnsQueryType::PTR)));
1505 
1506   EXPECT_THAT(response_client.address_results(), testing::IsEmpty());
1507   EXPECT_THAT(response_client.text_results(), testing::IsEmpty());
1508   EXPECT_THAT(response_client.hostname_results(), testing::IsEmpty());
1509 }
1510 #endif  // BUILDFLAG(ENABLE_MDNS)
1511 
1512 }  // namespace
1513 }  // namespace network
1514