1 // Copyright 2015 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.
5 #include "net/dns/host_resolver_mojo.h"
9 #include "base/memory/scoped_vector.h"
10 #include "net/base/address_list.h"
11 #include "net/base/net_errors.h"
12 #include "net/base/request_priority.h"
13 #include "net/base/test_completion_callback.h"
14 #include "net/dns/mojo_host_type_converters.h"
15 #include "net/test/event_waiter.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
18 #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h"
23 void Fail(int result
) {
24 FAIL() << "Unexpected callback called with error " << result
;
27 class MockMojoHostResolverRequest
: public mojo::ErrorHandler
{
29 MockMojoHostResolverRequest(interfaces::HostResolverRequestClientPtr client
,
30 const base::Closure
& error_callback
);
31 void OnConnectionError() override
;
34 interfaces::HostResolverRequestClientPtr client_
;
35 const base::Closure error_callback_
;
38 MockMojoHostResolverRequest::MockMojoHostResolverRequest(
39 interfaces::HostResolverRequestClientPtr client
,
40 const base::Closure
& error_callback
)
41 : client_(client
.Pass()), error_callback_(error_callback
) {
42 client_
.set_error_handler(this);
45 void MockMojoHostResolverRequest::OnConnectionError() {
46 error_callback_
.Run();
49 struct HostResolverAction
{
56 static scoped_ptr
<HostResolverAction
> ReturnError(Error error
) {
57 scoped_ptr
<HostResolverAction
> result(new HostResolverAction
);
58 result
->error
= error
;
62 static scoped_ptr
<HostResolverAction
> ReturnResult(
63 const AddressList
& address_list
) {
64 scoped_ptr
<HostResolverAction
> result(new HostResolverAction
);
65 result
->addresses
= interfaces::AddressList::From(address_list
);
69 static scoped_ptr
<HostResolverAction
> DropRequest() {
70 scoped_ptr
<HostResolverAction
> result(new HostResolverAction
);
71 result
->action
= DROP
;
75 static scoped_ptr
<HostResolverAction
> RetainRequest() {
76 scoped_ptr
<HostResolverAction
> result(new HostResolverAction
);
77 result
->action
= RETAIN
;
81 Action action
= COMPLETE
;
82 interfaces::AddressListPtr addresses
;
86 class MockMojoHostResolver
: public interfaces::HostResolver
,
87 public mojo::ErrorHandler
{
89 MockMojoHostResolver(mojo::InterfaceRequest
<interfaces::HostResolver
> request
,
90 const base::Closure
& resolver_connection_error_callback
,
91 const base::Closure
& request_connection_error_callback
);
92 ~MockMojoHostResolver() override
;
94 void AddAction(scoped_ptr
<HostResolverAction
> action
);
96 const mojo::Array
<interfaces::HostResolverRequestInfoPtr
>& requests() {
97 return requests_received_
;
101 // interfaces::HostResolver override.
102 void Resolve(interfaces::HostResolverRequestInfoPtr request_info
,
103 interfaces::HostResolverRequestClientPtr client
) override
;
105 // mojo::ErrorHandler override.
106 void OnConnectionError() override
;
108 mojo::Binding
<interfaces::HostResolver
> binding_
;
109 ScopedVector
<HostResolverAction
> actions_
;
110 size_t results_returned_
= 0;
111 mojo::Array
<interfaces::HostResolverRequestInfoPtr
> requests_received_
;
112 const base::Closure resolver_connection_error_callback_
;
113 const base::Closure request_connection_error_callback_
;
114 ScopedVector
<MockMojoHostResolverRequest
> requests_
;
117 MockMojoHostResolver::MockMojoHostResolver(
118 mojo::InterfaceRequest
<interfaces::HostResolver
> request
,
119 const base::Closure
& resolver_connection_error_callback
,
120 const base::Closure
& request_connection_error_callback
)
121 : binding_(this, request
.Pass()),
122 resolver_connection_error_callback_(resolver_connection_error_callback
),
123 request_connection_error_callback_(request_connection_error_callback
) {
124 binding_
.set_error_handler(this);
127 MockMojoHostResolver::~MockMojoHostResolver() {
128 EXPECT_EQ(results_returned_
, actions_
.size());
131 void MockMojoHostResolver::OnConnectionError() {
132 resolver_connection_error_callback_
.Run();
135 void MockMojoHostResolver::AddAction(scoped_ptr
<HostResolverAction
> action
) {
136 actions_
.push_back(action
.release());
139 void MockMojoHostResolver::Resolve(
140 interfaces::HostResolverRequestInfoPtr request_info
,
141 interfaces::HostResolverRequestClientPtr client
) {
142 requests_received_
.push_back(request_info
.Pass());
143 ASSERT_LE(results_returned_
, actions_
.size());
144 switch (actions_
[results_returned_
]->action
) {
145 case HostResolverAction::COMPLETE
:
146 client
->ReportResult(actions_
[results_returned_
]->error
,
147 actions_
[results_returned_
]->addresses
.Pass());
149 case HostResolverAction::RETAIN
:
150 requests_
.push_back(new MockMojoHostResolverRequest(
151 client
.Pass(), request_connection_error_callback_
));
153 case HostResolverAction::DROP
:
162 class HostResolverMojoTest
: public testing::Test
{
164 enum class ConnectionErrorSource
{
169 using Waiter
= EventWaiter
<ConnectionErrorSource
>;
171 void SetUp() override
{
172 interfaces::HostResolverPtr resolver_ptr
;
173 mock_resolver_
.reset(new MockMojoHostResolver(
174 mojo::GetProxy(&resolver_ptr
),
175 base::Bind(&Waiter::NotifyEvent
, base::Unretained(&waiter_
),
176 ConnectionErrorSource::RESOLVER
),
177 base::Bind(&Waiter::NotifyEvent
, base::Unretained(&waiter_
),
178 ConnectionErrorSource::REQUEST
)));
179 resolver_
.reset(new HostResolverMojo(
181 base::Bind(&Waiter::NotifyEvent
, base::Unretained(&waiter_
),
182 ConnectionErrorSource::CLIENT
)));
185 int Resolve(const HostResolver::RequestInfo
& request_info
,
186 AddressList
* result
) {
187 HostResolver::RequestHandle request_handle
= nullptr;
188 TestCompletionCallback callback
;
189 return callback
.GetResult(resolver_
->Resolve(
190 request_info
, DEFAULT_PRIORITY
, result
, callback
.callback(),
191 &request_handle
, BoundNetLog()));
194 scoped_ptr
<MockMojoHostResolver
> mock_resolver_
;
196 scoped_ptr
<HostResolverMojo
> resolver_
;
201 TEST_F(HostResolverMojoTest
, Basic
) {
202 AddressList address_list
;
203 IPAddressNumber address_number
;
204 ASSERT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &address_number
));
205 address_list
.push_back(IPEndPoint(address_number
, 12345));
206 address_list
.push_back(
207 IPEndPoint(ConvertIPv4NumberToIPv6Number(address_number
), 12345));
208 mock_resolver_
->AddAction(HostResolverAction::ReturnResult(address_list
));
209 HostResolver::RequestInfo
request_info(
210 HostPortPair::FromString("example.com:12345"));
212 EXPECT_EQ(OK
, Resolve(request_info
, &result
));
213 ASSERT_EQ(2u, result
.size());
214 EXPECT_EQ(address_list
[0], result
[0]);
215 EXPECT_EQ(address_list
[1], result
[1]);
217 ASSERT_EQ(1u, mock_resolver_
->requests().size());
218 interfaces::HostResolverRequestInfo
& request
= *mock_resolver_
->requests()[0];
219 EXPECT_EQ("example.com", request
.host
.To
<std::string
>());
220 EXPECT_EQ(12345, request
.port
);
221 EXPECT_EQ(interfaces::ADDRESS_FAMILY_UNSPECIFIED
, request
.address_family
);
222 EXPECT_FALSE(request
.is_my_ip_address
);
225 TEST_F(HostResolverMojoTest
, ResolveCachedResult
) {
226 AddressList address_list
;
227 IPAddressNumber address_number
;
228 ASSERT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &address_number
));
229 address_list
.push_back(IPEndPoint(address_number
, 12345));
230 address_list
.push_back(
231 IPEndPoint(ConvertIPv4NumberToIPv6Number(address_number
), 12345));
232 mock_resolver_
->AddAction(HostResolverAction::ReturnResult(address_list
));
233 HostResolver::RequestInfo
request_info(
234 HostPortPair::FromString("example.com:12345"));
236 ASSERT_EQ(OK
, Resolve(request_info
, &result
));
237 ASSERT_EQ(1u, mock_resolver_
->requests().size());
240 request_info
.set_host_port_pair(HostPortPair::FromString("example.com:6789"));
241 EXPECT_EQ(OK
, Resolve(request_info
, &result
));
242 ASSERT_EQ(2u, result
.size());
243 address_list
.clear();
244 address_list
.push_back(IPEndPoint(address_number
, 6789));
245 address_list
.push_back(
246 IPEndPoint(ConvertIPv4NumberToIPv6Number(address_number
), 6789));
247 EXPECT_EQ(address_list
[0], result
[0]);
248 EXPECT_EQ(address_list
[1], result
[1]);
249 EXPECT_EQ(1u, mock_resolver_
->requests().size());
251 mock_resolver_
->AddAction(HostResolverAction::ReturnResult(address_list
));
253 request_info
.set_allow_cached_response(false);
254 EXPECT_EQ(OK
, Resolve(request_info
, &result
));
255 ASSERT_EQ(2u, result
.size());
256 EXPECT_EQ(address_list
[0], result
[0]);
257 EXPECT_EQ(address_list
[1], result
[1]);
258 EXPECT_EQ(2u, mock_resolver_
->requests().size());
261 TEST_F(HostResolverMojoTest
, Multiple
) {
262 AddressList address_list
;
263 IPAddressNumber address_number
;
264 ASSERT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &address_number
));
265 address_list
.push_back(IPEndPoint(address_number
, 12345));
266 mock_resolver_
->AddAction(HostResolverAction::ReturnResult(address_list
));
267 mock_resolver_
->AddAction(
268 HostResolverAction::ReturnError(ERR_NAME_NOT_RESOLVED
));
269 HostResolver::RequestInfo
request_info1(
270 HostPortPair::FromString("example.com:12345"));
271 request_info1
.set_address_family(ADDRESS_FAMILY_IPV4
);
272 request_info1
.set_is_my_ip_address(true);
273 HostResolver::RequestInfo
request_info2(
274 HostPortPair::FromString("example.org:80"));
275 request_info2
.set_address_family(ADDRESS_FAMILY_IPV6
);
278 HostResolver::RequestHandle request_handle1
= nullptr;
279 HostResolver::RequestHandle request_handle2
= nullptr;
280 TestCompletionCallback callback1
;
281 TestCompletionCallback callback2
;
282 ASSERT_EQ(ERR_IO_PENDING
,
283 resolver_
->Resolve(request_info1
, DEFAULT_PRIORITY
, &result1
,
284 callback1
.callback(), &request_handle1
,
286 ASSERT_EQ(ERR_IO_PENDING
,
287 resolver_
->Resolve(request_info2
, DEFAULT_PRIORITY
, &result2
,
288 callback2
.callback(), &request_handle2
,
290 EXPECT_EQ(OK
, callback1
.GetResult(ERR_IO_PENDING
));
291 EXPECT_EQ(ERR_NAME_NOT_RESOLVED
, callback2
.GetResult(ERR_IO_PENDING
));
292 ASSERT_EQ(1u, result1
.size());
293 EXPECT_EQ(address_list
[0], result1
[0]);
294 ASSERT_EQ(0u, result2
.size());
296 ASSERT_EQ(2u, mock_resolver_
->requests().size());
297 interfaces::HostResolverRequestInfo
& request1
=
298 *mock_resolver_
->requests()[0];
299 EXPECT_EQ("example.com", request1
.host
.To
<std::string
>());
300 EXPECT_EQ(12345, request1
.port
);
301 EXPECT_EQ(interfaces::ADDRESS_FAMILY_IPV4
, request1
.address_family
);
302 EXPECT_TRUE(request1
.is_my_ip_address
);
303 interfaces::HostResolverRequestInfo
& request2
=
304 *mock_resolver_
->requests()[1];
305 EXPECT_EQ("example.org", request2
.host
.To
<std::string
>());
306 EXPECT_EQ(80, request2
.port
);
307 EXPECT_EQ(interfaces::ADDRESS_FAMILY_IPV6
, request2
.address_family
);
308 EXPECT_FALSE(request2
.is_my_ip_address
);
311 TEST_F(HostResolverMojoTest
, Error
) {
312 mock_resolver_
->AddAction(
313 HostResolverAction::ReturnError(ERR_NAME_NOT_RESOLVED
));
314 HostResolver::RequestInfo
request_info(
315 HostPortPair::FromString("example.com:8080"));
316 request_info
.set_address_family(ADDRESS_FAMILY_IPV4
);
318 EXPECT_EQ(ERR_NAME_NOT_RESOLVED
, Resolve(request_info
, &result
));
319 EXPECT_TRUE(result
.empty());
321 ASSERT_EQ(1u, mock_resolver_
->requests().size());
322 interfaces::HostResolverRequestInfo
& request
= *mock_resolver_
->requests()[0];
323 EXPECT_EQ("example.com", request
.host
.To
<std::string
>());
324 EXPECT_EQ(8080, request
.port
);
325 EXPECT_EQ(interfaces::ADDRESS_FAMILY_IPV4
, request
.address_family
);
326 EXPECT_FALSE(request
.is_my_ip_address
);
329 TEST_F(HostResolverMojoTest
, EmptyResult
) {
330 mock_resolver_
->AddAction(HostResolverAction::ReturnError(OK
));
331 HostResolver::RequestInfo
request_info(
332 HostPortPair::FromString("example.com:8080"));
334 EXPECT_EQ(OK
, Resolve(request_info
, &result
));
335 EXPECT_TRUE(result
.empty());
337 ASSERT_EQ(1u, mock_resolver_
->requests().size());
340 TEST_F(HostResolverMojoTest
, Cancel
) {
341 mock_resolver_
->AddAction(HostResolverAction::RetainRequest());
342 HostResolver::RequestInfo
request_info(
343 HostPortPair::FromString("example.com:80"));
344 request_info
.set_address_family(ADDRESS_FAMILY_IPV6
);
346 HostResolver::RequestHandle request_handle
= nullptr;
347 resolver_
->Resolve(request_info
, DEFAULT_PRIORITY
, &result
, base::Bind(&Fail
),
348 &request_handle
, BoundNetLog());
349 resolver_
->CancelRequest(request_handle
);
350 waiter_
.WaitForEvent(ConnectionErrorSource::REQUEST
);
351 EXPECT_TRUE(result
.empty());
353 ASSERT_EQ(1u, mock_resolver_
->requests().size());
354 interfaces::HostResolverRequestInfo
& request
= *mock_resolver_
->requests()[0];
355 EXPECT_EQ("example.com", request
.host
.To
<std::string
>());
356 EXPECT_EQ(80, request
.port
);
357 EXPECT_EQ(interfaces::ADDRESS_FAMILY_IPV6
, request
.address_family
);
358 EXPECT_FALSE(request
.is_my_ip_address
);
361 TEST_F(HostResolverMojoTest
, ImplDropsClientConnection
) {
362 mock_resolver_
->AddAction(HostResolverAction::DropRequest());
363 HostResolver::RequestInfo
request_info(
364 HostPortPair::FromString("example.com:1"));
366 EXPECT_EQ(ERR_FAILED
, Resolve(request_info
, &result
));
367 EXPECT_TRUE(result
.empty());
369 ASSERT_EQ(1u, mock_resolver_
->requests().size());
370 interfaces::HostResolverRequestInfo
& request
= *mock_resolver_
->requests()[0];
371 EXPECT_EQ("example.com", request
.host
.To
<std::string
>());
372 EXPECT_EQ(1, request
.port
);
373 EXPECT_EQ(interfaces::ADDRESS_FAMILY_UNSPECIFIED
, request
.address_family
);
374 EXPECT_FALSE(request
.is_my_ip_address
);
377 TEST_F(HostResolverMojoTest
, DestroyImpl
) {
378 mock_resolver_
.reset();
379 waiter_
.WaitForEvent(ConnectionErrorSource::CLIENT
);
382 TEST_F(HostResolverMojoTest
, DestroyClient
) {
384 waiter_
.WaitForEvent(ConnectionErrorSource::RESOLVER
);
387 TEST_F(HostResolverMojoTest
, ResolveFromCache_Miss
) {
388 HostResolver::RequestInfo
request_info(
389 HostPortPair::FromString("example.com:8080"));
391 EXPECT_EQ(ERR_DNS_CACHE_MISS
,
392 resolver_
->ResolveFromCache(request_info
, &result
, BoundNetLog()));
393 EXPECT_TRUE(result
.empty());
396 TEST_F(HostResolverMojoTest
, ResolveFromCache_Hit
) {
397 AddressList address_list
;
398 IPAddressNumber address_number
;
399 ASSERT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &address_number
));
400 address_list
.push_back(IPEndPoint(address_number
, 12345));
401 address_list
.push_back(
402 IPEndPoint(ConvertIPv4NumberToIPv6Number(address_number
), 12345));
403 mock_resolver_
->AddAction(HostResolverAction::ReturnResult(address_list
));
404 HostResolver::RequestInfo
request_info(
405 HostPortPair::FromString("example.com:12345"));
407 ASSERT_EQ(OK
, Resolve(request_info
, &result
));
408 EXPECT_EQ(1u, mock_resolver_
->requests().size());
412 resolver_
->ResolveFromCache(request_info
, &result
, BoundNetLog()));
413 ASSERT_EQ(2u, result
.size());
414 EXPECT_EQ(address_list
[0], result
[0]);
415 EXPECT_EQ(address_list
[1], result
[1]);
416 EXPECT_EQ(1u, mock_resolver_
->requests().size());
419 TEST_F(HostResolverMojoTest
, ResolveFromCache_CacheNotAllowed
) {
420 AddressList address_list
;
421 IPAddressNumber address_number
;
422 ASSERT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &address_number
));
423 address_list
.push_back(IPEndPoint(address_number
, 12345));
424 address_list
.push_back(
425 IPEndPoint(ConvertIPv4NumberToIPv6Number(address_number
), 12345));
426 mock_resolver_
->AddAction(HostResolverAction::ReturnResult(address_list
));
427 HostResolver::RequestInfo
request_info(
428 HostPortPair::FromString("example.com:12345"));
430 ASSERT_EQ(OK
, Resolve(request_info
, &result
));
431 EXPECT_EQ(1u, mock_resolver_
->requests().size());
434 request_info
.set_allow_cached_response(false);
435 EXPECT_EQ(ERR_DNS_CACHE_MISS
,
436 resolver_
->ResolveFromCache(request_info
, &result
, BoundNetLog()));
437 EXPECT_TRUE(result
.empty());
440 TEST_F(HostResolverMojoTest
, GetHostCache
) {
441 EXPECT_TRUE(resolver_
->GetHostCache());