Update broken references to image assets
[chromium-blink-merge.git] / chrome / browser / chromeos / proxy_config_service_impl_unittest.cc
blob121ef02ebde23ccb1777b0666b37a2437fa2bae6
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 <vector>
9 #include "base/format_macros.h"
10 #include "base/json/json_writer.h"
11 #include "base/logging.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/prefs/testing_pref_service.h"
14 #include "base/strings/stringprintf.h"
15 #include "chrome/browser/chromeos/net/proxy_config_handler.h"
16 #include "chrome/browser/chromeos/settings/cros_settings.h"
17 #include "chrome/browser/chromeos/settings/device_settings_service.h"
18 #include "chrome/browser/chromeos/ui_proxy_config.h"
19 #include "chrome/common/pref_names.h"
20 #include "chromeos/dbus/dbus_thread_manager.h"
21 #include "chromeos/dbus/shill_profile_client.h"
22 #include "chromeos/dbus/shill_service_client.h"
23 #include "chromeos/network/network_handler.h"
24 #include "chromeos/network/network_profile_handler.h"
25 #include "chromeos/network/network_state.h"
26 #include "chromeos/network/network_state_handler.h"
27 #include "chromeos/network/onc/onc_utils.h"
28 #include "components/pref_registry/testing_pref_service_syncable.h"
29 #include "content/public/test/test_browser_thread.h"
30 #include "net/proxy/proxy_config.h"
31 #include "net/proxy/proxy_config_service_common_unittest.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33 #include "third_party/cros_system_api/dbus/service_constants.h"
35 using content::BrowserThread;
37 namespace chromeos {
39 namespace {
41 struct Input {
42 UIProxyConfig::Mode mode;
43 std::string pac_url;
44 std::string server;
45 std::string bypass_rules;
48 // Builds an identifier for each test in an array.
49 #define TEST_DESC(desc) base::StringPrintf("at line %d <%s>", __LINE__, desc)
51 // Shortcuts to declare enums within chromeos's ProxyConfig.
52 #define MK_MODE(mode) UIProxyConfig::MODE_##mode
54 // Inspired from net/proxy/proxy_config_service_linux_unittest.cc.
55 const struct TestParams {
56 // Short description to identify the test
57 std::string description;
59 Input input;
61 // Expected outputs from fields of net::ProxyConfig (via IO).
62 bool auto_detect;
63 GURL pac_url;
64 net::ProxyRulesExpectation proxy_rules;
65 } tests[] = {
66 { // 0
67 TEST_DESC("No proxying"),
69 { // Input.
70 MK_MODE(DIRECT), // mode
73 // Expected result.
74 false, // auto_detect
75 GURL(), // pac_url
76 net::ProxyRulesExpectation::Empty(), // proxy_rules
79 { // 1
80 TEST_DESC("Auto detect"),
82 { // Input.
83 MK_MODE(AUTO_DETECT), // mode
86 // Expected result.
87 true, // auto_detect
88 GURL(), // pac_url
89 net::ProxyRulesExpectation::Empty(), // proxy_rules
92 { // 2
93 TEST_DESC("Valid PAC URL"),
95 { // Input.
96 MK_MODE(PAC_SCRIPT), // mode
97 "http://wpad/wpad.dat", // pac_url
100 // Expected result.
101 false, // auto_detect
102 GURL("http://wpad/wpad.dat"), // pac_url
103 net::ProxyRulesExpectation::Empty(), // proxy_rules
106 { // 3
107 TEST_DESC("Invalid PAC URL"),
109 { // Input.
110 MK_MODE(PAC_SCRIPT), // mode
111 "wpad.dat", // pac_url
114 // Expected result.
115 false, // auto_detect
116 GURL(), // pac_url
117 net::ProxyRulesExpectation::Empty(), // proxy_rules
120 { // 4
121 TEST_DESC("Single-host in proxy list"),
123 { // Input.
124 MK_MODE(SINGLE_PROXY), // mode
125 "", // pac_url
126 "www.google.com", // server
129 // Expected result.
130 false, // auto_detect
131 GURL(), // pac_url
132 net::ProxyRulesExpectation::Single( // proxy_rules
133 "www.google.com:80", // single proxy
134 "<local>"), // bypass rules
137 { // 5
138 TEST_DESC("Single-host, different port"),
140 { // Input.
141 MK_MODE(SINGLE_PROXY), // mode
142 "", // pac_url
143 "www.google.com:99", // server
146 // Expected result.
147 false, // auto_detect
148 GURL(), // pac_url
149 net::ProxyRulesExpectation::Single( // proxy_rules
150 "www.google.com:99", // single
151 "<local>"), // bypass rules
154 { // 6
155 TEST_DESC("Tolerate a scheme"),
157 { // Input.
158 MK_MODE(SINGLE_PROXY), // mode
159 "", // pac_url
160 "http://www.google.com:99", // server
163 // Expected result.
164 false, // auto_detect
165 GURL(), // pac_url
166 net::ProxyRulesExpectation::Single( // proxy_rules
167 "www.google.com:99", // single proxy
168 "<local>"), // bypass rules
171 { // 7
172 TEST_DESC("Per-scheme proxy rules"),
174 { // Input.
175 MK_MODE(PROXY_PER_SCHEME), // mode
176 "", // pac_url
177 "http=www.google.com:80;https=https://www.foo.com:110;"
178 "ftp=ftp.foo.com:121;socks=socks5://socks.com:888", // server
181 // Expected result.
182 false, // auto_detect
183 GURL(), // pac_url
184 net::ProxyRulesExpectation::PerSchemeWithSocks( // proxy_rules
185 "www.google.com:80", // http
186 "https://www.foo.com:110", // https
187 "ftp.foo.com:121", // ftp
188 "socks5://socks.com:888", // fallback proxy
189 "<local>"), // bypass rules
192 { // 8
193 TEST_DESC("Bypass rules"),
195 { // Input.
196 MK_MODE(SINGLE_PROXY), // mode
197 "", // pac_url
198 "www.google.com", // server
199 "*.google.com, *foo.com:99, 1.2.3.4:22, 127.0.0.1/8", // bypass_rules
202 // Expected result.
203 false, // auto_detect
204 GURL(), // pac_url
205 net::ProxyRulesExpectation::Single( // proxy_rules
206 "www.google.com:80", // single proxy
207 // bypass_rules
208 "*.google.com,*foo.com:99,1.2.3.4:22,127.0.0.1/8,<local>"),
210 }; // tests
212 const char kEthernetPolicy[] =
213 " { \"GUID\": \"{485d6076-dd44-6b6d-69787465725f5040}\","
214 " \"Type\": \"Ethernet\","
215 " \"Name\": \"MyEthernet\","
216 " \"Ethernet\": {"
217 " \"Authentication\": \"None\" },"
218 " \"ProxySettings\": {"
219 " \"PAC\": \"http://domain.com/x\","
220 " \"Type\": \"PAC\" }"
221 " }";
223 const char kUserProfilePath[] = "user_profile";
225 } // namespace
227 class ProxyConfigServiceImplTest : public testing::Test {
228 protected:
229 ProxyConfigServiceImplTest()
230 : ui_thread_(BrowserThread::UI, &loop_),
231 io_thread_(BrowserThread::IO, &loop_) {}
233 void SetUp() override {
234 DBusThreadManager::Initialize();
235 NetworkHandler::Initialize();
237 PrefProxyConfigTrackerImpl::RegisterPrefs(pref_service_.registry());
238 chromeos::proxy_config::RegisterPrefs(pref_service_.registry());
239 PrefProxyConfigTrackerImpl::RegisterProfilePrefs(profile_prefs_.registry());
240 chromeos::proxy_config::RegisterProfilePrefs(profile_prefs_.registry());
243 void SetUpProxyConfigService(PrefService* profile_prefs) {
244 config_service_impl_.reset(
245 new ProxyConfigServiceImpl(profile_prefs, &pref_service_));
246 proxy_config_service_ =
247 config_service_impl_->CreateTrackingProxyConfigService(
248 scoped_ptr<net::ProxyConfigService>());
250 // CreateTrackingProxyConfigService triggers update of initial prefs proxy
251 // config by tracker to chrome proxy config service, so flush all pending
252 // tasks so that tests start fresh.
253 loop_.RunUntilIdle();
256 void SetUpPrivateWiFi() {
257 ShillProfileClient::TestInterface* profile_test =
258 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface();
259 ShillServiceClient::TestInterface* service_test =
260 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
262 // Process any pending notifications before clearing services.
263 loop_.RunUntilIdle();
264 service_test->ClearServices();
266 // Sends a notification about the added profile.
267 profile_test->AddProfile(kUserProfilePath, "user_hash");
269 service_test->AddService("/service/stub_wifi2",
270 "stub_wifi2" /* guid */,
271 "wifi2_PSK",
272 shill::kTypeWifi, shill::kStateOnline,
273 true /* visible */);
274 profile_test->AddService(kUserProfilePath, "/service/stub_wifi2");
276 loop_.RunUntilIdle();
279 void SetUpSharedEthernet() {
280 ShillProfileClient::TestInterface* profile_test =
281 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface();
282 ShillServiceClient::TestInterface* service_test =
283 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
285 // Process any pending notifications before clearing services.
286 loop_.RunUntilIdle();
287 service_test->ClearServices();
289 // Sends a notification about the added profile.
290 profile_test->AddProfile(kUserProfilePath, "user_hash");
292 service_test->AddService("/service/ethernet", "stub_ethernet" /* guid */,
293 "eth0", shill::kTypeEthernet, shill::kStateOnline,
294 true /* visible */);
295 profile_test->AddService(NetworkProfileHandler::GetSharedProfilePath(),
296 "/service/ethernet");
298 loop_.RunUntilIdle();
301 void TearDown() override {
302 config_service_impl_->DetachFromPrefService();
303 loop_.RunUntilIdle();
304 config_service_impl_.reset();
305 proxy_config_service_.reset();
306 NetworkHandler::Shutdown();
307 DBusThreadManager::Shutdown();
310 void InitConfigWithTestInput(const Input& input,
311 base::DictionaryValue* result) {
312 scoped_ptr<base::DictionaryValue> new_config;
313 switch (input.mode) {
314 case MK_MODE(DIRECT):
315 new_config.reset(ProxyConfigDictionary::CreateDirect());
316 break;
317 case MK_MODE(AUTO_DETECT):
318 new_config.reset(ProxyConfigDictionary::CreateAutoDetect());
319 break;
320 case MK_MODE(PAC_SCRIPT):
321 new_config.reset(
322 ProxyConfigDictionary::CreatePacScript(input.pac_url, false));
323 break;
324 case MK_MODE(SINGLE_PROXY):
325 case MK_MODE(PROXY_PER_SCHEME):
326 new_config.reset(ProxyConfigDictionary::CreateFixedServers(
327 input.server, input.bypass_rules));
328 break;
330 result->Swap(new_config.get());
333 void SetUserConfigInShill(base::DictionaryValue* pref_proxy_config_dict) {
334 std::string proxy_config;
335 if (pref_proxy_config_dict)
336 base::JSONWriter::Write(*pref_proxy_config_dict, &proxy_config);
338 NetworkStateHandler* network_state_handler =
339 NetworkHandler::Get()->network_state_handler();
340 const NetworkState* network = network_state_handler->DefaultNetwork();
341 ASSERT_TRUE(network);
342 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()->
343 SetServiceProperty(network->path(),
344 shill::kProxyConfigProperty,
345 base::StringValue(proxy_config));
348 // Synchronously gets the latest proxy config.
349 void SyncGetLatestProxyConfig(net::ProxyConfig* config) {
350 *config = net::ProxyConfig();
351 // Let message loop process all messages. This will run
352 // ChromeProxyConfigService::UpdateProxyConfig, which is posted on IO from
353 // PrefProxyConfigTrackerImpl::OnProxyConfigChanged.
354 loop_.RunUntilIdle();
355 net::ProxyConfigService::ConfigAvailability availability =
356 proxy_config_service_->GetLatestProxyConfig(config);
358 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID, availability);
361 base::MessageLoop loop_;
362 scoped_ptr<net::ProxyConfigService> proxy_config_service_;
363 scoped_ptr<ProxyConfigServiceImpl> config_service_impl_;
364 TestingPrefServiceSimple pref_service_;
365 user_prefs::TestingPrefServiceSyncable profile_prefs_;
367 private:
368 ScopedTestDeviceSettingsService test_device_settings_service_;
369 ScopedTestCrosSettings test_cros_settings_;
370 content::TestBrowserThread ui_thread_;
371 content::TestBrowserThread io_thread_;
374 TEST_F(ProxyConfigServiceImplTest, NetworkProxy) {
375 SetUpPrivateWiFi();
376 // Create a ProxyConfigServiceImpl like for the system request context.
377 SetUpProxyConfigService(nullptr /* no profile prefs */);
378 for (size_t i = 0; i < arraysize(tests); ++i) {
379 SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "] %s", i,
380 tests[i].description.c_str()));
382 base::DictionaryValue test_config;
383 InitConfigWithTestInput(tests[i].input, &test_config);
384 SetUserConfigInShill(&test_config);
386 net::ProxyConfig config;
387 SyncGetLatestProxyConfig(&config);
389 EXPECT_EQ(tests[i].auto_detect, config.auto_detect());
390 EXPECT_EQ(tests[i].pac_url, config.pac_url());
391 EXPECT_TRUE(tests[i].proxy_rules.Matches(config.proxy_rules()));
395 TEST_F(ProxyConfigServiceImplTest, DynamicPrefsOverride) {
396 SetUpPrivateWiFi();
397 // Create a ProxyConfigServiceImpl like for the system request context.
398 SetUpProxyConfigService(nullptr /* no profile prefs */);
399 // Groupings of 3 test inputs to use for managed, recommended and network
400 // proxies respectively. Only valid and non-direct test inputs are used.
401 const size_t proxies[][3] = {
402 { 1, 2, 4, },
403 { 1, 4, 2, },
404 { 4, 2, 1, },
405 { 2, 1, 4, },
406 { 2, 4, 5, },
407 { 2, 5, 4, },
408 { 5, 4, 2, },
409 { 4, 2, 5, },
410 { 4, 5, 6, },
411 { 4, 6, 5, },
412 { 6, 5, 4, },
413 { 5, 4, 6, },
414 { 5, 6, 7, },
415 { 5, 7, 6, },
416 { 7, 6, 5, },
417 { 6, 5, 7, },
418 { 6, 7, 8, },
419 { 6, 8, 7, },
420 { 8, 7, 6, },
421 { 7, 6, 8, },
423 for (size_t i = 0; i < arraysize(proxies); ++i) {
424 const TestParams& managed_params = tests[proxies[i][0]];
425 const TestParams& recommended_params = tests[proxies[i][1]];
426 const TestParams& network_params = tests[proxies[i][2]];
428 SCOPED_TRACE(base::StringPrintf(
429 "Test[%" PRIuS "] managed=[%s], recommended=[%s], network=[%s]", i,
430 managed_params.description.c_str(),
431 recommended_params.description.c_str(),
432 network_params.description.c_str()));
434 base::DictionaryValue managed_config;
435 InitConfigWithTestInput(managed_params.input, &managed_config);
436 base::DictionaryValue recommended_config;
437 InitConfigWithTestInput(recommended_params.input, &recommended_config);
438 base::DictionaryValue network_config;
439 InitConfigWithTestInput(network_params.input, &network_config);
441 // Managed proxy pref should take effect over recommended proxy and
442 // non-existent network proxy.
443 SetUserConfigInShill(nullptr);
444 pref_service_.SetManagedPref(prefs::kProxy, managed_config.DeepCopy());
445 pref_service_.SetRecommendedPref(prefs::kProxy,
446 recommended_config.DeepCopy());
447 net::ProxyConfig actual_config;
448 SyncGetLatestProxyConfig(&actual_config);
449 EXPECT_EQ(managed_params.auto_detect, actual_config.auto_detect());
450 EXPECT_EQ(managed_params.pac_url, actual_config.pac_url());
451 EXPECT_TRUE(managed_params.proxy_rules.Matches(
452 actual_config.proxy_rules()));
454 // Recommended proxy pref should take effect when managed proxy pref is
455 // removed.
456 pref_service_.RemoveManagedPref(prefs::kProxy);
457 SyncGetLatestProxyConfig(&actual_config);
458 EXPECT_EQ(recommended_params.auto_detect, actual_config.auto_detect());
459 EXPECT_EQ(recommended_params.pac_url, actual_config.pac_url());
460 EXPECT_TRUE(recommended_params.proxy_rules.Matches(
461 actual_config.proxy_rules()));
463 // Network proxy should take take effect over recommended proxy pref.
464 SetUserConfigInShill(&network_config);
465 SyncGetLatestProxyConfig(&actual_config);
466 EXPECT_EQ(network_params.auto_detect, actual_config.auto_detect());
467 EXPECT_EQ(network_params.pac_url, actual_config.pac_url());
468 EXPECT_TRUE(network_params.proxy_rules.Matches(
469 actual_config.proxy_rules()));
471 // Managed proxy pref should take effect over network proxy.
472 pref_service_.SetManagedPref(prefs::kProxy, managed_config.DeepCopy());
473 SyncGetLatestProxyConfig(&actual_config);
474 EXPECT_EQ(managed_params.auto_detect, actual_config.auto_detect());
475 EXPECT_EQ(managed_params.pac_url, actual_config.pac_url());
476 EXPECT_TRUE(managed_params.proxy_rules.Matches(
477 actual_config.proxy_rules()));
479 // Network proxy should take effect over recommended proxy pref when managed
480 // proxy pref is removed.
481 pref_service_.RemoveManagedPref(prefs::kProxy);
482 SyncGetLatestProxyConfig(&actual_config);
483 EXPECT_EQ(network_params.auto_detect, actual_config.auto_detect());
484 EXPECT_EQ(network_params.pac_url, actual_config.pac_url());
485 EXPECT_TRUE(network_params.proxy_rules.Matches(
486 actual_config.proxy_rules()));
488 // Removing recommended proxy pref should have no effect on network proxy.
489 pref_service_.RemoveRecommendedPref(prefs::kProxy);
490 SyncGetLatestProxyConfig(&actual_config);
491 EXPECT_EQ(network_params.auto_detect, actual_config.auto_detect());
492 EXPECT_EQ(network_params.pac_url, actual_config.pac_url());
493 EXPECT_TRUE(network_params.proxy_rules.Matches(
494 actual_config.proxy_rules()));
498 // Tests whether the proxy settings from user policy are used for ethernet even
499 // if 'UseSharedProxies' is set to false.
500 // See https://crbug.com/454966 .
501 TEST_F(ProxyConfigServiceImplTest, SharedEthernetAndUserPolicy) {
502 SetUpSharedEthernet();
503 SetUpProxyConfigService(&profile_prefs_);
505 scoped_ptr<base::DictionaryValue> ethernet_policy(
506 chromeos::onc::ReadDictionaryFromJson(kEthernetPolicy));
508 scoped_ptr<base::ListValue> network_configs(new base::ListValue);
509 network_configs->Append(ethernet_policy.release());
511 profile_prefs_.SetUserPref(prefs::kUseSharedProxies,
512 new base::FundamentalValue(false));
513 profile_prefs_.SetManagedPref(prefs::kOpenNetworkConfiguration,
514 network_configs.release());
516 net::ProxyConfig actual_config;
517 SyncGetLatestProxyConfig(&actual_config);
518 net::ProxyConfig expected_config =
519 net::ProxyConfig::CreateFromCustomPacURL(GURL("http://domain.com/x"));
520 EXPECT_TRUE(expected_config.Equals(actual_config));
523 } // namespace chromeos