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