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

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

Powered by Google App Engine
This is Rietveld 408576698