Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / net / dns / mojo_host_resolver_impl_unittest.cc
blob4f7a05b47ee94dfced2ceae15deeaedb2ea667ad
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/mojo_host_resolver_impl.h"
7 #include <string>
9 #include "base/memory/scoped_ptr.h"
10 #include "base/run_loop.h"
11 #include "base/time/time.h"
12 #include "net/base/address_list.h"
13 #include "net/base/net_errors.h"
14 #include "net/base/net_util.h"
15 #include "net/dns/mock_host_resolver.h"
16 #include "net/dns/mojo_host_type_converters.h"
17 #include "net/log/net_log.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
20 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"
22 namespace net {
24 namespace {
26 class TestRequestClient : public interfaces::HostResolverRequestClient {
27 public:
28 explicit TestRequestClient(
29 mojo::InterfaceRequest<interfaces::HostResolverRequestClient> req)
30 : done_(false), binding_(this, req.Pass()) {
31 binding_.set_connection_error_handler(base::Bind(
32 &TestRequestClient::OnConnectionError, base::Unretained(this)));
35 void WaitForResult();
36 void WaitForConnectionError();
38 int32_t error_;
39 interfaces::AddressListPtr results_;
41 private:
42 // Overridden from interfaces::HostResolverRequestClient.
43 void ReportResult(int32_t error, interfaces::AddressListPtr results) override;
45 // Mojo error handler.
46 void OnConnectionError();
48 bool done_;
49 base::Closure run_loop_quit_closure_;
50 base::Closure connection_error_quit_closure_;
52 mojo::Binding<interfaces::HostResolverRequestClient> binding_;
55 void TestRequestClient::WaitForResult() {
56 if (done_)
57 return;
59 base::RunLoop run_loop;
60 run_loop_quit_closure_ = run_loop.QuitClosure();
61 run_loop.Run();
62 ASSERT_TRUE(done_);
65 void TestRequestClient::WaitForConnectionError() {
66 base::RunLoop run_loop;
67 connection_error_quit_closure_ = run_loop.QuitClosure();
68 run_loop.Run();
71 void TestRequestClient::ReportResult(int32_t error,
72 interfaces::AddressListPtr results) {
73 if (!run_loop_quit_closure_.is_null()) {
74 run_loop_quit_closure_.Run();
76 ASSERT_FALSE(done_);
77 error_ = error;
78 results_ = results.Pass();
79 done_ = true;
82 void TestRequestClient::OnConnectionError() {
83 if (!connection_error_quit_closure_.is_null())
84 connection_error_quit_closure_.Run();
87 class CallbackMockHostResolver : public MockHostResolver {
88 public:
89 CallbackMockHostResolver() {}
90 ~CallbackMockHostResolver() override {}
92 // Set a callback to run whenever Resolve is called. Callback is cleared after
93 // every run.
94 void SetResolveCallback(base::Closure callback) {
95 resolve_callback_ = callback;
98 // Overridden from MockHostResolver.
99 int Resolve(const RequestInfo& info,
100 RequestPriority priority,
101 AddressList* addresses,
102 const CompletionCallback& callback,
103 RequestHandle* out_req,
104 const BoundNetLog& net_log) override;
106 private:
107 base::Closure resolve_callback_;
110 int CallbackMockHostResolver::Resolve(const RequestInfo& info,
111 RequestPriority priority,
112 AddressList* addresses,
113 const CompletionCallback& callback,
114 RequestHandle* out_req,
115 const BoundNetLog& net_log) {
116 int result = MockHostResolver::Resolve(info, priority, addresses, callback,
117 out_req, net_log);
118 if (!resolve_callback_.is_null()) {
119 resolve_callback_.Run();
120 resolve_callback_.Reset();
122 return result;
125 } // namespace
127 class MojoHostResolverImplTest : public testing::Test {
128 protected:
129 void SetUp() override {
130 mock_host_resolver_.rules()->AddRule("example.com", "1.2.3.4");
131 mock_host_resolver_.rules()->AddRule("chromium.org", "8.8.8.8");
132 mock_host_resolver_.rules()->AddSimulatedFailure("failure.fail");
134 resolver_service_.reset(
135 new MojoHostResolverImpl(&mock_host_resolver_, BoundNetLog()));
138 interfaces::HostResolverRequestInfoPtr CreateRequest(const std::string& host,
139 uint16_t port,
140 bool is_my_ip_address) {
141 interfaces::HostResolverRequestInfoPtr request =
142 interfaces::HostResolverRequestInfo::New();
143 request->host = host;
144 request->port = port;
145 request->address_family = interfaces::ADDRESS_FAMILY_IPV4;
146 request->is_my_ip_address = is_my_ip_address;
147 return request.Pass();
150 // Wait until the mock resolver has received |num| resolve requests.
151 void WaitForRequests(size_t num) {
152 while (mock_host_resolver_.num_resolve() < num) {
153 base::RunLoop run_loop;
154 mock_host_resolver_.SetResolveCallback(run_loop.QuitClosure());
155 run_loop.Run();
159 CallbackMockHostResolver mock_host_resolver_;
160 scoped_ptr<MojoHostResolverImpl> resolver_service_;
163 TEST_F(MojoHostResolverImplTest, Resolve) {
164 interfaces::HostResolverRequestClientPtr client_ptr;
165 TestRequestClient client(mojo::GetProxy(&client_ptr));
167 interfaces::HostResolverRequestInfoPtr request =
168 CreateRequest("example.com", 80, false);
169 resolver_service_->Resolve(request.Pass(), client_ptr.Pass());
170 client.WaitForResult();
172 EXPECT_EQ(net::OK, client.error_);
173 AddressList address_list = (*client.results_).To<AddressList>();
174 EXPECT_EQ(1U, address_list.size());
175 EXPECT_EQ("1.2.3.4:80", address_list[0].ToString());
178 TEST_F(MojoHostResolverImplTest, ResolveSynchronous) {
179 interfaces::HostResolverRequestClientPtr client_ptr;
180 TestRequestClient client(mojo::GetProxy(&client_ptr));
182 mock_host_resolver_.set_synchronous_mode(true);
184 interfaces::HostResolverRequestInfoPtr request =
185 CreateRequest("example.com", 80, false);
186 resolver_service_->Resolve(request.Pass(), client_ptr.Pass());
187 client.WaitForResult();
189 EXPECT_EQ(net::OK, client.error_);
190 AddressList address_list = (*client.results_).To<AddressList>();
191 EXPECT_EQ(1U, address_list.size());
192 EXPECT_EQ("1.2.3.4:80", address_list[0].ToString());
195 TEST_F(MojoHostResolverImplTest, ResolveMultiple) {
196 interfaces::HostResolverRequestClientPtr client1_ptr;
197 TestRequestClient client1(mojo::GetProxy(&client1_ptr));
198 interfaces::HostResolverRequestClientPtr client2_ptr;
199 TestRequestClient client2(mojo::GetProxy(&client2_ptr));
201 mock_host_resolver_.set_ondemand_mode(true);
203 interfaces::HostResolverRequestInfoPtr request1 =
204 CreateRequest("example.com", 80, false);
205 resolver_service_->Resolve(request1.Pass(), client1_ptr.Pass());
206 interfaces::HostResolverRequestInfoPtr request2 =
207 CreateRequest("chromium.org", 80, false);
208 resolver_service_->Resolve(request2.Pass(), client2_ptr.Pass());
209 WaitForRequests(2);
210 mock_host_resolver_.ResolveAllPending();
212 client1.WaitForResult();
213 client2.WaitForResult();
215 EXPECT_EQ(net::OK, client1.error_);
216 AddressList address_list = (*client1.results_).To<AddressList>();
217 EXPECT_EQ(1U, address_list.size());
218 EXPECT_EQ("1.2.3.4:80", address_list[0].ToString());
219 EXPECT_EQ(net::OK, client2.error_);
220 address_list = (*client2.results_).To<AddressList>();
221 EXPECT_EQ(1U, address_list.size());
222 EXPECT_EQ("8.8.8.8:80", address_list[0].ToString());
225 TEST_F(MojoHostResolverImplTest, ResolveDuplicate) {
226 interfaces::HostResolverRequestClientPtr client1_ptr;
227 TestRequestClient client1(mojo::GetProxy(&client1_ptr));
228 interfaces::HostResolverRequestClientPtr client2_ptr;
229 TestRequestClient client2(mojo::GetProxy(&client2_ptr));
231 mock_host_resolver_.set_ondemand_mode(true);
233 interfaces::HostResolverRequestInfoPtr request1 =
234 CreateRequest("example.com", 80, false);
235 resolver_service_->Resolve(request1.Pass(), client1_ptr.Pass());
236 interfaces::HostResolverRequestInfoPtr request2 =
237 CreateRequest("example.com", 80, false);
238 resolver_service_->Resolve(request2.Pass(), client2_ptr.Pass());
239 WaitForRequests(2);
240 mock_host_resolver_.ResolveAllPending();
242 client1.WaitForResult();
243 client2.WaitForResult();
245 EXPECT_EQ(net::OK, client1.error_);
246 AddressList address_list = (*client1.results_).To<AddressList>();
247 EXPECT_EQ(1U, address_list.size());
248 EXPECT_EQ("1.2.3.4:80", address_list[0].ToString());
249 EXPECT_EQ(net::OK, client2.error_);
250 address_list = (*client2.results_).To<AddressList>();
251 EXPECT_EQ(1U, address_list.size());
252 EXPECT_EQ("1.2.3.4:80", address_list[0].ToString());
255 TEST_F(MojoHostResolverImplTest, ResolveFailure) {
256 interfaces::HostResolverRequestClientPtr client_ptr;
257 TestRequestClient client(mojo::GetProxy(&client_ptr));
259 interfaces::HostResolverRequestInfoPtr request =
260 CreateRequest("failure.fail", 80, false);
261 resolver_service_->Resolve(request.Pass(), client_ptr.Pass());
262 client.WaitForResult();
264 EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, client.error_);
265 EXPECT_TRUE(client.results_.is_null());
268 TEST_F(MojoHostResolverImplTest, DestroyClient) {
269 interfaces::HostResolverRequestClientPtr client_ptr;
270 scoped_ptr<TestRequestClient> client(
271 new TestRequestClient(mojo::GetProxy(&client_ptr)));
273 mock_host_resolver_.set_ondemand_mode(true);
275 interfaces::HostResolverRequestInfoPtr request =
276 CreateRequest("example.com", 80, false);
277 resolver_service_->Resolve(request.Pass(), client_ptr.Pass());
278 WaitForRequests(1);
280 client.reset();
281 base::RunLoop().RunUntilIdle();
283 mock_host_resolver_.ResolveAllPending();
284 base::RunLoop().RunUntilIdle();
287 } // namespace net