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