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

Side by Side Diff: net/proxy/mojo_proxy_resolver_impl_unittest.cc

Issue 896203003: Implement utility-side proxy resolver Mojo service. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@proxy-diffbase
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/proxy/mojo_proxy_resolver_impl.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/run_loop.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "net/base/net_errors.h"
13 #include "net/proxy/mock_proxy_resolver.h"
14 #include "net/proxy/proxy_info.h"
15 #include "net/proxy/proxy_server.h"
16 #include "net/proxy/type_converters.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
19 #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h"
20
21 namespace net {
22 namespace {
23
24 class TestRequestClient : public interfaces::ProxyResolverRequestClient,
Anand Mistry (off Chromium) 2015/02/10 03:54:08 I wonder if we can combine this with the host reso
Sam McNally 2015/02/10 06:27:42 As discussed, let's wait until we have another sim
25 public mojo::ErrorHandler {
26 public:
27 explicit TestRequestClient(interfaces::ProxyResolverRequestClientPtr* ptr);
28
29 void WaitForResult();
30 void WaitForConnectionError();
31
32 int error() { return error_; }
33 const mojo::Array<interfaces::ProxyServerPtr>& results() { return results_; }
34
35 private:
36 // interfaces::ProxyResolverRequestClient override.
37 void ReportResult(int32_t error,
38 mojo::Array<interfaces::ProxyServerPtr> results) override;
39
40 // mojo::ErrorHandler override.
41 void OnConnectionError() override;
42
43 bool done_ = false;
44 bool encountered_connection_error_ = false;
45 int32_t error_ = ERR_FAILED;
46 mojo::Array<interfaces::ProxyServerPtr> results_;
47 base::Closure run_loop_quit_closure_;
48 base::Closure connection_error_callback_;
49
50 mojo::Binding<interfaces::ProxyResolverRequestClient> binding_;
51 };
52
53 TestRequestClient::TestRequestClient(
54 interfaces::ProxyResolverRequestClientPtr* ptr)
55 : binding_(this, ptr) {
56 binding_.set_error_handler(this);
57 }
58
59 void TestRequestClient::WaitForResult() {
60 if (done_)
61 return;
62
63 base::RunLoop run_loop;
64 run_loop_quit_closure_ = run_loop.QuitClosure();
65 run_loop.Run();
66 ASSERT_TRUE(done_);
67 }
68
69 void TestRequestClient::WaitForConnectionError() {
70 if (encountered_connection_error_)
71 return;
72
73 base::RunLoop run_loop;
74 connection_error_callback_ = run_loop.QuitClosure();
75 run_loop.Run();
76 ASSERT_TRUE(encountered_connection_error_);
77 }
78
79 void TestRequestClient::ReportResult(
80 int32_t error,
81 mojo::Array<interfaces::ProxyServerPtr> results) {
82 if (!run_loop_quit_closure_.is_null()) {
83 run_loop_quit_closure_.Run();
84 }
85 ASSERT_FALSE(done_);
86 error_ = error;
87 results_ = results.Pass();
88 done_ = true;
89 }
90
91 void TestRequestClient::OnConnectionError() {
92 if (!connection_error_callback_.is_null())
93 connection_error_callback_.Run();
94 encountered_connection_error_ = true;
95 }
96
97 class SetPacScriptClient {
98 public:
99 base::Callback<void(int32_t)> CreateCallback();
100 int error() { return error_; }
101
102 private:
103 void ReportResult(int32_t error);
104
105 int32_t error_ = ERR_FAILED;
106 };
107
108 base::Callback<void(int32_t)> SetPacScriptClient::CreateCallback() {
109 return base::Bind(&SetPacScriptClient::ReportResult, base::Unretained(this));
110 }
111
112 void SetPacScriptClient::ReportResult(int32_t error) {
113 error_ = error;
114 }
115
116 class CallbackMockProxyResolver : public MockAsyncProxyResolverExpectsBytes {
117 public:
118 CallbackMockProxyResolver() {}
119 ~CallbackMockProxyResolver() override;
120
121 // MockAsyncProxyResolverExpectsBytes overrides.
122 int GetProxyForURL(const GURL& url,
123 ProxyInfo* results,
124 const net::CompletionCallback& callback,
125 RequestHandle* request_handle,
126 const BoundNetLog& net_log) override;
127 void CancelRequest(RequestHandle request_handle) override;
128 int SetPacScript(const scoped_refptr<ProxyResolverScriptData>& script_data,
129 const net::CompletionCallback& callback) override;
130
131 // Wait until the mock resolver has received a CancelRequest call.
132 void WaitForCancel();
133
134 // Queues a proxy result to be returned synchronously.
135 void ReturnProxySynchronously(const ProxyInfo& result);
136
137 // Queues a SetPacScript to be completed synchronously.
138 void CompleteSetPacScriptSynchronously();
139
140 private:
141 base::Closure cancel_callback_;
142 scoped_ptr<ProxyInfo> sync_result_;
143 bool set_pac_script_sync_ = false;
144 };
145
146 CallbackMockProxyResolver::~CallbackMockProxyResolver() {
147 EXPECT_TRUE(pending_requests().empty());
148 }
149
150 int CallbackMockProxyResolver::GetProxyForURL(
151 const GURL& url,
152 ProxyInfo* results,
153 const net::CompletionCallback& callback,
154 RequestHandle* request_handle,
155 const BoundNetLog& net_log) {
156 if (sync_result_) {
157 *results = *sync_result_;
158 sync_result_.reset();
159 return OK;
160 }
161 return MockAsyncProxyResolverExpectsBytes::GetProxyForURL(
162 url, results, callback, request_handle, net_log);
163 }
164
165 void CallbackMockProxyResolver::CancelRequest(RequestHandle request_handle) {
166 MockAsyncProxyResolverExpectsBytes::CancelRequest(request_handle);
167 if (!cancel_callback_.is_null()) {
168 cancel_callback_.Run();
169 cancel_callback_.Reset();
170 }
171 }
172
173 int CallbackMockProxyResolver::SetPacScript(
174 const scoped_refptr<ProxyResolverScriptData>& script_data,
175 const net::CompletionCallback& callback) {
176 if (set_pac_script_sync_) {
177 set_pac_script_sync_ = false;
178 return OK;
179 }
180 return MockAsyncProxyResolverExpectsBytes::SetPacScript(script_data,
181 callback);
182 }
183
184 void CallbackMockProxyResolver::WaitForCancel() {
185 while (cancelled_requests().empty()) {
186 base::RunLoop run_loop;
187 cancel_callback_ = run_loop.QuitClosure();
188 run_loop.Run();
189 }
190 }
191
192 void CallbackMockProxyResolver::ReturnProxySynchronously(
193 const ProxyInfo& result) {
194 sync_result_.reset(new ProxyInfo(result));
195 }
196
197 void CallbackMockProxyResolver::CompleteSetPacScriptSynchronously() {
198 set_pac_script_sync_ = true;
199 }
200
201 } // namespace
202
203 class MojoProxyResolverImplTest : public testing::Test {
204 protected:
205 void SetUp() override {
206 scoped_ptr<CallbackMockProxyResolver> mock_resolver(
207 new CallbackMockProxyResolver);
208 mock_proxy_resolver_ = mock_resolver.get();
209 resolver_.reset(new MojoProxyResolverImpl(mock_resolver.Pass()));
210 }
211
212 CallbackMockProxyResolver* mock_proxy_resolver_;
213
214 scoped_ptr<interfaces::ProxyResolver> resolver_;
215 };
216
217 TEST_F(MojoProxyResolverImplTest, GetProxyForUrl) {
218 interfaces::ProxyResolverRequestClientPtr client_ptr;
219 TestRequestClient client(&client_ptr);
220
221 resolver_->GetProxyForUrl("http://example.com", client_ptr.Pass());
222 ASSERT_EQ(1u, mock_proxy_resolver_->pending_requests().size());
223 scoped_refptr<MockAsyncProxyResolverBase::Request> request =
224 mock_proxy_resolver_->pending_requests()[0];
225 EXPECT_EQ(GURL("http://example.com"), request->url());
226 request->results()->UsePacString(
227 "PROXY proxy.example.com:1; "
228 "SOCKS4 socks4.example.com:2; "
229 "SOCKS5 socks5.example.com:3; "
230 "HTTPS https.example.com:4; "
231 "QUIC quic.example.com:65000; "
232 "DIRECT");
233 request->CompleteNow(OK);
234 client.WaitForResult();
235
236 EXPECT_EQ(net::OK, client.error());
237 std::vector<net::ProxyServer> servers =
238 client.results().To<std::vector<net::ProxyServer>>();
239 ASSERT_EQ(6u, servers.size());
240 EXPECT_EQ(ProxyServer::SCHEME_HTTP, servers[0].scheme());
241 EXPECT_EQ("proxy.example.com", servers[0].host_port_pair().host());
242 EXPECT_EQ(1, servers[0].host_port_pair().port());
243
244 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, servers[1].scheme());
245 EXPECT_EQ("socks4.example.com", servers[1].host_port_pair().host());
246 EXPECT_EQ(2, servers[1].host_port_pair().port());
247
248 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, servers[2].scheme());
249 EXPECT_EQ("socks5.example.com", servers[2].host_port_pair().host());
250 EXPECT_EQ(3, servers[2].host_port_pair().port());
251
252 EXPECT_EQ(ProxyServer::SCHEME_HTTPS, servers[3].scheme());
253 EXPECT_EQ("https.example.com", servers[3].host_port_pair().host());
254 EXPECT_EQ(4, servers[3].host_port_pair().port());
255
256 EXPECT_EQ(ProxyServer::SCHEME_QUIC, servers[4].scheme());
257 EXPECT_EQ("quic.example.com", servers[4].host_port_pair().host());
258 EXPECT_EQ(65000, servers[4].host_port_pair().port());
259
260 EXPECT_EQ(ProxyServer::SCHEME_DIRECT, servers[5].scheme());
261 }
262
263 TEST_F(MojoProxyResolverImplTest, GetProxyForUrlSynchronous) {
264 interfaces::ProxyResolverRequestClientPtr client_ptr;
265 TestRequestClient client(&client_ptr);
266
267 ProxyInfo result;
268 result.UsePacString("DIRECT");
269 mock_proxy_resolver_->ReturnProxySynchronously(result);
270 resolver_->GetProxyForUrl("http://example.com", client_ptr.Pass());
271 ASSERT_EQ(0u, mock_proxy_resolver_->pending_requests().size());
272 client.WaitForResult();
273
274 EXPECT_EQ(net::OK, client.error());
275 std::vector<net::ProxyServer> proxy_servers =
276 client.results().To<std::vector<net::ProxyServer>>();
277 ASSERT_EQ(1u, proxy_servers.size());
278 net::ProxyServer& server = proxy_servers[0];
279 EXPECT_TRUE(server.is_direct());
280 }
281
282 TEST_F(MojoProxyResolverImplTest, GetProxyForUrlFailure) {
283 interfaces::ProxyResolverRequestClientPtr client_ptr;
284 TestRequestClient client(&client_ptr);
285
286 resolver_->GetProxyForUrl("http://example.com", client_ptr.Pass());
287 ASSERT_EQ(1u, mock_proxy_resolver_->pending_requests().size());
288 scoped_refptr<MockAsyncProxyResolverBase::Request> request =
289 mock_proxy_resolver_->pending_requests()[0];
290 EXPECT_EQ(GURL("http://example.com"), request->url());
291 request->CompleteNow(ERR_FAILED);
292 client.WaitForResult();
293
294 EXPECT_EQ(ERR_FAILED, client.error());
295 std::vector<net::ProxyServer> proxy_servers =
296 client.results().To<std::vector<net::ProxyServer>>();
297 EXPECT_TRUE(proxy_servers.empty());
298 }
299
300 TEST_F(MojoProxyResolverImplTest, GetProxyForUrlMultiple) {
301 interfaces::ProxyResolverRequestClientPtr client_ptr1;
302 TestRequestClient client1(&client_ptr1);
303 interfaces::ProxyResolverRequestClientPtr client_ptr2;
304 TestRequestClient client2(&client_ptr2);
305
306 resolver_->GetProxyForUrl("http://example.com", client_ptr1.Pass());
307 resolver_->GetProxyForUrl("https://example.com", client_ptr2.Pass());
308 ASSERT_EQ(2u, mock_proxy_resolver_->pending_requests().size());
309 scoped_refptr<MockAsyncProxyResolverBase::Request> request1 =
310 mock_proxy_resolver_->pending_requests()[0];
311 EXPECT_EQ(GURL("http://example.com"), request1->url());
312 scoped_refptr<MockAsyncProxyResolverBase::Request> request2 =
313 mock_proxy_resolver_->pending_requests()[1];
314 EXPECT_EQ(GURL("https://example.com"), request2->url());
315 request1->results()->UsePacString("HTTPS proxy.example.com:12345");
316 request1->CompleteNow(OK);
317 request2->results()->UsePacString("SOCKS5 another-proxy.example.com:6789");
318 request2->CompleteNow(OK);
319 client1.WaitForResult();
320 client2.WaitForResult();
321
322 EXPECT_EQ(net::OK, client1.error());
323 std::vector<net::ProxyServer> proxy_servers1 =
324 client1.results().To<std::vector<net::ProxyServer>>();
325 ASSERT_EQ(1u, proxy_servers1.size());
326 net::ProxyServer& server1 = proxy_servers1[0];
327 EXPECT_EQ(ProxyServer::SCHEME_HTTPS, server1.scheme());
328 EXPECT_EQ("proxy.example.com", server1.host_port_pair().host());
329 EXPECT_EQ(12345, server1.host_port_pair().port());
330
331 EXPECT_EQ(net::OK, client2.error());
332 std::vector<net::ProxyServer> proxy_servers2 =
333 client2.results().To<std::vector<net::ProxyServer>>();
334 ASSERT_EQ(1u, proxy_servers1.size());
335 net::ProxyServer& server2 = proxy_servers2[0];
336 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, server2.scheme());
337 EXPECT_EQ("another-proxy.example.com", server2.host_port_pair().host());
338 EXPECT_EQ(6789, server2.host_port_pair().port());
339 }
340
341 TEST_F(MojoProxyResolverImplTest, SetPacScript) {
342 SetPacScriptClient client;
343
344 resolver_->SetPacScript("pac script", client.CreateCallback());
345 MockAsyncProxyResolverBase::SetPacScriptRequest* request =
346 mock_proxy_resolver_->pending_set_pac_script_request();
347 EXPECT_EQ("pac script", base::UTF16ToUTF8(request->script_data()->utf16()));
348 request->CompleteNow(OK);
349 EXPECT_EQ(OK, client.error());
350 }
351
352 TEST_F(MojoProxyResolverImplTest, SetPacScriptSynchronous) {
353 SetPacScriptClient client;
354
355 mock_proxy_resolver_->CompleteSetPacScriptSynchronously();
356 resolver_->SetPacScript("pac script", client.CreateCallback());
357 EXPECT_FALSE(mock_proxy_resolver_->pending_set_pac_script_request());
358 EXPECT_EQ(OK, client.error());
359 }
360
361 TEST_F(MojoProxyResolverImplTest, DestroyClient) {
362 interfaces::ProxyResolverRequestClientPtr client_ptr;
363 scoped_ptr<TestRequestClient> client(new TestRequestClient(&client_ptr));
364
365 resolver_->GetProxyForUrl("http://example.com", client_ptr.Pass());
366 ASSERT_EQ(1u, mock_proxy_resolver_->pending_requests().size());
367 scoped_refptr<MockAsyncProxyResolverBase::Request> request =
368 mock_proxy_resolver_->pending_requests()[0];
369 EXPECT_EQ(GURL("http://example.com"), request->url());
370 request->results()->UsePacString("PROXY proxy.example.com:8080");
371 client.reset();
372 mock_proxy_resolver_->WaitForCancel();
373 }
374
375 TEST_F(MojoProxyResolverImplTest, DestroyService) {
376 interfaces::ProxyResolverRequestClientPtr client_ptr;
377 TestRequestClient client1(&client_ptr);
378 SetPacScriptClient client2;
379
380 resolver_->GetProxyForUrl("http://example.com", client_ptr.Pass());
381 resolver_->SetPacScript("pac script", client2.CreateCallback());
382 ASSERT_EQ(1u, mock_proxy_resolver_->pending_requests().size());
383 scoped_refptr<MockAsyncProxyResolverBase::Request> request =
384 mock_proxy_resolver_->pending_requests()[0];
385 resolver_.reset();
386 client1.WaitForConnectionError();
387 EXPECT_EQ(ERR_ABORTED, client2.error());
388 }
389
390 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698