1 // Copyright 2014 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 "components/data_reduction_proxy/browser/data_reduction_proxy_config_service.h"
6
7 #include <string>
8
9 #include "base/memory/ref_counted.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/test/test_simple_task_runner.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 using testing::Mock;
16
17 namespace {
18
19 // Test system proxy rules.
20 static const char kSystemProxyRules[] = "http=http://system.com:80,direct://";
21
22 // Test data reduction proxy rules.
23 static const char kDataReductionProxyRules[] =
24 "http=https://foo.com:443,http://bar.com:80,direct://";
25
26 // Test data reduction proxy rules when in restricted mode.
27 static const char kDataReductionProxyRestrictedRules[] =
28 "http=http://bar.com:80,direct://";
29
30 } // namespace
31
32 namespace data_reduction_proxy {
33
34 class TestProxyConfigService : public net::ProxyConfigService {
35 public:
TestProxyConfigService()36 TestProxyConfigService()
37 : availability_(net::ProxyConfigService::CONFIG_VALID) {
38 config_.proxy_rules().ParseFromString(kSystemProxyRules);
39 }
40
SetProxyConfig(const net::ProxyConfig config,ConfigAvailability availability)41 void SetProxyConfig(const net::ProxyConfig config,
42 ConfigAvailability availability) {
43 config_ = config;
44 availability_ = availability;
45 FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, observers_,
46 OnProxyConfigChanged(config, availability));
47 }
48
AddObserver(net::ProxyConfigService::Observer * observer)49 virtual void AddObserver(
50 net::ProxyConfigService::Observer* observer) OVERRIDE {
51 observers_.AddObserver(observer);
52 }
53
RemoveObserver(net::ProxyConfigService::Observer * observer)54 virtual void RemoveObserver(
55 net::ProxyConfigService::Observer* observer) OVERRIDE {
56 observers_.RemoveObserver(observer);
57 }
58
GetLatestProxyConfig(net::ProxyConfig * config)59 virtual ConfigAvailability GetLatestProxyConfig(
60 net::ProxyConfig* config) OVERRIDE {
61 *config = config_;
62 return availability_;
63 }
64
65 private:
66 net::ProxyConfig config_;
67 ConfigAvailability availability_;
68 ObserverList<net::ProxyConfigService::Observer, true> observers_;
69 };
70
71
72 // A mock observer for capturing callbacks.
73 class MockObserver : public net::ProxyConfigService::Observer {
74 public:
75 MOCK_METHOD2(OnProxyConfigChanged,
76 void(const net::ProxyConfig&,
77 net::ProxyConfigService::ConfigAvailability));
78 };
79
80
81 class DataReductionProxyConfigServiceTest : public testing::Test {
82 public:
SetUp()83 virtual void SetUp() {
84 observer_.reset(new MockObserver());
85 base_service_ = new TestProxyConfigService();
86 scoped_ptr<net::ProxyConfigService> base_service(base_service_);
87 config_service_.reset(
88 new DataReductionProxyConfigService(base_service.Pass()));
89 }
90
EnableDataReductionProxy(bool data_reduction_proxy_enabled)91 void EnableDataReductionProxy(bool data_reduction_proxy_enabled) {
92 config_service_->enabled_ = data_reduction_proxy_enabled;
93 config_service_->config_.proxy_rules().ParseFromString(
94 kDataReductionProxyRules);
95 }
96
97 scoped_ptr<net::ProxyConfigService::Observer> observer_;
98
99 // Holds a weak pointer to the base service. Ownership is passed to
100 // |config_service_|.
101 TestProxyConfigService* base_service_;
102
103 scoped_ptr<DataReductionProxyConfigService> config_service_;
104 };
105
106 // Compares proxy configurations, but allows different identifiers.
107 MATCHER_P(ProxyConfigMatches, config, "") {
108 net::ProxyConfig reference(config);
109 reference.set_id(arg.id());
110 return reference.Equals(arg);
111 }
112
TEST_F(DataReductionProxyConfigServiceTest,GetLatestProxyConfigEnabled)113 TEST_F(DataReductionProxyConfigServiceTest, GetLatestProxyConfigEnabled) {
114 // Set up the |config_service_| as though Enable had been previously called
115 // and check that |GetLatestProxyConfigEnabled| return rules for the data
116 // reduction proxy.
117 EnableDataReductionProxy(true);
118 net::ProxyConfig::ProxyRules expected_rules;
119 expected_rules.ParseFromString(kDataReductionProxyRules);
120 net::ProxyConfig latest_config;
121 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
122 config_service_->GetLatestProxyConfig(&latest_config));
123 ASSERT_TRUE(latest_config.proxy_rules().Equals(expected_rules));
124 }
125
TEST_F(DataReductionProxyConfigServiceTest,GetLatestProxyConfigDisabledValid)126 TEST_F(DataReductionProxyConfigServiceTest, GetLatestProxyConfigDisabledValid) {
127 // Set up the |config_service_| with the data reduction proxy disabled and
128 // check that the underlying system config is returned.
129 EnableDataReductionProxy(false);
130 net::ProxyConfig::ProxyRules expected_rules;
131 expected_rules.ParseFromString(kSystemProxyRules);
132 net::ProxyConfig latest_config;
133 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
134 config_service_->GetLatestProxyConfig(&latest_config));
135 ASSERT_TRUE(latest_config.proxy_rules().Equals(expected_rules));
136 }
137
TEST_F(DataReductionProxyConfigServiceTest,GetLatestProxyConfigDisabledUnset)138 TEST_F(DataReductionProxyConfigServiceTest, GetLatestProxyConfigDisabledUnset) {
139 // Set up the |config_service_| with the data reduction proxy disabled and
140 // check that direct is returned if the the underlying system config is unset.
141 EnableDataReductionProxy(false);
142 base_service_->SetProxyConfig(net::ProxyConfig(),
143 net::ProxyConfigService::CONFIG_UNSET);
144 net::ProxyConfig latest_config;
145 EXPECT_EQ(net::ProxyConfigService::CONFIG_VALID,
146 config_service_->GetLatestProxyConfig(&latest_config));
147 ASSERT_TRUE(latest_config.Equals(net::ProxyConfig()));
148 }
149
TEST_F(DataReductionProxyConfigServiceTest,UpdateProxyConfig)150 TEST_F(DataReductionProxyConfigServiceTest, UpdateProxyConfig) {
151 MockObserver observer;
152 base::MessageLoopForUI loop;
153 config_service_->AddObserver(&observer);
154 // Firing the observers in the delegate should trigger a notification.
155 net::ProxyConfig config2;
156 config2.set_auto_detect(true);
157 EXPECT_CALL(observer, OnProxyConfigChanged(
158 ProxyConfigMatches(config2),
159 net::ProxyConfigService::CONFIG_VALID)).Times(1);
160 base_service_->SetProxyConfig(config2, net::ProxyConfigService::CONFIG_VALID);
161 loop.RunUntilIdle();
162 Mock::VerifyAndClearExpectations(&observer);
163
164 // Enable the data reduction proxy, which should trigger a notification.
165 net::ProxyConfig system_config;
166 system_config.proxy_rules().ParseFromString(kSystemProxyRules);
167 base_service_->SetProxyConfig(system_config,
168 net::ProxyConfigService::CONFIG_VALID);
169 net::ProxyConfig data_reduction_proxy_config;
170 data_reduction_proxy_config.proxy_rules().ParseFromString(
171 kDataReductionProxyRules);
172
173 EXPECT_CALL(observer, OnProxyConfigChanged(
174 ProxyConfigMatches(data_reduction_proxy_config),
175 net::ProxyConfigService::CONFIG_VALID)).Times(1);
176 config_service_->UpdateProxyConfig(true, data_reduction_proxy_config);
177 loop.RunUntilIdle();
178 Mock::VerifyAndClearExpectations(&observer);
179
180
181 // Disable the data reduction proxy, which should trigger a notification.
182 base_service_->SetProxyConfig(system_config,
183 net::ProxyConfigService::CONFIG_VALID);
184 EXPECT_CALL(observer, OnProxyConfigChanged(
185 ProxyConfigMatches(system_config),
186 net::ProxyConfigService::CONFIG_VALID)).Times(1);
187 config_service_->UpdateProxyConfig(false, data_reduction_proxy_config);
188 loop.RunUntilIdle();
189 Mock::VerifyAndClearExpectations(&observer);
190
191 config_service_->RemoveObserver(&observer);
192 }
193
TEST_F(DataReductionProxyConfigServiceTest,TrackerEnable)194 TEST_F(DataReductionProxyConfigServiceTest, TrackerEnable) {
195 MockObserver observer;
196 //base::MessageLoopForUI loop;
197 config_service_->AddObserver(&observer);
198 scoped_refptr<base::TestSimpleTaskRunner> task_runner_(
199 new base::TestSimpleTaskRunner());
200 DataReductionProxyConfigTracker tracker(config_service_.get(),
201 task_runner_.get());
202 net::ProxyConfig expected_config;
203 expected_config.proxy_rules().ParseFromString(kDataReductionProxyRules);
204 EXPECT_CALL(observer, OnProxyConfigChanged(
205 ProxyConfigMatches(expected_config),
206 net::ProxyConfigService::CONFIG_VALID)).Times(1);
207 tracker.Enable(false,
208 false,
209 "https://foo.com:443",
210 "http://bar.com:80",
211 "");
212 task_runner_->RunUntilIdle();
213 Mock::VerifyAndClearExpectations(&observer);
214
215 config_service_->RemoveObserver(&observer);
216 }
217
TEST_F(DataReductionProxyConfigServiceTest,TrackerEnableRestricted)218 TEST_F(DataReductionProxyConfigServiceTest, TrackerEnableRestricted) {
219 MockObserver observer;
220 //base::MessageLoopForUI loop;
221 config_service_->AddObserver(&observer);
222 scoped_refptr<base::TestSimpleTaskRunner> task_runner_(
223 new base::TestSimpleTaskRunner());
224 DataReductionProxyConfigTracker tracker(config_service_.get(),
225 task_runner_.get());
226 net::ProxyConfig expected_config;
227 expected_config.proxy_rules().ParseFromString(
228 kDataReductionProxyRestrictedRules);
229 EXPECT_CALL(observer, OnProxyConfigChanged(
230 ProxyConfigMatches(expected_config),
231 net::ProxyConfigService::CONFIG_VALID)).Times(1);
232 tracker.Enable(true,
233 false,
234 "https://foo.com:443",
235 "http://bar.com:80",
236 "");
237 task_runner_->RunUntilIdle();
238 Mock::VerifyAndClearExpectations(&observer);
239
240 config_service_->RemoveObserver(&observer);
241 }
242
TEST_F(DataReductionProxyConfigServiceTest,TrackerDisable)243 TEST_F(DataReductionProxyConfigServiceTest, TrackerDisable) {
244 MockObserver observer;
245 //base::MessageLoopForUI loop;
246 config_service_->AddObserver(&observer);
247 scoped_refptr<base::TestSimpleTaskRunner> task_runner_(
248 new base::TestSimpleTaskRunner());
249 DataReductionProxyConfigTracker tracker(config_service_.get(),
250 task_runner_.get());
251 net::ProxyConfig expected_config;
252 expected_config.proxy_rules().ParseFromString(kSystemProxyRules);
253 EXPECT_CALL(observer, OnProxyConfigChanged(
254 ProxyConfigMatches(expected_config),
255 net::ProxyConfigService::CONFIG_VALID)).Times(1);
256 tracker.Disable();
257 task_runner_->RunUntilIdle();
258 //loop.RunUntilIdle();
259 Mock::VerifyAndClearExpectations(&observer);
260
261 config_service_->RemoveObserver(&observer);
262 }
263
264
TEST_F(DataReductionProxyConfigServiceTest,TrackerBypassList)265 TEST_F(DataReductionProxyConfigServiceTest, TrackerBypassList) {
266 base::MessageLoopForUI loop;
267 scoped_refptr<base::TestSimpleTaskRunner> task_runner_(
268 new base::TestSimpleTaskRunner());
269 DataReductionProxyConfigTracker tracker(config_service_.get(),
270 task_runner_.get());
271 tracker.AddHostPatternToBypass("http://www.google.com");
272 tracker.AddHostPatternToBypass("fefe:13::abc/33");
273 tracker.AddURLPatternToBypass("foo.org/images/*");
274 tracker.AddURLPatternToBypass("http://foo.com/*");
275 tracker.AddURLPatternToBypass("http://baz.com:22/bar/*");
276 tracker.AddURLPatternToBypass("http://*bat.com/bar/*");
277
278 std::string expected[] = {
279 "http://www.google.com",
280 "fefe:13::abc/33",
281 "foo.org",
282 "http://foo.com",
283 "http://baz.com:22",
284 "http://*bat.com"
285 };
286
287 ASSERT_EQ(tracker.bypass_rules_.size(), 6u);
288 int i = 0;
289 for (std::vector<std::string>::iterator it = tracker.bypass_rules_.begin();
290 it != tracker.bypass_rules_.end(); ++it) {
291 EXPECT_EQ(expected[i++], *it);
292 }
293 }
294
295 } // namespace data_reduction_proxy
296