1 // Copyright (c) 2011 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 "chrome/browser/chromeos/proxy_config_service_impl.h"
6
7 #include <map>
8 #include <string>
9 #include <vector>
10
11 #include "base/format_macros.h"
12 #include "base/logging.h"
13 #include "base/string_util.h"
14 #include "base/stringprintf.h"
15 #include "chrome/browser/chromeos/cros/cros_library.h"
16 #include "content/browser/browser_thread.h"
17 #include "content/common/json_value_serializer.h"
18 #include "net/proxy/proxy_config_service_common_unittest.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "testing/platform_test.h"
21
22 namespace chromeos {
23
24 namespace {
25
26 struct Input { // Fields of chromeos::ProxyConfigServiceImpl::ProxyConfig.
27 ProxyConfigServiceImpl::ProxyConfig::Mode mode;
28 const char* pac_url;
29 const char* single_uri;
30 const char* http_uri;
31 const char* https_uri;
32 const char* ftp_uri;
33 const char* socks_uri;
34 const char* bypass_rules;
35 };
36
37 // Builds an identifier for each test in an array.
38 #define TEST_DESC(desc) base::StringPrintf("at line %d <%s>", __LINE__, desc)
39
40 // Shortcuts to declare enums within chromeos's ProxyConfig.
41 #define MK_MODE(mode) ProxyConfigServiceImpl::ProxyConfig::MODE_##mode
42 #define MK_SRC(src) ProxyConfigServiceImpl::ProxyConfig::SOURCE_##src
43 #define MK_SCHM(scheme) net::ProxyServer::SCHEME_##scheme
44
45 // Inspired from net/proxy/proxy_config_service_linux_unittest.cc.
46 const struct {
47 // Short description to identify the test
48 std::string description;
49
50 bool is_valid;
51 bool test_read_write_access;
52
53 Input input;
54
55 // Expected outputs from fields of net::ProxyConfig (via IO).
56 bool auto_detect;
57 GURL pac_url;
58 net::ProxyRulesExpectation proxy_rules;
59 } tests[] = {
60 {
61 TEST_DESC("No proxying"),
62
63 true, // is_valid
64 true, // test_read_write_access
65
66 { // Input.
67 MK_MODE(DIRECT), // mode
68 },
69
70 // Expected result.
71 false, // auto_detect
72 GURL(), // pac_url
73 net::ProxyRulesExpectation::Empty(), // proxy_rules
74 },
75
76 {
77 TEST_DESC("Auto detect"),
78
79 true, // is_valid
80 true, // test_read_write_access
81
82 { // Input.
83 MK_MODE(AUTO_DETECT), // mode
84 },
85
86 // Expected result.
87 true, // auto_detect
88 GURL(), // pac_url
89 net::ProxyRulesExpectation::Empty(), // proxy_rules
90 },
91
92 {
93 TEST_DESC("Valid PAC URL"),
94
95 true, // is_valid
96 true, // test_read_write_access
97
98 { // Input.
99 MK_MODE(PAC_SCRIPT), // mode
100 "http://wpad/wpad.dat", // pac_url
101 },
102
103 // Expected result.
104 false, // auto_detect
105 GURL("http://wpad/wpad.dat"), // pac_url
106 net::ProxyRulesExpectation::Empty(), // proxy_rules
107 },
108
109 {
110 TEST_DESC("Invalid PAC URL"),
111
112 false, // is_valid
113 false, // test_read_write_access
114
115 { // Input.
116 MK_MODE(PAC_SCRIPT), // mode
117 "wpad.dat", // pac_url
118 },
119
120 // Expected result.
121 false, // auto_detect
122 GURL(), // pac_url
123 net::ProxyRulesExpectation::Empty(), // proxy_rules
124 },
125
126 {
127 TEST_DESC("Single-host in proxy list"),
128
129 true, // is_valid
130 true, // test_read_write_access
131
132 { // Input.
133 MK_MODE(SINGLE_PROXY), // mode
134 NULL, // pac_url
135 "www.google.com", // single_uri
136 },
137
138 // Expected result.
139 false, // auto_detect
140 GURL(), // pac_url
141 net::ProxyRulesExpectation::Single( // proxy_rules
142 "www.google.com:80", // single proxy
143 ""), // bypass rules
144 },
145
146 {
147 TEST_DESC("Single-host, different port"),
148
149 true, // is_valid
150 false, // test_read_write_access
151
152 { // Input.
153 MK_MODE(SINGLE_PROXY), // mode
154 NULL, // pac_url
155 "www.google.com:99", // single_uri
156 },
157
158 // Expected result.
159 false, // auto_detect
160 GURL(), // pac_url
161 net::ProxyRulesExpectation::Single( // proxy_rules
162 "www.google.com:99", // single
163 ""), // bypass rules
164 },
165
166 {
167 TEST_DESC("Tolerate a scheme"),
168
169 true, // is_valid
170 false, // test_read_write_access
171
172 { // Input.
173 MK_MODE(SINGLE_PROXY), // mode
174 NULL, // pac_url
175 "http://www.google.com:99", // single_uri
176 },
177
178 // Expected result.
179 false, // auto_detect
180 GURL(), // pac_url
181 net::ProxyRulesExpectation::Single( // proxy_rules
182 "www.google.com:99", // single proxy
183 ""), // bypass rules
184 },
185
186 {
187 TEST_DESC("Per-scheme proxy rules"),
188
189 true, // is_valid
190 true, // test_read_write_access
191
192 { // Input.
193 MK_MODE(PROXY_PER_SCHEME), // mode
194 NULL, // pac_url
195 NULL, // single_uri
196 "www.google.com:80", // http_uri
197 "www.foo.com:110", // https_uri
198 "ftp.foo.com:121", // ftp_uri
199 "socks.com:888", // socks_uri
200 },
201
202 // Expected result.
203 false, // auto_detect
204 GURL(), // pac_url
205 net::ProxyRulesExpectation::PerSchemeWithSocks( // proxy_rules
206 "www.google.com:80", // http
207 "https://www.foo.com:110", // https
208 "ftp.foo.com:121", // ftp
209 "socks5://socks.com:888", // fallback proxy
210 ""), // bypass rules
211 },
212
213 {
214 TEST_DESC("Bypass rules"),
215
216 true, // is_valid
217 true, // test_read_write_access
218
219 { // Input.
220 MK_MODE(SINGLE_PROXY), // mode
221 NULL, // pac_url
222 "www.google.com", // single_uri
223 NULL, NULL, NULL, NULL, // per-proto
224 ".google.com, foo.com:99, 1.2.3.4:22, 127.0.0.1/8", // bypass_rules
225 },
226
227 // Expected result.
228 false, // auto_detect
229 GURL(), // pac_url
230 net::ProxyRulesExpectation::Single( // proxy_rules
231 "www.google.com:80", // single proxy
232 "*.google.com,*foo.com:99,1.2.3.4:22,127.0.0.1/8"), // bypass_rules
233 },
234 }; // tests
235
236 } // namespace
237
238 class ProxyConfigServiceImplTest : public PlatformTest {
239 protected:
ProxyConfigServiceImplTest()240 ProxyConfigServiceImplTest()
241 : ui_thread_(BrowserThread::UI, &message_loop_),
242 io_thread_(BrowserThread::IO, &message_loop_) {
243 }
244
~ProxyConfigServiceImplTest()245 virtual ~ProxyConfigServiceImplTest() {
246 config_service_ = NULL;
247 MessageLoop::current()->RunAllPending();
248 }
249
CreateConfigService(const ProxyConfigServiceImpl::ProxyConfig & init_config)250 void CreateConfigService(
251 const ProxyConfigServiceImpl::ProxyConfig& init_config) {
252 // Instantiate proxy config service with |init_config|.
253 config_service_ = new ProxyConfigServiceImpl(init_config);
254 }
255
SetAutomaticProxy(ProxyConfigServiceImpl::ProxyConfig::Mode mode,ProxyConfigServiceImpl::ProxyConfig::Source source,const char * pac_url,ProxyConfigServiceImpl::ProxyConfig * config,ProxyConfigServiceImpl::ProxyConfig::AutomaticProxy * automatic_proxy)256 void SetAutomaticProxy(
257 ProxyConfigServiceImpl::ProxyConfig::Mode mode,
258 ProxyConfigServiceImpl::ProxyConfig::Source source,
259 const char* pac_url,
260 ProxyConfigServiceImpl::ProxyConfig* config,
261 ProxyConfigServiceImpl::ProxyConfig::AutomaticProxy* automatic_proxy) {
262 config->mode = mode;
263 automatic_proxy->source = source;
264 if (pac_url)
265 automatic_proxy->pac_url = GURL(pac_url);
266 }
267
SetManualProxy(ProxyConfigServiceImpl::ProxyConfig::Mode mode,ProxyConfigServiceImpl::ProxyConfig::Source source,const char * server_uri,net::ProxyServer::Scheme scheme,ProxyConfigServiceImpl::ProxyConfig * config,ProxyConfigServiceImpl::ProxyConfig::ManualProxy * manual_proxy)268 void SetManualProxy(
269 ProxyConfigServiceImpl::ProxyConfig::Mode mode,
270 ProxyConfigServiceImpl::ProxyConfig::Source source,
271 const char* server_uri,
272 net::ProxyServer::Scheme scheme,
273 ProxyConfigServiceImpl::ProxyConfig* config,
274 ProxyConfigServiceImpl::ProxyConfig::ManualProxy* manual_proxy) {
275 if (!server_uri)
276 return;
277 config->mode = mode;
278 manual_proxy->source = source;
279 manual_proxy->server = net::ProxyServer::FromURI(server_uri, scheme);
280 }
281
InitConfigWithTestInput(const Input & input,ProxyConfigServiceImpl::ProxyConfig::Source source,ProxyConfigServiceImpl::ProxyConfig * init_config)282 void InitConfigWithTestInput(
283 const Input& input, ProxyConfigServiceImpl::ProxyConfig::Source source,
284 ProxyConfigServiceImpl::ProxyConfig* init_config) {
285 switch (input.mode) {
286 case MK_MODE(DIRECT):
287 case MK_MODE(AUTO_DETECT):
288 case MK_MODE(PAC_SCRIPT):
289 SetAutomaticProxy(input.mode, source, input.pac_url, init_config,
290 &init_config->automatic_proxy);
291 return;
292 case MK_MODE(SINGLE_PROXY):
293 SetManualProxy(input.mode, source, input.single_uri, MK_SCHM(HTTP),
294 init_config, &init_config->single_proxy);
295 break;
296 case MK_MODE(PROXY_PER_SCHEME):
297 SetManualProxy(input.mode, source, input.http_uri, MK_SCHM(HTTP),
298 init_config, &init_config->http_proxy);
299 SetManualProxy(input.mode, source, input.https_uri, MK_SCHM(HTTPS),
300 init_config, &init_config->https_proxy);
301 SetManualProxy(input.mode, source, input.ftp_uri, MK_SCHM(HTTP),
302 init_config, &init_config->ftp_proxy);
303 SetManualProxy(input.mode, source, input.socks_uri, MK_SCHM(SOCKS5),
304 init_config, &init_config->socks_proxy);
305 break;
306 }
307 if (input.bypass_rules) {
308 init_config->bypass_rules.ParseFromStringUsingSuffixMatching(
309 input.bypass_rules);
310 }
311 }
312
TestReadWriteAccessForMode(const Input & input,ProxyConfigServiceImpl::ProxyConfig::Source source)313 void TestReadWriteAccessForMode(const Input& input,
314 ProxyConfigServiceImpl::ProxyConfig::Source source) {
315 // Init config from |source|.
316 ProxyConfigServiceImpl::ProxyConfig init_config;
317 InitConfigWithTestInput(input, source, &init_config);
318 CreateConfigService(init_config);
319
320 ProxyConfigServiceImpl::ProxyConfig config;
321 config_service()->UIGetProxyConfig(&config);
322
323 // For owner, write access to config should be equal CanBeWrittenByOwner().
324 // For non-owner, config is never writeable.
325 bool expected_writeable_by_owner = CanBeWrittenByOwner(source);
326 if (config.mode == MK_MODE(PROXY_PER_SCHEME)) {
327 if (input.http_uri) {
328 EXPECT_EQ(expected_writeable_by_owner,
329 config.CanBeWrittenByUser(true, "http"));
330 EXPECT_FALSE(config.CanBeWrittenByUser(false, "http"));
331 }
332 if (input.https_uri) {
333 EXPECT_EQ(expected_writeable_by_owner,
334 config.CanBeWrittenByUser(true, "http"));
335 EXPECT_FALSE(config.CanBeWrittenByUser(false, "https"));
336 }
337 if (input.ftp_uri) {
338 EXPECT_EQ(expected_writeable_by_owner,
339 config.CanBeWrittenByUser(true, "http"));
340 EXPECT_FALSE(config.CanBeWrittenByUser(false, "ftp"));
341 }
342 if (input.socks_uri) {
343 EXPECT_EQ(expected_writeable_by_owner,
344 config.CanBeWrittenByUser(true, "http"));
345 EXPECT_FALSE(config.CanBeWrittenByUser(false, "socks"));
346 }
347 } else {
348 EXPECT_EQ(expected_writeable_by_owner,
349 config.CanBeWrittenByUser(true, std::string()));
350 EXPECT_FALSE(config.CanBeWrittenByUser(false, std::string()));
351 }
352 }
353
TestReadWriteAccessForScheme(ProxyConfigServiceImpl::ProxyConfig::Source source,const char * server_uri,const std::string & scheme)354 void TestReadWriteAccessForScheme(
355 ProxyConfigServiceImpl::ProxyConfig::Source source,
356 const char* server_uri,
357 const std::string& scheme) {
358 // Init with manual |scheme| proxy.
359 ProxyConfigServiceImpl::ProxyConfig init_config;
360 ProxyConfigServiceImpl::ProxyConfig::ManualProxy* proxy =
361 init_config.MapSchemeToProxy(scheme);
362 net::ProxyServer::Scheme net_scheme = MK_SCHM(HTTP);
363 if (scheme == "http" || scheme == "ftp")
364 net_scheme = MK_SCHM(HTTP);
365 else if (scheme == "https")
366 net_scheme = MK_SCHM(HTTPS);
367 else if (scheme == "socks")
368 net_scheme = MK_SCHM(SOCKS4);
369 SetManualProxy(MK_MODE(PROXY_PER_SCHEME), source, server_uri, net_scheme,
370 &init_config, proxy);
371 CreateConfigService(init_config);
372
373 ProxyConfigServiceImpl::ProxyConfig config;
374 config_service()->UIGetProxyConfig(&config);
375
376 // For owner, write access to config should be equal CanBeWrittenByOwner().
377 // For non-owner, config is never writeable.
378 bool expected_writeable_by_owner = CanBeWrittenByOwner(source);
379 EXPECT_EQ(expected_writeable_by_owner,
380 config.CanBeWrittenByUser(true, scheme));
381 EXPECT_FALSE(config.CanBeWrittenByUser(false, scheme));
382
383 const char* all_schemes[] = {
384 "http", "https", "ftp", "socks",
385 };
386
387 // Rest of protos should be writeable by owner, but not writeable by
388 // non-owner.
389 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(all_schemes); ++i) {
390 if (scheme == all_schemes[i])
391 continue;
392 EXPECT_TRUE(config.CanBeWrittenByUser(true, all_schemes[i]));
393 EXPECT_FALSE(config.CanBeWrittenByUser(false, all_schemes[i]));
394 }
395 }
396
397 // Synchronously gets the latest proxy config.
SyncGetLatestProxyConfig(net::ProxyConfig * config)398 bool SyncGetLatestProxyConfig(net::ProxyConfig* config) {
399 // Let message loop process all messages.
400 MessageLoop::current()->RunAllPending();
401 // Calls IOGetProxyConfig (which is called from
402 // ProxyConfigService::GetLatestProxyConfig), running on faked IO thread.
403 return config_service_->IOGetProxyConfig(config);
404 }
405
config_service() const406 ProxyConfigServiceImpl* config_service() const {
407 return config_service_;
408 }
409
410 private:
CanBeWrittenByOwner(ProxyConfigServiceImpl::ProxyConfig::Source source) const411 bool CanBeWrittenByOwner(
412 ProxyConfigServiceImpl::ProxyConfig::Source source) const {
413 return source == MK_SRC(POLICY) ? false : true;
414 }
415
416 ScopedStubCrosEnabler stub_cros_enabler_;
417 MessageLoop message_loop_;
418 BrowserThread ui_thread_;
419 BrowserThread io_thread_;
420
421 scoped_refptr<ProxyConfigServiceImpl> config_service_;
422 };
423
TEST_F(ProxyConfigServiceImplTest,ChromeosProxyConfigToNetProxyConfig)424 TEST_F(ProxyConfigServiceImplTest, ChromeosProxyConfigToNetProxyConfig) {
425 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
426 SCOPED_TRACE(StringPrintf("Test[%" PRIuS "] %s", i,
427 tests[i].description.c_str()));
428
429 ProxyConfigServiceImpl::ProxyConfig init_config;
430 InitConfigWithTestInput(tests[i].input, MK_SRC(OWNER), &init_config);
431 CreateConfigService(init_config);
432
433 net::ProxyConfig config;
434 SyncGetLatestProxyConfig(&config);
435
436 EXPECT_EQ(tests[i].auto_detect, config.auto_detect());
437 EXPECT_EQ(tests[i].pac_url, config.pac_url());
438 EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules()));
439 }
440 }
441
TEST_F(ProxyConfigServiceImplTest,ModifyFromUI)442 TEST_F(ProxyConfigServiceImplTest, ModifyFromUI) {
443 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
444 SCOPED_TRACE(StringPrintf("Test[%" PRIuS "] %s", i,
445 tests[i].description.c_str()));
446
447 // Init with direct.
448 ProxyConfigServiceImpl::ProxyConfig init_config;
449 SetAutomaticProxy(MK_MODE(DIRECT), MK_SRC(OWNER), NULL, &init_config,
450 &init_config.automatic_proxy);
451 CreateConfigService(init_config);
452
453 // Set config to tests[i].input via UI.
454 net::ProxyBypassRules bypass_rules;
455 const Input& input = tests[i].input;
456 switch (input.mode) {
457 case MK_MODE(DIRECT) :
458 config_service()->UISetProxyConfigToDirect();
459 break;
460 case MK_MODE(AUTO_DETECT) :
461 config_service()->UISetProxyConfigToAutoDetect();
462 break;
463 case MK_MODE(PAC_SCRIPT) :
464 config_service()->UISetProxyConfigToPACScript(GURL(input.pac_url));
465 break;
466 case MK_MODE(SINGLE_PROXY) :
467 config_service()->UISetProxyConfigToSingleProxy(
468 net::ProxyServer::FromURI(input.single_uri, MK_SCHM(HTTP)));
469 if (input.bypass_rules) {
470 bypass_rules.ParseFromStringUsingSuffixMatching(input.bypass_rules);
471 config_service()->UISetProxyConfigBypassRules(bypass_rules);
472 }
473 break;
474 case MK_MODE(PROXY_PER_SCHEME) :
475 if (input.http_uri) {
476 config_service()->UISetProxyConfigToProxyPerScheme("http",
477 net::ProxyServer::FromURI(input.http_uri, MK_SCHM(HTTP)));
478 }
479 if (input.https_uri) {
480 config_service()->UISetProxyConfigToProxyPerScheme("https",
481 net::ProxyServer::FromURI(input.https_uri, MK_SCHM(HTTPS)));
482 }
483 if (input.ftp_uri) {
484 config_service()->UISetProxyConfigToProxyPerScheme("ftp",
485 net::ProxyServer::FromURI(input.ftp_uri, MK_SCHM(HTTP)));
486 }
487 if (input.socks_uri) {
488 config_service()->UISetProxyConfigToProxyPerScheme("socks",
489 net::ProxyServer::FromURI(input.socks_uri, MK_SCHM(SOCKS5)));
490 }
491 if (input.bypass_rules) {
492 bypass_rules.ParseFromStringUsingSuffixMatching(input.bypass_rules);
493 config_service()->UISetProxyConfigBypassRules(bypass_rules);
494 }
495 break;
496 }
497
498 // Retrieve config from IO thread.
499 net::ProxyConfig io_config;
500 SyncGetLatestProxyConfig(&io_config);
501 EXPECT_EQ(tests[i].auto_detect, io_config.auto_detect());
502 EXPECT_EQ(tests[i].pac_url, io_config.pac_url());
503 EXPECT_TRUE(tests[i].proxy_rules.Matches(io_config.proxy_rules()));
504
505 // Retrieve config from UI thread.
506 ProxyConfigServiceImpl::ProxyConfig ui_config;
507 config_service()->UIGetProxyConfig(&ui_config);
508 EXPECT_EQ(input.mode, ui_config.mode);
509 if (tests[i].is_valid) {
510 if (input.pac_url)
511 EXPECT_EQ(GURL(input.pac_url), ui_config.automatic_proxy.pac_url);
512 const net::ProxyRulesExpectation& proxy_rules = tests[i].proxy_rules;
513 if (input.single_uri)
514 EXPECT_EQ(proxy_rules.single_proxy,
515 ui_config.single_proxy.server.ToURI());
516 if (input.http_uri)
517 EXPECT_EQ(proxy_rules.proxy_for_http,
518 ui_config.http_proxy.server.ToURI());
519 if (input.https_uri)
520 EXPECT_EQ(proxy_rules.proxy_for_https,
521 ui_config.https_proxy.server.ToURI());
522 if (input.ftp_uri)
523 EXPECT_EQ(proxy_rules.proxy_for_ftp,
524 ui_config.ftp_proxy.server.ToURI());
525 if (input.socks_uri) {
526 EXPECT_EQ(proxy_rules.fallback_proxy,
527 ui_config.socks_proxy.server.ToURI());
528 }
529 if (input.bypass_rules)
530 EXPECT_TRUE(bypass_rules.Equals(ui_config.bypass_rules));
531 }
532 }
533 }
534
TEST_F(ProxyConfigServiceImplTest,ProxyChangedObserver)535 TEST_F(ProxyConfigServiceImplTest, ProxyChangedObserver) {
536 // This is used to observe for OnProxyConfigChanged notification.
537 class ProxyChangedObserver : public net::ProxyConfigService::Observer {
538 public:
539 explicit ProxyChangedObserver(
540 const scoped_refptr<ProxyConfigServiceImpl>& config_service)
541 : config_service_(config_service) {
542 config_service_->AddObserver(this);
543 }
544 virtual ~ProxyChangedObserver() {
545 config_service_->RemoveObserver(this);
546 }
547 net::ProxyConfigService::ConfigAvailability availability() const {
548 return availability_;
549 }
550 const net::ProxyConfig& config() const {
551 return config_;
552 }
553
554 private:
555 virtual void OnProxyConfigChanged(
556 const net::ProxyConfig& config,
557 net::ProxyConfigService::ConfigAvailability availability) {
558 config_ = config;
559 availability_ = availability;
560 }
561
562 scoped_refptr<ProxyConfigServiceImpl> config_service_;
563 net::ProxyConfigService::ConfigAvailability availability_;
564 net::ProxyConfig config_;
565 };
566
567 // Init with direct.
568 ProxyConfigServiceImpl::ProxyConfig init_config;
569 SetAutomaticProxy(MK_MODE(DIRECT), MK_SRC(OWNER), NULL, &init_config,
570 &init_config.automatic_proxy);
571 CreateConfigService(init_config);
572
573 ProxyChangedObserver observer(config_service());
574
575 // Set to pac script from UI.
576 EXPECT_TRUE(config_service()->UISetProxyConfigToPACScript(
577 GURL("http://wpad.dat")));
578 // Retrieve config from IO thread.
579 net::ProxyConfig io_config;
580 SyncGetLatestProxyConfig(&io_config);
581
582 // Observer should have gotten the same new proxy config.
583 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID, observer.availability());
584 EXPECT_TRUE(io_config.Equals(observer.config()));
585 }
586
TEST_F(ProxyConfigServiceImplTest,SerializeAndDeserialize)587 TEST_F(ProxyConfigServiceImplTest, SerializeAndDeserialize) {
588 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
589 if (!tests[i].is_valid)
590 continue;
591
592 SCOPED_TRACE(StringPrintf("Test[%" PRIuS "] %s", i,
593 tests[i].description.c_str()));
594
595 ProxyConfigServiceImpl::ProxyConfig source_config;
596 InitConfigWithTestInput(tests[i].input, MK_SRC(OWNER), &source_config);
597
598 // Serialize source_config into std::string.
599 std::string serialized_value;
600 EXPECT_TRUE(source_config.Serialize(&serialized_value));
601
602 // Deserialize std:string into target_config.
603 ProxyConfigServiceImpl::ProxyConfig target_config;
604 EXPECT_TRUE(target_config.Deserialize(serialized_value));
605
606 // Compare the configs after serialization and deserialization.
607 net::ProxyConfig net_src_cfg;
608 net::ProxyConfig net_tgt_cfg;
609 source_config.ToNetProxyConfig(&net_src_cfg);
610 target_config.ToNetProxyConfig(&net_tgt_cfg);
611 #if !defined(NDEBUG)
612 if (!net_src_cfg.Equals(net_tgt_cfg)) {
613 std::string src_output, tgt_output;
614 JSONStringValueSerializer src_serializer(&src_output);
615 src_serializer.Serialize(*net_src_cfg.ToValue());
616 JSONStringValueSerializer tgt_serializer(&tgt_output);
617 tgt_serializer.Serialize(*net_tgt_cfg.ToValue());
618 VLOG(1) << "source:\n" << src_output
619 << "\ntarget:\n" << tgt_output;
620 }
621 #endif // !defined(NDEBUG)
622 EXPECT_TRUE(net_src_cfg.Equals(net_tgt_cfg));
623 }
624 }
625
TEST_F(ProxyConfigServiceImplTest,ReadWriteAccessForPolicySource)626 TEST_F(ProxyConfigServiceImplTest, ReadWriteAccessForPolicySource) {
627 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
628 if (!tests[i].test_read_write_access)
629 continue;
630 SCOPED_TRACE(StringPrintf("Test[%" PRIuS "] %s", i,
631 tests[i].description.c_str()));
632 TestReadWriteAccessForMode(tests[i].input, MK_SRC(POLICY));
633 }
634 }
635
TEST_F(ProxyConfigServiceImplTest,ReadWriteAccessForOwnerSource)636 TEST_F(ProxyConfigServiceImplTest, ReadWriteAccessForOwnerSource) {
637 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
638 if (!tests[i].test_read_write_access)
639 continue;
640 SCOPED_TRACE(StringPrintf("Test[%" PRIuS "] %s", i,
641 tests[i].description.c_str()));
642 TestReadWriteAccessForMode(tests[i].input, MK_SRC(OWNER));
643 }
644 }
645
TEST_F(ProxyConfigServiceImplTest,ReadWriteAccessForMixedSchemes)646 TEST_F(ProxyConfigServiceImplTest, ReadWriteAccessForMixedSchemes) {
647 const char* http_uri = "www.google.com:80";
648 const char* https_uri = "www.foo.com:110";
649 const char* ftp_uri = "ftp.foo.com:121";
650 const char* socks_uri = "socks.com:888";
651
652 // Init with policy source.
653 TestReadWriteAccessForScheme(MK_SRC(POLICY), http_uri, "http");
654 TestReadWriteAccessForScheme(MK_SRC(POLICY), https_uri, "https");
655 TestReadWriteAccessForScheme(MK_SRC(POLICY), ftp_uri, "ftp");
656 TestReadWriteAccessForScheme(MK_SRC(POLICY), socks_uri, "socks");
657
658 // Init with owner source.
659 TestReadWriteAccessForScheme(MK_SRC(OWNER), http_uri, "http");
660 TestReadWriteAccessForScheme(MK_SRC(OWNER), https_uri, "https");
661 TestReadWriteAccessForScheme(MK_SRC(OWNER), ftp_uri, "ftp");
662 TestReadWriteAccessForScheme(MK_SRC(OWNER), socks_uri, "socks");
663 }
664
665 } // namespace chromeos
666