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"
22 void Fail(int result
) {
23 FAIL() << "Unexpected callback called with error " << result
;
26 class MockMojoHostResolverRequest
{
28 MockMojoHostResolverRequest(interfaces::HostResolverRequestClientPtr client
,
29 const base::Closure
& error_callback
);
30 void OnConnectionError();
33 interfaces::HostResolverRequestClientPtr client_
;
34 const base::Closure error_callback_
;
37 MockMojoHostResolverRequest::MockMojoHostResolverRequest(
38 interfaces::HostResolverRequestClientPtr client
,
39 const base::Closure
& error_callback
)
40 : client_(client
.Pass()), error_callback_(error_callback
) {
41 client_
.set_connection_error_handler(base::Bind(
42 &MockMojoHostResolverRequest::OnConnectionError
, base::Unretained(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 HostResolverMojo::Impl
{
88 explicit MockMojoHostResolver(
89 const base::Closure
& request_connection_error_callback
);
90 ~MockMojoHostResolver() override
;
92 void AddAction(scoped_ptr
<HostResolverAction
> action
);
94 const mojo::Array
<interfaces::HostResolverRequestInfoPtr
>& requests() {
95 return requests_received_
;
98 void ResolveDns(interfaces::HostResolverRequestInfoPtr request_info
,
99 interfaces::HostResolverRequestClientPtr client
) override
;
102 ScopedVector
<HostResolverAction
> actions_
;
103 size_t results_returned_
= 0;
104 mojo::Array
<interfaces::HostResolverRequestInfoPtr
> requests_received_
;
105 const base::Closure request_connection_error_callback_
;
106 ScopedVector
<MockMojoHostResolverRequest
> requests_
;
109 MockMojoHostResolver::MockMojoHostResolver(
110 const base::Closure
& request_connection_error_callback
)
111 : request_connection_error_callback_(request_connection_error_callback
) {
114 MockMojoHostResolver::~MockMojoHostResolver() {
115 EXPECT_EQ(results_returned_
, actions_
.size());
118 void MockMojoHostResolver::AddAction(scoped_ptr
<HostResolverAction
> action
) {
119 actions_
.push_back(action
.Pass());
122 void MockMojoHostResolver::ResolveDns(
123 interfaces::HostResolverRequestInfoPtr request_info
,
124 interfaces::HostResolverRequestClientPtr client
) {
125 requests_received_
.push_back(request_info
.Pass());
126 ASSERT_LE(results_returned_
, actions_
.size());
127 switch (actions_
[results_returned_
]->action
) {
128 case HostResolverAction::COMPLETE
:
129 client
->ReportResult(actions_
[results_returned_
]->error
,
130 actions_
[results_returned_
]->addresses
.Pass());
132 case HostResolverAction::RETAIN
:
133 requests_
.push_back(new MockMojoHostResolverRequest(
134 client
.Pass(), request_connection_error_callback_
));
136 case HostResolverAction::DROP
:
145 class HostResolverMojoTest
: public testing::Test
{
147 enum class ConnectionErrorSource
{
150 using Waiter
= EventWaiter
<ConnectionErrorSource
>;
152 void SetUp() override
{
153 mock_resolver_
.reset(new MockMojoHostResolver(
154 base::Bind(&Waiter::NotifyEvent
, base::Unretained(&waiter_
),
155 ConnectionErrorSource::REQUEST
)));
156 resolver_
.reset(new HostResolverMojo(mock_resolver_
.get()));
159 int Resolve(const HostResolver::RequestInfo
& request_info
,
160 AddressList
* result
) {
161 HostResolver::RequestHandle request_handle
= nullptr;
162 TestCompletionCallback callback
;
163 return callback
.GetResult(resolver_
->Resolve(
164 request_info
, DEFAULT_PRIORITY
, result
, callback
.callback(),
165 &request_handle
, BoundNetLog()));
168 scoped_ptr
<MockMojoHostResolver
> mock_resolver_
;
170 scoped_ptr
<HostResolverMojo
> resolver_
;
175 TEST_F(HostResolverMojoTest
, Basic
) {
176 AddressList address_list
;
177 IPAddressNumber address_number
;
178 ASSERT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &address_number
));
179 address_list
.push_back(IPEndPoint(address_number
, 12345));
180 address_list
.push_back(
181 IPEndPoint(ConvertIPv4NumberToIPv6Number(address_number
), 12345));
182 mock_resolver_
->AddAction(HostResolverAction::ReturnResult(address_list
));
183 HostResolver::RequestInfo
request_info(
184 HostPortPair::FromString("example.com:12345"));
186 EXPECT_EQ(OK
, Resolve(request_info
, &result
));
187 ASSERT_EQ(2u, result
.size());
188 EXPECT_EQ(address_list
[0], result
[0]);
189 EXPECT_EQ(address_list
[1], result
[1]);
191 ASSERT_EQ(1u, mock_resolver_
->requests().size());
192 interfaces::HostResolverRequestInfo
& request
= *mock_resolver_
->requests()[0];
193 EXPECT_EQ("example.com", request
.host
.To
<std::string
>());
194 EXPECT_EQ(12345, request
.port
);
195 EXPECT_EQ(interfaces::ADDRESS_FAMILY_UNSPECIFIED
, request
.address_family
);
196 EXPECT_FALSE(request
.is_my_ip_address
);
199 TEST_F(HostResolverMojoTest
, ResolveCachedResult
) {
200 AddressList address_list
;
201 IPAddressNumber address_number
;
202 ASSERT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &address_number
));
203 address_list
.push_back(IPEndPoint(address_number
, 12345));
204 address_list
.push_back(
205 IPEndPoint(ConvertIPv4NumberToIPv6Number(address_number
), 12345));
206 mock_resolver_
->AddAction(HostResolverAction::ReturnResult(address_list
));
207 HostResolver::RequestInfo
request_info(
208 HostPortPair::FromString("example.com:12345"));
210 ASSERT_EQ(OK
, Resolve(request_info
, &result
));
211 ASSERT_EQ(1u, mock_resolver_
->requests().size());
214 request_info
.set_host_port_pair(HostPortPair::FromString("example.com:6789"));
215 EXPECT_EQ(OK
, Resolve(request_info
, &result
));
216 ASSERT_EQ(2u, result
.size());
217 address_list
.clear();
218 address_list
.push_back(IPEndPoint(address_number
, 6789));
219 address_list
.push_back(
220 IPEndPoint(ConvertIPv4NumberToIPv6Number(address_number
), 6789));
221 EXPECT_EQ(address_list
[0], result
[0]);
222 EXPECT_EQ(address_list
[1], result
[1]);
223 EXPECT_EQ(1u, mock_resolver_
->requests().size());
225 mock_resolver_
->AddAction(HostResolverAction::ReturnResult(address_list
));
227 request_info
.set_allow_cached_response(false);
228 EXPECT_EQ(OK
, Resolve(request_info
, &result
));
229 ASSERT_EQ(2u, result
.size());
230 EXPECT_EQ(address_list
[0], result
[0]);
231 EXPECT_EQ(address_list
[1], result
[1]);
232 EXPECT_EQ(2u, mock_resolver_
->requests().size());
235 TEST_F(HostResolverMojoTest
, Multiple
) {
236 AddressList address_list
;
237 IPAddressNumber address_number
;
238 ASSERT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &address_number
));
239 address_list
.push_back(IPEndPoint(address_number
, 12345));
240 mock_resolver_
->AddAction(HostResolverAction::ReturnResult(address_list
));
241 mock_resolver_
->AddAction(
242 HostResolverAction::ReturnError(ERR_NAME_NOT_RESOLVED
));
243 HostResolver::RequestInfo
request_info1(
244 HostPortPair::FromString("example.com:12345"));
245 request_info1
.set_address_family(ADDRESS_FAMILY_IPV4
);
246 request_info1
.set_is_my_ip_address(true);
247 HostResolver::RequestInfo
request_info2(
248 HostPortPair::FromString("example.org:80"));
249 request_info2
.set_address_family(ADDRESS_FAMILY_IPV6
);
252 HostResolver::RequestHandle request_handle1
= nullptr;
253 HostResolver::RequestHandle request_handle2
= nullptr;
254 TestCompletionCallback callback1
;
255 TestCompletionCallback callback2
;
256 ASSERT_EQ(ERR_IO_PENDING
,
257 resolver_
->Resolve(request_info1
, DEFAULT_PRIORITY
, &result1
,
258 callback1
.callback(), &request_handle1
,
260 ASSERT_EQ(ERR_IO_PENDING
,
261 resolver_
->Resolve(request_info2
, DEFAULT_PRIORITY
, &result2
,
262 callback2
.callback(), &request_handle2
,
264 EXPECT_EQ(OK
, callback1
.GetResult(ERR_IO_PENDING
));
265 EXPECT_EQ(ERR_NAME_NOT_RESOLVED
, callback2
.GetResult(ERR_IO_PENDING
));
266 ASSERT_EQ(1u, result1
.size());
267 EXPECT_EQ(address_list
[0], result1
[0]);
268 ASSERT_EQ(0u, result2
.size());
270 ASSERT_EQ(2u, mock_resolver_
->requests().size());
271 interfaces::HostResolverRequestInfo
& request1
=
272 *mock_resolver_
->requests()[0];
273 EXPECT_EQ("example.com", request1
.host
.To
<std::string
>());
274 EXPECT_EQ(12345, request1
.port
);
275 EXPECT_EQ(interfaces::ADDRESS_FAMILY_IPV4
, request1
.address_family
);
276 EXPECT_TRUE(request1
.is_my_ip_address
);
277 interfaces::HostResolverRequestInfo
& request2
=
278 *mock_resolver_
->requests()[1];
279 EXPECT_EQ("example.org", request2
.host
.To
<std::string
>());
280 EXPECT_EQ(80, request2
.port
);
281 EXPECT_EQ(interfaces::ADDRESS_FAMILY_IPV6
, request2
.address_family
);
282 EXPECT_FALSE(request2
.is_my_ip_address
);
285 TEST_F(HostResolverMojoTest
, Error
) {
286 mock_resolver_
->AddAction(
287 HostResolverAction::ReturnError(ERR_NAME_NOT_RESOLVED
));
288 HostResolver::RequestInfo
request_info(
289 HostPortPair::FromString("example.com:8080"));
290 request_info
.set_address_family(ADDRESS_FAMILY_IPV4
);
292 EXPECT_EQ(ERR_NAME_NOT_RESOLVED
, Resolve(request_info
, &result
));
293 EXPECT_TRUE(result
.empty());
295 ASSERT_EQ(1u, mock_resolver_
->requests().size());
296 interfaces::HostResolverRequestInfo
& request
= *mock_resolver_
->requests()[0];
297 EXPECT_EQ("example.com", request
.host
.To
<std::string
>());
298 EXPECT_EQ(8080, request
.port
);
299 EXPECT_EQ(interfaces::ADDRESS_FAMILY_IPV4
, request
.address_family
);
300 EXPECT_FALSE(request
.is_my_ip_address
);
303 TEST_F(HostResolverMojoTest
, EmptyResult
) {
304 mock_resolver_
->AddAction(HostResolverAction::ReturnError(OK
));
305 HostResolver::RequestInfo
request_info(
306 HostPortPair::FromString("example.com:8080"));
308 EXPECT_EQ(OK
, Resolve(request_info
, &result
));
309 EXPECT_TRUE(result
.empty());
311 ASSERT_EQ(1u, mock_resolver_
->requests().size());
314 TEST_F(HostResolverMojoTest
, Cancel
) {
315 mock_resolver_
->AddAction(HostResolverAction::RetainRequest());
316 HostResolver::RequestInfo
request_info(
317 HostPortPair::FromString("example.com:80"));
318 request_info
.set_address_family(ADDRESS_FAMILY_IPV6
);
320 HostResolver::RequestHandle request_handle
= nullptr;
321 resolver_
->Resolve(request_info
, DEFAULT_PRIORITY
, &result
, base::Bind(&Fail
),
322 &request_handle
, BoundNetLog());
323 resolver_
->CancelRequest(request_handle
);
324 waiter_
.WaitForEvent(ConnectionErrorSource::REQUEST
);
325 EXPECT_TRUE(result
.empty());
327 ASSERT_EQ(1u, mock_resolver_
->requests().size());
328 interfaces::HostResolverRequestInfo
& request
= *mock_resolver_
->requests()[0];
329 EXPECT_EQ("example.com", request
.host
.To
<std::string
>());
330 EXPECT_EQ(80, request
.port
);
331 EXPECT_EQ(interfaces::ADDRESS_FAMILY_IPV6
, request
.address_family
);
332 EXPECT_FALSE(request
.is_my_ip_address
);
335 TEST_F(HostResolverMojoTest
, ImplDropsClientConnection
) {
336 mock_resolver_
->AddAction(HostResolverAction::DropRequest());
337 HostResolver::RequestInfo
request_info(
338 HostPortPair::FromString("example.com:1"));
340 EXPECT_EQ(ERR_FAILED
, Resolve(request_info
, &result
));
341 EXPECT_TRUE(result
.empty());
343 ASSERT_EQ(1u, mock_resolver_
->requests().size());
344 interfaces::HostResolverRequestInfo
& request
= *mock_resolver_
->requests()[0];
345 EXPECT_EQ("example.com", request
.host
.To
<std::string
>());
346 EXPECT_EQ(1, request
.port
);
347 EXPECT_EQ(interfaces::ADDRESS_FAMILY_UNSPECIFIED
, request
.address_family
);
348 EXPECT_FALSE(request
.is_my_ip_address
);
351 TEST_F(HostResolverMojoTest
, ResolveFromCache_Miss
) {
352 HostResolver::RequestInfo
request_info(
353 HostPortPair::FromString("example.com:8080"));
355 EXPECT_EQ(ERR_DNS_CACHE_MISS
,
356 resolver_
->ResolveFromCache(request_info
, &result
, BoundNetLog()));
357 EXPECT_TRUE(result
.empty());
360 TEST_F(HostResolverMojoTest
, ResolveFromCache_Hit
) {
361 AddressList address_list
;
362 IPAddressNumber address_number
;
363 ASSERT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &address_number
));
364 address_list
.push_back(IPEndPoint(address_number
, 12345));
365 address_list
.push_back(
366 IPEndPoint(ConvertIPv4NumberToIPv6Number(address_number
), 12345));
367 mock_resolver_
->AddAction(HostResolverAction::ReturnResult(address_list
));
368 HostResolver::RequestInfo
request_info(
369 HostPortPair::FromString("example.com:12345"));
371 ASSERT_EQ(OK
, Resolve(request_info
, &result
));
372 EXPECT_EQ(1u, mock_resolver_
->requests().size());
376 resolver_
->ResolveFromCache(request_info
, &result
, BoundNetLog()));
377 ASSERT_EQ(2u, result
.size());
378 EXPECT_EQ(address_list
[0], result
[0]);
379 EXPECT_EQ(address_list
[1], result
[1]);
380 EXPECT_EQ(1u, mock_resolver_
->requests().size());
383 TEST_F(HostResolverMojoTest
, ResolveFromCache_CacheNotAllowed
) {
384 AddressList address_list
;
385 IPAddressNumber address_number
;
386 ASSERT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &address_number
));
387 address_list
.push_back(IPEndPoint(address_number
, 12345));
388 address_list
.push_back(
389 IPEndPoint(ConvertIPv4NumberToIPv6Number(address_number
), 12345));
390 mock_resolver_
->AddAction(HostResolverAction::ReturnResult(address_list
));
391 HostResolver::RequestInfo
request_info(
392 HostPortPair::FromString("example.com:12345"));
394 ASSERT_EQ(OK
, Resolve(request_info
, &result
));
395 EXPECT_EQ(1u, mock_resolver_
->requests().size());
398 request_info
.set_allow_cached_response(false);
399 EXPECT_EQ(ERR_DNS_CACHE_MISS
,
400 resolver_
->ResolveFromCache(request_info
, &result
, BoundNetLog()));
401 EXPECT_TRUE(result
.empty());
404 TEST_F(HostResolverMojoTest
, GetHostCache
) {
405 EXPECT_TRUE(resolver_
->GetHostCache());