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