Chromium Code Reviews| Index: chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc |
| diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..314e946fa3836f166d582261287a2788d6ba2e3b |
| --- /dev/null |
| +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc |
| @@ -0,0 +1,384 @@ |
| +// Copyright 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "base/android/jni_android.h" |
| +#include "base/android/jni_string.h" |
| +#include "base/android/scoped_java_ref.h" |
| +#include "base/base64.h" |
| +#include "base/command_line.h" |
| +#include "base/metrics/field_trial.h" |
| +#include "base/prefs/pref_registry_simple.h" |
| +#include "base/prefs/pref_service.h" |
| +#include "base/prefs/testing_pref_service.h" |
| +#include "base/strings/string_number_conversions.h" |
| +#include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h" |
| +#include "chrome/browser/prefs/proxy_prefs.h" |
| +#include "chrome/browser/prefs/scoped_user_pref_update.h" |
| +#include "chrome/common/chrome_switches.h" |
| +#include "chrome/common/metrics/variations/variations_util.h" |
| +#include "chrome/common/pref_names.h" |
| +#include "components/variations/entropy_provider.h" |
| +#include "net/url_request/test_url_fetcher_factory.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| +#include "url/gurl.h" |
| + |
| +const char kDataReductionProxyOrigin[] = "https://foo:443/"; |
| +const char kDataReductionProxyOriginHostPort[] = "foo:443"; |
| +const char kDataReductionProxyAuth[] = "12345"; |
| + |
| +const char kProbeURLWithOKResponse[] = "http://ok.org/"; |
| +const char kProbeURLWithBadResponse[] = "http://bad.org/"; |
| +const char kProbeURLWithNoResponse[] = "http://no.org/"; |
| + |
| +class TestDataReductionProxySettingsAndroid |
| + : public DataReductionProxySettingsAndroid { |
| + public: |
| + TestDataReductionProxySettingsAndroid(JNIEnv* env, jobject obj, |
| + PrefService* profile_prefs, |
| + PrefService* local_state_prefs) |
| + : DataReductionProxySettingsAndroid(env, obj), |
| + success_(false), |
| + fake_fetcher_request_count_(0), |
| + profile_prefs_for_testing_(profile_prefs), |
| + local_state_prefs_for_testing_(local_state_prefs) { |
| + InitPrefMembers(); |
| + } |
| + |
| + // DataReductionProxySettingsAndroid implementation: |
| + virtual net::URLFetcher* GetURLFetcher() OVERRIDE { |
| + if (test_url_.empty()) |
| + return NULL; |
| + net::URLFetcher* fetcher = new net::FakeURLFetcher(GURL(test_url_), this, |
| + response_, success_); |
| + fake_fetcher_request_count_++; |
| + return fetcher; |
| + } |
| + |
| + virtual PrefService* GetOriginalProfilePrefs() OVERRIDE { |
| + return profile_prefs_for_testing_; |
| + } |
| + virtual PrefService* GetLocalStatePrefs() OVERRIDE { |
| + return local_state_prefs_for_testing_; |
| + } |
| + |
| + void set_probe_result(const std::string& test_url, |
| + const std::string& response, |
| + bool success) { |
| + test_url_ = test_url; |
| + response_ = response; |
| + success_ = success; |
| + } |
| + |
| + int fake_fetcher_request_count() { |
|
mmenke
2013/09/26 18:09:44
nit: const
bengr
2013/09/27 00:28:13
Done.
|
| + return fake_fetcher_request_count_; |
| + } |
| + |
| + private: |
| + std::string test_url_; |
| + std::string response_; |
| + bool success_; |
| + int fake_fetcher_request_count_; |
| + PrefService* profile_prefs_for_testing_; |
| + PrefService* local_state_prefs_for_testing_; |
|
mmenke
2013/09/26 18:09:44
nit: Now that these are only in test code, the "f
bengr
2013/09/27 00:28:13
Done.
|
| +}; |
| + |
| +class DataReductionProxySettingsAndroidTest : public testing::Test { |
| + protected: |
| + DataReductionProxySettingsAndroidTest() { |
| + ResetFieldTrialList(); |
| + } |
| + |
| + void ResetFieldTrialList() { |
| + // Destroy the existing FieldTrialList before creating a new one to avoid |
| + // a DCHECK. |
| + field_trial_list_.reset(); |
| + field_trial_list_.reset(new base::FieldTrialList( |
| + new metrics::SHA1EntropyProvider("foo"))); |
| + chrome_variations::testing::ClearAllVariationParams(); |
|
mmenke
2013/09/26 18:09:44
Since we enable at the command line, I don't any o
bengr
2013/09/27 00:28:13
Done.
|
| + } |
| + |
| + // Creates and activates a field trial. |
| + static base::FieldTrial* CreateTestTrial(const std::string& name, |
| + const std::string& group_name) { |
| + base::FieldTrial* trial = base::FieldTrialList::CreateFieldTrial( |
| + name, group_name); |
| + trial->group(); |
| + return trial; |
| + } |
|
mmenke
2013/09/26 18:09:44
Again, doesn't seem to do anything.
bengr
2013/09/27 00:28:13
Done.
|
| + |
| + void AddProxyToCommandLine() { |
| + CommandLine::ForCurrentProcess()->AppendSwitchASCII( |
| + switches::kSpdyProxyAuthOrigin, kDataReductionProxyOrigin); |
| + CommandLine::ForCurrentProcess()->AppendSwitchASCII( |
| + switches::kSpdyProxyAuthValue, kDataReductionProxyAuth); |
| + } |
| + |
| + // testing::Test implementation: |
| + virtual void SetUp() OVERRIDE { |
| + PrefRegistrySimple* registry = pref_service_.registry(); |
| + registry->RegisterListPref(prefs::kDailyHttpOriginalContentLength); |
| + registry->RegisterListPref(prefs::kDailyHttpReceivedContentLength); |
| + registry->RegisterInt64Pref( |
| + prefs::kDailyHttpContentLengthLastUpdateDate, 0L); |
| + registry->RegisterDictionaryPref(prefs::kProxy); |
| + registry->RegisterBooleanPref(prefs::kSpdyProxyAuthEnabled, false); |
| + registry->RegisterBooleanPref(prefs::kSpdyProxyAuthWasEnabledBefore, false); |
| + settings_.reset(new TestDataReductionProxySettingsAndroid(NULL, NULL, |
| + &pref_service_, |
| + &pref_service_)); |
| + ListPrefUpdate original_update(&pref_service_, |
| + prefs::kDailyHttpOriginalContentLength); |
| + ListPrefUpdate received_update(&pref_service_, |
| + prefs::kDailyHttpReceivedContentLength); |
| + for (int64 i = 0; i < spdyproxy::kNumDaysInHistory; i++) { |
| + original_update->Insert(0, new StringValue(base::Int64ToString(2 * i))); |
| + received_update->Insert(0, new StringValue(base::Int64ToString(i))); |
| + } |
| + last_update_time_ = base::Time::Now().LocalMidnight(); |
| + pref_service_.SetInt64( |
| + prefs::kDailyHttpContentLengthLastUpdateDate, |
| + last_update_time_.ToInternalValue()); |
| + } |
| + |
| + void CheckProxyPrefSetToDataReductionProxy( |
| + const std::string& expected_pac_url) { |
| + const DictionaryValue* dict = pref_service_.GetDictionary(prefs::kProxy); |
| + std::string mode; |
| + std::string pac_url; |
| + dict->GetString("mode", &mode); |
|
mmenke
2013/09/26 18:09:44
Should probably assert on the result in these 4 Ge
bengr
2013/09/27 00:28:13
Done.
|
| + EXPECT_EQ(ProxyModeToString(ProxyPrefs::MODE_PAC_SCRIPT), mode); |
| + dict->GetString("pac_url", &pac_url); |
| + EXPECT_EQ(expected_pac_url, pac_url); |
| + } |
|
mmenke
2013/09/26 18:09:44
nit: Line break
bengr
2013/09/27 00:28:13
Done.
|
| + void CheckProxyPrefSetToSystem() { |
| + const DictionaryValue* dict = pref_service_.GetDictionary(prefs::kProxy); |
| + std::string mode; |
| + std::string pac_url; |
| + dict->GetString("mode", &mode); |
| + EXPECT_EQ(ProxyModeToString(ProxyPrefs::MODE_SYSTEM), mode); |
| + dict->GetString("pac_url", &pac_url); |
| + EXPECT_EQ(std::string(), pac_url); |
| + EXPECT_TRUE(pac_url.empty()); |
| + } |
| + |
| + void CheckProbe(bool initially_enabled, const std::string& probe_url, |
| + const std::string& response, bool request_success, |
| + bool expected_enabled) { |
| + settings_->AddDefaultProxyBypassRules(); |
|
mmenke
2013/09/26 18:09:44
I don't think we should be making this call, since
bengr
2013/09/27 00:28:13
Done.
|
| + std::string pac; |
| + base::Base64Encode(settings_->GetProxyPacScript(), &pac); |
| + std::string expected_pac_url = |
| + "data:application/x-ns-proxy-autoconfig;base64," + pac; |
| + pref_service_.SetBoolean(prefs::kSpdyProxyAuthEnabled, initially_enabled); |
| + settings_->set_probe_result(probe_url, response, request_success); |
| + settings_->MaybeActivateDataReductionProxy(false); |
| + base::MessageLoop::current()->RunUntilIdle(); |
| + if (expected_enabled) |
| + CheckProxyPrefSetToDataReductionProxy(expected_pac_url); |
| + else |
| + CheckProxyPrefSetToSystem(); |
| + } |
| + |
| + TestingPrefServiceSimple pref_service_; |
| + scoped_ptr<TestDataReductionProxySettingsAndroid> settings_; |
| + base::Time last_update_time_; |
| + // This is a singleton that will clear all set field trials on destruction. |
| + scoped_ptr<base::FieldTrialList> field_trial_list_; |
| +}; |
| + |
| +TEST_F(DataReductionProxySettingsAndroidTest, TestGetDataReductionProxyOrigin) { |
| + AddProxyToCommandLine(); |
| + JNIEnv* env = base::android::AttachCurrentThread(); |
| + DataReductionProxySettingsAndroid::Register(env); |
| + // SetUp() adds the origin to the command line, which should be returned here. |
| + ScopedJavaLocalRef<jstring> result = |
| + settings_->GetDataReductionProxyOrigin(env, NULL); |
| + ASSERT_TRUE(result.obj()); |
| + const base::android::JavaRef<jstring>& str_ref = result; |
| + EXPECT_EQ(kDataReductionProxyOrigin, ConvertJavaStringToUTF8(str_ref)); |
| +} |
| + |
| +TEST_F(DataReductionProxySettingsAndroidTest, TestGetDataReductionProxyAuth) { |
| + AddProxyToCommandLine(); |
| + JNIEnv* env = base::android::AttachCurrentThread(); |
| + DataReductionProxySettingsAndroid::Register(env); |
| + // SetUp() adds the auth string to the command line, which should be returned |
| + // here. |
| + ScopedJavaLocalRef<jstring> result = |
| + settings_->GetDataReductionProxyAuth(env, NULL); |
| + ASSERT_TRUE(result.obj()); |
| + const base::android::JavaRef<jstring>& str_ref = result; |
| + EXPECT_EQ(kDataReductionProxyAuth, ConvertJavaStringToUTF8(str_ref)); |
| +} |
| + |
| +// Test that the auth value set by preprocessor directive is not returned |
| +// when an origin is set via a switch. |
|
mmenke
2013/09/26 18:09:44
There is no preprocessor directive anyways in Chro
bengr
2013/09/27 00:28:13
Done.
|
| +TEST_F(DataReductionProxySettingsAndroidTest, |
| + TestGetDataReductionProxyAuthWithOriginSetViaSwitch) { |
| + CommandLine::ForCurrentProcess()->AppendSwitchASCII( |
| + switches::kSpdyProxyAuthOrigin, kDataReductionProxyOrigin); |
| + JNIEnv* env = base::android::AttachCurrentThread(); |
| + DataReductionProxySettingsAndroid::Register(env); |
|
mmenke
2013/09/26 18:09:44
optional: May want to just move these two lines i
bengr
2013/09/27 00:28:13
Done.
|
| + // SetUp() adds the auth string to the command line, which should be returned |
| + // here. |
| + ScopedJavaLocalRef<jstring> result = |
| + settings_->GetDataReductionProxyAuth(env, NULL); |
| + ASSERT_TRUE(result.obj()); |
| + const base::android::JavaRef<jstring>& str_ref = result; |
| + EXPECT_EQ(std::string(), ConvertJavaStringToUTF8(str_ref)); |
| +} |
| + |
| +// Confirm that the bypass rule functions generate the intended JavaScript |
| +// code for the Proxy PAC. |
| +TEST_F(DataReductionProxySettingsAndroidTest, TestBypassRules) { |
| + settings_->AddURLPatternToBypass("http://foo.com/*"); |
| + settings_->AddHostPatternToBypass("bar.com"); |
| + settings_->AddHostToBypass("127.0.0.1"); |
| + |
| + std::string expected[] = { |
| + "shExpMatch(url, \"http://foo.com/*\")", |
| + "shExpMatch(host, \"bar.com\")", |
| + "host == \"127.0.0.1\"" |
| + }; |
| + |
| + int i = 0; |
| + for (std::vector<std::string>::iterator it = settings_->bypass_rules_.begin(); |
| + it != settings_->bypass_rules_.end(); ++it) { |
| + EXPECT_EQ(expected[i++], *it); |
| + } |
| +} |
| + |
| +TEST_F(DataReductionProxySettingsAndroidTest, TestIsProxyEnabledOrManaged) { |
| + EXPECT_FALSE(settings_->IsDataReductionProxyEnabled(NULL, NULL)); |
| + EXPECT_FALSE(settings_->IsDataReductionProxyManaged(NULL, NULL)); |
| + |
| + pref_service_.SetBoolean(prefs::kSpdyProxyAuthEnabled, true); |
| + EXPECT_TRUE(settings_->IsDataReductionProxyEnabled(NULL, NULL)); |
| + EXPECT_FALSE(settings_->IsDataReductionProxyManaged(NULL, NULL)); |
| + |
| + pref_service_.SetManagedPref(prefs::kSpdyProxyAuthEnabled, |
| + base::Value::CreateBooleanValue(true)); |
| + EXPECT_TRUE(settings_->IsDataReductionProxyEnabled(NULL, NULL)); |
| + EXPECT_TRUE(settings_->IsDataReductionProxyManaged(NULL, NULL)); |
| +} |
| + |
| +TEST_F(DataReductionProxySettingsAndroidTest, TestSetProxyPac) { |
| + settings_->AddDefaultProxyBypassRules(); |
| + std::string pac; |
| + base::Base64Encode(settings_->GetProxyPacScript(), &pac); |
| + std::string expected_pac_url = |
| + "data:application/x-ns-proxy-autoconfig;base64," + pac; |
| + // Test setting the PAC, without generating histograms. |
| + settings_->has_turned_on_ = true; |
| + settings_->SetProxyPac(true, false); |
| + CheckProxyPrefSetToDataReductionProxy(expected_pac_url); |
| + |
| + // Test disabling the PAC, without generating histograms. |
| + settings_->has_turned_off_ = true; |
| + settings_->SetProxyPac(false, false); |
| + CheckProxyPrefSetToSystem(); |
| +} |
| + |
| +TEST_F(DataReductionProxySettingsAndroidTest, TestGetDailyContentLengths) { |
| + JNIEnv* env = base::android::AttachCurrentThread(); |
| + DataReductionProxySettingsAndroid::Register(env); |
| + ScopedJavaLocalRef<jlongArray> result = |
| + settings_->GetDailyContentLengths(env, |
| + prefs::kDailyHttpOriginalContentLength); |
| + ASSERT_TRUE(result.obj()); |
| + |
| + jsize java_array_len = env->GetArrayLength(result.obj()); |
| + ASSERT_EQ(static_cast<jsize>(spdyproxy::kNumDaysInHistory), java_array_len); |
| + |
| + jlong value; |
| + for (size_t i = 0; i < spdyproxy::kNumDaysInHistory; ++i) { |
| + env->GetLongArrayRegion(result.obj(), i, 1, &value); |
| + ASSERT_EQ( |
| + static_cast<long>((spdyproxy::kNumDaysInHistory - 1 - i) * 2), value); |
| + } |
| +} |
| + |
| +TEST_F(DataReductionProxySettingsAndroidTest, |
| + TestResetDataReductionStatistics) { |
| + int64 original_content_length; |
| + int64 received_content_length; |
| + int64 last_update_time; |
| + settings_->ResetDataReductionStatistics(); |
| + settings_->GetContentLengthsInternal(spdyproxy::kNumDaysInHistory, |
| + &original_content_length, |
| + &received_content_length, |
| + &last_update_time); |
| + EXPECT_EQ(0L, original_content_length); |
| + EXPECT_EQ(0L, received_content_length); |
| + EXPECT_EQ(last_update_time_.ToInternalValue(), last_update_time); |
| +} |
| + |
| +TEST_F(DataReductionProxySettingsAndroidTest, TestContentLengthsInternal) { |
| + int64 original_content_length; |
| + int64 received_content_length; |
| + int64 last_update_time; |
| + |
| + // Request |kNumDaysInHistory| days. |
| + settings_->GetContentLengthsInternal(spdyproxy::kNumDaysInHistory, |
| + &original_content_length, |
| + &received_content_length, |
| + &last_update_time); |
| + const unsigned int days = spdyproxy::kNumDaysInHistory; |
| + // Received content length history values are 0 to |kNumDaysInHistory - 1|. |
| + int64 expected_total_received_content_length = (days - 1L) * days / 2; |
| + // Original content length history values are 0 to |
| + // |2 * (kNumDaysInHistory - 1)|. |
| + long expected_total_original_content_length = (days - 1L) * days; |
| + EXPECT_EQ(expected_total_original_content_length, original_content_length); |
| + EXPECT_EQ(expected_total_received_content_length, received_content_length); |
| + EXPECT_EQ(last_update_time_.ToInternalValue(), last_update_time); |
| + |
| + // Request |kNumDaysInHistory - 1| days. |
| + settings_->GetContentLengthsInternal(spdyproxy::kNumDaysInHistory - 1, |
| + &original_content_length, |
| + &received_content_length, |
| + &last_update_time); |
| + expected_total_received_content_length -= (days - 1); |
| + expected_total_original_content_length -= 2 * (days - 1); |
| + EXPECT_EQ(expected_total_original_content_length, original_content_length); |
| + EXPECT_EQ(expected_total_received_content_length, received_content_length); |
| + |
| + // Request 0 days. |
| + settings_->GetContentLengthsInternal(0, |
| + &original_content_length, |
| + &received_content_length, |
| + &last_update_time); |
| + expected_total_received_content_length = 0; |
| + expected_total_original_content_length = 0; |
| + EXPECT_EQ(expected_total_original_content_length, original_content_length); |
| + EXPECT_EQ(expected_total_received_content_length, received_content_length); |
| + |
| + // Request 1 day. First day had 0 bytes so should be same as 0 days. |
| + settings_->GetContentLengthsInternal(1, |
| + &original_content_length, |
| + &received_content_length, |
| + &last_update_time); |
| + EXPECT_EQ(expected_total_original_content_length, original_content_length); |
| + EXPECT_EQ(expected_total_received_content_length, received_content_length); |
| +} |
| + |
| +TEST_F(DataReductionProxySettingsAndroidTest, |
| + TestMaybeActivateDataReductionProxy) { |
| + // TODO(bengr): Test enabling/disabling while a probe is outstanding. |
| + base::MessageLoop loop(base::MessageLoop::TYPE_UI); |
| + // The proxy is enabled initially. |
| + // Request succeeded but with bad response, expect proxy to be disabled. |
| + CheckProbe(true, kProbeURLWithBadResponse, "Bad", true, false); |
| + // Request succeeded with valid response, expect proxy to be enabled. |
| + CheckProbe(true, kProbeURLWithOKResponse, "OK", true, true); |
| + // Request failed, expect proxy to be disabled. |
| + CheckProbe(true, kProbeURLWithNoResponse, "", false, false); |
| + |
| + // The proxy is disabled initially. Probes should not be emitted to change |
| + // state. |
| + EXPECT_EQ(3, settings_->fake_fetcher_request_count()); |
| + CheckProbe(false, kProbeURLWithOKResponse, "OK", true, false); |
| + EXPECT_EQ(3, settings_->fake_fetcher_request_count()); |
| +} |
|
mmenke
2013/09/26 18:09:44
We never test OnIPAddressChanged, which follows a
mmenke
2013/09/26 18:09:44
Also, none of these tests call InitDataReductionPr
mmenke
2013/09/26 18:09:44
Also, none of the tests check that when prefs::kSp
bengr
2013/09/27 00:28:13
Done.
bengr
2013/09/27 00:28:13
Done.
bengr
2013/09/27 00:28:13
Done.
|
| + |