blob: af18b217e7cd04c4b8f55a00071c61ce55f0c773 [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_metrics.h"
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h"
#include "net/base/load_flags.h"
#include "net/log/net_log.h"
#include "net/proxy/proxy_server.h"
#include "net/proxy/proxy_service.h"
#include "net/socket/socket_test_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
using net::MockRead;
namespace data_reduction_proxy {
TEST(ChromeNetworkDailyDataSavingMetricsTest,
GetDataReductionProxyRequestType) {
base::MessageLoopForIO message_loop;
scoped_ptr<DataReductionProxyTestContext> test_context =
DataReductionProxyTestContext::Builder()
.WithParamsFlags(DataReductionProxyParams::kAllowed)
.WithParamsDefinitions(TestDataReductionProxyParams::HAS_ORIGIN)
.Build();
TestDataReductionProxyConfig* config = test_context->config();
net::ProxyConfig data_reduction_proxy_config;
data_reduction_proxy_config.proxy_rules().ParseFromString(
"http=" + config->test_params()->origin().host_port_pair().ToString() +
",direct://");
data_reduction_proxy_config.proxy_rules().bypass_rules.ParseFromString(
"localbypass.com");
struct TestCase {
GURL url;
net::ProxyServer proxy_server;
base::TimeDelta bypass_duration; // 0 indicates not bypassed.
int load_flags;
const char* response_headers;
DataReductionProxyRequestType expected_request_type;
};
const TestCase test_cases[] = {
{ GURL("http://foo.com"),
config->test_params()->origin(),
base::TimeDelta(),
net::LOAD_NORMAL,
"HTTP/1.1 200 OK\r\nVia: 1.1 Chrome-Compression-Proxy\r\n\r\n",
VIA_DATA_REDUCTION_PROXY,
},
{ GURL("https://foo.com"),
net::ProxyServer::Direct(),
base::TimeDelta(),
net::LOAD_NORMAL,
"HTTP/1.1 200 OK\r\n\r\n",
HTTPS,
},
{ GURL("http://foo.com"),
net::ProxyServer::Direct(),
base::TimeDelta::FromSeconds(1),
net::LOAD_NORMAL,
"HTTP/1.1 200 OK\r\n\r\n",
SHORT_BYPASS,
},
{ GURL("http://foo.com"),
net::ProxyServer::Direct(),
base::TimeDelta::FromMinutes(60),
net::LOAD_NORMAL,
"HTTP/1.1 200 OK\r\n\r\n",
LONG_BYPASS,
},
// Requests with LOAD_BYPASS_PROXY (e.g. block-once) should be classified as
// SHORT_BYPASS.
{ GURL("http://foo.com"),
net::ProxyServer::Direct(),
base::TimeDelta(),
net::LOAD_BYPASS_PROXY,
"HTTP/1.1 200 OK\r\n\r\n",
SHORT_BYPASS,
},
// Another proxy overriding the Data Reduction Proxy should be classified as
// SHORT_BYPASS.
{ GURL("http://foo.com"),
net::ProxyServer::FromPacString("PROXY otherproxy.net:80"),
base::TimeDelta(),
net::LOAD_NORMAL,
"HTTP/1.1 200 OK\r\n\r\n",
SHORT_BYPASS,
},
// Bypasses due to local bypass rules should be classified as SHORT_BYPASS.
{ GURL("http://localbypass.com"),
net::ProxyServer::Direct(),
base::TimeDelta(),
net::LOAD_NORMAL,
"HTTP/1.1 200 OK\r\n\r\n",
SHORT_BYPASS,
},
// Responses that seem like they should have come through the Data Reduction
// Proxy, but did not, should be classified as UNKNOWN_TYPE.
{ GURL("http://foo.com"),
net::ProxyServer::Direct(),
base::TimeDelta(),
net::LOAD_NORMAL,
"HTTP/1.1 200 OK\r\n\r\n",
UNKNOWN_TYPE,
},
};
for (const TestCase& test_case : test_cases) {
net::TestURLRequestContext context(true);
net::MockClientSocketFactory mock_socket_factory;
context.set_client_socket_factory(&mock_socket_factory);
// Set the |proxy_service| to use |test_case.proxy_server| for requests.
scoped_ptr<net::ProxyService> proxy_service(
net::ProxyService::CreateFixedFromPacResult(
test_case.proxy_server.ToPacString()));
context.set_proxy_service(proxy_service.get());
context.Init();
// Create a fake URLRequest and fill it with the appropriate response
// headers and proxy server by executing it with fake socket data.
net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK);
if (test_case.url.SchemeIsCryptographic())
mock_socket_factory.AddSSLSocketDataProvider(&ssl_socket_data_provider);
MockRead mock_reads[] = {
MockRead(test_case.response_headers),
MockRead("hello world"),
MockRead(net::SYNCHRONOUS, net::OK),
};
net::StaticSocketDataProvider socket_data_provider(
mock_reads, arraysize(mock_reads), nullptr, 0);
mock_socket_factory.AddSocketDataProvider(&socket_data_provider);
net::TestDelegate delegate;
scoped_ptr<net::URLRequest> request =
context.CreateRequest(test_case.url, net::IDLE, &delegate);
request->SetLoadFlags(test_case.load_flags);
request->Start();
test_context->RunUntilIdle();
// Mark the Data Reduction Proxy as bad if the test specifies to.
if (test_case.bypass_duration > base::TimeDelta()) {
net::ProxyInfo proxy_info;
proxy_info.UseProxyList(
data_reduction_proxy_config.proxy_rules().proxies_for_http);
EXPECT_TRUE(context.proxy_service()->MarkProxiesAsBadUntil(
proxy_info, test_case.bypass_duration, net::ProxyServer(),
net::BoundNetLog::Make(context.net_log(), net::NetLog::SOURCE_NONE)));
}
EXPECT_EQ(test_case.expected_request_type,
GetDataReductionProxyRequestType(
*request, data_reduction_proxy_config,
*test_context->config()));
}
}
} // namespace data_reduction_proxy