OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2013 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 "base/android/jni_android.h" | |
6 #include "base/android/jni_string.h" | |
7 #include "base/android/scoped_java_ref.h" | |
8 #include "base/base64.h" | |
9 #include "base/command_line.h" | |
10 #include "base/metrics/field_trial.h" | |
11 #include "base/prefs/pref_registry_simple.h" | |
12 #include "base/prefs/pref_service.h" | |
13 #include "base/prefs/testing_pref_service.h" | |
14 #include "base/strings/string_number_conversions.h" | |
15 #include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h" | |
16 #include "chrome/browser/prefs/proxy_prefs.h" | |
17 #include "chrome/browser/prefs/scoped_user_pref_update.h" | |
18 #include "chrome/common/chrome_switches.h" | |
19 #include "chrome/common/metrics/variations/variations_util.h" | |
20 #include "chrome/common/pref_names.h" | |
21 #include "components/variations/entropy_provider.h" | |
22 #include "net/url_request/test_url_fetcher_factory.h" | |
23 #include "testing/gtest/include/gtest/gtest.h" | |
24 #include "url/gurl.h" | |
25 | |
26 const char kDataReductionProxyOrigin[] = "https://foo:443/"; | |
27 const char kDataReductionProxyOriginHostPort[] = "foo:443"; | |
28 const char kDataReductionProxyAuth[] = "12345"; | |
29 | |
30 const char kProbeURLWithOKResponse[] = "http://ok.org/"; | |
31 const char kProbeURLWithBadResponse[] = "http://bad.org/"; | |
32 const char kProbeURLWithNoResponse[] = "http://no.org/"; | |
33 | |
34 class TestDataReductionProxySettingsAndroid | |
35 : public DataReductionProxySettingsAndroid { | |
36 public: | |
37 TestDataReductionProxySettingsAndroid(JNIEnv* env, jobject obj, | |
38 PrefService* profile_prefs, | |
39 PrefService* local_state_prefs) | |
40 : DataReductionProxySettingsAndroid(env, obj), | |
41 success_(false), | |
42 fake_fetcher_request_count_(0), | |
43 profile_prefs_(profile_prefs), | |
44 local_state_prefs_(local_state_prefs) { | |
45 } | |
46 | |
47 // DataReductionProxySettingsAndroid implementation: | |
48 virtual net::URLFetcher* GetURLFetcher() OVERRIDE { | |
49 if (test_url_.empty()) | |
50 return NULL; | |
51 net::URLFetcher* fetcher = new net::FakeURLFetcher(GURL(test_url_), this, | |
52 response_, success_); | |
53 fake_fetcher_request_count_++; | |
54 return fetcher; | |
55 } | |
56 | |
57 virtual PrefService* GetOriginalProfilePrefs() OVERRIDE { | |
58 return profile_prefs_; | |
59 } | |
60 virtual PrefService* GetLocalStatePrefs() OVERRIDE { | |
61 return local_state_prefs_; | |
62 } | |
63 | |
64 void set_probe_result(const std::string& test_url, | |
65 const std::string& response, | |
66 bool success) { | |
67 test_url_ = test_url; | |
68 response_ = response; | |
69 success_ = success; | |
70 } | |
71 | |
72 const int fake_fetcher_request_count() { | |
73 return fake_fetcher_request_count_; | |
74 } | |
75 | |
76 private: | |
77 std::string test_url_; | |
78 std::string response_; | |
79 bool success_; | |
80 int fake_fetcher_request_count_; | |
81 PrefService* profile_prefs_; | |
82 PrefService* local_state_prefs_; | |
83 }; | |
84 | |
85 class DataReductionProxySettingsAndroidTest : public testing::Test { | |
86 protected: | |
87 void AddProxyToCommandLine() { | |
88 CommandLine::ForCurrentProcess()->AppendSwitchASCII( | |
89 switches::kSpdyProxyAuthOrigin, kDataReductionProxyOrigin); | |
90 CommandLine::ForCurrentProcess()->AppendSwitchASCII( | |
91 switches::kSpdyProxyAuthValue, kDataReductionProxyAuth); | |
92 } | |
93 | |
94 // testing::Test implementation: | |
95 virtual void SetUp() OVERRIDE { | |
96 env_ = base::android::AttachCurrentThread(); | |
97 DataReductionProxySettingsAndroid::Register(env_); | |
98 PrefRegistrySimple* registry = pref_service_.registry(); | |
99 registry->RegisterListPref(prefs::kDailyHttpOriginalContentLength); | |
100 registry->RegisterListPref(prefs::kDailyHttpReceivedContentLength); | |
101 registry->RegisterInt64Pref( | |
102 prefs::kDailyHttpContentLengthLastUpdateDate, 0L); | |
103 registry->RegisterDictionaryPref(prefs::kProxy); | |
104 registry->RegisterBooleanPref(prefs::kSpdyProxyAuthEnabled, false); | |
105 registry->RegisterBooleanPref(prefs::kSpdyProxyAuthWasEnabledBefore, false); | |
106 settings_.reset(new TestDataReductionProxySettingsAndroid(NULL, NULL, | |
107 &pref_service_, | |
108 &pref_service_)); | |
109 ListPrefUpdate original_update(&pref_service_, | |
110 prefs::kDailyHttpOriginalContentLength); | |
111 ListPrefUpdate received_update(&pref_service_, | |
112 prefs::kDailyHttpReceivedContentLength); | |
113 for (int64 i = 0; i < spdyproxy::kNumDaysInHistory; i++) { | |
114 original_update->Insert(0, new StringValue(base::Int64ToString(2 * i))); | |
115 received_update->Insert(0, new StringValue(base::Int64ToString(i))); | |
116 } | |
117 last_update_time_ = base::Time::Now().LocalMidnight(); | |
118 pref_service_.SetInt64( | |
119 prefs::kDailyHttpContentLengthLastUpdateDate, | |
120 last_update_time_.ToInternalValue()); | |
121 } | |
122 | |
123 void CheckProxyPref(const std::string& expected_pac_url, | |
124 const std::string& expected_mode) { | |
125 const DictionaryValue* dict = pref_service_.GetDictionary(prefs::kProxy); | |
126 std::string mode; | |
127 std::string pac_url; | |
128 dict->GetString("mode", &mode); | |
129 ASSERT_EQ(expected_mode, mode); | |
130 dict->GetString("pac_url", &pac_url); | |
131 ASSERT_EQ(expected_pac_url, pac_url); | |
132 } | |
133 | |
134 void CheckProxyPac(bool expected_enabled) { | |
135 if (expected_enabled) { | |
136 std::string pac; | |
137 base::Base64Encode(settings_->GetProxyPacScript(), &pac); | |
138 std::string expected_pac_url = | |
139 "data:application/x-ns-proxy-autoconfig;base64," + pac; | |
140 CheckProxyPref(expected_pac_url, | |
141 ProxyModeToString(ProxyPrefs::MODE_PAC_SCRIPT)); | |
mmenke
2013/09/27 17:10:14
nit: -4 indent?
bengr
2013/10/04 23:14:43
Done.
| |
142 } else { | |
143 CheckProxyPref(std::string(), ProxyModeToString(ProxyPrefs::MODE_SYSTEM)); | |
144 } | |
145 } | |
146 | |
147 void CheckProbe(bool initially_enabled, const std::string& probe_url, | |
148 const std::string& response, bool request_success, | |
149 bool expected_enabled) { | |
150 pref_service_.SetBoolean(prefs::kSpdyProxyAuthEnabled, initially_enabled); | |
151 settings_->set_probe_result(probe_url, response, request_success); | |
152 settings_->MaybeActivateDataReductionProxy(false); | |
153 base::MessageLoop::current()->RunUntilIdle(); | |
154 CheckProxyPac(expected_enabled); | |
155 } | |
156 | |
157 void CheckProbeOnIPChange(const std::string& probe_url, | |
158 const std::string& response, | |
159 bool request_success, | |
160 bool expected_enabled) { | |
161 settings_->set_probe_result(probe_url, response, request_success); | |
162 settings_->OnIPAddressChanged(); | |
163 base::MessageLoop::current()->RunUntilIdle(); | |
164 CheckProxyPac(expected_enabled); | |
165 } | |
166 | |
167 void CheckOnPrefChange(bool enabled, const std::string& probe_url, | |
168 const std::string& response, bool request_success, | |
169 bool expected_enabled) { | |
170 settings_->set_probe_result(probe_url, response, request_success); | |
171 pref_service_.SetBoolean(prefs::kSpdyProxyAuthEnabled, enabled); | |
172 base::MessageLoop::current()->RunUntilIdle(); | |
173 CheckProxyPac(expected_enabled); | |
174 } | |
175 | |
176 void CheckInitDataReductionProxy(bool enabled_at_startup) { | |
177 AddProxyToCommandLine(); | |
178 base::MessageLoop loop(base::MessageLoop::TYPE_UI); | |
179 pref_service_.SetBoolean(prefs::kSpdyProxyAuthEnabled, enabled_at_startup); | |
180 settings_->set_probe_result(kProbeURLWithOKResponse, "OK", true); | |
181 settings_->InitDataReductionProxySettings(NULL, NULL); | |
182 base::MessageLoop::current()->RunUntilIdle(); | |
183 if (enabled_at_startup) { | |
184 CheckProxyPac(enabled_at_startup); | |
185 } else { | |
186 // This presumes the proxy pref hadn't been set up by Chrome. | |
187 CheckProxyPref(std::string(), std::string()); | |
188 } | |
189 } | |
190 | |
191 TestingPrefServiceSimple pref_service_; | |
192 scoped_ptr<TestDataReductionProxySettingsAndroid> settings_; | |
193 base::Time last_update_time_; | |
194 // This is a singleton that will clear all set field trials on destruction. | |
195 scoped_ptr<base::FieldTrialList> field_trial_list_; | |
196 JNIEnv* env_; | |
197 }; | |
198 | |
199 TEST_F(DataReductionProxySettingsAndroidTest, TestGetDataReductionProxyOrigin) { | |
200 AddProxyToCommandLine(); | |
201 // SetUp() adds the origin to the command line, which should be returned here. | |
202 ScopedJavaLocalRef<jstring> result = | |
203 settings_->GetDataReductionProxyOrigin(env_, NULL); | |
204 ASSERT_TRUE(result.obj()); | |
205 const base::android::JavaRef<jstring>& str_ref = result; | |
206 EXPECT_EQ(kDataReductionProxyOrigin, ConvertJavaStringToUTF8(str_ref)); | |
207 } | |
208 | |
209 TEST_F(DataReductionProxySettingsAndroidTest, TestGetDataReductionProxyAuth) { | |
210 AddProxyToCommandLine(); | |
211 // SetUp() adds the auth string to the command line, which should be returned | |
212 // here. | |
213 ScopedJavaLocalRef<jstring> result = | |
214 settings_->GetDataReductionProxyAuth(env_, NULL); | |
215 ASSERT_TRUE(result.obj()); | |
216 const base::android::JavaRef<jstring>& str_ref = result; | |
217 EXPECT_EQ(kDataReductionProxyAuth, ConvertJavaStringToUTF8(str_ref)); | |
218 } | |
219 | |
220 // Test that the auth value set by preprocessor directive is not returned | |
221 // when an origin is set via a switch. This test only does anything useful in | |
222 // Chrome builds. | |
223 TEST_F(DataReductionProxySettingsAndroidTest, | |
224 TestGetDataReductionProxyAuthWithOriginSetViaSwitch) { | |
225 CommandLine::ForCurrentProcess()->AppendSwitchASCII( | |
226 switches::kSpdyProxyAuthOrigin, kDataReductionProxyOrigin); | |
227 // SetUp() adds the auth string to the command line, which should be returned | |
228 // here. | |
229 ScopedJavaLocalRef<jstring> result = | |
230 settings_->GetDataReductionProxyAuth(env_, NULL); | |
231 ASSERT_TRUE(result.obj()); | |
232 const base::android::JavaRef<jstring>& str_ref = result; | |
233 EXPECT_EQ(std::string(), ConvertJavaStringToUTF8(str_ref)); | |
234 } | |
235 | |
236 // Confirm that the bypass rule functions generate the intended JavaScript | |
237 // code for the Proxy PAC. | |
238 TEST_F(DataReductionProxySettingsAndroidTest, TestBypassRules) { | |
239 settings_->AddURLPatternToBypass("http://foo.com/*"); | |
240 settings_->AddHostPatternToBypass("bar.com"); | |
241 settings_->AddHostToBypass("127.0.0.1"); | |
242 | |
243 std::string expected[] = { | |
244 "shExpMatch(url, 'http://foo.com/*')", | |
245 "shExpMatch(host, 'bar.com')", | |
246 "host == '127.0.0.1'" | |
247 }; | |
248 | |
249 int i = 0; | |
250 for (std::vector<std::string>::iterator it = settings_->bypass_rules_.begin(); | |
251 it != settings_->bypass_rules_.end(); ++it) { | |
252 EXPECT_EQ(expected[i++], *it); | |
253 } | |
254 } | |
255 | |
256 TEST_F(DataReductionProxySettingsAndroidTest, TestIsProxyEnabledOrManaged) { | |
257 settings_->InitPrefMembers(); | |
258 EXPECT_FALSE(settings_->IsDataReductionProxyEnabled(NULL, NULL)); | |
259 EXPECT_FALSE(settings_->IsDataReductionProxyManaged(NULL, NULL)); | |
260 | |
261 pref_service_.SetBoolean(prefs::kSpdyProxyAuthEnabled, true); | |
262 EXPECT_TRUE(settings_->IsDataReductionProxyEnabled(NULL, NULL)); | |
263 EXPECT_FALSE(settings_->IsDataReductionProxyManaged(NULL, NULL)); | |
264 | |
265 pref_service_.SetManagedPref(prefs::kSpdyProxyAuthEnabled, | |
266 base::Value::CreateBooleanValue(true)); | |
267 EXPECT_TRUE(settings_->IsDataReductionProxyEnabled(NULL, NULL)); | |
268 EXPECT_TRUE(settings_->IsDataReductionProxyManaged(NULL, NULL)); | |
269 } | |
270 | |
271 TEST_F(DataReductionProxySettingsAndroidTest, TestSetProxyPac) { | |
272 settings_->AddDefaultProxyBypassRules(); | |
273 std::string pac; | |
274 base::Base64Encode(settings_->GetProxyPacScript(), &pac); | |
275 std::string expected_pac_url = | |
276 "data:application/x-ns-proxy-autoconfig;base64," + pac; | |
277 // Test setting the PAC, without generating histograms. | |
278 settings_->has_turned_on_ = true; | |
279 settings_->SetProxyPac(true, false); | |
280 CheckProxyPref(expected_pac_url, | |
281 ProxyModeToString(ProxyPrefs::MODE_PAC_SCRIPT)); | |
mmenke
2013/09/27 17:10:14
nit: -4 indent
bengr
2013/10/04 23:14:43
Done.
| |
282 | |
283 // Test disabling the PAC, without generating histograms. | |
284 settings_->has_turned_off_ = true; | |
285 settings_->SetProxyPac(false, false); | |
286 CheckProxyPref(std::string(), ProxyModeToString(ProxyPrefs::MODE_SYSTEM)); | |
287 } | |
288 | |
289 TEST_F(DataReductionProxySettingsAndroidTest, TestGetDailyContentLengths) { | |
290 ScopedJavaLocalRef<jlongArray> result = | |
291 settings_->GetDailyContentLengths(env_, | |
292 prefs::kDailyHttpOriginalContentLength); | |
293 ASSERT_TRUE(result.obj()); | |
294 | |
295 jsize java_array_len = env_->GetArrayLength(result.obj()); | |
296 ASSERT_EQ(static_cast<jsize>(spdyproxy::kNumDaysInHistory), java_array_len); | |
297 | |
298 jlong value; | |
299 for (size_t i = 0; i < spdyproxy::kNumDaysInHistory; ++i) { | |
300 env_->GetLongArrayRegion(result.obj(), i, 1, &value); | |
301 ASSERT_EQ( | |
302 static_cast<long>((spdyproxy::kNumDaysInHistory - 1 - i) * 2), value); | |
303 } | |
304 } | |
305 | |
306 TEST_F(DataReductionProxySettingsAndroidTest, | |
307 TestResetDataReductionStatistics) { | |
308 int64 original_content_length; | |
309 int64 received_content_length; | |
310 int64 last_update_time; | |
311 settings_->ResetDataReductionStatistics(); | |
312 settings_->GetContentLengthsInternal(spdyproxy::kNumDaysInHistory, | |
313 &original_content_length, | |
314 &received_content_length, | |
315 &last_update_time); | |
316 EXPECT_EQ(0L, original_content_length); | |
317 EXPECT_EQ(0L, received_content_length); | |
318 EXPECT_EQ(last_update_time_.ToInternalValue(), last_update_time); | |
319 } | |
320 | |
321 TEST_F(DataReductionProxySettingsAndroidTest, TestContentLengthsInternal) { | |
322 int64 original_content_length; | |
323 int64 received_content_length; | |
324 int64 last_update_time; | |
325 | |
326 // Request |kNumDaysInHistory| days. | |
327 settings_->GetContentLengthsInternal(spdyproxy::kNumDaysInHistory, | |
328 &original_content_length, | |
329 &received_content_length, | |
330 &last_update_time); | |
331 const unsigned int days = spdyproxy::kNumDaysInHistory; | |
332 // Received content length history values are 0 to |kNumDaysInHistory - 1|. | |
333 int64 expected_total_received_content_length = (days - 1L) * days / 2; | |
334 // Original content length history values are 0 to | |
335 // |2 * (kNumDaysInHistory - 1)|. | |
336 long expected_total_original_content_length = (days - 1L) * days; | |
337 EXPECT_EQ(expected_total_original_content_length, original_content_length); | |
338 EXPECT_EQ(expected_total_received_content_length, received_content_length); | |
339 EXPECT_EQ(last_update_time_.ToInternalValue(), last_update_time); | |
340 | |
341 // Request |kNumDaysInHistory - 1| days. | |
342 settings_->GetContentLengthsInternal(spdyproxy::kNumDaysInHistory - 1, | |
343 &original_content_length, | |
344 &received_content_length, | |
345 &last_update_time); | |
346 expected_total_received_content_length -= (days - 1); | |
347 expected_total_original_content_length -= 2 * (days - 1); | |
348 EXPECT_EQ(expected_total_original_content_length, original_content_length); | |
349 EXPECT_EQ(expected_total_received_content_length, received_content_length); | |
350 | |
351 // Request 0 days. | |
352 settings_->GetContentLengthsInternal(0, | |
353 &original_content_length, | |
354 &received_content_length, | |
355 &last_update_time); | |
356 expected_total_received_content_length = 0; | |
357 expected_total_original_content_length = 0; | |
358 EXPECT_EQ(expected_total_original_content_length, original_content_length); | |
359 EXPECT_EQ(expected_total_received_content_length, received_content_length); | |
360 | |
361 // Request 1 day. First day had 0 bytes so should be same as 0 days. | |
362 settings_->GetContentLengthsInternal(1, | |
363 &original_content_length, | |
364 &received_content_length, | |
365 &last_update_time); | |
366 EXPECT_EQ(expected_total_original_content_length, original_content_length); | |
367 EXPECT_EQ(expected_total_received_content_length, received_content_length); | |
368 } | |
369 | |
370 TEST_F(DataReductionProxySettingsAndroidTest, | |
371 TestMaybeActivateDataReductionProxy) { | |
372 settings_->InitPrefMembers(); | |
373 // TODO(bengr): Test enabling/disabling while a probe is outstanding. | |
374 base::MessageLoop loop(base::MessageLoop::TYPE_UI); | |
375 // The proxy is enabled initially. | |
376 // Request succeeded but with bad response, expect proxy to be disabled. | |
377 CheckProbe(true, kProbeURLWithBadResponse, "Bad", true, false); | |
378 // Request succeeded with valid response, expect proxy to be enabled. | |
379 CheckProbe(true, kProbeURLWithOKResponse, "OK", true, true); | |
380 // Request failed, expect proxy to be disabled. | |
381 CheckProbe(true, kProbeURLWithNoResponse, "", false, false); | |
382 | |
383 // The proxy is disabled initially. Probes should not be emitted to change | |
384 // state. | |
385 EXPECT_EQ(3, settings_->fake_fetcher_request_count()); | |
386 CheckProbe(false, kProbeURLWithOKResponse, "OK", true, false); | |
387 EXPECT_EQ(3, settings_->fake_fetcher_request_count()); | |
388 } | |
389 | |
390 TEST_F(DataReductionProxySettingsAndroidTest, | |
391 TestOnIPAddressChanged) { | |
392 AddProxyToCommandLine(); | |
393 base::MessageLoop loop(base::MessageLoop::TYPE_UI); | |
394 // The proxy is enabled initially. | |
395 settings_->enabled_by_user_ = true; | |
396 settings_->SetProxyPac(true, true); | |
397 // IP address change triggers a probe that succeeds. Proxy remains enabled. | |
398 CheckProbeOnIPChange(kProbeURLWithOKResponse, "OK", true, true); | |
399 // IP address change triggers a probe that fails. Proxy is disabled. | |
400 CheckProbeOnIPChange(kProbeURLWithBadResponse, "Bad", true, false); | |
401 // IP address change triggers a probe that fails. Proxy remains disabled. | |
402 CheckProbeOnIPChange(kProbeURLWithBadResponse, "Bad", true, false); | |
mmenke
2013/09/27 17:10:14
Suggest a bad-> good transition, just to be comple
bengr
2013/10/04 23:14:43
Done.
| |
403 EXPECT_EQ(3, settings_->fake_fetcher_request_count()); | |
404 } | |
405 | |
406 TEST_F(DataReductionProxySettingsAndroidTest, | |
407 TestOnProxyEnabledPrefChange) { | |
408 AddProxyToCommandLine(); | |
409 settings_->InitPrefMembers(); | |
410 base::MessageLoop loop(base::MessageLoop::TYPE_UI); | |
411 LOG(WARNING) << "Before init pref members"; | |
412 // The proxy is enabled initially. | |
413 settings_->enabled_by_user_ = true; | |
414 settings_->SetProxyPac(true, true); | |
415 LOG(WARNING) << "after set proxy pac"; | |
416 // The pref is disabled, so correspondingly should be the proxy. | |
417 CheckOnPrefChange(false, kProbeURLWithOKResponse, "OK", true, false); | |
418 // The pref is enabled, so correspondingly should be the proxy. | |
419 CheckOnPrefChange(true, kProbeURLWithOKResponse, "OK", true, true); | |
420 EXPECT_EQ(1, settings_->fake_fetcher_request_count()); | |
421 } | |
422 | |
423 TEST_F(DataReductionProxySettingsAndroidTest, | |
424 TestInitDataReductionProxyOn) { | |
425 CheckInitDataReductionProxy(true); | |
426 } | |
427 | |
428 TEST_F(DataReductionProxySettingsAndroidTest, | |
429 TestInitDataReductionProxyOff) { | |
430 CheckInitDataReductionProxy(false); | |
431 } | |
432 | |
OLD | NEW |