Roll src/third_party/WebKit 9f7fb92:f103b33 (svn 202621:202622)
[chromium-blink-merge.git] / components / proxy_config / pref_proxy_config_tracker_impl_unittest.cc
blobba59df6ad279cec337ae2a51b3184188a8b696ad
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/proxy_config/pref_proxy_config_tracker_impl.h"
7 #include <string>
9 #include "base/command_line.h"
10 #include "base/files/file_path.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/prefs/pref_registry_simple.h"
13 #include "base/prefs/testing_pref_service.h"
14 #include "base/test/histogram_tester.h"
15 #include "base/thread_task_runner_handle.h"
16 #include "components/proxy_config/proxy_config_dictionary.h"
17 #include "components/proxy_config/proxy_config_pref_names.h"
18 #include "net/proxy/proxy_info.h"
19 #include "net/proxy/proxy_list.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "url/gurl.h"
24 using testing::_;
25 using testing::Mock;
27 namespace {
29 const char kFixedPacUrl[] = "http://chromium.org/fixed_pac_url";
31 // Testing proxy config service that allows us to fire notifications at will.
32 class TestProxyConfigService : public net::ProxyConfigService {
33 public:
34 TestProxyConfigService(const net::ProxyConfig& config,
35 ConfigAvailability availability)
36 : config_(config),
37 availability_(availability) {}
39 void SetProxyConfig(const net::ProxyConfig config,
40 ConfigAvailability availability) {
41 config_ = config;
42 availability_ = availability;
43 FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_,
44 OnProxyConfigChanged(config, availability));
47 private:
48 void AddObserver(net::ProxyConfigService::Observer* observer) override {
49 observers_.AddObserver(observer);
52 void RemoveObserver(net::ProxyConfigService::Observer* observer) override {
53 observers_.RemoveObserver(observer);
56 net::ProxyConfigService::ConfigAvailability GetLatestProxyConfig(
57 net::ProxyConfig* config) override {
58 *config = config_;
59 return availability_;
62 net::ProxyConfig config_;
63 ConfigAvailability availability_;
64 base::ObserverList<net::ProxyConfigService::Observer, true> observers_;
67 // A mock observer for capturing callbacks.
68 class MockObserver : public net::ProxyConfigService::Observer {
69 public:
70 MOCK_METHOD2(OnProxyConfigChanged,
71 void(const net::ProxyConfig&,
72 net::ProxyConfigService::ConfigAvailability));
75 class PrefProxyConfigTrackerImplTest : public testing::Test {
76 protected:
77 PrefProxyConfigTrackerImplTest() {
78 pref_service_.reset(new TestingPrefServiceSimple());
79 PrefProxyConfigTrackerImpl::RegisterPrefs(pref_service_->registry());
80 fixed_config_.set_pac_url(GURL(kFixedPacUrl));
81 delegate_service_ =
82 new TestProxyConfigService(fixed_config_,
83 net::ProxyConfigService::CONFIG_VALID);
84 proxy_config_tracker_.reset(new PrefProxyConfigTrackerImpl(
85 pref_service_.get(), base::ThreadTaskRunnerHandle::Get()));
86 proxy_config_service_ =
87 proxy_config_tracker_->CreateTrackingProxyConfigService(
88 scoped_ptr<net::ProxyConfigService>(delegate_service_));
89 // SetProxyConfigServiceImpl triggers update of initial prefs proxy
90 // config by tracker to chrome proxy config service, so flush all pending
91 // tasks so that tests start fresh.
92 loop_.RunUntilIdle();
95 ~PrefProxyConfigTrackerImplTest() override {
96 proxy_config_tracker_->DetachFromPrefService();
97 loop_.RunUntilIdle();
98 proxy_config_tracker_.reset();
99 proxy_config_service_.reset();
102 base::MessageLoop loop_;
103 scoped_ptr<TestingPrefServiceSimple> pref_service_;
104 TestProxyConfigService* delegate_service_; // weak
105 scoped_ptr<net::ProxyConfigService> proxy_config_service_;
106 net::ProxyConfig fixed_config_;
108 private:
109 scoped_ptr<PrefProxyConfigTrackerImpl> proxy_config_tracker_;
112 TEST_F(PrefProxyConfigTrackerImplTest, BaseConfiguration) {
113 net::ProxyConfig actual_config;
114 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
115 proxy_config_service_->GetLatestProxyConfig(&actual_config));
116 EXPECT_EQ(GURL(kFixedPacUrl), actual_config.pac_url());
119 TEST_F(PrefProxyConfigTrackerImplTest, DynamicPrefOverrides) {
120 pref_service_->SetManagedPref(proxy_config::prefs::kProxy,
121 ProxyConfigDictionary::CreateFixedServers(
122 "http://example.com:3128", std::string()));
123 loop_.RunUntilIdle();
125 net::ProxyConfig actual_config;
126 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
127 proxy_config_service_->GetLatestProxyConfig(&actual_config));
128 EXPECT_FALSE(actual_config.auto_detect());
129 EXPECT_EQ(net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY,
130 actual_config.proxy_rules().type);
131 EXPECT_EQ(actual_config.proxy_rules().single_proxies.Get(),
132 net::ProxyServer::FromURI("http://example.com:3128",
133 net::ProxyServer::SCHEME_HTTP));
135 pref_service_->SetManagedPref(proxy_config::prefs::kProxy,
136 ProxyConfigDictionary::CreateAutoDetect());
137 loop_.RunUntilIdle();
139 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
140 proxy_config_service_->GetLatestProxyConfig(&actual_config));
141 EXPECT_TRUE(actual_config.auto_detect());
144 // Compares proxy configurations, but allows different identifiers.
145 MATCHER_P(ProxyConfigMatches, config, "") {
146 net::ProxyConfig reference(config);
147 reference.set_id(arg.id());
148 return reference.Equals(arg);
151 TEST_F(PrefProxyConfigTrackerImplTest, Observers) {
152 const net::ProxyConfigService::ConfigAvailability CONFIG_VALID =
153 net::ProxyConfigService::CONFIG_VALID;
154 MockObserver observer;
155 proxy_config_service_->AddObserver(&observer);
157 // Firing the observers in the delegate should trigger a notification.
158 net::ProxyConfig config2;
159 config2.set_auto_detect(true);
160 EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(config2),
161 CONFIG_VALID)).Times(1);
162 delegate_service_->SetProxyConfig(config2, CONFIG_VALID);
163 loop_.RunUntilIdle();
164 Mock::VerifyAndClearExpectations(&observer);
166 // Override configuration, this should trigger a notification.
167 net::ProxyConfig pref_config;
168 pref_config.set_pac_url(GURL(kFixedPacUrl));
170 EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(pref_config),
171 CONFIG_VALID)).Times(1);
172 pref_service_->SetManagedPref(
173 proxy_config::prefs::kProxy,
174 ProxyConfigDictionary::CreatePacScript(kFixedPacUrl, false));
175 loop_.RunUntilIdle();
176 Mock::VerifyAndClearExpectations(&observer);
178 // Since there are pref overrides, delegate changes should be ignored.
179 net::ProxyConfig config3;
180 config3.proxy_rules().ParseFromString("http=config3:80");
181 EXPECT_CALL(observer, OnProxyConfigChanged(_, _)).Times(0);
182 fixed_config_.set_auto_detect(true);
183 delegate_service_->SetProxyConfig(config3, CONFIG_VALID);
184 loop_.RunUntilIdle();
185 Mock::VerifyAndClearExpectations(&observer);
187 // Clear the override should switch back to the fixed configuration.
188 EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(config3),
189 CONFIG_VALID)).Times(1);
190 pref_service_->RemoveManagedPref(proxy_config::prefs::kProxy);
191 loop_.RunUntilIdle();
192 Mock::VerifyAndClearExpectations(&observer);
194 // Delegate service notifications should show up again.
195 net::ProxyConfig config4;
196 config4.proxy_rules().ParseFromString("socks:config4");
197 EXPECT_CALL(observer, OnProxyConfigChanged(ProxyConfigMatches(config4),
198 CONFIG_VALID)).Times(1);
199 delegate_service_->SetProxyConfig(config4, CONFIG_VALID);
200 loop_.RunUntilIdle();
201 Mock::VerifyAndClearExpectations(&observer);
203 proxy_config_service_->RemoveObserver(&observer);
206 TEST_F(PrefProxyConfigTrackerImplTest, Fallback) {
207 const net::ProxyConfigService::ConfigAvailability CONFIG_VALID =
208 net::ProxyConfigService::CONFIG_VALID;
209 MockObserver observer;
210 net::ProxyConfig actual_config;
211 delegate_service_->SetProxyConfig(net::ProxyConfig::CreateDirect(),
212 net::ProxyConfigService::CONFIG_UNSET);
213 proxy_config_service_->AddObserver(&observer);
215 // Prepare test data.
216 net::ProxyConfig recommended_config = net::ProxyConfig::CreateAutoDetect();
217 net::ProxyConfig user_config =
218 net::ProxyConfig::CreateFromCustomPacURL(GURL(kFixedPacUrl));
220 // Set a recommended pref.
221 EXPECT_CALL(observer,
222 OnProxyConfigChanged(ProxyConfigMatches(recommended_config),
223 CONFIG_VALID)).Times(1);
224 pref_service_->SetRecommendedPref(proxy_config::prefs::kProxy,
225 ProxyConfigDictionary::CreateAutoDetect());
226 loop_.RunUntilIdle();
227 Mock::VerifyAndClearExpectations(&observer);
228 EXPECT_EQ(CONFIG_VALID,
229 proxy_config_service_->GetLatestProxyConfig(&actual_config));
230 EXPECT_TRUE(actual_config.Equals(recommended_config));
232 // Override in user prefs.
233 EXPECT_CALL(observer,
234 OnProxyConfigChanged(ProxyConfigMatches(user_config),
235 CONFIG_VALID)).Times(1);
236 pref_service_->SetManagedPref(
237 proxy_config::prefs::kProxy,
238 ProxyConfigDictionary::CreatePacScript(kFixedPacUrl, false));
239 loop_.RunUntilIdle();
240 Mock::VerifyAndClearExpectations(&observer);
241 EXPECT_EQ(CONFIG_VALID,
242 proxy_config_service_->GetLatestProxyConfig(&actual_config));
243 EXPECT_TRUE(actual_config.Equals(user_config));
245 // Go back to recommended pref.
246 EXPECT_CALL(observer,
247 OnProxyConfigChanged(ProxyConfigMatches(recommended_config),
248 CONFIG_VALID)).Times(1);
249 pref_service_->RemoveManagedPref(proxy_config::prefs::kProxy);
250 loop_.RunUntilIdle();
251 Mock::VerifyAndClearExpectations(&observer);
252 EXPECT_EQ(CONFIG_VALID,
253 proxy_config_service_->GetLatestProxyConfig(&actual_config));
254 EXPECT_TRUE(actual_config.Equals(recommended_config));
256 proxy_config_service_->RemoveObserver(&observer);
259 TEST_F(PrefProxyConfigTrackerImplTest, ExplicitSystemSettings) {
260 pref_service_->SetRecommendedPref(proxy_config::prefs::kProxy,
261 ProxyConfigDictionary::CreateAutoDetect());
262 pref_service_->SetUserPref(proxy_config::prefs::kProxy,
263 ProxyConfigDictionary::CreateSystem());
264 loop_.RunUntilIdle();
266 // Test if we actually use the system setting, which is |kFixedPacUrl|.
267 net::ProxyConfig actual_config;
268 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
269 proxy_config_service_->GetLatestProxyConfig(&actual_config));
270 EXPECT_EQ(GURL(kFixedPacUrl), actual_config.pac_url());
273 void CheckResolvedProxyMatches(net::ProxyConfig* config,
274 const GURL& url,
275 const std::string& result_string) {
276 net::ProxyInfo expected_result;
277 expected_result.UseNamedProxy(result_string);
279 net::ProxyInfo result;
280 config->proxy_rules().Apply(url, &result);
282 EXPECT_TRUE(expected_result.proxy_list().Equals(result.proxy_list()))
283 << "expected: " << expected_result.proxy_list().ToPacString()
284 << "\nactual: " << result.proxy_list().ToPacString();
287 TEST_F(PrefProxyConfigTrackerImplTest, ExcludeGooglezipDataReductionProxies) {
288 const std::string kDataReductionProxies =
289 "https://proxy.googlezip.net:443,compress.googlezip.net,"
290 "https://proxy-dev.googlezip.net:443,proxy-dev.googlezip.net,"
291 "quic://proxy.googlezip.net";
292 const int kNumDataReductionProxies = 5;
294 struct {
295 std::string initial_proxy_rules;
296 const char* http_proxy_info;
297 const char* https_proxy_info;
298 const char* ftp_proxy_info;
299 int expected_num_removed_proxies;
300 } test_cases[] = {
301 {"http=foopyhttp," + kDataReductionProxies +
302 ",direct://;https=foopyhttps," + kDataReductionProxies +
303 ",direct://;ftp=foopyftp," + kDataReductionProxies + ",direct://",
304 "foopyhttp;direct://",
305 "foopyhttps;direct://",
306 "foopyftp;direct://",
307 kNumDataReductionProxies * 3},
309 {"foopy," + kDataReductionProxies + ",direct://",
310 "foopy;direct://",
311 "foopy;direct://",
312 "foopy;direct://",
313 kNumDataReductionProxies},
315 {"http=" + kDataReductionProxies + ";https=" + kDataReductionProxies +
316 ";ftp=" + kDataReductionProxies,
317 "direct://",
318 "direct://",
319 "direct://",
320 kNumDataReductionProxies * 3},
322 {"http=" + kDataReductionProxies + ",foopy,direct://",
323 "foopy;direct://",
324 "direct://",
325 "direct://",
326 kNumDataReductionProxies},
328 {"foopy,direct://",
329 "foopy;direct://",
330 "foopy;direct://",
331 "foopy;direct://",
334 {"direct://",
335 "direct://",
336 "direct://",
337 "direct://",
341 // Test setting the proxy from a user pref.
342 for (const auto& test : test_cases) {
343 base::HistogramTester histogram_tester;
344 pref_service_->SetUserPref(proxy_config::prefs::kProxy,
345 ProxyConfigDictionary::CreateFixedServers(
346 test.initial_proxy_rules, std::string()));
347 loop_.RunUntilIdle();
349 net::ProxyConfig config;
350 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
351 proxy_config_service_->GetLatestProxyConfig(&config));
352 histogram_tester.ExpectUniqueSample(
353 "Net.PrefProxyConfig.GooglezipProxyRemovalCount",
354 test.expected_num_removed_proxies, 1);
356 CheckResolvedProxyMatches(&config, GURL("http://google.com"),
357 test.http_proxy_info);
358 CheckResolvedProxyMatches(&config, GURL("https://google.com"),
359 test.https_proxy_info);
360 CheckResolvedProxyMatches(&config, GURL("ftp://google.com"),
361 test.ftp_proxy_info);
365 } // namespace