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

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

Issue 917863005: Implementation of ProxyResolver that uses a Mojo service. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@sam-v8-pac-utility-proxy
Patch Set: Rebase 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/proxy_resolver_mojo.h"
6
7 #include <list>
8 #include <map>
9 #include <string>
10
11 #include "base/bind.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/run_loop.h"
14 #include "base/stl_util.h"
15 #include "mojo/common/common_type_converters.h"
16 #include "net/base/net_log.h"
17 #include "net/base/test_completion_callback.h"
18 #include "net/dns/mock_host_resolver.h"
19 #include "net/proxy/mojo_proxy_resolver_factory.h"
20 #include "net/proxy/mojo_type_converters.h"
21 #include "net/proxy/proxy_info.h"
22 #include "net/proxy/proxy_resolver_script_data.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "third_party/mojo/src/mojo/public/cpp/bindings/binding.h"
25 #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h"
26 #include "url/gurl.h"
27
28 namespace net {
29
30 namespace {
31
32 static const char kScriptData[] = "FooBarBaz";
33 static const char kScriptData2[] = "BlahBlahBlah";
34
35 struct SetPacScriptAction {
36 public:
37 enum Action {
38 COMPLETE,
39 DROP,
40 };
41
42 static SetPacScriptAction ReturnResult(int error) {
43 SetPacScriptAction result;
44 result.error = error;
45 return result;
46 }
47
48 static SetPacScriptAction DropRequest() {
49 SetPacScriptAction result;
50 result.action = DROP;
51 return result;
52 }
53
54 Action action = COMPLETE;
55 int error = OK;
56 };
57
58 class MockMojoProxyResolver : public interfaces::ProxyResolver {
59 public:
60 explicit MockMojoProxyResolver(
61 mojo::InterfaceRequest<interfaces::ProxyResolver> req)
62 : pac_script_calls_(0), binding_(this, req.Pass()) {}
63 ~MockMojoProxyResolver() override {
64 STLDeleteContainerPairSecondPointers(proxy_results_.begin(),
65 proxy_results_.end());
66 };
67
68 void AddPacScriptAction(SetPacScriptAction action);
69 // Returned script data is UTF8.
70 std::string GetPacScriptData() { return pac_script_data_; }
71 int GetPacScriptCalls() { return pac_script_calls_; }
72
73 void AddProxyResult(const GURL& url,
74 int error,
75 mojo::Array<interfaces::ProxyServerPtr> proxy_servers);
76 void CloseRequestClient(const GURL& url);
77
78 void Disconnect() { binding_.Close(); }
79
80 void WaitForSetPacScript();
81
82 private:
83 struct ProxyResults {
84 explicit ProxyResults(bool close)
85 : close(close), error(OK), proxy_servers() {}
86 ProxyResults(int err, mojo::Array<interfaces::ProxyServerPtr>& s)
87 : close(false), error(err), proxy_servers(s.Pass()) {}
88
89 bool close;
90 int error;
91 mojo::Array<interfaces::ProxyServerPtr> proxy_servers;
92 };
93
94 // Overridden from interfaces::ProxyResolver:
95 void SetPacScript(const mojo::String& data,
96 const mojo::Callback<void(int32_t)>& callback) override;
97 void GetProxyForUrl(
98 const mojo::String& url,
99 interfaces::ProxyResolverRequestClientPtr client) override;
100
101 std::string pac_script_data_;
102 std::list<SetPacScriptAction> pac_script_actions_;
103 int pac_script_calls_;
104 base::Closure pac_script_quit_closure_;
105
106 std::map<GURL, ProxyResults*> proxy_results_;
107
108 mojo::Binding<interfaces::ProxyResolver> binding_;
109 };
110
111 void MockMojoProxyResolver::AddProxyResult(
112 const GURL& url,
113 int error,
114 mojo::Array<interfaces::ProxyServerPtr> proxy_servers) {
115 proxy_results_[url] = new ProxyResults(error, proxy_servers);
116 }
117
118 void MockMojoProxyResolver::CloseRequestClient(const GURL& url) {
119 proxy_results_[url] = new ProxyResults(true);
120 }
121
122 void MockMojoProxyResolver::AddPacScriptAction(SetPacScriptAction action) {
123 pac_script_actions_.push_back(action);
124 }
125
126 void MockMojoProxyResolver::SetPacScript(
127 const mojo::String& data,
128 const mojo::Callback<void(int32_t)>& callback) {
129 pac_script_data_ = data.To<std::string>();
130 pac_script_calls_++;
131
132 DCHECK(!pac_script_actions_.empty());
133 SetPacScriptAction action = pac_script_actions_.front();
134 pac_script_actions_.pop_front();
135
136 switch (action.action) {
137 case SetPacScriptAction::COMPLETE:
138 callback.Run(action.error);
139 break;
140 case SetPacScriptAction::DROP:
141 binding_.Close();
142 break;
143 }
144
145 if (!pac_script_quit_closure_.is_null())
146 pac_script_quit_closure_.Run();
147 pac_script_quit_closure_.Reset();
148 }
149
150 void MockMojoProxyResolver::WaitForSetPacScript() {
151 if (pac_script_calls_)
152 return;
153
154 base::RunLoop run_loop;
155 pac_script_quit_closure_ = run_loop.QuitClosure();
156 run_loop.Run();
157 }
158
159 void MockMojoProxyResolver::GetProxyForUrl(
160 const mojo::String& url,
161 interfaces::ProxyResolverRequestClientPtr client) {
162 ProxyResults* result = proxy_results_[url.To<GURL>()];
163 ASSERT_NE(nullptr, result);
164 if (result->close) {
165 client.reset();
166 } else {
167 client->ReportResult(result->error, result->proxy_servers.Clone());
168 }
169 }
170
171 class TestMojoProxyResolverFactory : public MojoProxyResolverFactory {
172 public:
173 TestMojoProxyResolverFactory();
174 ~TestMojoProxyResolverFactory();
175
176 // Overridden from MojoProxyResolverFactory:
177 void Create(mojo::InterfaceRequest<interfaces::ProxyResolver> req,
178 interfaces::HostResolverPtr host_resolver) override;
179
180 MockMojoProxyResolver& GetMockResolver() { return *mock_proxy_resolver_; }
181
182 void AddFuturePacScriptAction(int creation, SetPacScriptAction action);
183
184 int num_create_calls() const { return num_create_calls_; }
185 void WaitForCreateCalls(int num);
186
187 private:
188 int num_create_calls_;
189 base::Closure run_loop_quit_closure_;
190 std::map<int, std::list<SetPacScriptAction>> pac_script_actions_;
191
192 scoped_ptr<MockMojoProxyResolver> mock_proxy_resolver_;
193 };
194
195 TestMojoProxyResolverFactory::TestMojoProxyResolverFactory()
196 : num_create_calls_(0) {
197 }
198
199 TestMojoProxyResolverFactory::~TestMojoProxyResolverFactory() {
200 }
201
202 void TestMojoProxyResolverFactory::Create(
203 mojo::InterfaceRequest<interfaces::ProxyResolver> req,
204 interfaces::HostResolverPtr host_resolver) {
205 mock_proxy_resolver_.reset(new MockMojoProxyResolver(req.Pass()));
206
207 for (const auto& action : pac_script_actions_[num_create_calls_])
208 mock_proxy_resolver_->AddPacScriptAction(action);
209 num_create_calls_++;
210
211 if (!run_loop_quit_closure_.is_null())
212 run_loop_quit_closure_.Run();
213 run_loop_quit_closure_.Reset();
214 }
215
216 void TestMojoProxyResolverFactory::AddFuturePacScriptAction(
217 int creation,
218 SetPacScriptAction action) {
219 pac_script_actions_[creation].push_back(action);
220 }
221
222 void TestMojoProxyResolverFactory::WaitForCreateCalls(int num) {
223 while (num_create_calls_ < num) {
224 base::RunLoop run_loop;
225 run_loop_quit_closure_ = run_loop.QuitClosure();
226 run_loop.Run();
227 }
228 }
229
230 class Request {
231 public:
232 Request(ProxyResolverMojo* resolver, const GURL& url);
233
234 int Resolve();
235 void Cancel();
236 int WaitForResult();
237
238 int error() const { return error_; }
239 const ProxyInfo& results() const { return results_; }
240
241 private:
242 // Completion callback for ProxyResolverMojo::Resolve.
243 void OnResolveDone(int error);
244
245 ProxyResolverMojo* resolver_;
246 const GURL url_;
247 ProxyInfo results_;
248 ProxyResolver::RequestHandle handle_;
249 int error_;
250
251 base::Closure quit_closure_;
252 };
253
254 Request::Request(ProxyResolverMojo* resolver, const GURL& url)
255 : resolver_(resolver), url_(url), error_(0) {
256 }
257
258 int Request::Resolve() {
259 BoundNetLog net_log;
260 error_ = resolver_->GetProxyForURL(
261 url_, &results_,
262 base::Bind(&Request::OnResolveDone, base::Unretained(this)), &handle_,
263 net_log);
264 return error_;
265 }
266
267 void Request::Cancel() {
268 resolver_->CancelRequest(handle_);
269 }
270
271 void Request::OnResolveDone(int error) {
272 error_ = error;
273 if (!quit_closure_.is_null())
274 quit_closure_.Run();
275 quit_closure_.Reset();
276 }
277
278 int Request::WaitForResult() {
279 base::RunLoop run_loop;
280 quit_closure_ = run_loop.QuitClosure();
281 run_loop.Run();
282 return error_;
283 }
284
285 } // namespace
286
287 class ProxyResolverMojoTest : public testing::Test {
288 protected:
289 void SetUp() override {
290 mock_host_resolver_.rules()->AddRule("example.com", "1.2.3.4");
291
292 proxy_resolver_mojo_.reset(new ProxyResolverMojo(
293 &mojo_proxy_resolver_factory_, &mock_host_resolver_));
294 }
295
296 scoped_ptr<Request> MakeRequest(const GURL& url) {
297 return make_scoped_ptr(new Request(proxy_resolver_mojo_.get(), url));
298 }
299
300 mojo::Array<interfaces::ProxyServerPtr> ProxyServersFromPacString(
301 const std::string& pac_string) {
302 ProxyInfo proxy_info;
303 proxy_info.UsePacString(pac_string);
304
305 return mojo::Array<interfaces::ProxyServerPtr>::From(
306 proxy_info.proxy_list().GetAll());
307 }
308
309 MockHostResolver mock_host_resolver_;
310 TestMojoProxyResolverFactory mojo_proxy_resolver_factory_;
311 scoped_ptr<ProxyResolverMojo> proxy_resolver_mojo_;
312 };
313
314 TEST_F(ProxyResolverMojoTest, SetPacScript) {
315 TestCompletionCallback callback;
316 scoped_refptr<ProxyResolverScriptData> pac_script(
317 ProxyResolverScriptData::FromUTF8(kScriptData));
318 mojo_proxy_resolver_factory_.GetMockResolver().AddPacScriptAction(
319 SetPacScriptAction::ReturnResult(OK));
320 EXPECT_EQ(OK, callback.GetResult(proxy_resolver_mojo_->SetPacScript(
321 pac_script, callback.callback())));
322 EXPECT_EQ(kScriptData,
323 mojo_proxy_resolver_factory_.GetMockResolver().GetPacScriptData());
324 }
325
326 TEST_F(ProxyResolverMojoTest, SetPacScript_Empty) {
327 TestCompletionCallback callback;
328 scoped_refptr<ProxyResolverScriptData> pac_script(
329 ProxyResolverScriptData::FromUTF8(""));
330 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED,
331 callback.GetResult(proxy_resolver_mojo_->SetPacScript(
332 pac_script, callback.callback())));
333 }
334
335 TEST_F(ProxyResolverMojoTest, SetPacScript_Url) {
336 TestCompletionCallback callback;
337 scoped_refptr<ProxyResolverScriptData> pac_script(
338 ProxyResolverScriptData::FromURL(GURL("http://www.example.com")));
339 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED,
340 callback.GetResult(proxy_resolver_mojo_->SetPacScript(
341 pac_script, callback.callback())));
342 }
343
344 TEST_F(ProxyResolverMojoTest, SetPacScript_Failed) {
345 TestCompletionCallback callback;
346 scoped_refptr<ProxyResolverScriptData> pac_script(
347 ProxyResolverScriptData::FromUTF8(kScriptData));
348 mojo_proxy_resolver_factory_.GetMockResolver().AddPacScriptAction(
349 SetPacScriptAction::ReturnResult(ERR_PAC_STATUS_NOT_OK));
350 EXPECT_EQ(ERR_PAC_STATUS_NOT_OK,
351 callback.GetResult(proxy_resolver_mojo_->SetPacScript(
352 pac_script, callback.callback())));
353 }
354
355 TEST_F(ProxyResolverMojoTest, SetPacScript_Disconnected) {
356 scoped_refptr<ProxyResolverScriptData> pac_script(
357 ProxyResolverScriptData::FromUTF8(kScriptData));
358 TestCompletionCallback callback;
359 EXPECT_EQ(ERR_IO_PENDING, proxy_resolver_mojo_->SetPacScript(
360 pac_script, callback.callback()));
361 mojo_proxy_resolver_factory_.GetMockResolver().Disconnect();
362 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, callback.GetResult(ERR_IO_PENDING));
363
364 // The service should have been recreated transparently.
365 mojo_proxy_resolver_factory_.WaitForCreateCalls(2);
366 }
367
368 TEST_F(ProxyResolverMojoTest, SetPacScript_SuccessThenDisconnect) {
369 mojo_proxy_resolver_factory_.GetMockResolver().AddPacScriptAction(
370 SetPacScriptAction::ReturnResult(OK));
371 mojo_proxy_resolver_factory_.GetMockResolver().AddPacScriptAction(
372 SetPacScriptAction::DropRequest());
373 mojo_proxy_resolver_factory_.AddFuturePacScriptAction(
374 1, SetPacScriptAction::ReturnResult(OK));
375 {
376 scoped_refptr<ProxyResolverScriptData> pac_script(
377 ProxyResolverScriptData::FromUTF8(kScriptData));
378 TestCompletionCallback callback;
379 EXPECT_EQ(OK, callback.GetResult(proxy_resolver_mojo_->SetPacScript(
380 pac_script, callback.callback())));
381 EXPECT_EQ(
382 kScriptData,
383 mojo_proxy_resolver_factory_.GetMockResolver().GetPacScriptData());
384 }
385
386 {
387 scoped_refptr<ProxyResolverScriptData> pac_script(
388 ProxyResolverScriptData::FromUTF8(kScriptData2));
389 TestCompletionCallback callback;
390 EXPECT_EQ(ERR_IO_PENDING, proxy_resolver_mojo_->SetPacScript(
391 pac_script, callback.callback()));
392 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, callback.GetResult(ERR_IO_PENDING));
393 }
394
395 // The service should have been recreated transparently.
396 mojo_proxy_resolver_factory_.WaitForCreateCalls(2);
397
398 // Wait for SetPacScript() to be run.
399 mojo_proxy_resolver_factory_.GetMockResolver().WaitForSetPacScript();
400 EXPECT_EQ(1,
401 mojo_proxy_resolver_factory_.GetMockResolver().GetPacScriptCalls());
402 EXPECT_EQ(kScriptData,
403 mojo_proxy_resolver_factory_.GetMockResolver().GetPacScriptData());
404 }
405
406 TEST_F(ProxyResolverMojoTest, SetPacScript_Cancel) {
407 scoped_refptr<ProxyResolverScriptData> pac_script(
408 ProxyResolverScriptData::FromUTF8(kScriptData));
409 TestCompletionCallback callback;
410 mojo_proxy_resolver_factory_.GetMockResolver().AddPacScriptAction(
411 SetPacScriptAction::ReturnResult(OK));
412 EXPECT_EQ(ERR_IO_PENDING, proxy_resolver_mojo_->SetPacScript(
413 pac_script, callback.callback()));
414 proxy_resolver_mojo_->CancelSetPacScript();
415 }
416
417 TEST_F(ProxyResolverMojoTest, SetPacScript_CancelAndSetAgain) {
418 scoped_refptr<ProxyResolverScriptData> pac_script(
419 ProxyResolverScriptData::FromUTF8(kScriptData));
420 mojo_proxy_resolver_factory_.GetMockResolver().AddPacScriptAction(
421 SetPacScriptAction::ReturnResult(ERR_FAILED));
422 mojo_proxy_resolver_factory_.GetMockResolver().AddPacScriptAction(
423 SetPacScriptAction::ReturnResult(ERR_UNEXPECTED));
424 TestCompletionCallback callback1;
425 EXPECT_EQ(ERR_IO_PENDING, proxy_resolver_mojo_->SetPacScript(
426 pac_script, callback1.callback()));
427 proxy_resolver_mojo_->CancelSetPacScript();
428
429 TestCompletionCallback callback2;
430 EXPECT_EQ(ERR_IO_PENDING, proxy_resolver_mojo_->SetPacScript(
431 pac_script, callback2.callback()));
432 EXPECT_EQ(ERR_UNEXPECTED, callback2.GetResult(ERR_IO_PENDING));
433 EXPECT_EQ(2,
434 mojo_proxy_resolver_factory_.GetMockResolver().GetPacScriptCalls());
435 }
436
437 TEST_F(ProxyResolverMojoTest, GetProxyForURL) {
438 scoped_ptr<Request> request(MakeRequest(GURL("http://www.example.com")));
439 mojo_proxy_resolver_factory_.GetMockResolver().AddProxyResult(
440 GURL("http://www.example.com"), OK, ProxyServersFromPacString("DIRECT"));
441 EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
442 EXPECT_EQ(OK, request->WaitForResult());
443
444 EXPECT_EQ("DIRECT", request->results().ToPacString());
445 }
446
447 TEST_F(ProxyResolverMojoTest, GetProxyForURL_MultipleResults) {
448 static const char kPacString[] =
449 "PROXY foo1:80;DIRECT;SOCKS foo2:1234;"
450 "SOCKS5 foo3:1080;HTTPS foo4:443;QUIC foo6:8888";
451 scoped_ptr<Request> request(MakeRequest(GURL("http://www.example.com")));
452 mojo_proxy_resolver_factory_.GetMockResolver().AddProxyResult(
453 GURL("http://www.example.com"), OK,
454 ProxyServersFromPacString(kPacString));
455 EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
456 EXPECT_EQ(OK, request->WaitForResult());
457
458 EXPECT_EQ(kPacString, request->results().ToPacString());
459 }
460
461 TEST_F(ProxyResolverMojoTest, GetProxyForURL_Error) {
462 scoped_ptr<Request> request(MakeRequest(GURL("http://www.example.com")));
463 mojo_proxy_resolver_factory_.GetMockResolver().AddProxyResult(
464 GURL("http://www.example.com"), ERR_UNEXPECTED,
465 mojo::Array<interfaces::ProxyServerPtr>());
466 EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
467 EXPECT_EQ(ERR_UNEXPECTED, request->WaitForResult());
468
469 EXPECT_TRUE(request->results().is_empty());
470 }
471
472 TEST_F(ProxyResolverMojoTest, GetProxyForURL_Cancel) {
473 scoped_ptr<Request> request(MakeRequest(GURL("http://www.example.com")));
474 mojo_proxy_resolver_factory_.GetMockResolver().AddProxyResult(
475 GURL("http://www.example.com"), OK, ProxyServersFromPacString("DIRECT"));
476 EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
477 request->Cancel();
478 }
479
480 TEST_F(ProxyResolverMojoTest, GetProxyForURL_MultipleRequests) {
481 mojo_proxy_resolver_factory_.GetMockResolver().AddProxyResult(
482 GURL("http://www.example.com"), OK, ProxyServersFromPacString("DIRECT"));
483 mojo_proxy_resolver_factory_.GetMockResolver().AddProxyResult(
484 GURL("https://www.chromium.org"), OK,
485 ProxyServersFromPacString("HTTPS foo:443"));
486
487 scoped_ptr<Request> request1(MakeRequest(GURL("http://www.example.com")));
488 EXPECT_EQ(ERR_IO_PENDING, request1->Resolve());
489 scoped_ptr<Request> request2(MakeRequest(GURL("https://www.chromium.org")));
490 EXPECT_EQ(ERR_IO_PENDING, request2->Resolve());
491
492 EXPECT_EQ(OK, request1->WaitForResult());
493 EXPECT_EQ(OK, request2->WaitForResult());
494
495 EXPECT_EQ("DIRECT", request1->results().ToPacString());
496 EXPECT_EQ("HTTPS foo:443", request2->results().ToPacString());
497 }
498
499 TEST_F(ProxyResolverMojoTest, GetProxyForURL_Disconnect) {
500 {
501 scoped_ptr<Request> request(MakeRequest(GURL("http://www.example.com")));
502 mojo_proxy_resolver_factory_.GetMockResolver().AddProxyResult(
503 GURL("http://www.example.com"), OK,
504 ProxyServersFromPacString("DIRECT"));
505 EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
506 mojo_proxy_resolver_factory_.GetMockResolver().Disconnect();
507 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, request->WaitForResult());
508 EXPECT_TRUE(request->results().is_empty());
509 }
510
511 // The service should have been recreated transparently.
512 mojo_proxy_resolver_factory_.WaitForCreateCalls(2);
513
514 {
515 scoped_ptr<Request> request(MakeRequest(GURL("http://www.example.com")));
516 mojo_proxy_resolver_factory_.GetMockResolver().AddProxyResult(
517 GURL("http://www.example.com"), OK,
518 ProxyServersFromPacString("DIRECT"));
519 EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
520 EXPECT_EQ(OK, request->WaitForResult());
521 EXPECT_EQ("DIRECT", request->results().ToPacString());
522 }
523 }
524
525 TEST_F(ProxyResolverMojoTest, GetProxyForURL_ClientClosed) {
526 scoped_ptr<Request> request(MakeRequest(GURL("http://www.example.com")));
527 mojo_proxy_resolver_factory_.GetMockResolver().CloseRequestClient(
528 GURL("http://www.example.com"));
529 EXPECT_EQ(ERR_IO_PENDING, request->Resolve());
530 EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, request->WaitForResult());
531
532 EXPECT_TRUE(request->results().is_empty());
533 }
534
535 } // namespace net
OLDNEW
« net/proxy/proxy_resolver_mojo.cc ('K') | « net/proxy/proxy_resolver_mojo.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698