Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / components / data_reduction_proxy / browser / data_reduction_proxy_settings_unittest.cc
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_settings.h"
6
7 #include "base/command_line.h"
8 #include "base/md5.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "components/data_reduction_proxy/browser/data_reduction_proxy_settings_test_utils.h"
12 #include "components/data_reduction_proxy/common/data_reduction_proxy_pref_names.h"
13 #include "components/data_reduction_proxy/common/data_reduction_proxy_switches.h"
14 #include "net/http/http_auth.h"
15 #include "net/http/http_auth_cache.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "url/gurl.h"
19
20 namespace {
21
22 const char kDataReductionProxy[] = "https://foo.com:443/";
23 const char kDataReductionProxyDev[] = "http://foo-dev.com:80";
24 const char kDataReductionProxyFallback[] = "http://bar.com:80";
25 const char kDataReductionProxyKey[] = "12345";
26
27 const char kProbeURLWithOKResponse[] = "http://ok.org/";
28 const char kProbeURLWithBadResponse[] = "http://bad.org/";
29 const char kProbeURLWithNoResponse[] = "http://no.org/";
30
31 }  // namespace
32
33 namespace data_reduction_proxy {
34
35 class DataReductionProxySettingsTest
36     : public ConcreteDataReductionProxySettingsTest<
37           DataReductionProxySettings> {
38 };
39
40
41 TEST_F(DataReductionProxySettingsTest, TestAuthenticationInit) {
42   AddProxyToCommandLine();
43   net::HttpAuthCache cache;
44   DataReductionProxySettings::InitDataReductionAuthentication(
45       &cache, kDataReductionProxyKey);
46   DataReductionProxySettings::DataReductionProxyList proxies =
47       DataReductionProxySettings::GetDataReductionProxies();
48   for (DataReductionProxySettings::DataReductionProxyList::iterator it =
49            proxies.begin();  it != proxies.end(); ++it) {
50     net::HttpAuthCache::Entry* entry = cache.LookupByPath(*it,
51                                                           std::string("/"));
52     EXPECT_TRUE(entry != NULL);
53     EXPECT_EQ(net::HttpAuth::AUTH_SCHEME_SPDYPROXY, entry->scheme());
54     EXPECT_EQ("SpdyProxy", entry->auth_challenge().substr(0,9));
55   }
56   GURL bad_server = GURL("https://bad.proxy.com/");
57   net::HttpAuthCache::Entry* entry =
58       cache.LookupByPath(bad_server, std::string());
59   EXPECT_TRUE(entry == NULL);
60 }
61
62 TEST_F(DataReductionProxySettingsTest, TestGetDataReductionProxyOrigin) {
63   AddProxyToCommandLine();
64   // SetUp() adds the origin to the command line, which should be returned here.
65   std::string result =
66       DataReductionProxySettings::GetDataReductionProxyOrigin();
67   EXPECT_EQ(kDataReductionProxy, result);
68 }
69
70 TEST_F(DataReductionProxySettingsTest, TestGetDataReductionProxyDevOrigin) {
71   AddProxyToCommandLine();
72   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
73       switches::kDataReductionProxyDev, kDataReductionProxyDev);
74   std::string result =
75       DataReductionProxySettings::GetDataReductionProxyOrigin();
76   EXPECT_EQ(kDataReductionProxyDev, result);
77 }
78
79 TEST_F(DataReductionProxySettingsTest, TestGetDataReductionProxies) {
80   DataReductionProxySettings::DataReductionProxyList proxies =
81       DataReductionProxySettings::GetDataReductionProxies();
82
83   unsigned int expected_proxy_size = 0u;
84 #if defined(SPDY_PROXY_AUTH_ORIGIN)
85   ++expected_proxy_size;
86 #endif
87 #if defined(DATA_REDUCTION_FALLBACK_HOST)
88   ++expected_proxy_size;
89 #endif
90
91   EXPECT_EQ(expected_proxy_size, proxies.size());
92
93   // Adding just the fallback on the command line shouldn't add a proxy unless
94   // there was already one compiled in.
95   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
96       switches::kDataReductionProxyFallback, kDataReductionProxyFallback);
97   proxies = DataReductionProxySettings::GetDataReductionProxies();
98
99   // So: if there weren't any proxies before, there still won't be.
100   // If there were one or two, there will be two now.
101   expected_proxy_size = expected_proxy_size == 0u ? 0u : 2u;
102
103   EXPECT_EQ(expected_proxy_size, proxies.size());
104
105   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
106     switches::kDataReductionProxy, kDataReductionProxy);
107   proxies = DataReductionProxySettings::GetDataReductionProxies();
108   EXPECT_EQ(2u, proxies.size());
109
110   // Command line proxies have precedence, so even if there were other values
111   // compiled in, these should be the ones in the list.
112   EXPECT_EQ("foo.com", proxies[0].host());
113   EXPECT_EQ(443 ,proxies[0].EffectiveIntPort());
114   EXPECT_EQ("bar.com", proxies[1].host());
115   EXPECT_EQ(80, proxies[1].EffectiveIntPort());
116 }
117
118 TEST_F(DataReductionProxySettingsTest, TestAuthHashGeneration) {
119   AddProxyToCommandLine();
120   std::string salt = "8675309";  // Jenny's number to test the hash generator.
121   std::string salted_key = salt + kDataReductionProxyKey + salt;
122   base::string16 expected_hash = base::UTF8ToUTF16(base::MD5String(salted_key));
123   EXPECT_EQ(expected_hash,
124             DataReductionProxySettings::AuthHashForSalt(
125                 8675309, kDataReductionProxyKey));
126 }
127
128 // Test that the auth key set by preprocessor directive is not used
129 // when an origin is set via a switch. This test only does anything useful in
130 // Chrome builds.
131 TEST_F(DataReductionProxySettingsTest,
132        TestAuthHashGenerationWithOriginSetViaSwitch) {
133   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
134       switches::kDataReductionProxy, kDataReductionProxy);
135   EXPECT_EQ(base::string16(),
136             DataReductionProxySettings::AuthHashForSalt(
137                 8675309, kDataReductionProxyKey));
138 }
139
140 TEST_F(DataReductionProxySettingsTest, TestIsProxyEnabledOrManaged) {
141   AddProxyToCommandLine();
142   settings_->InitPrefMembers();
143     base::MessageLoopForUI loop;
144     // The proxy is disabled initially.
145     settings_->enabled_by_user_ = false;
146     settings_->SetProxyConfigs(false, false, false);
147
148   EXPECT_FALSE(settings_->IsDataReductionProxyEnabled());
149   EXPECT_FALSE(settings_->IsDataReductionProxyManaged());
150
151   CheckOnPrefChange(true, true, false);
152   EXPECT_TRUE(settings_->IsDataReductionProxyEnabled());
153   EXPECT_FALSE(settings_->IsDataReductionProxyManaged());
154
155   CheckOnPrefChange(true, true, true);
156   EXPECT_TRUE(settings_->IsDataReductionProxyEnabled());
157   EXPECT_TRUE(settings_->IsDataReductionProxyManaged());
158 }
159
160 TEST_F(DataReductionProxySettingsTest, TestAcceptableChallenges) {
161   AddProxyToCommandLine();
162   typedef struct {
163     std::string host;
164     std::string realm;
165     bool expected_to_succeed;
166   } challenge_test;
167
168   challenge_test tests[] = {
169     {"foo.com:443", "", false},                 // 0. No realm.
170     {"foo.com:443", "xxx", false},              // 1. Wrong realm.
171     {"foo.com:443", "spdyproxy", false},        // 2. Case matters.
172     {"foo.com:443", "SpdyProxy", true},         // 3. OK.
173     {"foo.com:443", "SpdyProxy1234567", true},  // 4. OK
174     {"bar.com:80", "SpdyProxy1234567", true},   // 5. OK.
175     {"foo.com:443", "SpdyProxyxxx", true},      // 6. OK
176     {"", "SpdyProxy1234567", false},            // 7. No challenger.
177     {"xxx.net:443", "SpdyProxy1234567", false}, // 8. Wrong host.
178     {"foo.com", "SpdyProxy1234567", false},     // 9. No port.
179     {"foo.com:80", "SpdyProxy1234567", false},  // 10.Wrong port.
180     {"bar.com:81", "SpdyProxy1234567", false},  // 11.Wrong port.
181   };
182
183   for (int i = 0; i <= 11; ++i) {
184     scoped_refptr<net::AuthChallengeInfo> auth_info(new net::AuthChallengeInfo);
185     auth_info->challenger = net::HostPortPair::FromString(tests[i].host);
186     auth_info->realm = tests[i].realm;
187     EXPECT_EQ(tests[i].expected_to_succeed,
188               DataReductionProxySettings::IsAcceptableAuthChallenge(
189                   auth_info.get()));
190   }
191 }
192
193 TEST_F(DataReductionProxySettingsTest, TestChallengeTokens) {
194   AddProxyToCommandLine();
195   typedef struct {
196     std::string realm;
197     bool expected_empty_token;
198   } token_test;
199
200   token_test tests[] = {
201     {"", true},                  // 0. No realm.
202     {"xxx", true},               // 1. realm too short.
203     {"spdyproxy", true},         // 2. no salt.
204     {"SpdyProxyxxx", true},      // 3. Salt not an int.
205     {"SpdyProxy1234567", false}, // 4. OK
206   };
207
208   for (int i = 0; i <= 4; ++i) {
209     scoped_refptr<net::AuthChallengeInfo> auth_info(new net::AuthChallengeInfo);
210     auth_info->challenger =
211         net::HostPortPair::FromString(kDataReductionProxy);
212     auth_info->realm = tests[i].realm;
213     base::string16 token = settings_->GetTokenForAuthChallenge(auth_info.get());
214     EXPECT_EQ(tests[i].expected_empty_token, token.empty());
215   }
216 }
217
218 TEST_F(DataReductionProxySettingsTest, TestResetDataReductionStatistics) {
219   int64 original_content_length;
220   int64 received_content_length;
221   int64 last_update_time;
222   settings_->ResetDataReductionStatistics();
223   settings_->GetContentLengths(kNumDaysInHistory,
224                                &original_content_length,
225                                &received_content_length,
226                                &last_update_time);
227   EXPECT_EQ(0L, original_content_length);
228   EXPECT_EQ(0L, received_content_length);
229   EXPECT_EQ(last_update_time_.ToInternalValue(), last_update_time);
230 }
231
232 TEST_F(DataReductionProxySettingsTest, TestContentLengths) {
233   int64 original_content_length;
234   int64 received_content_length;
235   int64 last_update_time;
236
237   // Request |kNumDaysInHistory| days.
238   settings_->GetContentLengths(kNumDaysInHistory,
239                                &original_content_length,
240                                &received_content_length,
241                                &last_update_time);
242   const unsigned int days = kNumDaysInHistory;
243   // Received content length history values are 0 to |kNumDaysInHistory - 1|.
244   int64 expected_total_received_content_length = (days - 1L) * days / 2;
245   // Original content length history values are 0 to
246   // |2 * (kNumDaysInHistory - 1)|.
247   long expected_total_original_content_length = (days - 1L) * days;
248   EXPECT_EQ(expected_total_original_content_length, original_content_length);
249   EXPECT_EQ(expected_total_received_content_length, received_content_length);
250   EXPECT_EQ(last_update_time_.ToInternalValue(), last_update_time);
251
252   // Request |kNumDaysInHistory - 1| days.
253   settings_->GetContentLengths(kNumDaysInHistory - 1,
254                                &original_content_length,
255                                &received_content_length,
256                                &last_update_time);
257   expected_total_received_content_length -= (days - 1);
258   expected_total_original_content_length -= 2 * (days - 1);
259   EXPECT_EQ(expected_total_original_content_length, original_content_length);
260   EXPECT_EQ(expected_total_received_content_length, received_content_length);
261
262   // Request 0 days.
263   settings_->GetContentLengths(0,
264                                &original_content_length,
265                                &received_content_length,
266                                &last_update_time);
267   expected_total_received_content_length = 0;
268   expected_total_original_content_length = 0;
269   EXPECT_EQ(expected_total_original_content_length, original_content_length);
270   EXPECT_EQ(expected_total_received_content_length, received_content_length);
271
272   // Request 1 day. First day had 0 bytes so should be same as 0 days.
273   settings_->GetContentLengths(1,
274                                &original_content_length,
275                                &received_content_length,
276                                &last_update_time);
277   EXPECT_EQ(expected_total_original_content_length, original_content_length);
278   EXPECT_EQ(expected_total_received_content_length, received_content_length);
279 }
280
281 // TODO(marq): Add a test to verify that MaybeActivateDataReductionProxy
282 // is called when the pref in |settings_| is enabled.
283 TEST_F(DataReductionProxySettingsTest, TestMaybeActivateDataReductionProxy) {
284   AddProxyToCommandLine();
285
286   // Initialize the pref member in |settings_| without the usual callback
287   // so it won't trigger MaybeActivateDataReductionProxy when the pref value
288   // is set.
289   settings_->spdy_proxy_auth_enabled_.Init(
290       prefs::kDataReductionProxyEnabled,
291       settings_->GetOriginalProfilePrefs());
292
293   // TODO(bengr): Test enabling/disabling while a probe is outstanding.
294   base::MessageLoopForUI loop;
295   // The proxy is enabled and unrestructed initially.
296   // Request succeeded but with bad response, expect proxy to be restricted.
297   CheckProbe(true, kProbeURLWithBadResponse, "Bad", true, true, true, false);
298   // Request succeeded with valid response, expect proxy to be unrestricted.
299   CheckProbe(true, kProbeURLWithOKResponse, "OK", true, true, false, false);
300   // Request failed, expect proxy to be enabled but restricted.
301   CheckProbe(true, kProbeURLWithNoResponse, "", false, true, true, false);
302   // The proxy is disabled initially. Probes should not be emitted to change
303   // state.
304   CheckProbe(false, kProbeURLWithOKResponse, "OK", true, false, false, false);
305 }
306
307 TEST_F(DataReductionProxySettingsTest, TestOnIPAddressChanged) {
308   AddProxyToCommandLine();
309   base::MessageLoopForUI loop;
310   // The proxy is enabled initially.
311   pref_service_.SetBoolean(prefs::kDataReductionProxyEnabled, true);
312   settings_->spdy_proxy_auth_enabled_.Init(
313       prefs::kDataReductionProxyEnabled,
314       settings_->GetOriginalProfilePrefs());
315   settings_->enabled_by_user_ = true;
316   settings_->restricted_by_carrier_ = false;
317   settings_->SetProxyConfigs(true, false, true);
318   // IP address change triggers a probe that succeeds. Proxy remains
319   // unrestricted.
320   CheckProbeOnIPChange(kProbeURLWithOKResponse, "OK", true, false, false);
321   // IP address change triggers a probe that fails. Proxy is restricted.
322   CheckProbeOnIPChange(kProbeURLWithBadResponse, "Bad", true, true, false);
323   // IP address change triggers a probe that fails. Proxy remains restricted.
324   CheckProbeOnIPChange(kProbeURLWithBadResponse, "Bad", true, true, false);
325   // IP address change triggers a probe that succeed. Proxy is unrestricted.
326   CheckProbeOnIPChange(kProbeURLWithBadResponse, "OK", true, false, false);
327 }
328
329 TEST_F(DataReductionProxySettingsTest, TestOnProxyEnabledPrefChange) {
330   AddProxyToCommandLine();
331   settings_->InitPrefMembers();
332   base::MessageLoopForUI loop;
333   // The proxy is enabled initially.
334   settings_->enabled_by_user_ = true;
335   settings_->SetProxyConfigs(true, false, true);
336   // The pref is disabled, so correspondingly should be the proxy.
337   CheckOnPrefChange(false, false, false);
338   // The pref is enabled, so correspondingly should be the proxy.
339   CheckOnPrefChange(true, true, false);
340 }
341
342 TEST_F(DataReductionProxySettingsTest, TestInitDataReductionProxyOn) {
343   MockSettings* settings = static_cast<MockSettings*>(settings_.get());
344   EXPECT_CALL(*settings, RecordStartupState(PROXY_ENABLED));
345
346   pref_service_.SetBoolean(prefs::kDataReductionProxyEnabled, true);
347   CheckInitDataReductionProxy(true);
348 }
349
350 TEST_F(DataReductionProxySettingsTest, TestInitDataReductionProxyOff) {
351   // InitDataReductionProxySettings with the preference off will directly call
352   // LogProxyState.
353   MockSettings* settings = static_cast<MockSettings*>(settings_.get());
354   EXPECT_CALL(*settings, RecordStartupState(PROXY_DISABLED));
355
356   pref_service_.SetBoolean(prefs::kDataReductionProxyEnabled, false);
357   CheckInitDataReductionProxy(false);
358 }
359
360 TEST_F(DataReductionProxySettingsTest, TestSetProxyFromCommandLine) {
361   MockSettings* settings = static_cast<MockSettings*>(settings_.get());
362   EXPECT_CALL(*settings, RecordStartupState(PROXY_ENABLED));
363
364   CommandLine::ForCurrentProcess()->AppendSwitch(
365       switches::kEnableDataReductionProxy);
366   CheckInitDataReductionProxy(true);
367 }
368
369 TEST_F(DataReductionProxySettingsTest, TestGetDailyContentLengths) {
370   DataReductionProxySettings::ContentLengthList result =
371       settings_->GetDailyContentLengths(prefs::kDailyHttpOriginalContentLength);
372
373   ASSERT_FALSE(result.empty());
374   ASSERT_EQ(kNumDaysInHistory, result.size());
375
376   for (size_t i = 0; i < kNumDaysInHistory; ++i) {
377     long expected_length =
378         static_cast<long>((kNumDaysInHistory - 1 - i) * 2);
379     ASSERT_EQ(expected_length, result[i]);
380   }
381 }
382
383 TEST_F(DataReductionProxySettingsTest, CheckInitMetricsWhenNotAllowed) {
384   // No call to |AddProxyToCommandLine()| was made, so the proxy feature
385   // should be unavailable.
386   base::MessageLoopForUI loop;
387   DataReductionProxySettings::SetAllowed(false);
388   EXPECT_FALSE(DataReductionProxySettings::IsDataReductionProxyAllowed());
389   MockSettings* settings = static_cast<MockSettings*>(settings_.get());
390   EXPECT_CALL(*settings, RecordStartupState(PROXY_NOT_AVAILABLE));
391
392   scoped_ptr<DataReductionProxyConfigurator> configurator(
393       new TestDataReductionProxyConfig());
394   settings_->SetProxyConfigurator(configurator.Pass());
395   scoped_refptr<net::TestURLRequestContextGetter> request_context =
396       new net::TestURLRequestContextGetter(base::MessageLoopProxy::current());
397   settings_->InitDataReductionProxySettings(&pref_service_,
398                                             &pref_service_,
399                                             request_context.get());
400
401   base::MessageLoop::current()->RunUntilIdle();
402 }
403
404 }  // namespace data_reduction_proxy