OLD | NEW |
---|---|
(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_service_impl.h" | |
6 | |
7 #include <string> | |
8 | |
9 #include "base/memory/scoped_ptr.h" | |
10 #include "base/message_loop/message_loop.h" | |
11 #include "base/run_loop.h" | |
12 #include "base/time/time.h" | |
13 #include "net/base/address_list.h" | |
14 #include "net/base/net_errors.h" | |
15 #include "net/base/net_util.h" | |
16 #include "net/dns/mock_host_resolver.h" | |
17 #include "net/dns/type_converters.h" | |
18 #include "testing/gtest/include/gtest/gtest.h" | |
19 #include "third_party/mojo/src/mojo/edk/embedder/test_embedder.h" | |
20 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h" | |
21 | |
22 namespace net { | |
23 | |
24 namespace { | |
25 | |
26 class TestRequestClient : public interfaces::HostResolverRequestClient { | |
27 public: | |
28 TestRequestClient() : done_(false), run_loop_(nullptr), binding_(this) {} | |
29 | |
30 void Bind(interfaces::HostResolverRequestClientPtr* ptr); | |
Sam McNally
2015/02/05 23:58:36
Is there a reason for not doing this in the constr
Anand Mistry (off Chromium)
2015/02/06 06:32:41
Nope.
| |
31 void WaitForResult(base::RunLoop* run_loop); | |
32 | |
33 // Overridden from interfaces::HostResolverRequestClient. | |
34 void ReportResult(int32_t error, interfaces::AddressListPtr results) override; | |
35 | |
36 int32_t error_; | |
37 interfaces::AddressListPtr results_; | |
38 | |
39 private: | |
40 bool done_; | |
41 base::RunLoop* run_loop_; | |
Sam McNally
2015/02/05 23:58:36
Store the base::Closure returned by RunLoop::QuitC
Anand Mistry (off Chromium)
2015/02/06 06:32:41
Done.
| |
42 | |
43 mojo::Binding<interfaces::HostResolverRequestClient> binding_; | |
44 }; | |
45 | |
46 void TestRequestClient::Bind(interfaces::HostResolverRequestClientPtr* ptr) { | |
47 binding_.Bind(ptr); | |
48 } | |
49 | |
50 void TestRequestClient::WaitForResult(base::RunLoop* run_loop) { | |
51 if (done_) | |
52 return; | |
53 | |
54 run_loop_ = run_loop; | |
55 run_loop->Run(); | |
56 ASSERT_TRUE(done_); | |
57 } | |
58 | |
59 void TestRequestClient::ReportResult(int32_t error, | |
60 interfaces::AddressListPtr results) { | |
61 ASSERT_FALSE(done_); | |
Sam McNally
2015/02/05 23:58:36
Quitting the RunLoop first might avoid test failur
Anand Mistry (off Chromium)
2015/02/06 06:32:41
Done.
| |
62 error_ = error; | |
63 results_ = results.Pass(); | |
64 done_ = true; | |
65 if (run_loop_) { | |
66 run_loop_->Quit(); | |
67 } | |
68 } | |
69 | |
70 } // namespace | |
71 | |
72 class HostResolverServiceImplTest : public testing::Test { | |
73 protected: | |
74 static void SetUpTestCase() { | |
75 mojo::embedder::test::InitWithSimplePlatformSupport(); | |
Sam McNally
2015/02/05 23:58:36
This should be in net/test/run_all_unittests.cc.
Anand Mistry (off Chromium)
2015/02/06 06:32:41
Done.
| |
76 } | |
77 | |
78 void SetUp() override { | |
79 mock_host_resolver_.rules()->AddRule("example.com", "1.2.3.4"); | |
80 mock_host_resolver_.rules()->AddRule("chromium.org", "8.8.8.8"); | |
81 mock_host_resolver_.rules()->AddSimulatedFailure("failure.fail"); | |
82 | |
83 resolver_service_.reset(new HostResolverServiceImpl(&mock_host_resolver_)); | |
84 resolver_service_binding_.reset( | |
Sam McNally
2015/02/05 23:58:36
It seems a bit weird for the Binding to not be a m
Anand Mistry (off Chromium)
2015/02/06 06:32:41
I thought about it, but right now, it's not clear
| |
85 new mojo::Binding<interfaces::HostResolverService>( | |
86 resolver_service_.get())); | |
87 resolver_service_binding_->Bind(&resolver_service_ptr_); | |
88 } | |
89 | |
90 interfaces::HostResolverRequestInfoPtr CreateRequest(const std::string& host, | |
91 uint8_t port, | |
eroman
2015/02/05 19:51:11
Please make this 16bit for consistency
Anand Mistry (off Chromium)
2015/02/06 06:32:41
Oops.
| |
92 bool is_my_ip_address) { | |
93 interfaces::HostResolverRequestInfoPtr request = | |
94 interfaces::HostResolverRequestInfo::New(); | |
95 request->host = host; | |
96 request->port = port; | |
97 request->address_family = interfaces::ADDRESS_FAMILY_IPV4; | |
98 request->is_my_ip_address = is_my_ip_address; | |
99 return request.Pass(); | |
100 } | |
101 | |
102 void WaitForOutstandingRequests(size_t num) { | |
eroman
2015/02/05 19:51:11
Please explain this method, this doesn't look like
Anand Mistry (off Chromium)
2015/02/06 06:32:41
Added a better explanation. I don't like it either
| |
103 // Can't just use RunLoop::RunUntilIdle() since Mojo internally may be using | |
104 // another message loop. | |
105 while (resolver_service_->OutstandingRequestsForTesting() < num) { | |
106 base::RunLoop run_loop; | |
107 base::MessageLoop::current()->PostDelayedTask( | |
108 FROM_HERE, run_loop.QuitClosure(), | |
109 base::TimeDelta::FromMilliseconds(10)); | |
110 run_loop.Run(); | |
111 } | |
112 } | |
113 | |
114 MockHostResolver mock_host_resolver_; | |
115 scoped_ptr<HostResolverServiceImpl> resolver_service_; | |
116 | |
117 scoped_ptr<mojo::Binding<interfaces::HostResolverService>> | |
118 resolver_service_binding_; | |
119 interfaces::HostResolverServicePtr resolver_service_ptr_; | |
Sam McNally
2015/02/05 23:58:36
For the most part I don't think it's valuable to u
Anand Mistry (off Chromium)
2015/02/06 06:32:41
I disagree. I think it's good to test this with Mo
| |
120 }; | |
121 | |
122 TEST_F(HostResolverServiceImplTest, Resolve) { | |
123 TestRequestClient client; | |
124 interfaces::HostResolverRequestClientPtr client_ptr; | |
125 client.Bind(&client_ptr); | |
126 | |
127 interfaces::HostResolverRequestInfoPtr request = | |
128 CreateRequest("example.com", 80, false); | |
129 resolver_service_ptr_->Resolve(request.Pass(), client_ptr.Pass()); | |
130 base::RunLoop run_loop; | |
131 client.WaitForResult(&run_loop); | |
132 | |
133 EXPECT_EQ(net::OK, client.error_); | |
134 AddressList address_list = (*client.results_).To<AddressList>(); | |
135 EXPECT_EQ(1U, address_list.size()); | |
136 EXPECT_EQ("1.2.3.4:80", address_list[0].ToString()); | |
137 } | |
138 | |
139 TEST_F(HostResolverServiceImplTest, ResolveSynchronous) { | |
140 TestRequestClient client; | |
141 interfaces::HostResolverRequestClientPtr client_ptr; | |
142 client.Bind(&client_ptr); | |
143 | |
144 mock_host_resolver_.set_synchronous_mode(true); | |
145 | |
146 interfaces::HostResolverRequestInfoPtr request = | |
147 CreateRequest("example.com", 80, false); | |
148 resolver_service_ptr_->Resolve(request.Pass(), client_ptr.Pass()); | |
149 base::RunLoop run_loop; | |
150 client.WaitForResult(&run_loop); | |
151 | |
152 EXPECT_EQ(net::OK, client.error_); | |
153 AddressList address_list = (*client.results_).To<AddressList>(); | |
154 EXPECT_EQ(1U, address_list.size()); | |
155 EXPECT_EQ("1.2.3.4:80", address_list[0].ToString()); | |
156 } | |
157 | |
158 TEST_F(HostResolverServiceImplTest, ResolveMultiple) { | |
159 TestRequestClient client1; | |
160 interfaces::HostResolverRequestClientPtr client1_ptr; | |
161 client1.Bind(&client1_ptr); | |
162 TestRequestClient client2; | |
163 interfaces::HostResolverRequestClientPtr client2_ptr; | |
164 client2.Bind(&client2_ptr); | |
165 | |
166 mock_host_resolver_.set_ondemand_mode(true); | |
167 | |
168 interfaces::HostResolverRequestInfoPtr request1 = | |
169 CreateRequest("example.com", 80, false); | |
170 resolver_service_ptr_->Resolve(request1.Pass(), client1_ptr.Pass()); | |
171 interfaces::HostResolverRequestInfoPtr request2 = | |
172 CreateRequest("chromium.org", 80, false); | |
173 resolver_service_ptr_->Resolve(request2.Pass(), client2_ptr.Pass()); | |
174 WaitForOutstandingRequests(2); | |
175 mock_host_resolver_.ResolveAllPending(); | |
176 | |
177 base::RunLoop run_loop1; | |
178 client1.WaitForResult(&run_loop1); | |
179 base::RunLoop run_loop2; | |
180 client2.WaitForResult(&run_loop2); | |
181 | |
182 EXPECT_EQ(net::OK, client1.error_); | |
183 AddressList address_list = (*client1.results_).To<AddressList>(); | |
184 EXPECT_EQ(1U, address_list.size()); | |
185 EXPECT_EQ("1.2.3.4:80", address_list[0].ToString()); | |
186 EXPECT_EQ(net::OK, client2.error_); | |
187 address_list = (*client2.results_).To<AddressList>(); | |
188 EXPECT_EQ(1U, address_list.size()); | |
189 EXPECT_EQ("8.8.8.8:80", address_list[0].ToString()); | |
190 } | |
191 | |
192 TEST_F(HostResolverServiceImplTest, ResolveDuplicate) { | |
193 TestRequestClient client1; | |
194 interfaces::HostResolverRequestClientPtr client1_ptr; | |
195 client1.Bind(&client1_ptr); | |
196 TestRequestClient client2; | |
197 interfaces::HostResolverRequestClientPtr client2_ptr; | |
198 client2.Bind(&client2_ptr); | |
199 | |
200 mock_host_resolver_.set_ondemand_mode(true); | |
201 | |
202 interfaces::HostResolverRequestInfoPtr request1 = | |
203 CreateRequest("example.com", 80, false); | |
204 resolver_service_ptr_->Resolve(request1.Pass(), client1_ptr.Pass()); | |
205 interfaces::HostResolverRequestInfoPtr request2 = | |
206 CreateRequest("example.com", 80, false); | |
207 resolver_service_ptr_->Resolve(request2.Pass(), client2_ptr.Pass()); | |
208 WaitForOutstandingRequests(2); | |
209 mock_host_resolver_.ResolveAllPending(); | |
210 | |
211 base::RunLoop run_loop1; | |
212 client1.WaitForResult(&run_loop1); | |
213 base::RunLoop run_loop2; | |
214 client2.WaitForResult(&run_loop2); | |
215 | |
216 EXPECT_EQ(net::OK, client1.error_); | |
217 AddressList address_list = (*client1.results_).To<AddressList>(); | |
218 EXPECT_EQ(1U, address_list.size()); | |
219 EXPECT_EQ("1.2.3.4:80", address_list[0].ToString()); | |
220 EXPECT_EQ(net::OK, client2.error_); | |
221 address_list = (*client2.results_).To<AddressList>(); | |
222 EXPECT_EQ(1U, address_list.size()); | |
223 EXPECT_EQ("1.2.3.4:80", address_list[0].ToString()); | |
224 } | |
225 | |
226 TEST_F(HostResolverServiceImplTest, ResolveFailure) { | |
227 TestRequestClient client; | |
228 interfaces::HostResolverRequestClientPtr client_ptr; | |
229 client.Bind(&client_ptr); | |
230 | |
231 interfaces::HostResolverRequestInfoPtr request = | |
232 CreateRequest("failure.fail", 80, false); | |
233 resolver_service_ptr_->Resolve(request.Pass(), client_ptr.Pass()); | |
234 base::RunLoop run_loop; | |
235 client.WaitForResult(&run_loop); | |
236 | |
237 EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, client.error_); | |
238 EXPECT_TRUE(client.results_.is_null()); | |
239 } | |
240 | |
241 TEST_F(HostResolverServiceImplTest, DestroyClient) { | |
Sam McNally
2015/02/05 23:58:36
I'm not sure what this is testing. As far as I can
Anand Mistry (off Chromium)
2015/02/06 06:32:41
Destroying the client should (and does) cause a co
| |
242 scoped_ptr<TestRequestClient> client(new TestRequestClient); | |
243 interfaces::HostResolverRequestClientPtr client_ptr; | |
244 client->Bind(&client_ptr); | |
245 | |
246 mock_host_resolver_.set_ondemand_mode(true); | |
247 | |
248 interfaces::HostResolverRequestInfoPtr request = | |
249 CreateRequest("example.com", 80, false); | |
250 resolver_service_ptr_->Resolve(request.Pass(), client_ptr.Pass()); | |
251 WaitForOutstandingRequests(1); | |
252 | |
253 client.reset(); | |
254 base::RunLoop().RunUntilIdle(); | |
255 | |
256 mock_host_resolver_.ResolveAllPending(); | |
257 base::RunLoop().RunUntilIdle(); | |
258 } | |
259 | |
260 TEST_F(HostResolverServiceImplTest, DestroyService) { | |
261 TestRequestClient client; | |
262 interfaces::HostResolverRequestClientPtr client_ptr; | |
263 client.Bind(&client_ptr); | |
264 | |
265 mock_host_resolver_.set_ondemand_mode(true); | |
266 | |
267 interfaces::HostResolverRequestInfoPtr request = | |
268 CreateRequest("example.com", 80, false); | |
269 resolver_service_ptr_->Resolve(request.Pass(), client_ptr.Pass()); | |
270 WaitForOutstandingRequests(1); | |
271 | |
272 resolver_service_binding_.reset(); | |
273 resolver_service_.reset(); | |
274 base::RunLoop().RunUntilIdle(); | |
275 | |
276 mock_host_resolver_.ResolveAllPending(); | |
277 base::RunLoop().RunUntilIdle(); | |
Sam McNally
2015/02/05 23:58:36
Check that the client detected that its pipe close
Anand Mistry (off Chromium)
2015/02/06 06:32:41
Done.
| |
278 } | |
279 | |
280 } // namespace net | |
OLD | NEW |