Revert 168224 - Update V8 to version 3.15.4.
[chromium-blink-merge.git] / chrome / browser / chromeos / proxy_config_service_impl_unittest.cc
blob5730262976df041a2f03a97c07f804f3f3a0ac5a
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.
5 #include "chrome/browser/chromeos/proxy_config_service_impl.h"
7 #include <map>
8 #include <string>
9 #include <vector>
11 #include "base/format_macros.h"
12 #include "base/logging.h"
13 #include "base/message_loop.h"
14 #include "base/string_util.h"
15 #include "base/stringprintf.h"
16 #include "chrome/browser/chromeos/cros/cros_library.h"
17 #include "chrome/common/pref_names.h"
18 #include "chrome/test/base/testing_pref_service.h"
19 #include "chromeos/dbus/dbus_thread_manager.h"
20 #include "content/public/test/test_browser_thread.h"
21 #include "net/proxy/proxy_config_service_common_unittest.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 using content::BrowserThread;
26 namespace chromeos {
28 namespace {
30 struct Input { // Fields of chromeos::ProxyConfigServiceImpl::ProxyConfig.
31 ProxyConfigServiceImpl::ProxyConfig::Mode mode;
32 const char* pac_url;
33 const char* single_uri;
34 const char* http_uri;
35 const char* https_uri;
36 const char* ftp_uri;
37 const char* socks_uri;
38 const char* bypass_rules;
41 // Builds an identifier for each test in an array.
42 #define TEST_DESC(desc) base::StringPrintf("at line %d <%s>", __LINE__, desc)
44 // Shortcuts to declare enums within chromeos's ProxyConfig.
45 #define MK_MODE(mode) ProxyConfigServiceImpl::ProxyConfig::MODE_##mode
46 #define MK_SCHM(scheme) net::ProxyServer::SCHEME_##scheme
47 #define MK_AVAIL(avail) net::ProxyConfigService::CONFIG_##avail
49 // Inspired from net/proxy/proxy_config_service_linux_unittest.cc.
50 const struct TestParams {
51 // Short description to identify the test
52 std::string description;
54 bool is_valid;
56 Input input;
58 // Expected outputs from fields of net::ProxyConfig (via IO).
59 bool auto_detect;
60 GURL pac_url;
61 net::ProxyRulesExpectation proxy_rules;
62 } tests[] = {
63 { // 0
64 TEST_DESC("No proxying"),
66 true, // is_valid
68 { // Input.
69 MK_MODE(DIRECT), // mode
72 // Expected result.
73 false, // auto_detect
74 GURL(), // pac_url
75 net::ProxyRulesExpectation::Empty(), // proxy_rules
78 { // 1
79 TEST_DESC("Auto detect"),
81 true, // is_valid
83 { // Input.
84 MK_MODE(AUTO_DETECT), // mode
87 // Expected result.
88 true, // auto_detect
89 GURL(), // pac_url
90 net::ProxyRulesExpectation::Empty(), // proxy_rules
93 { // 2
94 TEST_DESC("Valid PAC URL"),
96 true, // is_valid
98 { // Input.
99 MK_MODE(PAC_SCRIPT), // mode
100 "http://wpad/wpad.dat", // pac_url
103 // Expected result.
104 false, // auto_detect
105 GURL("http://wpad/wpad.dat"), // pac_url
106 net::ProxyRulesExpectation::Empty(), // proxy_rules
109 { // 3
110 TEST_DESC("Invalid PAC URL"),
112 false, // is_valid
114 { // Input.
115 MK_MODE(PAC_SCRIPT), // mode
116 "wpad.dat", // pac_url
119 // Expected result.
120 false, // auto_detect
121 GURL(), // pac_url
122 net::ProxyRulesExpectation::Empty(), // proxy_rules
125 { // 4
126 TEST_DESC("Single-host in proxy list"),
128 true, // is_valid
130 { // Input.
131 MK_MODE(SINGLE_PROXY), // mode
132 NULL, // pac_url
133 "www.google.com", // single_uri
136 // Expected result.
137 false, // auto_detect
138 GURL(), // pac_url
139 net::ProxyRulesExpectation::Single( // proxy_rules
140 "www.google.com:80", // single proxy
141 "<local>"), // bypass rules
144 { // 5
145 TEST_DESC("Single-host, different port"),
147 true, // is_valid
149 { // Input.
150 MK_MODE(SINGLE_PROXY), // mode
151 NULL, // pac_url
152 "www.google.com:99", // single_uri
155 // Expected result.
156 false, // auto_detect
157 GURL(), // pac_url
158 net::ProxyRulesExpectation::Single( // proxy_rules
159 "www.google.com:99", // single
160 "<local>"), // bypass rules
163 { // 6
164 TEST_DESC("Tolerate a scheme"),
166 true, // is_valid
168 { // Input.
169 MK_MODE(SINGLE_PROXY), // mode
170 NULL, // pac_url
171 "http://www.google.com:99", // single_uri
174 // Expected result.
175 false, // auto_detect
176 GURL(), // pac_url
177 net::ProxyRulesExpectation::Single( // proxy_rules
178 "www.google.com:99", // single proxy
179 "<local>"), // bypass rules
182 { // 7
183 TEST_DESC("Per-scheme proxy rules"),
185 true, // is_valid
187 { // Input.
188 MK_MODE(PROXY_PER_SCHEME), // mode
189 NULL, // pac_url
190 NULL, // single_uri
191 "www.google.com:80", // http_uri
192 "www.foo.com:110", // https_uri
193 "ftp.foo.com:121", // ftp_uri
194 "socks.com:888", // socks_uri
197 // Expected result.
198 false, // auto_detect
199 GURL(), // pac_url
200 net::ProxyRulesExpectation::PerSchemeWithSocks( // proxy_rules
201 "www.google.com:80", // http
202 "https://www.foo.com:110", // https
203 "ftp.foo.com:121", // ftp
204 "socks5://socks.com:888", // fallback proxy
205 "<local>"), // bypass rules
208 { // 8
209 TEST_DESC("Bypass rules"),
211 true, // is_valid
213 { // Input.
214 MK_MODE(SINGLE_PROXY), // mode
215 NULL, // pac_url
216 "www.google.com", // single_uri
217 NULL, NULL, NULL, NULL, // per-proto
218 "*.google.com, *foo.com:99, 1.2.3.4:22, 127.0.0.1/8", // bypass_rules
221 // Expected result.
222 false, // auto_detect
223 GURL(), // pac_url
224 net::ProxyRulesExpectation::Single( // proxy_rules
225 "www.google.com:80", // single proxy
226 // bypass_rules
227 "*.google.com,*foo.com:99,1.2.3.4:22,127.0.0.1/8,<local>"),
229 }; // tests
231 template<typename TESTBASE>
232 class ProxyConfigServiceImplTestBase : public TESTBASE {
233 protected:
234 ProxyConfigServiceImplTestBase()
235 : ui_thread_(BrowserThread::UI, &loop_),
236 io_thread_(BrowserThread::IO, &loop_) {}
238 virtual void Init(PrefService* pref_service) {
239 ASSERT_TRUE(pref_service);
240 DBusThreadManager::Initialize();
241 PrefProxyConfigTrackerImpl::RegisterPrefs(pref_service);
242 ProxyConfigServiceImpl::RegisterPrefs(pref_service);
243 proxy_config_service_.reset(new ChromeProxyConfigService(NULL, true));
244 config_service_impl_.reset(new ProxyConfigServiceImpl(pref_service));
245 config_service_impl_->SetChromeProxyConfigService(
246 proxy_config_service_.get());
247 // SetChromeProxyConfigService triggers update of initial prefs proxy
248 // config by tracker to chrome proxy config service, so flush all pending
249 // tasks so that tests start fresh.
250 loop_.RunAllPending();
253 virtual void TearDown() {
254 config_service_impl_->DetachFromPrefService();
255 loop_.RunAllPending();
256 config_service_impl_.reset();
257 proxy_config_service_.reset();
258 DBusThreadManager::Shutdown();
261 void SetAutomaticProxy(
262 ProxyConfigServiceImpl::ProxyConfig::Mode mode,
263 const char* pac_url,
264 ProxyConfigServiceImpl::ProxyConfig* config,
265 ProxyConfigServiceImpl::ProxyConfig::AutomaticProxy* automatic_proxy) {
266 config->mode = mode;
267 config->state = ProxyPrefs::CONFIG_SYSTEM;
268 if (pac_url)
269 automatic_proxy->pac_url = GURL(pac_url);
272 void SetManualProxy(
273 ProxyConfigServiceImpl::ProxyConfig::Mode mode,
274 const char* server_uri,
275 net::ProxyServer::Scheme scheme,
276 ProxyConfigServiceImpl::ProxyConfig* config,
277 ProxyConfigServiceImpl::ProxyConfig::ManualProxy* manual_proxy) {
278 if (!server_uri)
279 return;
280 config->mode = mode;
281 config->state = ProxyPrefs::CONFIG_SYSTEM;
282 manual_proxy->server = net::ProxyServer::FromURI(server_uri, scheme);
285 void InitConfigWithTestInput(
286 const Input& input, ProxyConfigServiceImpl::ProxyConfig* test_config) {
287 switch (input.mode) {
288 case MK_MODE(DIRECT):
289 case MK_MODE(AUTO_DETECT):
290 case MK_MODE(PAC_SCRIPT):
291 SetAutomaticProxy(input.mode, input.pac_url, test_config,
292 &test_config->automatic_proxy);
293 return;
294 case MK_MODE(SINGLE_PROXY):
295 SetManualProxy(input.mode, input.single_uri, MK_SCHM(HTTP),
296 test_config, &test_config->single_proxy);
297 break;
298 case MK_MODE(PROXY_PER_SCHEME):
299 SetManualProxy(input.mode, input.http_uri, MK_SCHM(HTTP),
300 test_config, &test_config->http_proxy);
301 SetManualProxy(input.mode, input.https_uri, MK_SCHM(HTTPS),
302 test_config, &test_config->https_proxy);
303 SetManualProxy(input.mode, input.ftp_uri, MK_SCHM(HTTP),
304 test_config, &test_config->ftp_proxy);
305 SetManualProxy(input.mode, input.socks_uri, MK_SCHM(SOCKS5),
306 test_config, &test_config->socks_proxy);
307 break;
309 if (input.bypass_rules)
310 test_config->bypass_rules.ParseFromString(input.bypass_rules);
313 // Synchronously gets the latest proxy config.
314 net::ProxyConfigService::ConfigAvailability SyncGetLatestProxyConfig(
315 net::ProxyConfig* config) {
316 *config = net::ProxyConfig();
317 // Let message loop process all messages.
318 loop_.RunAllPending();
319 // Calls ChromeProIOGetProxyConfig (which is called from
320 // ProxyConfigService::GetLatestProxyConfig), running on faked IO thread.
321 return proxy_config_service_->GetLatestProxyConfig(config);
324 MessageLoop loop_;
325 scoped_ptr<ChromeProxyConfigService> proxy_config_service_;
326 scoped_ptr<ProxyConfigServiceImpl> config_service_impl_;
328 private:
329 // Default stub state has ethernet as the active connected network and
330 // PROFILE_SHARED as profile type, which this unittest expects.
331 ScopedStubCrosEnabler stub_cros_enabler_;
332 content::TestBrowserThread ui_thread_;
333 content::TestBrowserThread io_thread_;
336 class ProxyConfigServiceImplTest
337 : public ProxyConfigServiceImplTestBase<testing::Test> {
338 protected:
339 virtual void SetUp() {
340 Init(&pref_service_);
343 TestingPrefService pref_service_;
346 TEST_F(ProxyConfigServiceImplTest, NetworkProxy) {
347 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
348 SCOPED_TRACE(StringPrintf("Test[%" PRIuS "] %s", i,
349 tests[i].description.c_str()));
351 ProxyConfigServiceImpl::ProxyConfig test_config;
352 InitConfigWithTestInput(tests[i].input, &test_config);
353 config_service_impl_->SetTesting(&test_config);
355 net::ProxyConfig config;
356 EXPECT_EQ(MK_AVAIL(VALID), SyncGetLatestProxyConfig(&config));
358 EXPECT_EQ(tests[i].auto_detect, config.auto_detect());
359 EXPECT_EQ(tests[i].pac_url, config.pac_url());
360 EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules()));
364 TEST_F(ProxyConfigServiceImplTest, ModifyFromUI) {
365 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
366 SCOPED_TRACE(StringPrintf("Test[%" PRIuS "] %s", i,
367 tests[i].description.c_str()));
369 // Init with direct.
370 ProxyConfigServiceImpl::ProxyConfig test_config;
371 SetAutomaticProxy(MK_MODE(DIRECT), NULL, &test_config,
372 &test_config.automatic_proxy);
373 config_service_impl_->SetTesting(&test_config);
375 // Set config to tests[i].input via UI.
376 net::ProxyBypassRules bypass_rules;
377 const Input& input = tests[i].input;
378 switch (input.mode) {
379 case MK_MODE(DIRECT) :
380 config_service_impl_->UISetProxyConfigToDirect();
381 break;
382 case MK_MODE(AUTO_DETECT) :
383 config_service_impl_->UISetProxyConfigToAutoDetect();
384 break;
385 case MK_MODE(PAC_SCRIPT) :
386 config_service_impl_->UISetProxyConfigToPACScript(GURL(input.pac_url));
387 break;
388 case MK_MODE(SINGLE_PROXY) :
389 config_service_impl_->UISetProxyConfigToSingleProxy(
390 net::ProxyServer::FromURI(input.single_uri, MK_SCHM(HTTP)));
391 if (input.bypass_rules) {
392 bypass_rules.ParseFromString(input.bypass_rules);
393 config_service_impl_->UISetProxyConfigBypassRules(bypass_rules);
395 break;
396 case MK_MODE(PROXY_PER_SCHEME) :
397 if (input.http_uri) {
398 config_service_impl_->UISetProxyConfigToProxyPerScheme("http",
399 net::ProxyServer::FromURI(input.http_uri, MK_SCHM(HTTP)));
401 if (input.https_uri) {
402 config_service_impl_->UISetProxyConfigToProxyPerScheme("https",
403 net::ProxyServer::FromURI(input.https_uri, MK_SCHM(HTTPS)));
405 if (input.ftp_uri) {
406 config_service_impl_->UISetProxyConfigToProxyPerScheme("ftp",
407 net::ProxyServer::FromURI(input.ftp_uri, MK_SCHM(HTTP)));
409 if (input.socks_uri) {
410 config_service_impl_->UISetProxyConfigToProxyPerScheme("socks",
411 net::ProxyServer::FromURI(input.socks_uri, MK_SCHM(SOCKS5)));
413 if (input.bypass_rules) {
414 bypass_rules.ParseFromString(input.bypass_rules);
415 config_service_impl_->UISetProxyConfigBypassRules(bypass_rules);
417 break;
420 // Retrieve config from IO thread.
421 net::ProxyConfig io_config;
422 EXPECT_EQ(MK_AVAIL(VALID), SyncGetLatestProxyConfig(&io_config));
423 EXPECT_EQ(tests[i].auto_detect, io_config.auto_detect());
424 EXPECT_EQ(tests[i].pac_url, io_config.pac_url());
425 EXPECT_TRUE(tests[i].proxy_rules.Matches(io_config.proxy_rules()));
427 // Retrieve config from UI thread.
428 ProxyConfigServiceImpl::ProxyConfig ui_config;
429 config_service_impl_->UIGetProxyConfig(&ui_config);
430 EXPECT_EQ(input.mode, ui_config.mode);
431 if (tests[i].is_valid) {
432 if (input.pac_url)
433 EXPECT_EQ(GURL(input.pac_url), ui_config.automatic_proxy.pac_url);
434 const net::ProxyRulesExpectation& proxy_rules = tests[i].proxy_rules;
435 if (input.single_uri)
436 EXPECT_EQ(proxy_rules.single_proxy,
437 ui_config.single_proxy.server.ToURI());
438 if (input.http_uri)
439 EXPECT_EQ(proxy_rules.proxy_for_http,
440 ui_config.http_proxy.server.ToURI());
441 if (input.https_uri)
442 EXPECT_EQ(proxy_rules.proxy_for_https,
443 ui_config.https_proxy.server.ToURI());
444 if (input.ftp_uri)
445 EXPECT_EQ(proxy_rules.proxy_for_ftp,
446 ui_config.ftp_proxy.server.ToURI());
447 if (input.socks_uri) {
448 EXPECT_EQ(proxy_rules.fallback_proxy,
449 ui_config.socks_proxy.server.ToURI());
451 if (input.bypass_rules)
452 EXPECT_TRUE(bypass_rules.Equals(ui_config.bypass_rules));
457 TEST_F(ProxyConfigServiceImplTest, DynamicPrefsOverride) {
458 // Groupings of 3 test inputs to use for managed, recommended and network
459 // proxies respectively. Only valid and non-direct test inputs are used.
460 const size_t proxies[][3] = {
461 { 1, 2, 4, },
462 { 1, 4, 2, },
463 { 4, 2, 1, },
464 { 2, 1, 4, },
465 { 2, 4, 5, },
466 { 2, 5, 4, },
467 { 5, 4, 2, },
468 { 4, 2, 5, },
469 { 4, 5, 6, },
470 { 4, 6, 5, },
471 { 6, 5, 4, },
472 { 5, 4, 6, },
473 { 5, 6, 7, },
474 { 5, 7, 6, },
475 { 7, 6, 5, },
476 { 6, 5, 7, },
477 { 6, 7, 8, },
478 { 6, 8, 7, },
479 { 8, 7, 6, },
480 { 7, 6, 8, },
482 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(proxies); ++i) {
483 const TestParams& managed_params = tests[proxies[i][0]];
484 const TestParams& recommended_params = tests[proxies[i][1]];
485 const TestParams& network_params = tests[proxies[i][2]];
487 SCOPED_TRACE(StringPrintf(
488 "Test[%" PRIuS "] managed=[%s], recommended=[%s], network=[%s]", i,
489 managed_params.description.c_str(),
490 recommended_params.description.c_str(),
491 network_params.description.c_str()));
493 ProxyConfigServiceImpl::ProxyConfig managed_config;
494 InitConfigWithTestInput(managed_params.input, &managed_config);
495 ProxyConfigServiceImpl::ProxyConfig recommended_config;
496 InitConfigWithTestInput(recommended_params.input, &recommended_config);
497 ProxyConfigServiceImpl::ProxyConfig network_config;
498 InitConfigWithTestInput(network_params.input, &network_config);
500 // Managed proxy pref should take effect over recommended proxy and
501 // non-existent network proxy.
502 config_service_impl_->SetTesting(NULL);
503 pref_service_.SetManagedPref(prefs::kProxy,
504 managed_config.ToPrefProxyConfig());
505 pref_service_.SetRecommendedPref(prefs::kProxy,
506 recommended_config.ToPrefProxyConfig());
507 net::ProxyConfig actual_config;
508 EXPECT_EQ(MK_AVAIL(VALID), SyncGetLatestProxyConfig(&actual_config));
509 EXPECT_EQ(managed_params.auto_detect, actual_config.auto_detect());
510 EXPECT_EQ(managed_params.pac_url, actual_config.pac_url());
511 EXPECT_TRUE(managed_params.proxy_rules.Matches(
512 actual_config.proxy_rules()));
514 // Recommended proxy pref should take effect when managed proxy pref is
515 // removed.
516 pref_service_.RemoveManagedPref(prefs::kProxy);
517 EXPECT_EQ(MK_AVAIL(VALID), SyncGetLatestProxyConfig(&actual_config));
518 EXPECT_EQ(recommended_params.auto_detect, actual_config.auto_detect());
519 EXPECT_EQ(recommended_params.pac_url, actual_config.pac_url());
520 EXPECT_TRUE(recommended_params.proxy_rules.Matches(
521 actual_config.proxy_rules()));
523 // Network proxy should take take effect over recommended proxy pref.
524 config_service_impl_->SetTesting(&network_config);
525 EXPECT_EQ(MK_AVAIL(VALID), SyncGetLatestProxyConfig(&actual_config));
526 EXPECT_EQ(network_params.auto_detect, actual_config.auto_detect());
527 EXPECT_EQ(network_params.pac_url, actual_config.pac_url());
528 EXPECT_TRUE(network_params.proxy_rules.Matches(
529 actual_config.proxy_rules()));
531 // Managed proxy pref should take effect over network proxy.
532 pref_service_.SetManagedPref(prefs::kProxy,
533 managed_config.ToPrefProxyConfig());
534 EXPECT_EQ(MK_AVAIL(VALID), SyncGetLatestProxyConfig(&actual_config));
535 EXPECT_EQ(managed_params.auto_detect, actual_config.auto_detect());
536 EXPECT_EQ(managed_params.pac_url, actual_config.pac_url());
537 EXPECT_TRUE(managed_params.proxy_rules.Matches(
538 actual_config.proxy_rules()));
540 // Network proxy should take effect over recommended proxy pref when managed
541 // proxy pref is removed.
542 pref_service_.RemoveManagedPref(prefs::kProxy);
543 EXPECT_EQ(MK_AVAIL(VALID), SyncGetLatestProxyConfig(&actual_config));
544 EXPECT_EQ(network_params.auto_detect, actual_config.auto_detect());
545 EXPECT_EQ(network_params.pac_url, actual_config.pac_url());
546 EXPECT_TRUE(network_params.proxy_rules.Matches(
547 actual_config.proxy_rules()));
549 // Removing recommended proxy pref should have no effect on network proxy.
550 pref_service_.RemoveRecommendedPref(prefs::kProxy);
551 EXPECT_EQ(MK_AVAIL(VALID), SyncGetLatestProxyConfig(&actual_config));
552 EXPECT_EQ(network_params.auto_detect, actual_config.auto_detect());
553 EXPECT_EQ(network_params.pac_url, actual_config.pac_url());
554 EXPECT_TRUE(network_params.proxy_rules.Matches(
555 actual_config.proxy_rules()));
559 } // namespace
561 } // namespace chromeos