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 "net/proxy/proxy_config_service_linux.h" 6 7 #include <map> 8 #include <string> 9 #include <vector> 10 11 #include "base/file_path.h" 12 #include "base/file_util.h" 13 #include "base/format_macros.h" 14 #include "base/logging.h" 15 #include "base/string_util.h" 16 #include "base/stringprintf.h" 17 #include "base/synchronization/waitable_event.h" 18 #include "base/task.h" 19 #include "base/threading/thread.h" 20 #include "net/proxy/proxy_config.h" 21 #include "net/proxy/proxy_config_service_common_unittest.h" 22 #include "testing/gtest/include/gtest/gtest.h" 23 #include "testing/platform_test.h" 24 25 namespace net { 26 namespace { 27 28 // Set of values for all environment variables that we might 29 // query. NULL represents an unset variable. 30 struct EnvVarValues { 31 // The strange capitalization is so that the field matches the 32 // environment variable name exactly. 33 const char *DESKTOP_SESSION, *HOME, 34 *KDEHOME, *KDE_SESSION_VERSION, 35 *auto_proxy, *all_proxy, 36 *http_proxy, *https_proxy, *ftp_proxy, 37 *SOCKS_SERVER, *SOCKS_VERSION, 38 *no_proxy; 39 }; 40 41 // Undo macro pollution from GDK includes (from message_loop.h). 42 #undef TRUE 43 #undef FALSE 44 45 // So as to distinguish between an unset gconf boolean variable and 46 // one that is false. 47 enum BoolSettingValue { 48 UNSET = 0, TRUE, FALSE 49 }; 50 51 // Set of values for all gconf settings that we might query. 52 struct GConfValues { 53 // strings 54 const char *mode, *autoconfig_url, 55 *http_host, *secure_host, *ftp_host, *socks_host; 56 // integers 57 int http_port, secure_port, ftp_port, socks_port; 58 // booleans 59 BoolSettingValue use_proxy, same_proxy, use_auth; 60 // string list 61 std::vector<std::string> ignore_hosts; 62 }; 63 64 // Mapping from a setting name to the location of the corresponding 65 // value (inside a EnvVarValues or GConfValues struct). 66 template<typename value_type> 67 struct SettingsTable { 68 typedef std::map<std::string, value_type*> map_type; 69 70 // Gets the value from its location 71 value_type Get(const std::string& key) { 72 typename map_type::const_iterator it = settings.find(key); 73 // In case there's a typo or the unittest becomes out of sync. 74 CHECK(it != settings.end()) << "key " << key << " not found"; 75 value_type* value_ptr = it->second; 76 return *value_ptr; 77 } 78 79 map_type settings; 80 }; 81 82 class MockEnvironment : public base::Environment { 83 public: 84 MockEnvironment() { 85 #define ENTRY(x) table.settings[#x] = &values.x 86 ENTRY(DESKTOP_SESSION); 87 ENTRY(HOME); 88 ENTRY(KDEHOME); 89 ENTRY(KDE_SESSION_VERSION); 90 ENTRY(auto_proxy); 91 ENTRY(all_proxy); 92 ENTRY(http_proxy); 93 ENTRY(https_proxy); 94 ENTRY(ftp_proxy); 95 ENTRY(no_proxy); 96 ENTRY(SOCKS_SERVER); 97 ENTRY(SOCKS_VERSION); 98 #undef ENTRY 99 Reset(); 100 } 101 102 // Zeros all environment values. 103 void Reset() { 104 EnvVarValues zero_values = { 0 }; 105 values = zero_values; 106 } 107 108 // Begin base::Environment implementation. 109 virtual bool GetVar(const char* variable_name, std::string* result) { 110 const char* env_value = table.Get(variable_name); 111 if (env_value) { 112 // Note that the variable may be defined but empty. 113 *result = env_value; 114 return true; 115 } 116 return false; 117 } 118 119 virtual bool SetVar(const char* variable_name, const std::string& new_value) { 120 ADD_FAILURE(); 121 return false; 122 } 123 124 virtual bool UnSetVar(const char* variable_name) { 125 ADD_FAILURE(); 126 return false; 127 } 128 // End base::Environment implementation. 129 130 // Intentionally public, for convenience when setting up a test. 131 EnvVarValues values; 132 133 private: 134 SettingsTable<const char*> table; 135 }; 136 137 class MockGConfSettingGetter 138 : public ProxyConfigServiceLinux::GConfSettingGetter { 139 public: 140 MockGConfSettingGetter() { 141 #define ENTRY(key, field) \ 142 strings_table.settings["/system/" key] = &values.field 143 ENTRY("proxy/mode", mode); 144 ENTRY("proxy/autoconfig_url", autoconfig_url); 145 ENTRY("http_proxy/host", http_host); 146 ENTRY("proxy/secure_host", secure_host); 147 ENTRY("proxy/ftp_host", ftp_host); 148 ENTRY("proxy/socks_host", socks_host); 149 #undef ENTRY 150 #define ENTRY(key, field) \ 151 ints_table.settings["/system/" key] = &values.field 152 ENTRY("http_proxy/port", http_port); 153 ENTRY("proxy/secure_port", secure_port); 154 ENTRY("proxy/ftp_port", ftp_port); 155 ENTRY("proxy/socks_port", socks_port); 156 #undef ENTRY 157 #define ENTRY(key, field) \ 158 bools_table.settings["/system/" key] = &values.field 159 ENTRY("http_proxy/use_http_proxy", use_proxy); 160 ENTRY("http_proxy/use_same_proxy", same_proxy); 161 ENTRY("http_proxy/use_authentication", use_auth); 162 #undef ENTRY 163 string_lists_table.settings["/system/http_proxy/ignore_hosts"] = 164 &values.ignore_hosts; 165 Reset(); 166 } 167 168 // Zeros all environment values. 169 void Reset() { 170 GConfValues zero_values = { 0 }; 171 values = zero_values; 172 } 173 174 virtual bool Init(MessageLoop* glib_default_loop, 175 MessageLoopForIO* file_loop) { 176 return true; 177 } 178 179 virtual void Shutdown() {} 180 181 virtual bool SetupNotification(ProxyConfigServiceLinux::Delegate* delegate) { 182 return true; 183 } 184 185 virtual MessageLoop* GetNotificationLoop() { 186 return NULL; 187 } 188 189 virtual const char* GetDataSource() { 190 return "test"; 191 } 192 193 virtual bool GetString(const char* key, std::string* result) { 194 const char* value = strings_table.Get(key); 195 if (value) { 196 *result = value; 197 return true; 198 } 199 return false; 200 } 201 202 virtual bool GetInt(const char* key, int* result) { 203 // We don't bother to distinguish unset keys from 0 values. 204 *result = ints_table.Get(key); 205 return true; 206 } 207 208 virtual bool GetBoolean(const char* key, bool* result) { 209 BoolSettingValue value = bools_table.Get(key); 210 switch (value) { 211 case UNSET: 212 return false; 213 case TRUE: 214 *result = true; 215 break; 216 case FALSE: 217 *result = false; 218 } 219 return true; 220 } 221 222 virtual bool GetStringList(const char* key, 223 std::vector<std::string>* result) { 224 *result = string_lists_table.Get(key); 225 // We don't bother to distinguish unset keys from empty lists. 226 return !result->empty(); 227 } 228 229 virtual bool BypassListIsReversed() { 230 return false; 231 } 232 233 virtual bool MatchHostsUsingSuffixMatching() { 234 return false; 235 } 236 237 // Intentionally public, for convenience when setting up a test. 238 GConfValues values; 239 240 private: 241 SettingsTable<const char*> strings_table; 242 SettingsTable<int> ints_table; 243 SettingsTable<BoolSettingValue> bools_table; 244 SettingsTable<std::vector<std::string> > string_lists_table; 245 }; 246 247 } // namespace 248 } // namespace net 249 250 // This helper class runs ProxyConfigServiceLinux::GetLatestProxyConfig() on 251 // the IO thread and synchronously waits for the result. 252 // Some code duplicated from proxy_script_fetcher_unittest.cc. 253 class SynchConfigGetter { 254 public: 255 // Takes ownership of |config_service|. 256 explicit SynchConfigGetter(net::ProxyConfigServiceLinux* config_service) 257 : event_(false, false), 258 io_thread_("IO_Thread"), 259 config_service_(config_service) { 260 // Start an IO thread. 261 base::Thread::Options options; 262 options.message_loop_type = MessageLoop::TYPE_IO; 263 io_thread_.StartWithOptions(options); 264 265 // Make sure the thread started. 266 io_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod( 267 this, &SynchConfigGetter::Init)); 268 Wait(); 269 } 270 271 ~SynchConfigGetter() { 272 // Let the config service post a destroy message to the IO thread 273 // before cleaning up that thread. 274 delete config_service_; 275 // Clean up the IO thread. 276 io_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod( 277 this, &SynchConfigGetter::Cleanup)); 278 Wait(); 279 } 280 281 // Does gconf setup and initial fetch of the proxy config, 282 // all on the calling thread (meant to be the thread with the 283 // default glib main loop, which is the UI thread). 284 void SetupAndInitialFetch() { 285 MessageLoop* file_loop = io_thread_.message_loop(); 286 DCHECK_EQ(MessageLoop::TYPE_IO, file_loop->type()); 287 // We pass the mock IO thread as both the IO and file threads. 288 config_service_->SetupAndFetchInitialConfig( 289 MessageLoop::current(), io_thread_.message_loop(), 290 static_cast<MessageLoopForIO*>(file_loop)); 291 } 292 // Synchronously gets the proxy config. 293 net::ProxyConfigService::ConfigAvailability SyncGetLatestProxyConfig( 294 net::ProxyConfig* config) { 295 io_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod( 296 this, &SynchConfigGetter::GetLatestConfigOnIOThread)); 297 Wait(); 298 *config = proxy_config_; 299 return get_latest_config_result_; 300 } 301 302 private: 303 // [Runs on |io_thread_|] 304 void Init() { 305 event_.Signal(); 306 } 307 308 // Calls GetLatestProxyConfig, running on |io_thread_| Signals |event_| 309 // on completion. 310 void GetLatestConfigOnIOThread() { 311 get_latest_config_result_ = 312 config_service_->GetLatestProxyConfig(&proxy_config_); 313 event_.Signal(); 314 } 315 316 // [Runs on |io_thread_|] Signals |event_| on cleanup completion. 317 void Cleanup() { 318 MessageLoop::current()->RunAllPending(); 319 event_.Signal(); 320 } 321 322 void Wait() { 323 event_.Wait(); 324 event_.Reset(); 325 } 326 327 base::WaitableEvent event_; 328 base::Thread io_thread_; 329 330 net::ProxyConfigServiceLinux* config_service_; 331 332 // The config obtained by |io_thread_| and read back by the main 333 // thread. 334 net::ProxyConfig proxy_config_; 335 336 // Return value from GetLatestProxyConfig(). 337 net::ProxyConfigService::ConfigAvailability get_latest_config_result_; 338 }; 339 340 DISABLE_RUNNABLE_METHOD_REFCOUNT(SynchConfigGetter); 341 342 namespace net { 343 344 // This test fixture is only really needed for the KDEConfigParser test case, 345 // but all the test cases with the same prefix ("ProxyConfigServiceLinuxTest") 346 // must use the same test fixture class (also "ProxyConfigServiceLinuxTest"). 347 class ProxyConfigServiceLinuxTest : public PlatformTest { 348 protected: 349 virtual void SetUp() { 350 PlatformTest::SetUp(); 351 // Set up a temporary KDE home directory. 352 std::string prefix("ProxyConfigServiceLinuxTest_user_home"); 353 file_util::CreateNewTempDirectory(prefix, &user_home_); 354 kde_home_ = user_home_.Append(FILE_PATH_LITERAL(".kde")); 355 FilePath path = kde_home_.Append(FILE_PATH_LITERAL("share")); 356 path = path.Append(FILE_PATH_LITERAL("config")); 357 file_util::CreateDirectory(path); 358 kioslaverc_ = path.Append(FILE_PATH_LITERAL("kioslaverc")); 359 // Set up paths but do not create the directory for .kde4. 360 kde4_home_ = user_home_.Append(FILE_PATH_LITERAL(".kde4")); 361 path = kde4_home_.Append(FILE_PATH_LITERAL("share")); 362 kde4_config_ = path.Append(FILE_PATH_LITERAL("config")); 363 kioslaverc4_ = kde4_config_.Append(FILE_PATH_LITERAL("kioslaverc")); 364 } 365 366 virtual void TearDown() { 367 // Delete the temporary KDE home directory. 368 file_util::Delete(user_home_, true); 369 PlatformTest::TearDown(); 370 } 371 372 FilePath user_home_; 373 // KDE3 paths. 374 FilePath kde_home_; 375 FilePath kioslaverc_; 376 // KDE4 paths. 377 FilePath kde4_home_; 378 FilePath kde4_config_; 379 FilePath kioslaverc4_; 380 }; 381 382 // Builds an identifier for each test in an array. 383 #define TEST_DESC(desc) base::StringPrintf("at line %d <%s>", __LINE__, desc) 384 385 TEST_F(ProxyConfigServiceLinuxTest, BasicGConfTest) { 386 std::vector<std::string> empty_ignores; 387 388 std::vector<std::string> google_ignores; 389 google_ignores.push_back("*.google.com"); 390 391 // Inspired from proxy_config_service_win_unittest.cc. 392 // Very neat, but harder to track down failures though. 393 const struct { 394 // Short description to identify the test 395 std::string description; 396 397 // Input. 398 GConfValues values; 399 400 // Expected outputs (availability and fields of ProxyConfig). 401 ProxyConfigService::ConfigAvailability availability; 402 bool auto_detect; 403 GURL pac_url; 404 ProxyRulesExpectation proxy_rules; 405 } tests[] = { 406 { 407 TEST_DESC("No proxying"), 408 { // Input. 409 "none", // mode 410 "", // autoconfig_url 411 "", "", "", "", // hosts 412 0, 0, 0, 0, // ports 413 FALSE, FALSE, FALSE, // use, same, auth 414 empty_ignores, // ignore_hosts 415 }, 416 417 // Expected result. 418 ProxyConfigService::CONFIG_VALID, 419 false, // auto_detect 420 GURL(), // pac_url 421 ProxyRulesExpectation::Empty(), 422 }, 423 424 { 425 TEST_DESC("Auto detect"), 426 { // Input. 427 "auto", // mode 428 "", // autoconfig_url 429 "", "", "", "", // hosts 430 0, 0, 0, 0, // ports 431 FALSE, FALSE, FALSE, // use, same, auth 432 empty_ignores, // ignore_hosts 433 }, 434 435 // Expected result. 436 ProxyConfigService::CONFIG_VALID, 437 true, // auto_detect 438 GURL(), // pac_url 439 ProxyRulesExpectation::Empty(), 440 }, 441 442 { 443 TEST_DESC("Valid PAC URL"), 444 { // Input. 445 "auto", // mode 446 "http://wpad/wpad.dat", // autoconfig_url 447 "", "", "", "", // hosts 448 0, 0, 0, 0, // ports 449 FALSE, FALSE, FALSE, // use, same, auth 450 empty_ignores, // ignore_hosts 451 }, 452 453 // Expected result. 454 ProxyConfigService::CONFIG_VALID, 455 false, // auto_detect 456 GURL("http://wpad/wpad.dat"), // pac_url 457 ProxyRulesExpectation::Empty(), 458 }, 459 460 { 461 TEST_DESC("Invalid PAC URL"), 462 { // Input. 463 "auto", // mode 464 "wpad.dat", // autoconfig_url 465 "", "", "", "", // hosts 466 0, 0, 0, 0, // ports 467 FALSE, FALSE, FALSE, // use, same, auth 468 empty_ignores, // ignore_hosts 469 }, 470 471 // Expected result. 472 ProxyConfigService::CONFIG_VALID, 473 false, // auto_detect 474 GURL(), // pac_url 475 ProxyRulesExpectation::Empty(), 476 }, 477 478 { 479 TEST_DESC("Single-host in proxy list"), 480 { // Input. 481 "manual", // mode 482 "", // autoconfig_url 483 "www.google.com", "", "", "", // hosts 484 80, 0, 0, 0, // ports 485 TRUE, TRUE, FALSE, // use, same, auth 486 empty_ignores, // ignore_hosts 487 }, 488 489 // Expected result. 490 ProxyConfigService::CONFIG_VALID, 491 false, // auto_detect 492 GURL(), // pac_url 493 ProxyRulesExpectation::Single( 494 "www.google.com:80", // single proxy 495 ""), // bypass rules 496 }, 497 498 { 499 TEST_DESC("use_http_proxy is honored"), 500 { // Input. 501 "manual", // mode 502 "", // autoconfig_url 503 "www.google.com", "", "", "", // hosts 504 80, 0, 0, 0, // ports 505 FALSE, TRUE, FALSE, // use, same, auth 506 empty_ignores, // ignore_hosts 507 }, 508 509 // Expected result. 510 ProxyConfigService::CONFIG_VALID, 511 false, // auto_detect 512 GURL(), // pac_url 513 ProxyRulesExpectation::Empty(), 514 }, 515 516 { 517 TEST_DESC("use_http_proxy and use_same_proxy are optional"), 518 { // Input. 519 "manual", // mode 520 "", // autoconfig_url 521 "www.google.com", "", "", "", // hosts 522 80, 0, 0, 0, // ports 523 UNSET, UNSET, FALSE, // use, same, auth 524 empty_ignores, // ignore_hosts 525 }, 526 527 // Expected result. 528 ProxyConfigService::CONFIG_VALID, 529 false, // auto_detect 530 GURL(), // pac_url 531 ProxyRulesExpectation::PerScheme( 532 "www.google.com:80", // http 533 "", // https 534 "", // ftp 535 ""), // bypass rules 536 }, 537 538 { 539 TEST_DESC("Single-host, different port"), 540 { // Input. 541 "manual", // mode 542 "", // autoconfig_url 543 "www.google.com", "", "", "", // hosts 544 88, 0, 0, 0, // ports 545 TRUE, TRUE, FALSE, // use, same, auth 546 empty_ignores, // ignore_hosts 547 }, 548 549 // Expected result. 550 ProxyConfigService::CONFIG_VALID, 551 false, // auto_detect 552 GURL(), // pac_url 553 ProxyRulesExpectation::Single( 554 "www.google.com:88", // single proxy 555 ""), // bypass rules 556 }, 557 558 { 559 TEST_DESC("Per-scheme proxy rules"), 560 { // Input. 561 "manual", // mode 562 "", // autoconfig_url 563 "www.google.com", // http_host 564 "www.foo.com", // secure_host 565 "ftp.foo.com", // ftp 566 "", // socks 567 88, 110, 121, 0, // ports 568 TRUE, FALSE, FALSE, // use, same, auth 569 empty_ignores, // ignore_hosts 570 }, 571 572 // Expected result. 573 ProxyConfigService::CONFIG_VALID, 574 false, // auto_detect 575 GURL(), // pac_url 576 ProxyRulesExpectation::PerScheme( 577 "www.google.com:88", // http 578 "www.foo.com:110", // https 579 "ftp.foo.com:121", // ftp 580 ""), // bypass rules 581 }, 582 583 { 584 TEST_DESC("socks"), 585 { // Input. 586 "manual", // mode 587 "", // autoconfig_url 588 "", "", "", "socks.com", // hosts 589 0, 0, 0, 99, // ports 590 TRUE, FALSE, FALSE, // use, same, auth 591 empty_ignores, // ignore_hosts 592 }, 593 594 // Expected result. 595 ProxyConfigService::CONFIG_VALID, 596 false, // auto_detect 597 GURL(), // pac_url 598 ProxyRulesExpectation::Single( 599 "socks5://socks.com:99", // single proxy 600 "") // bypass rules 601 }, 602 603 { 604 TEST_DESC("Bypass *.google.com"), 605 { // Input. 606 "manual", // mode 607 "", // autoconfig_url 608 "www.google.com", "", "", "", // hosts 609 80, 0, 0, 0, // ports 610 TRUE, TRUE, FALSE, // use, same, auth 611 google_ignores, // ignore_hosts 612 }, 613 614 ProxyConfigService::CONFIG_VALID, 615 false, // auto_detect 616 GURL(), // pac_url 617 ProxyRulesExpectation::Single( 618 "www.google.com:80", // single proxy 619 "*.google.com"), // bypass rules 620 }, 621 }; 622 623 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 624 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "] %s", i, 625 tests[i].description.c_str())); 626 MockEnvironment* env = new MockEnvironment; 627 MockGConfSettingGetter* gconf_getter = new MockGConfSettingGetter; 628 SynchConfigGetter sync_config_getter( 629 new ProxyConfigServiceLinux(env, gconf_getter)); 630 ProxyConfig config; 631 gconf_getter->values = tests[i].values; 632 sync_config_getter.SetupAndInitialFetch(); 633 ProxyConfigService::ConfigAvailability availability = 634 sync_config_getter.SyncGetLatestProxyConfig(&config); 635 EXPECT_EQ(tests[i].availability, availability); 636 637 if (availability == ProxyConfigService::CONFIG_VALID) { 638 EXPECT_EQ(tests[i].auto_detect, config.auto_detect()); 639 EXPECT_EQ(tests[i].pac_url, config.pac_url()); 640 EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules())); 641 } 642 } 643 } 644 645 TEST_F(ProxyConfigServiceLinuxTest, BasicEnvTest) { 646 // Inspired from proxy_config_service_win_unittest.cc. 647 const struct { 648 // Short description to identify the test 649 std::string description; 650 651 // Input. 652 EnvVarValues values; 653 654 // Expected outputs (availability and fields of ProxyConfig). 655 ProxyConfigService::ConfigAvailability availability; 656 bool auto_detect; 657 GURL pac_url; 658 ProxyRulesExpectation proxy_rules; 659 } tests[] = { 660 { 661 TEST_DESC("No proxying"), 662 { // Input. 663 NULL, // DESKTOP_SESSION 664 NULL, // HOME 665 NULL, // KDEHOME 666 NULL, // KDE_SESSION_VERSION 667 NULL, // auto_proxy 668 NULL, // all_proxy 669 NULL, NULL, NULL, // per-proto proxies 670 NULL, NULL, // SOCKS 671 "*", // no_proxy 672 }, 673 674 // Expected result. 675 ProxyConfigService::CONFIG_VALID, 676 false, // auto_detect 677 GURL(), // pac_url 678 ProxyRulesExpectation::Empty(), 679 }, 680 681 { 682 TEST_DESC("Auto detect"), 683 { // Input. 684 NULL, // DESKTOP_SESSION 685 NULL, // HOME 686 NULL, // KDEHOME 687 NULL, // KDE_SESSION_VERSION 688 "", // auto_proxy 689 NULL, // all_proxy 690 NULL, NULL, NULL, // per-proto proxies 691 NULL, NULL, // SOCKS 692 NULL, // no_proxy 693 }, 694 695 // Expected result. 696 ProxyConfigService::CONFIG_VALID, 697 true, // auto_detect 698 GURL(), // pac_url 699 ProxyRulesExpectation::Empty(), 700 }, 701 702 { 703 TEST_DESC("Valid PAC URL"), 704 { // Input. 705 NULL, // DESKTOP_SESSION 706 NULL, // HOME 707 NULL, // KDEHOME 708 NULL, // KDE_SESSION_VERSION 709 "http://wpad/wpad.dat", // auto_proxy 710 NULL, // all_proxy 711 NULL, NULL, NULL, // per-proto proxies 712 NULL, NULL, // SOCKS 713 NULL, // no_proxy 714 }, 715 716 // Expected result. 717 ProxyConfigService::CONFIG_VALID, 718 false, // auto_detect 719 GURL("http://wpad/wpad.dat"), // pac_url 720 ProxyRulesExpectation::Empty(), 721 }, 722 723 { 724 TEST_DESC("Invalid PAC URL"), 725 { // Input. 726 NULL, // DESKTOP_SESSION 727 NULL, // HOME 728 NULL, // KDEHOME 729 NULL, // KDE_SESSION_VERSION 730 "wpad.dat", // auto_proxy 731 NULL, // all_proxy 732 NULL, NULL, NULL, // per-proto proxies 733 NULL, NULL, // SOCKS 734 NULL, // no_proxy 735 }, 736 737 // Expected result. 738 ProxyConfigService::CONFIG_VALID, 739 false, // auto_detect 740 GURL(), // pac_url 741 ProxyRulesExpectation::Empty(), 742 }, 743 744 { 745 TEST_DESC("Single-host in proxy list"), 746 { // Input. 747 NULL, // DESKTOP_SESSION 748 NULL, // HOME 749 NULL, // KDEHOME 750 NULL, // KDE_SESSION_VERSION 751 NULL, // auto_proxy 752 "www.google.com", // all_proxy 753 NULL, NULL, NULL, // per-proto proxies 754 NULL, NULL, // SOCKS 755 NULL, // no_proxy 756 }, 757 758 // Expected result. 759 ProxyConfigService::CONFIG_VALID, 760 false, // auto_detect 761 GURL(), // pac_url 762 ProxyRulesExpectation::Single( 763 "www.google.com:80", // single proxy 764 ""), // bypass rules 765 }, 766 767 { 768 TEST_DESC("Single-host, different port"), 769 { // Input. 770 NULL, // DESKTOP_SESSION 771 NULL, // HOME 772 NULL, // KDEHOME 773 NULL, // KDE_SESSION_VERSION 774 NULL, // auto_proxy 775 "www.google.com:99", // all_proxy 776 NULL, NULL, NULL, // per-proto proxies 777 NULL, NULL, // SOCKS 778 NULL, // no_proxy 779 }, 780 781 // Expected result. 782 ProxyConfigService::CONFIG_VALID, 783 false, // auto_detect 784 GURL(), // pac_url 785 ProxyRulesExpectation::Single( 786 "www.google.com:99", // single 787 ""), // bypass rules 788 }, 789 790 { 791 TEST_DESC("Tolerate a scheme"), 792 { // Input. 793 NULL, // DESKTOP_SESSION 794 NULL, // HOME 795 NULL, // KDEHOME 796 NULL, // KDE_SESSION_VERSION 797 NULL, // auto_proxy 798 "http://www.google.com:99", // all_proxy 799 NULL, NULL, NULL, // per-proto proxies 800 NULL, NULL, // SOCKS 801 NULL, // no_proxy 802 }, 803 804 // Expected result. 805 ProxyConfigService::CONFIG_VALID, 806 false, // auto_detect 807 GURL(), // pac_url 808 ProxyRulesExpectation::Single( 809 "www.google.com:99", // single proxy 810 ""), // bypass rules 811 }, 812 813 { 814 TEST_DESC("Per-scheme proxy rules"), 815 { // Input. 816 NULL, // DESKTOP_SESSION 817 NULL, // HOME 818 NULL, // KDEHOME 819 NULL, // KDE_SESSION_VERSION 820 NULL, // auto_proxy 821 NULL, // all_proxy 822 "www.google.com:80", "www.foo.com:110", "ftp.foo.com:121", // per-proto 823 NULL, NULL, // SOCKS 824 NULL, // no_proxy 825 }, 826 827 // Expected result. 828 ProxyConfigService::CONFIG_VALID, 829 false, // auto_detect 830 GURL(), // pac_url 831 ProxyRulesExpectation::PerScheme( 832 "www.google.com:80", // http 833 "www.foo.com:110", // https 834 "ftp.foo.com:121", // ftp 835 ""), // bypass rules 836 }, 837 838 { 839 TEST_DESC("socks"), 840 { // Input. 841 NULL, // DESKTOP_SESSION 842 NULL, // HOME 843 NULL, // KDEHOME 844 NULL, // KDE_SESSION_VERSION 845 NULL, // auto_proxy 846 "", // all_proxy 847 NULL, NULL, NULL, // per-proto proxies 848 "socks.com:888", NULL, // SOCKS 849 NULL, // no_proxy 850 }, 851 852 // Expected result. 853 ProxyConfigService::CONFIG_VALID, 854 false, // auto_detect 855 GURL(), // pac_url 856 ProxyRulesExpectation::Single( 857 "socks5://socks.com:888", // single proxy 858 ""), // bypass rules 859 }, 860 861 { 862 TEST_DESC("socks4"), 863 { // Input. 864 NULL, // DESKTOP_SESSION 865 NULL, // HOME 866 NULL, // KDEHOME 867 NULL, // KDE_SESSION_VERSION 868 NULL, // auto_proxy 869 "", // all_proxy 870 NULL, NULL, NULL, // per-proto proxies 871 "socks.com:888", "4", // SOCKS 872 NULL, // no_proxy 873 }, 874 875 // Expected result. 876 ProxyConfigService::CONFIG_VALID, 877 false, // auto_detect 878 GURL(), // pac_url 879 ProxyRulesExpectation::Single( 880 "socks4://socks.com:888", // single proxy 881 ""), // bypass rules 882 }, 883 884 { 885 TEST_DESC("socks default port"), 886 { // Input. 887 NULL, // DESKTOP_SESSION 888 NULL, // HOME 889 NULL, // KDEHOME 890 NULL, // KDE_SESSION_VERSION 891 NULL, // auto_proxy 892 "", // all_proxy 893 NULL, NULL, NULL, // per-proto proxies 894 "socks.com", NULL, // SOCKS 895 NULL, // no_proxy 896 }, 897 898 // Expected result. 899 ProxyConfigService::CONFIG_VALID, 900 false, // auto_detect 901 GURL(), // pac_url 902 ProxyRulesExpectation::Single( 903 "socks5://socks.com:1080", // single proxy 904 ""), // bypass rules 905 }, 906 907 { 908 TEST_DESC("bypass"), 909 { // Input. 910 NULL, // DESKTOP_SESSION 911 NULL, // HOME 912 NULL, // KDEHOME 913 NULL, // KDE_SESSION_VERSION 914 NULL, // auto_proxy 915 "www.google.com", // all_proxy 916 NULL, NULL, NULL, // per-proto 917 NULL, NULL, // SOCKS 918 ".google.com, foo.com:99, 1.2.3.4:22, 127.0.0.1/8", // no_proxy 919 }, 920 921 // Expected result. 922 ProxyConfigService::CONFIG_VALID, 923 false, // auto_detect 924 GURL(), // pac_url 925 ProxyRulesExpectation::Single( 926 "www.google.com:80", 927 "*.google.com,*foo.com:99,1.2.3.4:22,127.0.0.1/8"), 928 }, 929 }; 930 931 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 932 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "] %s", i, 933 tests[i].description.c_str())); 934 MockEnvironment* env = new MockEnvironment; 935 MockGConfSettingGetter* gconf_getter = new MockGConfSettingGetter; 936 SynchConfigGetter sync_config_getter( 937 new ProxyConfigServiceLinux(env, gconf_getter)); 938 ProxyConfig config; 939 env->values = tests[i].values; 940 sync_config_getter.SetupAndInitialFetch(); 941 ProxyConfigService::ConfigAvailability availability = 942 sync_config_getter.SyncGetLatestProxyConfig(&config); 943 EXPECT_EQ(tests[i].availability, availability); 944 945 if (availability == ProxyConfigService::CONFIG_VALID) { 946 EXPECT_EQ(tests[i].auto_detect, config.auto_detect()); 947 EXPECT_EQ(tests[i].pac_url, config.pac_url()); 948 EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules())); 949 } 950 } 951 } 952 953 TEST_F(ProxyConfigServiceLinuxTest, GconfNotification) { 954 MockEnvironment* env = new MockEnvironment; 955 MockGConfSettingGetter* gconf_getter = new MockGConfSettingGetter; 956 ProxyConfigServiceLinux* service = 957 new ProxyConfigServiceLinux(env, gconf_getter); 958 SynchConfigGetter sync_config_getter(service); 959 ProxyConfig config; 960 961 // Start with no proxy. 962 gconf_getter->values.mode = "none"; 963 sync_config_getter.SetupAndInitialFetch(); 964 EXPECT_EQ(ProxyConfigService::CONFIG_VALID, 965 sync_config_getter.SyncGetLatestProxyConfig(&config)); 966 EXPECT_FALSE(config.auto_detect()); 967 968 // Now set to auto-detect. 969 gconf_getter->values.mode = "auto"; 970 // Simulate gconf notification callback. 971 service->OnCheckProxyConfigSettings(); 972 EXPECT_EQ(ProxyConfigService::CONFIG_VALID, 973 sync_config_getter.SyncGetLatestProxyConfig(&config)); 974 EXPECT_TRUE(config.auto_detect()); 975 } 976 977 TEST_F(ProxyConfigServiceLinuxTest, KDEConfigParser) { 978 // One of the tests below needs a worst-case long line prefix. We build it 979 // programmatically so that it will always be the right size. 980 std::string long_line; 981 size_t limit = ProxyConfigServiceLinux::GConfSettingGetter::BUFFER_SIZE - 1; 982 for (size_t i = 0; i < limit; ++i) 983 long_line += "-"; 984 985 // Inspired from proxy_config_service_win_unittest.cc. 986 const struct { 987 // Short description to identify the test 988 std::string description; 989 990 // Input. 991 std::string kioslaverc; 992 EnvVarValues env_values; 993 994 // Expected outputs (availability and fields of ProxyConfig). 995 ProxyConfigService::ConfigAvailability availability; 996 bool auto_detect; 997 GURL pac_url; 998 ProxyRulesExpectation proxy_rules; 999 } tests[] = { 1000 { 1001 TEST_DESC("No proxying"), 1002 1003 // Input. 1004 "[Proxy Settings]\nProxyType=0\n", 1005 {}, // env_values 1006 1007 // Expected result. 1008 ProxyConfigService::CONFIG_VALID, 1009 false, // auto_detect 1010 GURL(), // pac_url 1011 ProxyRulesExpectation::Empty(), 1012 }, 1013 1014 { 1015 TEST_DESC("Auto detect"), 1016 1017 // Input. 1018 "[Proxy Settings]\nProxyType=3\n", 1019 {}, // env_values 1020 1021 // Expected result. 1022 ProxyConfigService::CONFIG_VALID, 1023 true, // auto_detect 1024 GURL(), // pac_url 1025 ProxyRulesExpectation::Empty(), 1026 }, 1027 1028 { 1029 TEST_DESC("Valid PAC URL"), 1030 1031 // Input. 1032 "[Proxy Settings]\nProxyType=2\n" 1033 "Proxy Config Script=http://wpad/wpad.dat\n", 1034 {}, // env_values 1035 1036 // Expected result. 1037 ProxyConfigService::CONFIG_VALID, 1038 false, // auto_detect 1039 GURL("http://wpad/wpad.dat"), // pac_url 1040 ProxyRulesExpectation::Empty(), 1041 }, 1042 1043 { 1044 TEST_DESC("Per-scheme proxy rules"), 1045 1046 // Input. 1047 "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n" 1048 "httpsProxy=www.foo.com\nftpProxy=ftp.foo.com\n", 1049 {}, // env_values 1050 1051 // Expected result. 1052 ProxyConfigService::CONFIG_VALID, 1053 false, // auto_detect 1054 GURL(), // pac_url 1055 ProxyRulesExpectation::PerScheme( 1056 "www.google.com:80", // http 1057 "www.foo.com:80", // https 1058 "ftp.foo.com:80", // http 1059 ""), // bypass rules 1060 }, 1061 1062 { 1063 TEST_DESC("Only HTTP proxy specified"), 1064 1065 // Input. 1066 "[Proxy Settings]\nProxyType=1\n" 1067 "httpProxy=www.google.com\n", 1068 {}, // env_values 1069 1070 // Expected result. 1071 ProxyConfigService::CONFIG_VALID, 1072 false, // auto_detect 1073 GURL(), // pac_url 1074 ProxyRulesExpectation::PerScheme( 1075 "www.google.com:80", // http 1076 "", // https 1077 "", // ftp 1078 ""), // bypass rules 1079 }, 1080 1081 { 1082 TEST_DESC("Only HTTP proxy specified, different port"), 1083 1084 // Input. 1085 "[Proxy Settings]\nProxyType=1\n" 1086 "httpProxy=www.google.com:88\n", 1087 {}, // env_values 1088 1089 // Expected result. 1090 ProxyConfigService::CONFIG_VALID, 1091 false, // auto_detect 1092 GURL(), // pac_url 1093 ProxyRulesExpectation::PerScheme( 1094 "www.google.com:88", // http 1095 "", // https 1096 "", // ftp 1097 ""), // bypass rules 1098 }, 1099 1100 { 1101 TEST_DESC("Bypass *.google.com"), 1102 1103 // Input. 1104 "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n" 1105 "NoProxyFor=.google.com\n", 1106 {}, // env_values 1107 1108 // Expected result. 1109 ProxyConfigService::CONFIG_VALID, 1110 false, // auto_detect 1111 GURL(), // pac_url 1112 ProxyRulesExpectation::PerScheme( 1113 "www.google.com:80", // http 1114 "", // https 1115 "", // ftp 1116 "*.google.com"), // bypass rules 1117 }, 1118 1119 { 1120 TEST_DESC("Bypass *.google.com and *.kde.org"), 1121 1122 // Input. 1123 "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n" 1124 "NoProxyFor=.google.com,.kde.org\n", 1125 {}, // env_values 1126 1127 // Expected result. 1128 ProxyConfigService::CONFIG_VALID, 1129 false, // auto_detect 1130 GURL(), // pac_url 1131 ProxyRulesExpectation::PerScheme( 1132 "www.google.com:80", // http 1133 "", // https 1134 "", // ftp 1135 "*.google.com,*.kde.org"), // bypass rules 1136 }, 1137 1138 { 1139 TEST_DESC("Correctly parse bypass list with ReversedException"), 1140 1141 // Input. 1142 "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n" 1143 "NoProxyFor=.google.com\nReversedException=true\n", 1144 {}, // env_values 1145 1146 // Expected result. 1147 ProxyConfigService::CONFIG_VALID, 1148 false, // auto_detect 1149 GURL(), // pac_url 1150 ProxyRulesExpectation::PerSchemeWithBypassReversed( 1151 "www.google.com:80", // http 1152 "", // https 1153 "", // ftp 1154 "*.google.com"), // bypass rules 1155 }, 1156 1157 { 1158 TEST_DESC("Treat all hostname patterns as wildcard patterns"), 1159 1160 // Input. 1161 "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n" 1162 "NoProxyFor=google.com,kde.org,<local>\n", 1163 {}, // env_values 1164 1165 // Expected result. 1166 ProxyConfigService::CONFIG_VALID, 1167 false, // auto_detect 1168 GURL(), // pac_url 1169 ProxyRulesExpectation::PerScheme( 1170 "www.google.com:80", // http 1171 "", // https 1172 "", // ftp 1173 "*google.com,*kde.org,<local>"), // bypass rules 1174 }, 1175 1176 { 1177 TEST_DESC("Allow trailing whitespace after boolean value"), 1178 1179 // Input. 1180 "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n" 1181 "NoProxyFor=.google.com\nReversedException=true \n", 1182 {}, // env_values 1183 1184 // Expected result. 1185 ProxyConfigService::CONFIG_VALID, 1186 false, // auto_detect 1187 GURL(), // pac_url 1188 ProxyRulesExpectation::PerSchemeWithBypassReversed( 1189 "www.google.com:80", // http 1190 "", // https 1191 "", // ftp 1192 "*.google.com"), // bypass rules 1193 }, 1194 1195 { 1196 TEST_DESC("Ignore settings outside [Proxy Settings]"), 1197 1198 // Input. 1199 "httpsProxy=www.foo.com\n[Proxy Settings]\nProxyType=1\n" 1200 "httpProxy=www.google.com\n[Other Section]\nftpProxy=ftp.foo.com\n", 1201 {}, // env_values 1202 1203 // Expected result. 1204 ProxyConfigService::CONFIG_VALID, 1205 false, // auto_detect 1206 GURL(), // pac_url 1207 ProxyRulesExpectation::PerScheme( 1208 "www.google.com:80", // http 1209 "", // https 1210 "", // ftp 1211 ""), // bypass rules 1212 }, 1213 1214 { 1215 TEST_DESC("Handle CRLF line endings"), 1216 1217 // Input. 1218 "[Proxy Settings]\r\nProxyType=1\r\nhttpProxy=www.google.com\r\n", 1219 {}, // env_values 1220 1221 // Expected result. 1222 ProxyConfigService::CONFIG_VALID, 1223 false, // auto_detect 1224 GURL(), // pac_url 1225 ProxyRulesExpectation::PerScheme( 1226 "www.google.com:80", // http 1227 "", // https 1228 "", // ftp 1229 ""), // bypass rules 1230 }, 1231 1232 { 1233 TEST_DESC("Handle blank lines and mixed line endings"), 1234 1235 // Input. 1236 "[Proxy Settings]\r\n\nProxyType=1\n\r\nhttpProxy=www.google.com\n\n", 1237 {}, // env_values 1238 1239 // Expected result. 1240 ProxyConfigService::CONFIG_VALID, 1241 false, // auto_detect 1242 GURL(), // pac_url 1243 ProxyRulesExpectation::PerScheme( 1244 "www.google.com:80", // http 1245 "", // https 1246 "", // ftp 1247 ""), // bypass rules 1248 }, 1249 1250 { 1251 TEST_DESC("Handle localized settings"), 1252 1253 // Input. 1254 "[Proxy Settings]\nProxyType[$e]=1\nhttpProxy[$e]=www.google.com\n", 1255 {}, // env_values 1256 1257 // Expected result. 1258 ProxyConfigService::CONFIG_VALID, 1259 false, // auto_detect 1260 GURL(), // pac_url 1261 ProxyRulesExpectation::PerScheme( 1262 "www.google.com:80", // http 1263 "", // https 1264 "", // ftp 1265 ""), // bypass rules 1266 }, 1267 1268 { 1269 TEST_DESC("Ignore malformed localized settings"), 1270 1271 // Input. 1272 "[Proxy Settings]\nProxyType=1\nhttpProxy=www.google.com\n" 1273 "httpsProxy$e]=www.foo.com\nftpProxy=ftp.foo.com\n", 1274 {}, // env_values 1275 1276 // Expected result. 1277 ProxyConfigService::CONFIG_VALID, 1278 false, // auto_detect 1279 GURL(), // pac_url 1280 ProxyRulesExpectation::PerScheme( 1281 "www.google.com:80", // http 1282 "", // https 1283 "ftp.foo.com:80", // ftp 1284 ""), // bypass rules 1285 }, 1286 1287 { 1288 TEST_DESC("Handle strange whitespace"), 1289 1290 // Input. 1291 "[Proxy Settings]\nProxyType [$e] =2\n" 1292 " Proxy Config Script = http:// foo\n", 1293 {}, // env_values 1294 1295 // Expected result. 1296 ProxyConfigService::CONFIG_VALID, 1297 false, // auto_detect 1298 GURL("http:// foo"), // pac_url 1299 ProxyRulesExpectation::Empty(), 1300 }, 1301 1302 { 1303 TEST_DESC("Ignore all of a line which is too long"), 1304 1305 // Input. 1306 std::string("[Proxy Settings]\nProxyType=1\nftpProxy=ftp.foo.com\n") + 1307 long_line + "httpsProxy=www.foo.com\nhttpProxy=www.google.com\n", 1308 {}, // env_values 1309 1310 // Expected result. 1311 ProxyConfigService::CONFIG_VALID, 1312 false, // auto_detect 1313 GURL(), // pac_url 1314 ProxyRulesExpectation::PerScheme( 1315 "www.google.com:80", // http 1316 "", // https 1317 "ftp.foo.com:80", // ftp 1318 ""), // bypass rules 1319 }, 1320 1321 { 1322 TEST_DESC("Indirect Proxy - no env vars set"), 1323 1324 // Input. 1325 "[Proxy Settings]\nProxyType=4\nhttpProxy=http_proxy\n" 1326 "httpsProxy=https_proxy\nftpProxy=ftp_proxy\nNoProxyFor=no_proxy\n", 1327 {}, // env_values 1328 1329 // Expected result. 1330 ProxyConfigService::CONFIG_VALID, 1331 false, // auto_detect 1332 GURL(), // pac_url 1333 ProxyRulesExpectation::Empty(), 1334 }, 1335 1336 { 1337 TEST_DESC("Indirect Proxy - with env vars set"), 1338 1339 // Input. 1340 "[Proxy Settings]\nProxyType=4\nhttpProxy=http_proxy\n" 1341 "httpsProxy=https_proxy\nftpProxy=ftp_proxy\nNoProxyFor=no_proxy\n", 1342 { // env_values 1343 NULL, // DESKTOP_SESSION 1344 NULL, // HOME 1345 NULL, // KDEHOME 1346 NULL, // KDE_SESSION_VERSION 1347 NULL, // auto_proxy 1348 NULL, // all_proxy 1349 "www.normal.com", // http_proxy 1350 "www.secure.com", // https_proxy 1351 "ftp.foo.com", // ftp_proxy 1352 NULL, NULL, // SOCKS 1353 ".google.com, .kde.org", // no_proxy 1354 }, 1355 1356 // Expected result. 1357 ProxyConfigService::CONFIG_VALID, 1358 false, // auto_detect 1359 GURL(), // pac_url 1360 ProxyRulesExpectation::PerScheme( 1361 "www.normal.com:80", // http 1362 "www.secure.com:80", // https 1363 "ftp.foo.com:80", // ftp 1364 "*.google.com,*.kde.org"), // bypass rules 1365 }, 1366 1367 }; 1368 1369 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { 1370 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "] %s", i, 1371 tests[i].description.c_str())); 1372 MockEnvironment* env = new MockEnvironment; 1373 env->values = tests[i].env_values; 1374 // Force the KDE getter to be used and tell it where the test is. 1375 env->values.DESKTOP_SESSION = "kde4"; 1376 env->values.KDEHOME = kde_home_.value().c_str(); 1377 SynchConfigGetter sync_config_getter( 1378 new ProxyConfigServiceLinux(env)); 1379 ProxyConfig config; 1380 // Overwrite the kioslaverc file. 1381 file_util::WriteFile(kioslaverc_, tests[i].kioslaverc.c_str(), 1382 tests[i].kioslaverc.length()); 1383 sync_config_getter.SetupAndInitialFetch(); 1384 ProxyConfigService::ConfigAvailability availability = 1385 sync_config_getter.SyncGetLatestProxyConfig(&config); 1386 EXPECT_EQ(tests[i].availability, availability); 1387 1388 if (availability == ProxyConfigService::CONFIG_VALID) { 1389 EXPECT_EQ(tests[i].auto_detect, config.auto_detect()); 1390 EXPECT_EQ(tests[i].pac_url, config.pac_url()); 1391 EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules())); 1392 } 1393 } 1394 } 1395 1396 TEST_F(ProxyConfigServiceLinuxTest, KDEHomePicker) { 1397 // Auto detect proxy settings. 1398 std::string slaverc3 = "[Proxy Settings]\nProxyType=3\n"; 1399 // Valid PAC URL. 1400 std::string slaverc4 = "[Proxy Settings]\nProxyType=2\n" 1401 "Proxy Config Script=http://wpad/wpad.dat\n"; 1402 GURL slaverc4_pac_url("http://wpad/wpad.dat"); 1403 1404 // Overwrite the .kde kioslaverc file. 1405 file_util::WriteFile(kioslaverc_, slaverc3.c_str(), slaverc3.length()); 1406 1407 // If .kde4 exists it will mess up the first test. It should not, as 1408 // we created the directory for $HOME in the test setup. 1409 CHECK(!file_util::DirectoryExists(kde4_home_)); 1410 1411 { SCOPED_TRACE("KDE4, no .kde4 directory, verify fallback"); 1412 MockEnvironment* env = new MockEnvironment; 1413 env->values.DESKTOP_SESSION = "kde4"; 1414 env->values.HOME = user_home_.value().c_str(); 1415 SynchConfigGetter sync_config_getter( 1416 new ProxyConfigServiceLinux(env)); 1417 ProxyConfig config; 1418 sync_config_getter.SetupAndInitialFetch(); 1419 EXPECT_EQ(ProxyConfigService::CONFIG_VALID, 1420 sync_config_getter.SyncGetLatestProxyConfig(&config)); 1421 EXPECT_TRUE(config.auto_detect()); 1422 EXPECT_EQ(GURL(), config.pac_url()); 1423 } 1424 1425 // Now create .kde4 and put a kioslaverc in the config directory. 1426 // Note that its timestamp will be at least as new as the .kde one. 1427 file_util::CreateDirectory(kde4_config_); 1428 file_util::WriteFile(kioslaverc4_, slaverc4.c_str(), slaverc4.length()); 1429 CHECK(file_util::PathExists(kioslaverc4_)); 1430 1431 { SCOPED_TRACE("KDE4, .kde4 directory present, use it"); 1432 MockEnvironment* env = new MockEnvironment; 1433 env->values.DESKTOP_SESSION = "kde4"; 1434 env->values.HOME = user_home_.value().c_str(); 1435 SynchConfigGetter sync_config_getter( 1436 new ProxyConfigServiceLinux(env)); 1437 ProxyConfig config; 1438 sync_config_getter.SetupAndInitialFetch(); 1439 EXPECT_EQ(ProxyConfigService::CONFIG_VALID, 1440 sync_config_getter.SyncGetLatestProxyConfig(&config)); 1441 EXPECT_FALSE(config.auto_detect()); 1442 EXPECT_EQ(slaverc4_pac_url, config.pac_url()); 1443 } 1444 1445 { SCOPED_TRACE("KDE3, .kde4 directory present, ignore it"); 1446 MockEnvironment* env = new MockEnvironment; 1447 env->values.DESKTOP_SESSION = "kde"; 1448 env->values.HOME = user_home_.value().c_str(); 1449 SynchConfigGetter sync_config_getter( 1450 new ProxyConfigServiceLinux(env)); 1451 ProxyConfig config; 1452 sync_config_getter.SetupAndInitialFetch(); 1453 EXPECT_EQ(ProxyConfigService::CONFIG_VALID, 1454 sync_config_getter.SyncGetLatestProxyConfig(&config)); 1455 EXPECT_TRUE(config.auto_detect()); 1456 EXPECT_EQ(GURL(), config.pac_url()); 1457 } 1458 1459 { SCOPED_TRACE("KDE4, .kde4 directory present, KDEHOME set to .kde"); 1460 MockEnvironment* env = new MockEnvironment; 1461 env->values.DESKTOP_SESSION = "kde4"; 1462 env->values.HOME = user_home_.value().c_str(); 1463 env->values.KDEHOME = kde_home_.value().c_str(); 1464 SynchConfigGetter sync_config_getter( 1465 new ProxyConfigServiceLinux(env)); 1466 ProxyConfig config; 1467 sync_config_getter.SetupAndInitialFetch(); 1468 EXPECT_EQ(ProxyConfigService::CONFIG_VALID, 1469 sync_config_getter.SyncGetLatestProxyConfig(&config)); 1470 EXPECT_TRUE(config.auto_detect()); 1471 EXPECT_EQ(GURL(), config.pac_url()); 1472 } 1473 1474 // Finally, make the .kde4 config directory older than the .kde directory 1475 // and make sure we then use .kde instead of .kde4 since it's newer. 1476 file_util::SetLastModifiedTime(kde4_config_, base::Time()); 1477 1478 { SCOPED_TRACE("KDE4, very old .kde4 directory present, use .kde"); 1479 MockEnvironment* env = new MockEnvironment; 1480 env->values.DESKTOP_SESSION = "kde4"; 1481 env->values.HOME = user_home_.value().c_str(); 1482 SynchConfigGetter sync_config_getter( 1483 new ProxyConfigServiceLinux(env)); 1484 ProxyConfig config; 1485 sync_config_getter.SetupAndInitialFetch(); 1486 EXPECT_EQ(ProxyConfigService::CONFIG_VALID, 1487 sync_config_getter.SyncGetLatestProxyConfig(&config)); 1488 EXPECT_TRUE(config.auto_detect()); 1489 EXPECT_EQ(GURL(), config.pac_url()); 1490 } 1491 } 1492 1493 } // namespace net 1494