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: 240 ProxyConfigServiceImplTest() 241 : ui_thread_(BrowserThread::UI, &message_loop_), 242 io_thread_(BrowserThread::IO, &message_loop_) { 243 } 244 245 virtual ~ProxyConfigServiceImplTest() { 246 config_service_ = NULL; 247 MessageLoop::current()->RunAllPending(); 248 } 249 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 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 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 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 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 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. 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 406 ProxyConfigServiceImpl* config_service() const { 407 return config_service_; 408 } 409 410 private: 411 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 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 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 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 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 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 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 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