Index: components/data_reduction_proxy/core/browser/data_reduction_proxy_usage_stats_unittest.cc |
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_usage_stats_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_usage_stats_unittest.cc |
deleted file mode 100644 |
index d5c2e684dbccd71238992077055b565da4bacdb6..0000000000000000000000000000000000000000 |
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_usage_stats_unittest.cc |
+++ /dev/null |
@@ -1,924 +0,0 @@ |
-// 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_usage_stats.h" |
- |
-#include <set> |
-#include <string> |
-#include <vector> |
- |
-#include "base/bind.h" |
-#include "base/memory/scoped_ptr.h" |
-#include "base/metrics/histogram.h" |
-#include "base/prefs/testing_pref_service.h" |
-#include "base/test/histogram_tester.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_configurator.h" |
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h" |
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h" |
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h" |
-#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h" |
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers_test_utils.h" |
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h" |
-#include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h" |
-#include "net/base/host_port_pair.h" |
-#include "net/base/load_flags.h" |
-#include "net/base/net_errors.h" |
-#include "net/base/net_log.h" |
-#include "net/base/request_priority.h" |
-#include "net/dns/mock_host_resolver.h" |
-#include "net/http/http_response_headers.h" |
-#include "net/http/http_util.h" |
-#include "net/socket/socket_test_util.h" |
-#include "net/url_request/url_request.h" |
-#include "net/url_request/url_request_context_getter.h" |
-#include "net/url_request/url_request_context_storage.h" |
-#include "net/url_request/url_request_intercepting_job_factory.h" |
-#include "net/url_request/url_request_interceptor.h" |
-#include "net/url_request/url_request_job_factory_impl.h" |
-#include "net/url_request/url_request_status.h" |
-#include "net/url_request/url_request_test_job.h" |
-#include "net/url_request/url_request_test_util.h" |
-#include "testing/gmock/include/gmock/gmock.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
- |
-using net::MockRead; |
-using net::MockWrite; |
-using testing::Return; |
- |
-namespace data_reduction_proxy { |
- |
-namespace { |
- |
-const std::string kBody = "hello"; |
-const std::string kNextBody = "hello again"; |
-const std::string kErrorBody = "bad"; |
- |
-} // namespace |
- |
-class DataReductionProxyUsageStatsTest : public testing::Test { |
- public: |
- DataReductionProxyUsageStatsTest() |
- : context_(true) { |
- context_.Init(); |
- |
- // The |test_job_factory_| takes ownership of the interceptor. |
- test_job_interceptor_ = new net::TestJobInterceptor(); |
- EXPECT_TRUE(test_job_factory_.SetProtocolHandler(url::kHttpScheme, |
- test_job_interceptor_)); |
- |
- context_.set_job_factory(&test_job_factory_); |
- |
- test_context_ = |
- DataReductionProxyTestContext::Builder() |
- .WithParamsFlags(DataReductionProxyParams::kAllowed | |
- DataReductionProxyParams::kFallbackAllowed | |
- DataReductionProxyParams::kPromoAllowed) |
- .WithParamsDefinitions( |
- TestDataReductionProxyParams::HAS_EVERYTHING & |
- ~TestDataReductionProxyParams::HAS_DEV_ORIGIN & |
- ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN) |
- .WithMockConfig() |
- .Build(); |
- mock_url_request_ = context_.CreateRequest(GURL(), net::IDLE, &delegate_); |
- } |
- |
- scoped_ptr<net::URLRequest> CreateURLRequestWithResponseHeaders( |
- const GURL& url, |
- const std::string& raw_response_headers) { |
- scoped_ptr<net::URLRequest> fake_request = context_.CreateRequest( |
- url, net::IDLE, &delegate_); |
- |
- // Create a test job that will fill in the given response headers for the |
- // |fake_request|. |
- scoped_refptr<net::URLRequestTestJob> test_job( |
- new net::URLRequestTestJob(fake_request.get(), |
- context_.network_delegate(), |
- raw_response_headers, std::string(), true)); |
- |
- // Configure the interceptor to use the test job to handle the next request. |
- test_job_interceptor_->set_main_intercept_job(test_job.get()); |
- fake_request->Start(); |
- test_context_->RunUntilIdle(); |
- |
- EXPECT_TRUE(fake_request->response_headers() != NULL); |
- return fake_request.Pass(); |
- } |
- |
- bool IsUnreachable() const { |
- return test_context_->settings()->IsDataReductionProxyUnreachable(); |
- } |
- |
- protected: |
- scoped_ptr<DataReductionProxyUsageStats> BuildUsageStats() { |
- return make_scoped_ptr( |
- new DataReductionProxyUsageStats( |
- test_context_->config(), |
- test_context_->unreachable_callback(), |
- test_context_->task_runner())).Pass(); |
- } |
- |
- net::URLRequest* url_request() { |
- return mock_url_request_.get(); |
- } |
- |
- MockDataReductionProxyConfig* config() const { |
- return test_context_->mock_config(); |
- } |
- |
- void RunUntilIdle() { |
- test_context_->RunUntilIdle(); |
- } |
- |
- private: |
- net::TestURLRequestContext context_; |
- net::TestDelegate delegate_; |
- scoped_ptr<net::URLRequest> mock_url_request_; |
- // |test_job_interceptor_| is owned by |test_job_factory_|. |
- net::TestJobInterceptor* test_job_interceptor_; |
- net::URLRequestJobFactoryImpl test_job_factory_; |
- scoped_ptr<DataReductionProxyTestContext> test_context_; |
-}; |
- |
-TEST_F(DataReductionProxyUsageStatsTest, IsDataReductionProxyUnreachable) { |
- net::ProxyServer fallback_proxy_server = |
- net::ProxyServer::FromURI("foo.com", net::ProxyServer::SCHEME_HTTP); |
- data_reduction_proxy::DataReductionProxyTypeInfo proxy_info; |
- struct TestCase { |
- bool fallback_proxy_server_is_data_reduction_proxy; |
- bool was_proxy_used; |
- bool is_unreachable; |
- }; |
- const TestCase test_cases[] = { |
- { |
- false, |
- false, |
- false |
- }, |
- { |
- false, |
- true, |
- false |
- }, |
- { |
- true, |
- true, |
- false |
- }, |
- { |
- true, |
- false, |
- true |
- } |
- }; |
- for (size_t i = 0; i < arraysize(test_cases); ++i) { |
- TestCase test_case = test_cases[i]; |
- |
- EXPECT_CALL(*config(), IsDataReductionProxy(testing::_, testing::_)) |
- .WillRepeatedly(testing::Return( |
- test_case.fallback_proxy_server_is_data_reduction_proxy)); |
- EXPECT_CALL(*config(), |
- WasDataReductionProxyUsed(url_request(), testing::_)) |
- .WillRepeatedly(testing::Return(test_case.was_proxy_used)); |
- |
- scoped_ptr<DataReductionProxyUsageStats> usage_stats = BuildUsageStats(); |
- |
- usage_stats->OnProxyFallback(fallback_proxy_server, |
- net::ERR_PROXY_CONNECTION_FAILED); |
- usage_stats->OnUrlRequestCompleted(url_request(), false); |
- RunUntilIdle(); |
- |
- EXPECT_EQ(test_case.is_unreachable, IsUnreachable()); |
- } |
-} |
- |
-TEST_F(DataReductionProxyUsageStatsTest, ProxyUnreachableThenReachable) { |
- net::ProxyServer fallback_proxy_server = |
- net::ProxyServer::FromURI("foo.com", net::ProxyServer::SCHEME_HTTP); |
- scoped_ptr<DataReductionProxyUsageStats> usage_stats = BuildUsageStats(); |
- EXPECT_CALL(*config(), IsDataReductionProxy(testing::_, testing::_)) |
- .WillOnce(testing::Return(true)); |
- EXPECT_CALL(*config(), |
- WasDataReductionProxyUsed(url_request(), testing::_)) |
- .WillOnce(testing::Return(true)); |
- |
- // proxy falls back |
- usage_stats->OnProxyFallback(fallback_proxy_server, |
- net::ERR_PROXY_CONNECTION_FAILED); |
- RunUntilIdle(); |
- EXPECT_TRUE(IsUnreachable()); |
- |
- // proxy succeeds |
- usage_stats->OnUrlRequestCompleted(url_request(), false); |
- RunUntilIdle(); |
- EXPECT_FALSE(IsUnreachable()); |
-} |
- |
-TEST_F(DataReductionProxyUsageStatsTest, ProxyReachableThenUnreachable) { |
- net::ProxyServer fallback_proxy_server = |
- net::ProxyServer::FromURI("foo.com", net::ProxyServer::SCHEME_HTTP); |
- scoped_ptr<DataReductionProxyUsageStats> usage_stats = BuildUsageStats(); |
- EXPECT_CALL(*config(), |
- WasDataReductionProxyUsed(url_request(), testing::_)) |
- .WillOnce(testing::Return(true)); |
- EXPECT_CALL(*config(), IsDataReductionProxy(testing::_, testing::_)) |
- .WillRepeatedly(testing::Return(true)); |
- |
- // Proxy succeeds. |
- usage_stats->OnUrlRequestCompleted(url_request(), false); |
- RunUntilIdle(); |
- EXPECT_FALSE(IsUnreachable()); |
- |
- // Then proxy falls back indefinitely. |
- usage_stats->OnProxyFallback(fallback_proxy_server, |
- net::ERR_PROXY_CONNECTION_FAILED); |
- usage_stats->OnProxyFallback(fallback_proxy_server, |
- net::ERR_PROXY_CONNECTION_FAILED); |
- usage_stats->OnProxyFallback(fallback_proxy_server, |
- net::ERR_PROXY_CONNECTION_FAILED); |
- usage_stats->OnProxyFallback(fallback_proxy_server, |
- net::ERR_PROXY_CONNECTION_FAILED); |
- RunUntilIdle(); |
- EXPECT_TRUE(IsUnreachable()); |
-} |
- |
-TEST_F(DataReductionProxyUsageStatsTest, |
- DetectAndRecordMissingViaHeaderResponseCode) { |
- const std::string kPrimaryHistogramName = |
- "DataReductionProxy.MissingViaHeader.ResponseCode.Primary"; |
- const std::string kFallbackHistogramName = |
- "DataReductionProxy.MissingViaHeader.ResponseCode.Fallback"; |
- |
- struct TestCase { |
- bool is_primary; |
- const char* headers; |
- int expected_primary_sample; // -1 indicates no expected sample. |
- int expected_fallback_sample; // -1 indicates no expected sample. |
- }; |
- const TestCase test_cases[] = { |
- { |
- true, |
- "HTTP/1.1 200 OK\n" |
- "Via: 1.1 Chrome-Compression-Proxy\n", |
- -1, |
- -1 |
- }, |
- { |
- false, |
- "HTTP/1.1 200 OK\n" |
- "Via: 1.1 Chrome-Compression-Proxy\n", |
- -1, |
- -1 |
- }, |
- { |
- true, |
- "HTTP/1.1 200 OK\n", |
- 200, |
- -1 |
- }, |
- { |
- false, |
- "HTTP/1.1 200 OK\n", |
- -1, |
- 200 |
- }, |
- { |
- true, |
- "HTTP/1.1 304 Not Modified\n", |
- 304, |
- -1 |
- }, |
- { |
- false, |
- "HTTP/1.1 304 Not Modified\n", |
- -1, |
- 304 |
- }, |
- { |
- true, |
- "HTTP/1.1 404 Not Found\n", |
- 404, |
- -1 |
- }, |
- { |
- false, |
- "HTTP/1.1 404 Not Found\n", |
- -1, |
- 404 |
- } |
- }; |
- |
- for (size_t i = 0; i < arraysize(test_cases); ++i) { |
- base::HistogramTester histogram_tester; |
- std::string raw_headers(test_cases[i].headers); |
- HeadersToRaw(&raw_headers); |
- scoped_refptr<net::HttpResponseHeaders> headers( |
- new net::HttpResponseHeaders(raw_headers)); |
- |
- DataReductionProxyUsageStats::DetectAndRecordMissingViaHeaderResponseCode( |
- test_cases[i].is_primary, headers.get()); |
- |
- if (test_cases[i].expected_primary_sample == -1) { |
- histogram_tester.ExpectTotalCount(kPrimaryHistogramName, 0); |
- } else { |
- histogram_tester.ExpectUniqueSample( |
- kPrimaryHistogramName, test_cases[i].expected_primary_sample, 1); |
- } |
- |
- if (test_cases[i].expected_fallback_sample == -1) { |
- histogram_tester.ExpectTotalCount(kFallbackHistogramName, 0); |
- } else { |
- histogram_tester.ExpectUniqueSample( |
- kFallbackHistogramName, test_cases[i].expected_fallback_sample, 1); |
- } |
- } |
-} |
- |
-TEST_F(DataReductionProxyUsageStatsTest, RecordMissingViaHeaderBytes) { |
- const std::string k4xxHistogramName = |
- "DataReductionProxy.MissingViaHeader.Bytes.4xx"; |
- const std::string kOtherHistogramName = |
- "DataReductionProxy.MissingViaHeader.Bytes.Other"; |
- const int64 kResponseContentLength = 100; |
- |
- struct TestCase { |
- bool was_proxy_used; |
- const char* headers; |
- bool is_4xx_sample_expected; |
- bool is_other_sample_expected; |
- }; |
- const TestCase test_cases[] = { |
- // Nothing should be recorded for requests that don't use the proxy. |
- { |
- false, |
- "HTTP/1.1 404 Not Found\n", |
- false, |
- false |
- }, |
- { |
- false, |
- "HTTP/1.1 200 OK\n", |
- false, |
- false |
- }, |
- // Nothing should be recorded for responses that have the via header. |
- { |
- true, |
- "HTTP/1.1 404 Not Found\n" |
- "Via: 1.1 Chrome-Compression-Proxy\n", |
- false, |
- false |
- }, |
- { |
- true, |
- "HTTP/1.1 200 OK\n" |
- "Via: 1.1 Chrome-Compression-Proxy\n", |
- false, |
- false |
- }, |
- // 4xx responses that used the proxy and don't have the via header should be |
- // recorded. |
- { |
- true, |
- "HTTP/1.1 404 Not Found\n", |
- true, |
- false |
- }, |
- { |
- true, |
- "HTTP/1.1 400 Bad Request\n", |
- true, |
- false |
- }, |
- { |
- true, |
- "HTTP/1.1 499 Big Client Error Response Code\n", |
- true, |
- false |
- }, |
- // Non-4xx responses that used the proxy and don't have the via header |
- // should be recorded. |
- { |
- true, |
- "HTTP/1.1 200 OK\n", |
- false, |
- true |
- }, |
- { |
- true, |
- "HTTP/1.1 399 Big Redirection Response Code\n", |
- false, |
- true |
- }, |
- { |
- true, |
- "HTTP/1.1 500 Internal Server Error\n", |
- false, |
- true |
- } |
- }; |
- |
- for (size_t i = 0; i < arraysize(test_cases); ++i) { |
- base::HistogramTester histogram_tester; |
- scoped_ptr<DataReductionProxyUsageStats> usage_stats = BuildUsageStats(); |
- |
- std::string raw_headers(test_cases[i].headers); |
- HeadersToRaw(&raw_headers); |
- |
- scoped_ptr<net::URLRequest> fake_request( |
- CreateURLRequestWithResponseHeaders(GURL("http://www.google.com/"), |
- raw_headers)); |
- fake_request->set_received_response_content_length(kResponseContentLength); |
- |
- EXPECT_CALL(*config(), |
- WasDataReductionProxyUsed(fake_request.get(), testing::_)) |
- .WillRepeatedly(Return(test_cases[i].was_proxy_used)); |
- |
- usage_stats->RecordMissingViaHeaderBytes(*fake_request); |
- |
- if (test_cases[i].is_4xx_sample_expected) { |
- histogram_tester.ExpectUniqueSample(k4xxHistogramName, |
- kResponseContentLength, 1); |
- } else { |
- histogram_tester.ExpectTotalCount(k4xxHistogramName, 0); |
- } |
- |
- if (test_cases[i].is_other_sample_expected) { |
- histogram_tester.ExpectUniqueSample(kOtherHistogramName, |
- kResponseContentLength, 1); |
- } else { |
- histogram_tester.ExpectTotalCount(kOtherHistogramName, 0); |
- } |
- } |
-} |
- |
-TEST_F(DataReductionProxyUsageStatsTest, RequestCompletionErrorCodes) { |
- const std::string kPrimaryHistogramName = |
- "DataReductionProxy.RequestCompletionErrorCodes.Primary"; |
- const std::string kFallbackHistogramName = |
- "DataReductionProxy.RequestCompletionErrorCodes.Fallback"; |
- const std::string kPrimaryMainFrameHistogramName = |
- "DataReductionProxy.RequestCompletionErrorCodes.MainFrame.Primary"; |
- const std::string kFallbackMainFrameHistogramName = |
- "DataReductionProxy.RequestCompletionErrorCodes.MainFrame.Fallback"; |
- |
- struct TestCase { |
- bool was_proxy_used; |
- bool is_load_bypass_proxy; |
- bool is_fallback; |
- bool is_main_frame; |
- net::Error net_error; |
- }; |
- |
- const TestCase test_cases[] = { |
- {false, true, false, true, net::OK}, |
- {false, true, false, false, net::ERR_TOO_MANY_REDIRECTS}, |
- {false, false, false, true, net::OK}, |
- {false, false, false, false, net::ERR_TOO_MANY_REDIRECTS}, |
- {true, false, false, true, net::OK}, |
- {true, false, false, true, net::ERR_TOO_MANY_REDIRECTS}, |
- {true, false, false, false, net::OK}, |
- {true, false, false, false, net::ERR_TOO_MANY_REDIRECTS}, |
- {true, false, true, true, net::OK}, |
- {true, false, true, true, net::ERR_TOO_MANY_REDIRECTS}, |
- {true, false, true, false, net::OK}, |
- {true, false, true, false, net::ERR_TOO_MANY_REDIRECTS} |
- }; |
- |
- for (size_t i = 0; i < arraysize(test_cases); ++i) { |
- base::HistogramTester histogram_tester; |
- scoped_ptr<DataReductionProxyUsageStats> usage_stats = BuildUsageStats(); |
- |
- std::string raw_headers("HTTP/1.1 200 OK\n" |
- "Via: 1.1 Chrome-Compression-Proxy\n"); |
- HeadersToRaw(&raw_headers); |
- scoped_ptr<net::URLRequest> fake_request( |
- CreateURLRequestWithResponseHeaders(GURL("http://www.google.com/"), |
- raw_headers)); |
- if (test_cases[i].is_load_bypass_proxy) { |
- fake_request->SetLoadFlags(fake_request->load_flags() | |
- net::LOAD_BYPASS_PROXY); |
- } |
- if (test_cases[i].is_main_frame) { |
- fake_request->SetLoadFlags(fake_request->load_flags() | |
- net::LOAD_MAIN_FRAME); |
- } |
- |
- int net_error_int = static_cast<int>(test_cases[i].net_error); |
- if (test_cases[i].net_error != net::OK) { |
- fake_request->CancelWithError(net_error_int); |
- } |
- |
- DataReductionProxyTypeInfo proxy_info; |
- proxy_info.is_fallback = test_cases[i].is_fallback; |
- EXPECT_CALL(*config(), WasDataReductionProxyUsed(fake_request.get(), |
- testing::NotNull())) |
- .WillRepeatedly(testing::DoAll(testing::SetArgPointee<1>(proxy_info), |
- Return(test_cases[i].was_proxy_used))); |
- |
- usage_stats->OnUrlRequestCompleted(fake_request.get(), false); |
- |
- if (test_cases[i].was_proxy_used && !test_cases[i].is_load_bypass_proxy && |
- !test_cases[i].is_fallback) { |
- histogram_tester.ExpectUniqueSample( |
- kPrimaryHistogramName, -net_error_int, 1); |
- } else { |
- histogram_tester.ExpectTotalCount(kPrimaryHistogramName, 0); |
- } |
- if (test_cases[i].was_proxy_used && !test_cases[i].is_load_bypass_proxy && |
- test_cases[i].is_fallback) { |
- histogram_tester.ExpectUniqueSample( |
- kFallbackHistogramName, -net_error_int, 1); |
- } else { |
- histogram_tester.ExpectTotalCount(kFallbackHistogramName, 0); |
- } |
- if (test_cases[i].was_proxy_used && !test_cases[i].is_load_bypass_proxy && |
- !test_cases[i].is_fallback && test_cases[i].is_main_frame) { |
- histogram_tester.ExpectUniqueSample( |
- kPrimaryMainFrameHistogramName, -net_error_int, 1); |
- } else { |
- histogram_tester.ExpectTotalCount(kPrimaryMainFrameHistogramName, 0); |
- } |
- if (test_cases[i].was_proxy_used && !test_cases[i].is_load_bypass_proxy && |
- test_cases[i].is_fallback && test_cases[i].is_main_frame) { |
- histogram_tester.ExpectUniqueSample( |
- kFallbackMainFrameHistogramName, -net_error_int, 1); |
- } else { |
- histogram_tester.ExpectTotalCount(kFallbackMainFrameHistogramName, 0); |
- } |
- } |
-} |
- |
-// End-to-end tests for the DataReductionProxy.BypassedBytes histograms. |
-class DataReductionProxyUsageStatsEndToEndTest : public testing::Test { |
- public: |
- DataReductionProxyUsageStatsEndToEndTest() |
- : context_(true), context_storage_(&context_) {} |
- |
- ~DataReductionProxyUsageStatsEndToEndTest() override { |
- drp_test_context_->io_data()->ShutdownOnUIThread(); |
- drp_test_context_->RunUntilIdle(); |
- } |
- |
- void SetUp() override { |
- // Only use the primary data reduction proxy in order to make it easier to |
- // test bypassed bytes due to proxy fallbacks. This way, a test just needs |
- // to cause one proxy fallback in order for the data reduction proxy to be |
- // fully bypassed. |
- drp_test_context_ = |
- DataReductionProxyTestContext::Builder() |
- .WithParamsFlags(DataReductionProxyParams::kAllowed) |
- .WithParamsDefinitions( |
- TestDataReductionProxyParams::HAS_EVERYTHING & |
- ~TestDataReductionProxyParams::HAS_DEV_ORIGIN & |
- ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN) |
- .WithURLRequestContext(&context_) |
- .WithMockClientSocketFactory(&mock_socket_factory_) |
- .Build(); |
- drp_test_context_->AttachToURLRequestContext(&context_storage_); |
- context_.set_client_socket_factory(&mock_socket_factory_); |
- } |
- |
- // Create and execute a fake request using the data reduction proxy stack. |
- // Passing in nullptr for |retry_response_headers| indicates that the request |
- // is not expected to be retried. |
- void CreateAndExecuteRequest(const GURL& url, |
- const char* initial_response_headers, |
- const char* initial_response_body, |
- const char* retry_response_headers, |
- const char* retry_response_body) { |
- // Support HTTPS URLs. |
- net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK); |
- if (url.SchemeIsSecure()) { |
- mock_socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider); |
- } |
- |
- // Prepare for the initial response. |
- MockRead initial_data_reads[] = { |
- MockRead(initial_response_headers), |
- MockRead(initial_response_body), |
- MockRead(net::SYNCHRONOUS, net::OK), |
- }; |
- net::StaticSocketDataProvider initial_socket_data_provider( |
- initial_data_reads, arraysize(initial_data_reads), nullptr, 0); |
- mock_socket_factory_.AddSocketDataProvider(&initial_socket_data_provider); |
- |
- // Prepare for the response from retrying the request, if applicable. |
- // |retry_data_reads| and |retry_socket_data_provider| are out here so that |
- // they stay in scope for when the request is executed. |
- std::vector<MockRead> retry_data_reads; |
- scoped_ptr<net::StaticSocketDataProvider> retry_socket_data_provider; |
- if (retry_response_headers) { |
- retry_data_reads.push_back(MockRead(retry_response_headers)); |
- retry_data_reads.push_back(MockRead(retry_response_body)); |
- retry_data_reads.push_back(MockRead(net::SYNCHRONOUS, net::OK)); |
- |
- retry_socket_data_provider.reset(new net::StaticSocketDataProvider( |
- &retry_data_reads.front(), retry_data_reads.size(), nullptr, 0)); |
- mock_socket_factory_.AddSocketDataProvider( |
- retry_socket_data_provider.get()); |
- } |
- |
- scoped_ptr<net::URLRequest> request( |
- context_.CreateRequest(url, net::IDLE, &delegate_)); |
- request->set_method("GET"); |
- request->SetLoadFlags(net::LOAD_NORMAL); |
- request->Start(); |
- drp_test_context_->RunUntilIdle(); |
- } |
- |
- void set_proxy_service(net::ProxyService* proxy_service) { |
- context_.set_proxy_service(proxy_service); |
- } |
- |
- void set_host_resolver(net::HostResolver* host_resolver) { |
- context_.set_host_resolver(host_resolver); |
- } |
- |
- const DataReductionProxySettings* settings() const { |
- return drp_test_context_->settings(); |
- } |
- |
- TestDataReductionProxyConfig* config() const { |
- return drp_test_context_->config(); |
- } |
- |
- void ClearBadProxies() { |
- context_.proxy_service()->ClearBadProxiesCache(); |
- } |
- |
- void InitializeContext() { |
- context_.Init(); |
- drp_test_context_->EnableDataReductionProxyWithSecureProxyCheckSuccess(); |
- } |
- |
- void ExpectOtherBypassedBytesHistogramsEmpty( |
- const base::HistogramTester& histogram_tester, |
- const std::set<std::string>& excluded_histograms) const { |
- const std::string kHistograms[] = { |
- "DataReductionProxy.BypassedBytes.NotBypassed", |
- "DataReductionProxy.BypassedBytes.SSL", |
- "DataReductionProxy.BypassedBytes.LocalBypassRules", |
- "DataReductionProxy.BypassedBytes.ProxyOverridden", |
- "DataReductionProxy.BypassedBytes.Current", |
- "DataReductionProxy.BypassedBytes.ShortAll", |
- "DataReductionProxy.BypassedBytes.ShortTriggeringRequest", |
- "DataReductionProxy.BypassedBytes.ShortAudioVideo", |
- "DataReductionProxy.BypassedBytes.MediumAll", |
- "DataReductionProxy.BypassedBytes.MediumTriggeringRequest", |
- "DataReductionProxy.BypassedBytes.LongAll", |
- "DataReductionProxy.BypassedBytes.LongTriggeringRequest", |
- "DataReductionProxy.BypassedBytes.MissingViaHeader4xx", |
- "DataReductionProxy.BypassedBytes.MissingViaHeaderOther", |
- "DataReductionProxy.BypassedBytes.Malformed407", |
- "DataReductionProxy.BypassedBytes.Status500HttpInternalServerError", |
- "DataReductionProxy.BypassedBytes.Status502HttpBadGateway", |
- "DataReductionProxy.BypassedBytes.Status503HttpServiceUnavailable", |
- "DataReductionProxy.BypassedBytes.NetworkErrorOther", |
- }; |
- |
- for (const std::string& histogram : kHistograms) { |
- if (excluded_histograms.find(histogram) == |
- excluded_histograms.end()) { |
- histogram_tester.ExpectTotalCount(histogram, 0); |
- } |
- } |
- } |
- |
- void ExpectOtherBypassedBytesHistogramsEmpty( |
- const base::HistogramTester& histogram_tester, |
- const std::string& excluded_histogram) const { |
- std::set<std::string> excluded_histograms; |
- excluded_histograms.insert(excluded_histogram); |
- ExpectOtherBypassedBytesHistogramsEmpty(histogram_tester, |
- excluded_histograms); |
- } |
- |
- void ExpectOtherBypassedBytesHistogramsEmpty( |
- const base::HistogramTester& histogram_tester, |
- const std::string& first_excluded_histogram, |
- const std::string& second_excluded_histogram) const { |
- std::set<std::string> excluded_histograms; |
- excluded_histograms.insert(first_excluded_histogram); |
- excluded_histograms.insert(second_excluded_histogram); |
- ExpectOtherBypassedBytesHistogramsEmpty(histogram_tester, |
- excluded_histograms); |
- } |
- |
- private: |
- net::TestDelegate delegate_; |
- net::MockClientSocketFactory mock_socket_factory_; |
- net::TestURLRequestContext context_; |
- net::URLRequestContextStorage context_storage_; |
- scoped_ptr<DataReductionProxyTestContext> drp_test_context_; |
-}; |
- |
-TEST_F(DataReductionProxyUsageStatsEndToEndTest, BypassedBytesNoRetry) { |
- struct TestCase { |
- GURL url; |
- const char* histogram_name; |
- const char* initial_response_headers; |
- }; |
- const TestCase test_cases[] = { |
- { GURL("http://foo.com"), |
- "DataReductionProxy.BypassedBytes.NotBypassed", |
- "HTTP/1.1 200 OK\r\n" |
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n", |
- }, |
- { GURL("https://foo.com"), |
- "DataReductionProxy.BypassedBytes.SSL", |
- "HTTP/1.1 200 OK\r\n\r\n", |
- }, |
- { GURL("http://localhost"), |
- "DataReductionProxy.BypassedBytes.LocalBypassRules", |
- "HTTP/1.1 200 OK\r\n\r\n", |
- }, |
- }; |
- |
- InitializeContext(); |
- for (const TestCase& test_case : test_cases) { |
- ClearBadProxies(); |
- base::HistogramTester histogram_tester; |
- CreateAndExecuteRequest(test_case.url, test_case.initial_response_headers, |
- kBody.c_str(), nullptr, nullptr); |
- |
- histogram_tester.ExpectUniqueSample(test_case.histogram_name, kBody.size(), |
- 1); |
- ExpectOtherBypassedBytesHistogramsEmpty(histogram_tester, |
- test_case.histogram_name); |
- } |
-} |
- |
-TEST_F(DataReductionProxyUsageStatsEndToEndTest, BypassedBytesProxyOverridden) { |
- scoped_ptr<net::ProxyService> proxy_service( |
- net::ProxyService::CreateFixed("http://test.com:80")); |
- set_proxy_service(proxy_service.get()); |
- InitializeContext(); |
- |
- base::HistogramTester histogram_tester; |
- CreateAndExecuteRequest(GURL("http://foo.com"), "HTTP/1.1 200 OK\r\n\r\n", |
- kBody.c_str(), nullptr, nullptr); |
- |
- histogram_tester.ExpectUniqueSample( |
- "DataReductionProxy.BypassedBytes.ProxyOverridden", kBody.size(), 1); |
- ExpectOtherBypassedBytesHistogramsEmpty( |
- histogram_tester, "DataReductionProxy.BypassedBytes.ProxyOverridden"); |
-} |
- |
-TEST_F(DataReductionProxyUsageStatsEndToEndTest, BypassedBytesCurrent) { |
- InitializeContext(); |
- base::HistogramTester histogram_tester; |
- CreateAndExecuteRequest(GURL("http://foo.com"), |
- "HTTP/1.1 502 Bad Gateway\r\n" |
- "Via: 1.1 Chrome-Compression-Proxy\r\n" |
- "Chrome-Proxy: block-once\r\n\r\n", |
- kErrorBody.c_str(), "HTTP/1.1 200 OK\r\n\r\n", |
- kBody.c_str()); |
- |
- histogram_tester.ExpectUniqueSample( |
- "DataReductionProxy.BypassedBytes.Current", kBody.size(), 1); |
- ExpectOtherBypassedBytesHistogramsEmpty( |
- histogram_tester, "DataReductionProxy.BypassedBytes.Current"); |
-} |
- |
-TEST_F(DataReductionProxyUsageStatsEndToEndTest, BypassedBytesShortAudioVideo) { |
- InitializeContext(); |
- base::HistogramTester histogram_tester; |
- CreateAndExecuteRequest(GURL("http://foo.com"), |
- "HTTP/1.1 502 Bad Gateway\r\n" |
- "Via: 1.1 Chrome-Compression-Proxy\r\n" |
- "Chrome-Proxy: block=1\r\n\r\n", |
- kErrorBody.c_str(), |
- "HTTP/1.1 200 OK\r\n" |
- "Content-Type: video/mp4\r\n\r\n", |
- kBody.c_str()); |
- |
- histogram_tester.ExpectUniqueSample( |
- "DataReductionProxy.BypassedBytes.ShortAudioVideo", kBody.size(), 1); |
- ExpectOtherBypassedBytesHistogramsEmpty( |
- histogram_tester, "DataReductionProxy.BypassedBytes.ShortAudioVideo"); |
-} |
- |
-TEST_F(DataReductionProxyUsageStatsEndToEndTest, BypassedBytesExplicitBypass) { |
- struct TestCase { |
- const char* triggering_histogram_name; |
- const char* all_histogram_name; |
- const char* initial_response_headers; |
- }; |
- const TestCase test_cases[] = { |
- { "DataReductionProxy.BypassedBytes.ShortTriggeringRequest", |
- "DataReductionProxy.BypassedBytes.ShortAll", |
- "HTTP/1.1 502 Bad Gateway\r\n" |
- "Via: 1.1 Chrome-Compression-Proxy\r\n" |
- "Chrome-Proxy: block=1\r\n\r\n", |
- }, |
- { "DataReductionProxy.BypassedBytes.MediumTriggeringRequest", |
- "DataReductionProxy.BypassedBytes.MediumAll", |
- "HTTP/1.1 502 Bad Gateway\r\n" |
- "Via: 1.1 Chrome-Compression-Proxy\r\n" |
- "Chrome-Proxy: block=0\r\n\r\n", |
- }, |
- { "DataReductionProxy.BypassedBytes.LongTriggeringRequest", |
- "DataReductionProxy.BypassedBytes.LongAll", |
- "HTTP/1.1 502 Bad Gateway\r\n" |
- "Via: 1.1 Chrome-Compression-Proxy\r\n" |
- "Chrome-Proxy: block=3600\r\n\r\n", |
- }, |
- }; |
- |
- InitializeContext(); |
- for (const TestCase& test_case : test_cases) { |
- ClearBadProxies(); |
- base::HistogramTester histogram_tester; |
- |
- CreateAndExecuteRequest( |
- GURL("http://foo.com"), test_case.initial_response_headers, |
- kErrorBody.c_str(), "HTTP/1.1 200 OK\r\n\r\n", kBody.c_str()); |
- // The first request caused the proxy to be marked as bad, so this second |
- // request should not come through the proxy. |
- CreateAndExecuteRequest(GURL("http://bar.com"), "HTTP/1.1 200 OK\r\n\r\n", |
- kNextBody.c_str(), nullptr, nullptr); |
- |
- histogram_tester.ExpectUniqueSample(test_case.triggering_histogram_name, |
- kBody.size(), 1); |
- histogram_tester.ExpectUniqueSample(test_case.all_histogram_name, |
- kNextBody.size(), 1); |
- ExpectOtherBypassedBytesHistogramsEmpty(histogram_tester, |
- test_case.triggering_histogram_name, |
- test_case.all_histogram_name); |
- } |
-} |
- |
-TEST_F(DataReductionProxyUsageStatsEndToEndTest, |
- BypassedBytesClientSideFallback) { |
- struct TestCase { |
- const char* histogram_name; |
- const char* initial_response_headers; |
- }; |
- const TestCase test_cases[] = { |
- { "DataReductionProxy.BypassedBytes.MissingViaHeader4xx", |
- "HTTP/1.1 414 Request-URI Too Long\r\n\r\n", |
- }, |
- { "DataReductionProxy.BypassedBytes.MissingViaHeaderOther", |
- "HTTP/1.1 200 OK\r\n\r\n", |
- }, |
- { "DataReductionProxy.BypassedBytes.Malformed407", |
- "HTTP/1.1 407 Proxy Authentication Required\r\n\r\n", |
- }, |
- { "DataReductionProxy.BypassedBytes.Status500HttpInternalServerError", |
- "HTTP/1.1 500 Internal Server Error\r\n\r\n", |
- }, |
- { "DataReductionProxy.BypassedBytes.Status502HttpBadGateway", |
- "HTTP/1.1 502 Bad Gateway\r\n\r\n", |
- }, |
- { "DataReductionProxy.BypassedBytes.Status503HttpServiceUnavailable", |
- "HTTP/1.1 503 Service Unavailable\r\n\r\n", |
- }, |
- }; |
- |
- InitializeContext(); |
- for (const TestCase& test_case : test_cases) { |
- ClearBadProxies(); |
- base::HistogramTester histogram_tester; |
- |
- CreateAndExecuteRequest( |
- GURL("http://foo.com"), test_case.initial_response_headers, |
- kErrorBody.c_str(), "HTTP/1.1 200 OK\r\n\r\n", kBody.c_str()); |
- // The first request caused the proxy to be marked as bad, so this second |
- // request should not come through the proxy. |
- CreateAndExecuteRequest(GURL("http://bar.com"), "HTTP/1.1 200 OK\r\n\r\n", |
- kNextBody.c_str(), nullptr, nullptr); |
- |
- histogram_tester.ExpectTotalCount(test_case.histogram_name, 2); |
- histogram_tester.ExpectBucketCount(test_case.histogram_name, kBody.size(), |
- 1); |
- histogram_tester.ExpectBucketCount(test_case.histogram_name, |
- kNextBody.size(), 1); |
- ExpectOtherBypassedBytesHistogramsEmpty(histogram_tester, |
- test_case.histogram_name); |
- } |
-} |
- |
-TEST_F(DataReductionProxyUsageStatsEndToEndTest, BypassedBytesNetErrorOther) { |
- // Make the data reduction proxy host fail to resolve. |
- scoped_ptr<net::MockHostResolver> host_resolver(new net::MockHostResolver()); |
- host_resolver->rules()->AddSimulatedFailure( |
- config()->test_params()->origin().host_port_pair().host()); |
- set_host_resolver(host_resolver.get()); |
- InitializeContext(); |
- |
- base::HistogramTester histogram_tester; |
- CreateAndExecuteRequest(GURL("http://foo.com"), "HTTP/1.1 200 OK\r\n\r\n", |
- kBody.c_str(), nullptr, nullptr); |
- |
- histogram_tester.ExpectUniqueSample( |
- "DataReductionProxy.BypassedBytes.NetworkErrorOther", kBody.size(), 1); |
- ExpectOtherBypassedBytesHistogramsEmpty( |
- histogram_tester, "DataReductionProxy.BypassedBytes.NetworkErrorOther"); |
- histogram_tester.ExpectUniqueSample( |
- "DataReductionProxy.BypassOnNetworkErrorPrimary", |
- -net::ERR_PROXY_CONNECTION_FAILED, 1); |
-} |
- |
-} // namespace data_reduction_proxy |