Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Side by Side Diff: net/dns/host_resolver_mojo_unittest.cc

Issue 904313003: Implement utility-side host resolver Mojo client. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mojo-proxy-resolver
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "net/dns/host_resolver_mojo.h"
6
7 #include <string>
8
9 #include "base/barrier_closure.h"
10 #include "base/memory/scoped_vector.h"
11 #include "base/run_loop.h"
12 #include "net/base/net_errors.h"
13 #include "net/base/request_priority.h"
14 #include "net/dns/type_converters.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
17 #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h"
18
19 namespace net {
20 namespace {
21
22 enum class ConnectionErrorSource {
23 NONE,
24 RESOLVER,
25 REQUEST,
26 CLIENT,
27 };
28
29 void OnResolveComplete(int* error_out,
30 const base::Closure& quit_run_loop,
31 int error) {
32 if (!quit_run_loop.is_null())
33 quit_run_loop.Run();
34 *error_out = error;
35 }
36
37 void Fail(int result) {
38 FAIL() << "Unexpected callback called with error " << result;
39 }
40
41 class MockMojoHostResolverRequest : public mojo::ErrorHandler {
42 public:
43 MockMojoHostResolverRequest(interfaces::HostResolverRequestClientPtr client,
44 const base::Closure& error_callback);
45 void OnConnectionError() override;
46
47 private:
48 interfaces::HostResolverRequestClientPtr client_;
49 const base::Closure error_callback_;
50 };
51
52 MockMojoHostResolverRequest::MockMojoHostResolverRequest(
53 interfaces::HostResolverRequestClientPtr client,
54 const base::Closure& error_callback)
55 : client_(client.Pass()), error_callback_(error_callback) {
56 client_.set_error_handler(this);
57 }
58
59 void MockMojoHostResolverRequest::OnConnectionError() {
60 error_callback_.Run();
61 }
62
63 struct HostResolverAction {
64 public:
65 enum Action {
66 COMPLETE,
67 DROP,
68 RETAIN,
69 };
70
71 static scoped_ptr<HostResolverAction> ReturnError(int error) {
72 scoped_ptr<HostResolverAction> result(new HostResolverAction);
73 result->error = error;
74 return result.Pass();
75 }
76
77 static scoped_ptr<HostResolverAction> ReturnResult(
78 const AddressList& address_list) {
79 scoped_ptr<HostResolverAction> result(new HostResolverAction);
80 result->addresses = interfaces::AddressList::From(address_list);
81 return result.Pass();
82 }
83
84 static scoped_ptr<HostResolverAction> DropRequest() {
85 scoped_ptr<HostResolverAction> result(new HostResolverAction);
86 result->action = DROP;
87 return result.Pass();
88 }
89
90 static scoped_ptr<HostResolverAction> RetainRequest() {
91 scoped_ptr<HostResolverAction> result(new HostResolverAction);
92 result->action = RETAIN;
93 return result.Pass();
94 }
95
96 Action action = COMPLETE;
97 interfaces::AddressListPtr addresses;
98 int error = OK;
99 };
100
101 class MockMojoHostResolver : public interfaces::HostResolver,
102 public mojo::ErrorHandler {
103 public:
104 explicit MockMojoHostResolver(
Anand Mistry (off Chromium) 2015/02/16 06:32:44 Can you add a destructor that does: ASSERT_EQ(resu
Sam McNally 2015/02/16 07:24:44 Done.
105 mojo::InterfaceRequest<interfaces::HostResolver> request,
106 const base::Closure& resolver_connection_error_callback,
107 const base::Closure& request_connection_error_callback);
108
109 void AddAction(scoped_ptr<HostResolverAction> action);
110
111 const mojo::Array<interfaces::HostResolverRequestInfoPtr>& requests() {
112 return requests_received_;
113 }
114
115 private:
116 // interfaces::HostResolver override.
117 void Resolve(interfaces::HostResolverRequestInfoPtr request_info,
118 interfaces::HostResolverRequestClientPtr client) override;
119
120 // mojo::ErrorHandler override.
121 void OnConnectionError() override;
122
123 mojo::Binding<interfaces::HostResolver> binding_;
124 ScopedVector<HostResolverAction> actions_;
125 size_t results_returned_ = 0;
126 mojo::Array<interfaces::HostResolverRequestInfoPtr> requests_received_;
127 const base::Closure resolver_connection_error_callback_;
128 const base::Closure request_connection_error_callback_;
129 ScopedVector<MockMojoHostResolverRequest> requests_;
130 };
131
132 MockMojoHostResolver::MockMojoHostResolver(
133 mojo::InterfaceRequest<interfaces::HostResolver> request,
134 const base::Closure& resolver_connection_error_callback,
135 const base::Closure& request_connection_error_callback)
136 : binding_(this, request.Pass()),
137 resolver_connection_error_callback_(resolver_connection_error_callback),
138 request_connection_error_callback_(request_connection_error_callback) {
139 binding_.set_error_handler(this);
140 }
141
142 void MockMojoHostResolver::OnConnectionError() {
143 resolver_connection_error_callback_.Run();
144 }
145
146 void MockMojoHostResolver::AddAction(scoped_ptr<HostResolverAction> action) {
147 actions_.push_back(action.release());
148 }
149
150 void MockMojoHostResolver::Resolve(
151 interfaces::HostResolverRequestInfoPtr request_info,
152 interfaces::HostResolverRequestClientPtr client) {
153 requests_received_.push_back(request_info.Pass());
154 ASSERT_LE(results_returned_, actions_.size());
155 switch (actions_[results_returned_]->action) {
156 case HostResolverAction::COMPLETE:
157 client->ReportResult(actions_[results_returned_]->error,
158 actions_[results_returned_]->addresses.Pass());
159 break;
160 case HostResolverAction::RETAIN:
161 requests_.push_back(new MockMojoHostResolverRequest(
162 client.Pass(), request_connection_error_callback_));
163 break;
164 case HostResolverAction::DROP:
165 client.reset();
166 break;
167 }
168 results_returned_++;
169 }
170
171 } // namespace
172
173 class HostResolverMojoTest : public testing::Test, public mojo::ErrorHandler {
174 protected:
175 void SetUp() override {
176 interfaces::HostResolverPtr resolver_ptr;
177 mock_resolver_.reset(new MockMojoHostResolver(
178 mojo::GetProxy(&resolver_ptr),
179 base::Bind(&HostResolverMojoTest::HandleConnectionError,
180 base::Unretained(this), ConnectionErrorSource::RESOLVER),
181 base::Bind(&HostResolverMojoTest::HandleConnectionError,
182 base::Unretained(this), ConnectionErrorSource::REQUEST)));
183 resolver_.reset(new HostResolverMojo(resolver_ptr.Pass(), this));
184 }
185
186 void OnConnectionError() override {
187 HandleConnectionError(ConnectionErrorSource::CLIENT);
188 }
189
190 void HandleConnectionError(ConnectionErrorSource source) {
191 if (!run_loop_quit_closure_.is_null())
192 run_loop_quit_closure_.Run();
193 ASSERT_EQ(expected_connection_error_source_, source);
194 }
195
196 int Resolve(const HostResolver::RequestInfo& request_info,
197 AddressList* result) {
198 HostResolver::RequestHandle request_handle = nullptr;
199 base::RunLoop run_loop;
200 int error = 1;
201 resolver_->Resolve(
202 request_info, DEFAULT_PRIORITY, result,
203 base::Bind(&OnResolveComplete, &error, run_loop.QuitClosure()),
Anand Mistry (off Chromium) 2015/02/16 06:32:44 net::TestCompletionCallback
Sam McNally 2015/02/16 07:24:44 Done.
204 &request_handle, BoundNetLog());
205 run_loop.Run();
206 return error;
207 }
208
209 void WaitForConnectionError(ConnectionErrorSource source) {
210 expected_connection_error_source_ = source;
211 base::RunLoop run_loop;
212 run_loop_quit_closure_ = run_loop.QuitClosure();
213 run_loop.Run();
214 }
215
216 scoped_ptr<MockMojoHostResolver> mock_resolver_;
217
218 scoped_ptr<HostResolverMojo> resolver_;
219
220 ConnectionErrorSource expected_connection_error_source_ =
221 ConnectionErrorSource::NONE;
222 base::Closure run_loop_quit_closure_;
223 };
224
225 TEST_F(HostResolverMojoTest, Basic) {
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"));
235 AddressList result;
236 EXPECT_EQ(OK, Resolve(request_info, &result));
237 ASSERT_EQ(2u, result.size());
238 EXPECT_EQ(address_list[0], result[0]);
239 EXPECT_EQ(address_list[1], result[1]);
240
241 ASSERT_EQ(1u, mock_resolver_->requests().size());
242 interfaces::HostResolverRequestInfo& request = *mock_resolver_->requests()[0];
243 EXPECT_EQ("example.com", request.host.To<std::string>());
244 EXPECT_EQ(12345, request.port);
245 EXPECT_EQ(interfaces::ADDRESS_FAMILY_UNSPECIFIED, request.address_family);
246 EXPECT_FALSE(request.is_my_ip_address);
247 }
248
249 TEST_F(HostResolverMojoTest, Multiple) {
250 AddressList address_list;
251 IPAddressNumber address_number;
252 ASSERT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &address_number));
253 address_list.push_back(IPEndPoint(address_number, 12345));
254 mock_resolver_->AddAction(HostResolverAction::ReturnResult(address_list));
255 mock_resolver_->AddAction(
256 HostResolverAction::ReturnError(ERR_NAME_NOT_RESOLVED));
257 HostResolver::RequestInfo request_info1(
258 HostPortPair::FromString("example.com:12345"));
259 request_info1.set_address_family(ADDRESS_FAMILY_IPV4);
260 request_info1.set_is_my_ip_address(true);
261 HostResolver::RequestInfo request_info2(
262 HostPortPair::FromString("example.org:80"));
263 request_info2.set_address_family(ADDRESS_FAMILY_IPV6);
264 AddressList result1;
265 AddressList result2;
266 HostResolver::RequestHandle request_handle1 = nullptr;
267 HostResolver::RequestHandle request_handle2 = nullptr;
268 int error1 = 1;
269 int error2 = 1;
270 base::RunLoop run_loop;
271 base::Closure barrier = base::BarrierClosure(2, run_loop.QuitClosure());
272 resolver_->Resolve(request_info1, DEFAULT_PRIORITY, &result1,
273 base::Bind(&OnResolveComplete, &error1, barrier),
274 &request_handle1, BoundNetLog());
275 resolver_->Resolve(request_info2, DEFAULT_PRIORITY, &result2,
276 base::Bind(&OnResolveComplete, &error2, barrier),
277 &request_handle2, BoundNetLog());
278 run_loop.Run();
279 EXPECT_EQ(OK, error1);
280 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, error2);
281 ASSERT_EQ(1u, result1.size());
282 EXPECT_EQ(address_list[0], result1[0]);
283 ASSERT_EQ(0u, result2.size());
284
285 ASSERT_EQ(2u, mock_resolver_->requests().size());
286 interfaces::HostResolverRequestInfo& request1 =
287 *mock_resolver_->requests()[0];
288 EXPECT_EQ("example.com", request1.host.To<std::string>());
289 EXPECT_EQ(12345, request1.port);
290 EXPECT_EQ(interfaces::ADDRESS_FAMILY_IPV4, request1.address_family);
291 EXPECT_TRUE(request1.is_my_ip_address);
292 interfaces::HostResolverRequestInfo& request2 =
293 *mock_resolver_->requests()[1];
294 EXPECT_EQ("example.org", request2.host.To<std::string>());
295 EXPECT_EQ(80, request2.port);
296 EXPECT_EQ(interfaces::ADDRESS_FAMILY_IPV6, request2.address_family);
297 EXPECT_FALSE(request2.is_my_ip_address);
298 }
299
300 TEST_F(HostResolverMojoTest, Error) {
301 mock_resolver_->AddAction(
302 HostResolverAction::ReturnError(ERR_NAME_NOT_RESOLVED));
303 HostResolver::RequestInfo request_info(
304 HostPortPair::FromString("example.com:8080"));
305 request_info.set_address_family(ADDRESS_FAMILY_IPV4);
306 AddressList result;
307 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, Resolve(request_info, &result));
308 EXPECT_TRUE(result.empty());
309
310 ASSERT_EQ(1u, mock_resolver_->requests().size());
311 interfaces::HostResolverRequestInfo& request = *mock_resolver_->requests()[0];
312 EXPECT_EQ("example.com", request.host.To<std::string>());
313 EXPECT_EQ(8080, request.port);
314 EXPECT_EQ(interfaces::ADDRESS_FAMILY_IPV4, request.address_family);
315 EXPECT_FALSE(request.is_my_ip_address);
316 }
317
318 TEST_F(HostResolverMojoTest, EmptyResult) {
319 mock_resolver_->AddAction(HostResolverAction::ReturnError(OK));
320 HostResolver::RequestInfo request_info(
321 HostPortPair::FromString("example.com:8080"));
322 AddressList result;
323 EXPECT_EQ(OK, Resolve(request_info, &result));
324 EXPECT_TRUE(result.empty());
325
326 ASSERT_EQ(1u, mock_resolver_->requests().size());
327 }
328
329 TEST_F(HostResolverMojoTest, Cancel) {
330 mock_resolver_->AddAction(HostResolverAction::RetainRequest());
331 HostResolver::RequestInfo request_info(
332 HostPortPair::FromString("example.com:80"));
333 request_info.set_address_family(ADDRESS_FAMILY_IPV6);
334 AddressList result;
335 HostResolver::RequestHandle request_handle = nullptr;
336 resolver_->Resolve(request_info, DEFAULT_PRIORITY, &result, base::Bind(&Fail),
337 &request_handle, BoundNetLog());
338 resolver_->CancelRequest(request_handle);
339 WaitForConnectionError(ConnectionErrorSource::REQUEST);
340 EXPECT_TRUE(result.empty());
341
342 ASSERT_EQ(1u, mock_resolver_->requests().size());
343 interfaces::HostResolverRequestInfo& request = *mock_resolver_->requests()[0];
344 EXPECT_EQ("example.com", request.host.To<std::string>());
345 EXPECT_EQ(80, request.port);
346 EXPECT_EQ(interfaces::ADDRESS_FAMILY_IPV6, request.address_family);
347 EXPECT_FALSE(request.is_my_ip_address);
348 }
349
350 TEST_F(HostResolverMojoTest, ImplDropsClientConnection) {
351 mock_resolver_->AddAction(HostResolverAction::DropRequest());
352 HostResolver::RequestInfo request_info(
353 HostPortPair::FromString("example.com:1"));
354 AddressList result;
355 EXPECT_EQ(ERR_FAILED, Resolve(request_info, &result));
356 EXPECT_TRUE(result.empty());
357
358 ASSERT_EQ(1u, mock_resolver_->requests().size());
359 interfaces::HostResolverRequestInfo& request = *mock_resolver_->requests()[0];
360 EXPECT_EQ("example.com", request.host.To<std::string>());
361 EXPECT_EQ(1, request.port);
362 EXPECT_EQ(interfaces::ADDRESS_FAMILY_UNSPECIFIED, request.address_family);
363 EXPECT_FALSE(request.is_my_ip_address);
364 }
365
366 TEST_F(HostResolverMojoTest, DestroyImpl) {
367 mock_resolver_.reset();
368 WaitForConnectionError(ConnectionErrorSource::CLIENT);
369 }
370
371 TEST_F(HostResolverMojoTest, DestroyClient) {
372 resolver_.reset();
373 WaitForConnectionError(ConnectionErrorSource::RESOLVER);
374 }
375
376 TEST_F(HostResolverMojoTest, ResolveFromCache) {
377 HostResolver::RequestInfo request_info(
378 HostPortPair::FromString("example.com:8080"));
379 AddressList result;
380 EXPECT_EQ(ERR_DNS_CACHE_MISS,
381 resolver_->ResolveFromCache(request_info, &result, BoundNetLog()));
382 EXPECT_TRUE(result.empty());
383 }
384
385 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698