blob: a964b50a4eac99ef3c09d5c0900c8b0afde88c77 [file] [log] [blame]
// Copyright 2014 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 "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h"
#include <memory>
#include <string>
#include <vector>
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_task_environment.h"
#include "base/time/default_clock.h"
#include "base/values.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
#include "components/data_reduction_proxy/core/browser/network_properties_manager.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_server.h"
#include "components/data_reduction_proxy/proto/client_config.pb.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "net/base/proxy_server.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace data_reduction_proxy {
class DataReductionProxyConfiguratorTest : public testing::Test {
public:
void SetUp() override {
test_prefs.registry()->RegisterDictionaryPref(prefs::kNetworkProperties);
manager_.reset(new NetworkPropertiesManager(
base::DefaultClock::GetInstance(), &test_prefs,
base::ThreadTaskRunnerHandle::Get()));
manager_->OnChangeInNetworkID("test");
test_context_ = DataReductionProxyTestContext::Builder().Build();
config_.reset(new DataReductionProxyConfigurator(
test_context_->net_log(), test_context_->event_creator()));
}
void TearDown() override {
// Reset the state of |manager_|.
manager_->SetIsSecureProxyDisallowedByCarrier(false);
manager_->SetIsCaptivePortal(false);
manager_->SetHasWarmupURLProbeFailed(false, false, false);
manager_->SetHasWarmupURLProbeFailed(false, true, false);
manager_->SetHasWarmupURLProbeFailed(true, false, false);
manager_->SetHasWarmupURLProbeFailed(true, true, false);
}
std::vector<DataReductionProxyServer> BuildProxyList(
const std::string& first,
enum ProxyServer_ProxyType first_proxy_type,
const std::string& second,
enum ProxyServer_ProxyType second_proxy_type) {
std::vector<DataReductionProxyServer> proxies;
if (!first.empty()) {
net::ProxyServer proxy =
net::ProxyServer::FromURI(first, net::ProxyServer::SCHEME_HTTP);
EXPECT_TRUE(proxy.is_valid()) << first;
proxies.push_back(DataReductionProxyServer(proxy, first_proxy_type));
}
if (!second.empty()) {
net::ProxyServer proxy =
net::ProxyServer::FromURI(second, net::ProxyServer::SCHEME_HTTP);
EXPECT_TRUE(proxy.is_valid()) << second;
proxies.push_back(DataReductionProxyServer(proxy, second_proxy_type));
}
return proxies;
}
void CheckProxyConfig(
const net::ProxyConfig::ProxyRules::Type& expected_rules_type,
const std::string& expected_http_proxies,
const std::string& expected_bypass_list) {
test_context_->RunUntilIdle();
const net::ProxyConfig::ProxyRules& rules =
config_->GetProxyConfig().proxy_rules();
ASSERT_EQ(expected_rules_type, rules.type);
if (net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME ==
expected_rules_type) {
ASSERT_EQ(expected_http_proxies, rules.proxies_for_http.ToPacString());
ASSERT_EQ(std::string(), rules.proxies_for_https.ToPacString());
ASSERT_EQ(expected_bypass_list, rules.bypass_rules.ToString());
}
}
void CheckProbeProxyConfig(
const std::vector<DataReductionProxyServer>& http_proxies,
bool probe_url_config,
const net::ProxyConfig::ProxyRules::Type& expected_rules_type,
const std::string& expected_http_proxies,
const std::string& expected_bypass_list) {
test_context_->RunUntilIdle();
net::ProxyConfig::ProxyRules rules =
config_->CreateProxyConfig(probe_url_config, *manager_, http_proxies)
.proxy_rules();
ASSERT_EQ(expected_rules_type, rules.type);
if (net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME ==
expected_rules_type) {
ASSERT_EQ(expected_http_proxies, rules.proxies_for_http.ToPacString());
ASSERT_EQ(std::string(), rules.proxies_for_https.ToPacString());
ASSERT_EQ(expected_bypass_list, rules.bypass_rules.ToString());
}
}
TestingPrefServiceSimple test_prefs;
base::test::ScopedTaskEnvironment scoped_task_environment_;
std::unique_ptr<DataReductionProxyTestContext> test_context_;
std::unique_ptr<DataReductionProxyConfigurator> config_;
std::unique_ptr<NetworkPropertiesManager> manager_;
};
TEST_F(DataReductionProxyConfiguratorTest, TestUnrestricted) {
config_->Enable(*manager_,
BuildProxyList("https://www.foo.com:443", ProxyServer::CORE,
"http://www.bar.com:80", ProxyServer::CORE));
CheckProxyConfig(net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME,
"HTTPS www.foo.com:443;PROXY www.bar.com:80;DIRECT",
std::string());
}
TEST_F(DataReductionProxyConfiguratorTest, TestUnrestrictedQuic) {
config_->Enable(*manager_,
BuildProxyList("quic://www.foo.com:443", ProxyServer::CORE,
"http://www.bar.com:80", ProxyServer::CORE));
CheckProxyConfig(net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME,
"QUIC www.foo.com:443;PROXY www.bar.com:80;DIRECT",
std::string());
}
TEST_F(DataReductionProxyConfiguratorTest, TestUnrestrictedWithBypassRule) {
config_->SetBypassRules("<local>, *.goo.com");
config_->Enable(*manager_,
BuildProxyList("https://www.foo.com:443", ProxyServer::CORE,
"http://www.bar.com:80", ProxyServer::CORE));
CheckProxyConfig(net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME,
"HTTPS www.foo.com:443;PROXY www.bar.com:80;DIRECT",
"<local>;*.goo.com;");
}
TEST_F(DataReductionProxyConfiguratorTest, TestUnrestrictedWithBypassRuleQuic) {
config_->SetBypassRules("<local>, *.goo.com");
config_->Enable(*manager_,
BuildProxyList("quic://www.foo.com:443", ProxyServer::CORE,
"http://www.bar.com:80", ProxyServer::CORE));
CheckProxyConfig(net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME,
"QUIC www.foo.com:443;PROXY www.bar.com:80;DIRECT",
"<local>;*.goo.com;");
}
TEST_F(DataReductionProxyConfiguratorTest, TestUnrestrictedWithoutFallback) {
config_->Enable(*manager_,
BuildProxyList("https://www.foo.com:443", ProxyServer::CORE,
std::string(), ProxyServer::CORE));
CheckProxyConfig(net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME,
"HTTPS www.foo.com:443;DIRECT", std::string());
}
TEST_F(DataReductionProxyConfiguratorTest,
TestUnrestrictedWithoutFallbackQuic) {
config_->Enable(*manager_,
BuildProxyList("quic://www.foo.com:443", ProxyServer::CORE,
std::string(), ProxyServer::CORE));
CheckProxyConfig(net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME,
"QUIC www.foo.com:443;DIRECT", std::string());
}
TEST_F(DataReductionProxyConfiguratorTest, TestSecureRestrictedProxiesAreCore) {
manager_->SetHasWarmupURLProbeFailed(true, true, true);
config_->Enable(*manager_,
BuildProxyList("https://www.foo.com:443", ProxyServer::CORE,
"http://www.bar.com:80", ProxyServer::CORE));
CheckProxyConfig(net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME,
"PROXY www.bar.com:80;DIRECT", std::string());
}
TEST_F(DataReductionProxyConfiguratorTest, TestSecureNonCoreRestricted) {
base::HistogramTester histogram_tester;
manager_->SetHasWarmupURLProbeFailed(true, false, true);
config_->Enable(*manager_,
BuildProxyList("https://www.foo.com:443", ProxyServer::CORE,
"http://www.bar.com:80", ProxyServer::CORE));
CheckProxyConfig(net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME,
"HTTPS www.foo.com:443;PROXY www.bar.com:80;DIRECT",
std::string());
manager_->SetHasWarmupURLProbeFailed(true, false, false);
histogram_tester.ExpectUniqueSample(
"DataReductionProxy.WarmupURL.FetchAttemptsBeforeSuccess.Secure.NonCore",
0, 1);
}
TEST_F(DataReductionProxyConfiguratorTest,
TestSecureRestrictedProxiesAreNonCore) {
manager_->SetHasWarmupURLProbeFailed(true, true, true);
config_->Enable(
*manager_,
BuildProxyList("https://www.foo.com:443", ProxyServer::UNSPECIFIED_TYPE,
"http://www.bar.com:80", ProxyServer::UNSPECIFIED_TYPE));
CheckProxyConfig(net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME,
"HTTPS www.foo.com:443;PROXY www.bar.com:80;DIRECT",
std::string());
}
TEST_F(DataReductionProxyConfiguratorTest, TestInsecureCoreRestricted) {
manager_->SetHasWarmupURLProbeFailed(false, true, true);
config_->Enable(*manager_,
BuildProxyList("https://www.foo.com:443", ProxyServer::CORE,
"http://www.bar.com:80", ProxyServer::CORE));
CheckProxyConfig(net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME,
"HTTPS www.foo.com:443;DIRECT", std::string());
}
TEST_F(DataReductionProxyConfiguratorTest, TestInsecureNonCoreRestricted) {
manager_->SetHasWarmupURLProbeFailed(false, false, true);
config_->Enable(*manager_,
BuildProxyList("https://www.foo.com:443", ProxyServer::CORE,
"http://www.bar.com:80", ProxyServer::CORE));
CheckProxyConfig(net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME,
"HTTPS www.foo.com:443;PROXY www.bar.com:80;DIRECT",
std::string());
}
TEST_F(DataReductionProxyConfiguratorTest, TestSecureInsecureCoreRestricted) {
manager_->SetHasWarmupURLProbeFailed(true, true, true);
manager_->SetHasWarmupURLProbeFailed(false, true, true);
config_->Enable(*manager_,
BuildProxyList("https://www.foo.com:443", ProxyServer::CORE,
"http://www.bar.com:80", ProxyServer::CORE));
CheckProxyConfig(net::ProxyConfig::ProxyRules::Type::EMPTY, "",
std::string());
}
TEST_F(DataReductionProxyConfiguratorTest, TestRestrictedQuic) {
base::HistogramTester histogram_tester;
manager_->SetHasWarmupURLProbeFailed(true, true, true);
config_->Enable(*manager_,
BuildProxyList("quic://www.foo.com:443", ProxyServer::CORE,
"http://www.bar.com:80", ProxyServer::CORE));
CheckProxyConfig(net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME,
"PROXY www.bar.com:80;DIRECT", std::string());
manager_->SetHasWarmupURLProbeFailed(true, true, false);
histogram_tester.ExpectUniqueSample(
"DataReductionProxy.WarmupURL.FetchAttemptsBeforeSuccess.Secure.Core", 0,
1);
manager_->OnWarmupFetchInitiated(true, true);
manager_->SetHasWarmupURLProbeFailed(true, true, false);
histogram_tester.ExpectBucketCount(
"DataReductionProxy.WarmupURL.FetchAttemptsBeforeSuccess.Secure.Core", 1,
1);
manager_->OnWarmupFetchInitiated(true, true);
manager_->SetHasWarmupURLProbeFailed(true, true, false);
histogram_tester.ExpectBucketCount(
"DataReductionProxy.WarmupURL.FetchAttemptsBeforeSuccess.Secure.Core", 2,
1);
histogram_tester.ExpectTotalCount(
"DataReductionProxy.WarmupURL.FetchAttemptsBeforeSuccess.Secure.Core", 3);
}
TEST_F(DataReductionProxyConfiguratorTest, TestDisable) {
config_->Enable(*manager_,
BuildProxyList("https://www.foo.com:443", ProxyServer::CORE,
"http://www.bar.com:80", ProxyServer::CORE));
config_->Disable();
CheckProxyConfig(net::ProxyConfig::ProxyRules::Type::EMPTY, std::string(),
std::string());
}
TEST_F(DataReductionProxyConfiguratorTest, TestBypassList) {
config_->SetBypassRules("http://www.google.com, fefe:13::abc/33");
net::ProxyBypassRules expected;
expected.AddRuleFromString("http://www.google.com");
expected.AddRuleFromString("fefe:13::abc/33");
EXPECT_TRUE(expected.Equals(config_->bypass_rules_));
}
TEST_F(DataReductionProxyConfiguratorTest,
TestProbeSecureInsecureCoreRestricted) {
manager_->SetHasWarmupURLProbeFailed(true, true, true);
manager_->SetHasWarmupURLProbeFailed(false, true, true);
const std::vector<DataReductionProxyServer>& http_proxies =
BuildProxyList("https://www.foo.com:443", ProxyServer::CORE,
"http://www.bar.com:80", ProxyServer::CORE);
config_->Enable(*manager_, http_proxies);
CheckProbeProxyConfig(http_proxies, true /* probe_url_config */,
net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME,
"HTTPS www.foo.com:443;PROXY www.bar.com:80;DIRECT",
std::string());
CheckProbeProxyConfig(http_proxies, false /* probe_url_config */,
net::ProxyConfig::ProxyRules::Type::EMPTY, "",
std::string());
}
} // namespace data_reduction_proxy