Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / net / dns / host_resolver_mojo_unittest.cc
blob209bda88a812cf1396d9251dde1525c585b4d714
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"
7 #include <string>
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"
19 namespace net {
20 namespace {
22 void Fail(int result) {
23 FAIL() << "Unexpected callback called with error " << result;
26 class MockMojoHostResolverRequest {
27 public:
28 MockMojoHostResolverRequest(interfaces::HostResolverRequestClientPtr client,
29 const base::Closure& error_callback);
30 void OnConnectionError();
32 private:
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 {
50 enum Action {
51 COMPLETE,
52 DROP,
53 RETAIN,
56 static scoped_ptr<HostResolverAction> ReturnError(Error error) {
57 scoped_ptr<HostResolverAction> result(new HostResolverAction);
58 result->error = error;
59 return result.Pass();
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);
66 return result.Pass();
69 static scoped_ptr<HostResolverAction> DropRequest() {
70 scoped_ptr<HostResolverAction> result(new HostResolverAction);
71 result->action = DROP;
72 return result.Pass();
75 static scoped_ptr<HostResolverAction> RetainRequest() {
76 scoped_ptr<HostResolverAction> result(new HostResolverAction);
77 result->action = RETAIN;
78 return result.Pass();
81 Action action = COMPLETE;
82 interfaces::AddressListPtr addresses;
83 Error error = OK;
86 class MockMojoHostResolver : public HostResolverMojo::Impl {
87 public:
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;
101 private:
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());
131 break;
132 case HostResolverAction::RETAIN:
133 requests_.push_back(new MockMojoHostResolverRequest(
134 client.Pass(), request_connection_error_callback_));
135 break;
136 case HostResolverAction::DROP:
137 client.reset();
138 break;
140 results_returned_++;
143 } // namespace
145 class HostResolverMojoTest : public testing::Test {
146 protected:
147 enum class ConnectionErrorSource {
148 REQUEST,
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_;
172 Waiter waiter_;
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"));
185 AddressList result;
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"));
209 AddressList result;
210 ASSERT_EQ(OK, Resolve(request_info, &result));
211 ASSERT_EQ(1u, mock_resolver_->requests().size());
213 result.clear();
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));
226 result.clear();
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);
250 AddressList result1;
251 AddressList result2;
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,
259 BoundNetLog()));
260 ASSERT_EQ(ERR_IO_PENDING,
261 resolver_->Resolve(request_info2, DEFAULT_PRIORITY, &result2,
262 callback2.callback(), &request_handle2,
263 BoundNetLog()));
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);
291 AddressList result;
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"));
307 AddressList result;
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);
319 AddressList result;
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"));
339 AddressList result;
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"));
354 AddressList result;
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"));
370 AddressList result;
371 ASSERT_EQ(OK, Resolve(request_info, &result));
372 EXPECT_EQ(1u, mock_resolver_->requests().size());
374 result.clear();
375 EXPECT_EQ(OK,
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"));
393 AddressList result;
394 ASSERT_EQ(OK, Resolve(request_info, &result));
395 EXPECT_EQ(1u, mock_resolver_->requests().size());
397 result.clear();
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());
408 } // namespace net