Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_usag e_stats.h" | 5 #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_bypa ss_stats.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 14 #include "base/prefs/testing_pref_service.h" | 14 #include "base/prefs/testing_pref_service.h" |
| 15 #include "base/test/histogram_tester.h" | 15 #include "base/test/histogram_tester.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 50 namespace data_reduction_proxy { | 50 namespace data_reduction_proxy { |
| 51 | 51 |
| 52 namespace { | 52 namespace { |
| 53 | 53 |
| 54 const std::string kBody = "hello"; | 54 const std::string kBody = "hello"; |
| 55 const std::string kNextBody = "hello again"; | 55 const std::string kNextBody = "hello again"; |
| 56 const std::string kErrorBody = "bad"; | 56 const std::string kErrorBody = "bad"; |
| 57 | 57 |
| 58 } // namespace | 58 } // namespace |
| 59 | 59 |
| 60 class DataReductionProxyUsageStatsTest : public testing::Test { | 60 class DataReductionProxyBypassStatsTest : public testing::Test { |
| 61 public: | 61 public: |
| 62 DataReductionProxyUsageStatsTest() | 62 DataReductionProxyBypassStatsTest() : context_(true) { |
| 63 : context_(true) { | |
| 64 context_.Init(); | 63 context_.Init(); |
| 65 | 64 |
| 66 // The |test_job_factory_| takes ownership of the interceptor. | 65 // The |test_job_factory_| takes ownership of the interceptor. |
| 67 test_job_interceptor_ = new net::TestJobInterceptor(); | 66 test_job_interceptor_ = new net::TestJobInterceptor(); |
| 68 EXPECT_TRUE(test_job_factory_.SetProtocolHandler(url::kHttpScheme, | 67 EXPECT_TRUE(test_job_factory_.SetProtocolHandler(url::kHttpScheme, |
| 69 test_job_interceptor_)); | 68 test_job_interceptor_)); |
| 70 | 69 |
| 71 context_.set_job_factory(&test_job_factory_); | 70 context_.set_job_factory(&test_job_factory_); |
| 72 | 71 |
| 73 test_context_ = | 72 test_context_ = |
| 74 DataReductionProxyTestContext::Builder() | 73 DataReductionProxyTestContext::Builder() |
| 75 .WithParamsFlags(DataReductionProxyParams::kAllowed | | 74 .WithParamsFlags(DataReductionProxyParams::kAllowed | |
| 76 DataReductionProxyParams::kFallbackAllowed | | 75 DataReductionProxyParams::kFallbackAllowed | |
| 77 DataReductionProxyParams::kPromoAllowed) | 76 DataReductionProxyParams::kPromoAllowed) |
| 78 .WithParamsDefinitions( | 77 .WithParamsDefinitions( |
| 79 TestDataReductionProxyParams::HAS_EVERYTHING & | 78 TestDataReductionProxyParams::HAS_EVERYTHING & |
| 80 ~TestDataReductionProxyParams::HAS_DEV_ORIGIN & | 79 ~TestDataReductionProxyParams::HAS_DEV_ORIGIN & |
| 81 ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN) | 80 ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN) |
| 82 .WithMockConfig() | 81 .WithMockConfig() |
| 83 .Build(); | 82 .Build(); |
| 84 mock_url_request_ = context_.CreateRequest(GURL(), net::IDLE, &delegate_, | 83 mock_url_request_ = |
| 85 NULL); | 84 context_.CreateRequest(GURL(), net::IDLE, &delegate_, NULL); |
| 86 } | 85 } |
| 87 | 86 |
| 88 scoped_ptr<net::URLRequest> CreateURLRequestWithResponseHeaders( | 87 scoped_ptr<net::URLRequest> CreateURLRequestWithResponseHeaders( |
| 89 const GURL& url, | 88 const GURL& url, |
| 90 const std::string& raw_response_headers) { | 89 const std::string& raw_response_headers) { |
| 91 scoped_ptr<net::URLRequest> fake_request = context_.CreateRequest( | 90 scoped_ptr<net::URLRequest> fake_request = |
| 92 url, net::IDLE, &delegate_, NULL); | 91 context_.CreateRequest(url, net::IDLE, &delegate_, NULL); |
| 93 | 92 |
| 94 // Create a test job that will fill in the given response headers for the | 93 // Create a test job that will fill in the given response headers for the |
| 95 // |fake_request|. | 94 // |fake_request|. |
| 96 scoped_refptr<net::URLRequestTestJob> test_job( | 95 scoped_refptr<net::URLRequestTestJob> test_job(new net::URLRequestTestJob( |
| 97 new net::URLRequestTestJob(fake_request.get(), | 96 fake_request.get(), context_.network_delegate(), raw_response_headers, |
| 98 context_.network_delegate(), | 97 std::string(), true)); |
| 99 raw_response_headers, std::string(), true)); | |
| 100 | 98 |
| 101 // Configure the interceptor to use the test job to handle the next request. | 99 // Configure the interceptor to use the test job to handle the next request. |
| 102 test_job_interceptor_->set_main_intercept_job(test_job.get()); | 100 test_job_interceptor_->set_main_intercept_job(test_job.get()); |
| 103 fake_request->Start(); | 101 fake_request->Start(); |
| 104 test_context_->RunUntilIdle(); | 102 test_context_->RunUntilIdle(); |
| 105 | 103 |
| 106 EXPECT_TRUE(fake_request->response_headers() != NULL); | 104 EXPECT_TRUE(fake_request->response_headers() != NULL); |
| 107 return fake_request.Pass(); | 105 return fake_request.Pass(); |
| 108 } | 106 } |
| 109 | 107 |
| 110 bool IsUnreachable() const { | 108 bool IsUnreachable() const { |
| 111 return test_context_->settings()->IsDataReductionProxyUnreachable(); | 109 return test_context_->settings()->IsDataReductionProxyUnreachable(); |
| 112 } | 110 } |
| 113 | 111 |
| 114 protected: | 112 protected: |
| 115 scoped_ptr<DataReductionProxyUsageStats> BuildUsageStats() { | 113 scoped_ptr<DataReductionProxyBypassStats> BuildBypassStats() { |
| 116 return make_scoped_ptr( | 114 return make_scoped_ptr(new DataReductionProxyBypassStats( |
| 117 new DataReductionProxyUsageStats( | 115 test_context_->config(), |
| 118 test_context_->config(), | 116 test_context_->unreachable_callback(), |
| 119 test_context_->unreachable_callback(), | 117 test_context_->task_runner())).Pass(); |
| 120 test_context_->task_runner())).Pass(); | |
| 121 } | 118 } |
| 122 | 119 |
| 123 net::URLRequest* url_request() { | 120 net::URLRequest* url_request() { return mock_url_request_.get(); } |
| 124 return mock_url_request_.get(); | |
| 125 } | |
| 126 | 121 |
| 127 MockDataReductionProxyConfig* config() const { | 122 MockDataReductionProxyConfig* config() const { |
| 128 return test_context_->mock_config(); | 123 return test_context_->mock_config(); |
| 129 } | 124 } |
| 130 | 125 |
| 131 void RunUntilIdle() { | 126 void RunUntilIdle() { test_context_->RunUntilIdle(); } |
| 132 test_context_->RunUntilIdle(); | |
| 133 } | |
| 134 | 127 |
| 135 private: | 128 private: |
| 136 net::TestURLRequestContext context_; | 129 net::TestURLRequestContext context_; |
| 137 net::TestDelegate delegate_; | 130 net::TestDelegate delegate_; |
| 138 scoped_ptr<net::URLRequest> mock_url_request_; | 131 scoped_ptr<net::URLRequest> mock_url_request_; |
| 139 // |test_job_interceptor_| is owned by |test_job_factory_|. | 132 // |test_job_interceptor_| is owned by |test_job_factory_|. |
| 140 net::TestJobInterceptor* test_job_interceptor_; | 133 net::TestJobInterceptor* test_job_interceptor_; |
| 141 net::URLRequestJobFactoryImpl test_job_factory_; | 134 net::URLRequestJobFactoryImpl test_job_factory_; |
| 142 scoped_ptr<DataReductionProxyTestContext> test_context_; | 135 scoped_ptr<DataReductionProxyTestContext> test_context_; |
| 143 }; | 136 }; |
| 144 | 137 |
| 145 TEST_F(DataReductionProxyUsageStatsTest, IsDataReductionProxyUnreachable) { | 138 TEST_F(DataReductionProxyBypassStatsTest, IsDataReductionProxyUnreachable) { |
| 146 net::ProxyServer fallback_proxy_server = | 139 net::ProxyServer fallback_proxy_server = |
| 147 net::ProxyServer::FromURI("foo.com", net::ProxyServer::SCHEME_HTTP); | 140 net::ProxyServer::FromURI("foo.com", net::ProxyServer::SCHEME_HTTP); |
| 148 data_reduction_proxy::DataReductionProxyTypeInfo proxy_info; | 141 data_reduction_proxy::DataReductionProxyTypeInfo proxy_info; |
| 149 struct TestCase { | 142 struct TestCase { |
| 150 bool fallback_proxy_server_is_data_reduction_proxy; | 143 bool fallback_proxy_server_is_data_reduction_proxy; |
| 151 bool was_proxy_used; | 144 bool was_proxy_used; |
| 152 bool is_unreachable; | 145 bool is_unreachable; |
| 153 }; | 146 }; |
| 154 const TestCase test_cases[] = { | 147 const TestCase test_cases[] = {{false, false, false}, |
|
bengr
2015/03/24 15:47:27
Why did you change this? It has nothing to do with
zhuoyu.qian
2015/03/28 03:06:58
Done.
| |
| 155 { | 148 {false, true, false}, |
| 156 false, | 149 {true, true, false}, |
| 157 false, | 150 {true, false, true}}; |
| 158 false | |
| 159 }, | |
| 160 { | |
| 161 false, | |
| 162 true, | |
| 163 false | |
| 164 }, | |
| 165 { | |
| 166 true, | |
| 167 true, | |
| 168 false | |
| 169 }, | |
| 170 { | |
| 171 true, | |
| 172 false, | |
| 173 true | |
| 174 } | |
| 175 }; | |
| 176 for (size_t i = 0; i < arraysize(test_cases); ++i) { | 151 for (size_t i = 0; i < arraysize(test_cases); ++i) { |
| 177 TestCase test_case = test_cases[i]; | 152 TestCase test_case = test_cases[i]; |
| 178 | 153 |
| 179 EXPECT_CALL(*config(), IsDataReductionProxy(testing::_, testing::_)) | 154 EXPECT_CALL(*config(), IsDataReductionProxy(testing::_, testing::_)) |
| 180 .WillRepeatedly(testing::Return( | 155 .WillRepeatedly(testing::Return( |
| 181 test_case.fallback_proxy_server_is_data_reduction_proxy)); | 156 test_case.fallback_proxy_server_is_data_reduction_proxy)); |
| 182 EXPECT_CALL(*config(), | 157 EXPECT_CALL(*config(), WasDataReductionProxyUsed(url_request(), testing::_)) |
| 183 WasDataReductionProxyUsed(url_request(), testing::_)) | |
| 184 .WillRepeatedly(testing::Return(test_case.was_proxy_used)); | 158 .WillRepeatedly(testing::Return(test_case.was_proxy_used)); |
| 185 | 159 |
| 186 scoped_ptr<DataReductionProxyUsageStats> usage_stats = BuildUsageStats(); | 160 scoped_ptr<DataReductionProxyBypassStats> bypass_stats = BuildBypassStats(); |
| 187 | 161 |
| 188 usage_stats->OnProxyFallback(fallback_proxy_server, | 162 bypass_stats->OnProxyFallback(fallback_proxy_server, |
| 189 net::ERR_PROXY_CONNECTION_FAILED); | 163 net::ERR_PROXY_CONNECTION_FAILED); |
| 190 usage_stats->OnUrlRequestCompleted(url_request(), false); | 164 bypass_stats->OnUrlRequestCompleted(url_request(), false); |
| 191 RunUntilIdle(); | 165 RunUntilIdle(); |
| 192 | 166 |
| 193 EXPECT_EQ(test_case.is_unreachable, IsUnreachable()); | 167 EXPECT_EQ(test_case.is_unreachable, IsUnreachable()); |
| 194 } | 168 } |
| 195 } | 169 } |
| 196 | 170 |
| 197 TEST_F(DataReductionProxyUsageStatsTest, ProxyUnreachableThenReachable) { | 171 TEST_F(DataReductionProxyBypassStatsTest, ProxyUnreachableThenReachable) { |
| 198 net::ProxyServer fallback_proxy_server = | 172 net::ProxyServer fallback_proxy_server = |
| 199 net::ProxyServer::FromURI("foo.com", net::ProxyServer::SCHEME_HTTP); | 173 net::ProxyServer::FromURI("foo.com", net::ProxyServer::SCHEME_HTTP); |
| 200 scoped_ptr<DataReductionProxyUsageStats> usage_stats = BuildUsageStats(); | 174 scoped_ptr<DataReductionProxyBypassStats> bypass_stats = BuildBypassStats(); |
| 201 EXPECT_CALL(*config(), IsDataReductionProxy(testing::_, testing::_)) | 175 EXPECT_CALL(*config(), IsDataReductionProxy(testing::_, testing::_)) |
| 202 .WillOnce(testing::Return(true)); | 176 .WillOnce(testing::Return(true)); |
| 203 EXPECT_CALL(*config(), | 177 EXPECT_CALL(*config(), WasDataReductionProxyUsed(url_request(), testing::_)) |
| 204 WasDataReductionProxyUsed(url_request(), testing::_)) | |
| 205 .WillOnce(testing::Return(true)); | 178 .WillOnce(testing::Return(true)); |
| 206 | 179 |
| 207 // proxy falls back | 180 // proxy falls back |
| 208 usage_stats->OnProxyFallback(fallback_proxy_server, | 181 bypass_stats->OnProxyFallback(fallback_proxy_server, |
| 209 net::ERR_PROXY_CONNECTION_FAILED); | 182 net::ERR_PROXY_CONNECTION_FAILED); |
| 210 RunUntilIdle(); | 183 RunUntilIdle(); |
| 211 EXPECT_TRUE(IsUnreachable()); | 184 EXPECT_TRUE(IsUnreachable()); |
| 212 | 185 |
| 213 // proxy succeeds | 186 // proxy succeeds |
| 214 usage_stats->OnUrlRequestCompleted(url_request(), false); | 187 bypass_stats->OnUrlRequestCompleted(url_request(), false); |
| 215 RunUntilIdle(); | 188 RunUntilIdle(); |
| 216 EXPECT_FALSE(IsUnreachable()); | 189 EXPECT_FALSE(IsUnreachable()); |
| 217 } | 190 } |
| 218 | 191 |
| 219 TEST_F(DataReductionProxyUsageStatsTest, ProxyReachableThenUnreachable) { | 192 TEST_F(DataReductionProxyBypassStatsTest, ProxyReachableThenUnreachable) { |
| 220 net::ProxyServer fallback_proxy_server = | 193 net::ProxyServer fallback_proxy_server = |
| 221 net::ProxyServer::FromURI("foo.com", net::ProxyServer::SCHEME_HTTP); | 194 net::ProxyServer::FromURI("foo.com", net::ProxyServer::SCHEME_HTTP); |
| 222 scoped_ptr<DataReductionProxyUsageStats> usage_stats = BuildUsageStats(); | 195 scoped_ptr<DataReductionProxyBypassStats> bypass_stats = BuildBypassStats(); |
| 223 EXPECT_CALL(*config(), | 196 EXPECT_CALL(*config(), WasDataReductionProxyUsed(url_request(), testing::_)) |
| 224 WasDataReductionProxyUsed(url_request(), testing::_)) | |
| 225 .WillOnce(testing::Return(true)); | 197 .WillOnce(testing::Return(true)); |
| 226 EXPECT_CALL(*config(), IsDataReductionProxy(testing::_, testing::_)) | 198 EXPECT_CALL(*config(), IsDataReductionProxy(testing::_, testing::_)) |
| 227 .WillRepeatedly(testing::Return(true)); | 199 .WillRepeatedly(testing::Return(true)); |
| 228 | 200 |
| 229 // Proxy succeeds. | 201 // Proxy succeeds. |
| 230 usage_stats->OnUrlRequestCompleted(url_request(), false); | 202 bypass_stats->OnUrlRequestCompleted(url_request(), false); |
| 231 RunUntilIdle(); | 203 RunUntilIdle(); |
| 232 EXPECT_FALSE(IsUnreachable()); | 204 EXPECT_FALSE(IsUnreachable()); |
| 233 | 205 |
| 234 // Then proxy falls back indefinitely. | 206 // Then proxy falls back indefinitely. |
| 235 usage_stats->OnProxyFallback(fallback_proxy_server, | 207 bypass_stats->OnProxyFallback(fallback_proxy_server, |
| 236 net::ERR_PROXY_CONNECTION_FAILED); | 208 net::ERR_PROXY_CONNECTION_FAILED); |
| 237 usage_stats->OnProxyFallback(fallback_proxy_server, | 209 bypass_stats->OnProxyFallback(fallback_proxy_server, |
| 238 net::ERR_PROXY_CONNECTION_FAILED); | 210 net::ERR_PROXY_CONNECTION_FAILED); |
| 239 usage_stats->OnProxyFallback(fallback_proxy_server, | 211 bypass_stats->OnProxyFallback(fallback_proxy_server, |
| 240 net::ERR_PROXY_CONNECTION_FAILED); | 212 net::ERR_PROXY_CONNECTION_FAILED); |
| 241 usage_stats->OnProxyFallback(fallback_proxy_server, | 213 bypass_stats->OnProxyFallback(fallback_proxy_server, |
| 242 net::ERR_PROXY_CONNECTION_FAILED); | 214 net::ERR_PROXY_CONNECTION_FAILED); |
| 243 RunUntilIdle(); | 215 RunUntilIdle(); |
| 244 EXPECT_TRUE(IsUnreachable()); | 216 EXPECT_TRUE(IsUnreachable()); |
| 245 } | 217 } |
| 246 | 218 |
| 247 TEST_F(DataReductionProxyUsageStatsTest, | 219 TEST_F(DataReductionProxyBypassStatsTest, |
| 248 DetectAndRecordMissingViaHeaderResponseCode) { | 220 DetectAndRecordMissingViaHeaderResponseCode) { |
| 249 const std::string kPrimaryHistogramName = | 221 const std::string kPrimaryHistogramName = |
| 250 "DataReductionProxy.MissingViaHeader.ResponseCode.Primary"; | 222 "DataReductionProxy.MissingViaHeader.ResponseCode.Primary"; |
| 251 const std::string kFallbackHistogramName = | 223 const std::string kFallbackHistogramName = |
| 252 "DataReductionProxy.MissingViaHeader.ResponseCode.Fallback"; | 224 "DataReductionProxy.MissingViaHeader.ResponseCode.Fallback"; |
| 253 | 225 |
| 254 struct TestCase { | 226 struct TestCase { |
| 255 bool is_primary; | 227 bool is_primary; |
| 256 const char* headers; | 228 const char* headers; |
| 257 int expected_primary_sample; // -1 indicates no expected sample. | 229 int expected_primary_sample; // -1 indicates no expected sample. |
| 258 int expected_fallback_sample; // -1 indicates no expected sample. | 230 int expected_fallback_sample; // -1 indicates no expected sample. |
| 259 }; | 231 }; |
| 260 const TestCase test_cases[] = { | 232 const TestCase test_cases[] = { |
| 261 { | 233 {true, |
|
bengr
2015/03/24 15:47:27
Same here. Please don't change the formatting.
zhuoyu.qian
2015/03/28 03:06:58
Done.
| |
| 262 true, | 234 "HTTP/1.1 200 OK\n" |
| 263 "HTTP/1.1 200 OK\n" | 235 "Via: 1.1 Chrome-Compression-Proxy\n", |
| 264 "Via: 1.1 Chrome-Compression-Proxy\n", | 236 -1, |
| 265 -1, | 237 -1}, |
| 266 -1 | 238 {false, |
| 267 }, | 239 "HTTP/1.1 200 OK\n" |
| 268 { | 240 "Via: 1.1 Chrome-Compression-Proxy\n", |
| 269 false, | 241 -1, |
| 270 "HTTP/1.1 200 OK\n" | 242 -1}, |
| 271 "Via: 1.1 Chrome-Compression-Proxy\n", | 243 {true, "HTTP/1.1 200 OK\n", 200, -1}, |
| 272 -1, | 244 {false, "HTTP/1.1 200 OK\n", -1, 200}, |
| 273 -1 | 245 {true, "HTTP/1.1 304 Not Modified\n", 304, -1}, |
| 274 }, | 246 {false, "HTTP/1.1 304 Not Modified\n", -1, 304}, |
| 275 { | 247 {true, "HTTP/1.1 404 Not Found\n", 404, -1}, |
| 276 true, | 248 {false, "HTTP/1.1 404 Not Found\n", -1, 404}}; |
| 277 "HTTP/1.1 200 OK\n", | |
| 278 200, | |
| 279 -1 | |
| 280 }, | |
| 281 { | |
| 282 false, | |
| 283 "HTTP/1.1 200 OK\n", | |
| 284 -1, | |
| 285 200 | |
| 286 }, | |
| 287 { | |
| 288 true, | |
| 289 "HTTP/1.1 304 Not Modified\n", | |
| 290 304, | |
| 291 -1 | |
| 292 }, | |
| 293 { | |
| 294 false, | |
| 295 "HTTP/1.1 304 Not Modified\n", | |
| 296 -1, | |
| 297 304 | |
| 298 }, | |
| 299 { | |
| 300 true, | |
| 301 "HTTP/1.1 404 Not Found\n", | |
| 302 404, | |
| 303 -1 | |
| 304 }, | |
| 305 { | |
| 306 false, | |
| 307 "HTTP/1.1 404 Not Found\n", | |
| 308 -1, | |
| 309 404 | |
| 310 } | |
| 311 }; | |
| 312 | 249 |
| 313 for (size_t i = 0; i < arraysize(test_cases); ++i) { | 250 for (size_t i = 0; i < arraysize(test_cases); ++i) { |
| 314 base::HistogramTester histogram_tester; | 251 base::HistogramTester histogram_tester; |
| 315 std::string raw_headers(test_cases[i].headers); | 252 std::string raw_headers(test_cases[i].headers); |
| 316 HeadersToRaw(&raw_headers); | 253 HeadersToRaw(&raw_headers); |
| 317 scoped_refptr<net::HttpResponseHeaders> headers( | 254 scoped_refptr<net::HttpResponseHeaders> headers( |
| 318 new net::HttpResponseHeaders(raw_headers)); | 255 new net::HttpResponseHeaders(raw_headers)); |
| 319 | 256 |
| 320 DataReductionProxyUsageStats::DetectAndRecordMissingViaHeaderResponseCode( | 257 DataReductionProxyBypassStats::DetectAndRecordMissingViaHeaderResponseCode( |
| 321 test_cases[i].is_primary, headers.get()); | 258 test_cases[i].is_primary, headers.get()); |
| 322 | 259 |
| 323 if (test_cases[i].expected_primary_sample == -1) { | 260 if (test_cases[i].expected_primary_sample == -1) { |
| 324 histogram_tester.ExpectTotalCount(kPrimaryHistogramName, 0); | 261 histogram_tester.ExpectTotalCount(kPrimaryHistogramName, 0); |
| 325 } else { | 262 } else { |
| 326 histogram_tester.ExpectUniqueSample( | 263 histogram_tester.ExpectUniqueSample( |
| 327 kPrimaryHistogramName, test_cases[i].expected_primary_sample, 1); | 264 kPrimaryHistogramName, test_cases[i].expected_primary_sample, 1); |
| 328 } | 265 } |
| 329 | 266 |
| 330 if (test_cases[i].expected_fallback_sample == -1) { | 267 if (test_cases[i].expected_fallback_sample == -1) { |
| 331 histogram_tester.ExpectTotalCount(kFallbackHistogramName, 0); | 268 histogram_tester.ExpectTotalCount(kFallbackHistogramName, 0); |
| 332 } else { | 269 } else { |
| 333 histogram_tester.ExpectUniqueSample( | 270 histogram_tester.ExpectUniqueSample( |
| 334 kFallbackHistogramName, test_cases[i].expected_fallback_sample, 1); | 271 kFallbackHistogramName, test_cases[i].expected_fallback_sample, 1); |
| 335 } | 272 } |
| 336 } | 273 } |
| 337 } | 274 } |
| 338 | 275 |
| 339 TEST_F(DataReductionProxyUsageStatsTest, RecordMissingViaHeaderBytes) { | 276 TEST_F(DataReductionProxyBypassStatsTest, RecordMissingViaHeaderBytes) { |
| 340 const std::string k4xxHistogramName = | 277 const std::string k4xxHistogramName = |
| 341 "DataReductionProxy.MissingViaHeader.Bytes.4xx"; | 278 "DataReductionProxy.MissingViaHeader.Bytes.4xx"; |
| 342 const std::string kOtherHistogramName = | 279 const std::string kOtherHistogramName = |
| 343 "DataReductionProxy.MissingViaHeader.Bytes.Other"; | 280 "DataReductionProxy.MissingViaHeader.Bytes.Other"; |
| 344 const int64 kResponseContentLength = 100; | 281 const int64 kResponseContentLength = 100; |
| 345 | 282 |
| 346 struct TestCase { | 283 struct TestCase { |
| 347 bool was_proxy_used; | 284 bool was_proxy_used; |
| 348 const char* headers; | 285 const char* headers; |
| 349 bool is_4xx_sample_expected; | 286 bool is_4xx_sample_expected; |
| 350 bool is_other_sample_expected; | 287 bool is_other_sample_expected; |
| 351 }; | 288 }; |
| 352 const TestCase test_cases[] = { | 289 const TestCase test_cases[] = { |
|
bengr
2015/03/24 15:47:27
And here.
zhuoyu.qian
2015/03/28 03:06:58
Done.
| |
| 353 // Nothing should be recorded for requests that don't use the proxy. | 290 // Nothing should be recorded for requests that don't use the proxy. |
| 354 { | 291 {false, "HTTP/1.1 404 Not Found\n", false, false}, |
| 355 false, | 292 {false, "HTTP/1.1 200 OK\n", false, false}, |
| 356 "HTTP/1.1 404 Not Found\n", | 293 // Nothing should be recorded for responses that have the via header. |
| 357 false, | 294 {true, |
| 358 false | 295 "HTTP/1.1 404 Not Found\n" |
| 359 }, | 296 "Via: 1.1 Chrome-Compression-Proxy\n", |
| 360 { | 297 false, |
| 361 false, | 298 false}, |
| 362 "HTTP/1.1 200 OK\n", | 299 {true, |
| 363 false, | 300 "HTTP/1.1 200 OK\n" |
| 364 false | 301 "Via: 1.1 Chrome-Compression-Proxy\n", |
| 365 }, | 302 false, |
| 366 // Nothing should be recorded for responses that have the via header. | 303 false}, |
| 367 { | 304 // 4xx responses that used the proxy and don't have the via header should |
| 368 true, | 305 // be |
| 369 "HTTP/1.1 404 Not Found\n" | 306 // recorded. |
| 370 "Via: 1.1 Chrome-Compression-Proxy\n", | 307 {true, "HTTP/1.1 404 Not Found\n", true, false}, |
| 371 false, | 308 {true, "HTTP/1.1 400 Bad Request\n", true, false}, |
| 372 false | 309 {true, "HTTP/1.1 499 Big Client Error Response Code\n", true, false}, |
| 373 }, | 310 // Non-4xx responses that used the proxy and don't have the via header |
| 374 { | 311 // should be recorded. |
| 375 true, | 312 {true, "HTTP/1.1 200 OK\n", false, true}, |
| 376 "HTTP/1.1 200 OK\n" | 313 {true, "HTTP/1.1 399 Big Redirection Response Code\n", false, true}, |
| 377 "Via: 1.1 Chrome-Compression-Proxy\n", | 314 {true, "HTTP/1.1 500 Internal Server Error\n", false, true}}; |
| 378 false, | |
| 379 false | |
| 380 }, | |
| 381 // 4xx responses that used the proxy and don't have the via header should be | |
| 382 // recorded. | |
| 383 { | |
| 384 true, | |
| 385 "HTTP/1.1 404 Not Found\n", | |
| 386 true, | |
| 387 false | |
| 388 }, | |
| 389 { | |
| 390 true, | |
| 391 "HTTP/1.1 400 Bad Request\n", | |
| 392 true, | |
| 393 false | |
| 394 }, | |
| 395 { | |
| 396 true, | |
| 397 "HTTP/1.1 499 Big Client Error Response Code\n", | |
| 398 true, | |
| 399 false | |
| 400 }, | |
| 401 // Non-4xx responses that used the proxy and don't have the via header | |
| 402 // should be recorded. | |
| 403 { | |
| 404 true, | |
| 405 "HTTP/1.1 200 OK\n", | |
| 406 false, | |
| 407 true | |
| 408 }, | |
| 409 { | |
| 410 true, | |
| 411 "HTTP/1.1 399 Big Redirection Response Code\n", | |
| 412 false, | |
| 413 true | |
| 414 }, | |
| 415 { | |
| 416 true, | |
| 417 "HTTP/1.1 500 Internal Server Error\n", | |
| 418 false, | |
| 419 true | |
| 420 } | |
| 421 }; | |
| 422 | 315 |
| 423 for (size_t i = 0; i < arraysize(test_cases); ++i) { | 316 for (size_t i = 0; i < arraysize(test_cases); ++i) { |
| 424 base::HistogramTester histogram_tester; | 317 base::HistogramTester histogram_tester; |
| 425 scoped_ptr<DataReductionProxyUsageStats> usage_stats = BuildUsageStats(); | 318 scoped_ptr<DataReductionProxyBypassStats> bypass_stats = BuildBypassStats(); |
| 426 | 319 |
| 427 std::string raw_headers(test_cases[i].headers); | 320 std::string raw_headers(test_cases[i].headers); |
| 428 HeadersToRaw(&raw_headers); | 321 HeadersToRaw(&raw_headers); |
| 429 | 322 |
| 430 scoped_ptr<net::URLRequest> fake_request( | 323 scoped_ptr<net::URLRequest> fake_request( |
| 431 CreateURLRequestWithResponseHeaders(GURL("http://www.google.com/"), | 324 CreateURLRequestWithResponseHeaders(GURL("http://www.google.com/"), |
| 432 raw_headers)); | 325 raw_headers)); |
| 433 fake_request->set_received_response_content_length(kResponseContentLength); | 326 fake_request->set_received_response_content_length(kResponseContentLength); |
| 434 | 327 |
| 435 EXPECT_CALL(*config(), | 328 EXPECT_CALL(*config(), |
| 436 WasDataReductionProxyUsed(fake_request.get(), testing::_)) | 329 WasDataReductionProxyUsed(fake_request.get(), testing::_)) |
| 437 .WillRepeatedly(Return(test_cases[i].was_proxy_used)); | 330 .WillRepeatedly(Return(test_cases[i].was_proxy_used)); |
| 438 | 331 |
| 439 usage_stats->RecordMissingViaHeaderBytes(*fake_request); | 332 bypass_stats->RecordMissingViaHeaderBytes(*fake_request); |
| 440 | 333 |
| 441 if (test_cases[i].is_4xx_sample_expected) { | 334 if (test_cases[i].is_4xx_sample_expected) { |
| 442 histogram_tester.ExpectUniqueSample(k4xxHistogramName, | 335 histogram_tester.ExpectUniqueSample(k4xxHistogramName, |
| 443 kResponseContentLength, 1); | 336 kResponseContentLength, 1); |
| 444 } else { | 337 } else { |
| 445 histogram_tester.ExpectTotalCount(k4xxHistogramName, 0); | 338 histogram_tester.ExpectTotalCount(k4xxHistogramName, 0); |
| 446 } | 339 } |
| 447 | 340 |
| 448 if (test_cases[i].is_other_sample_expected) { | 341 if (test_cases[i].is_other_sample_expected) { |
| 449 histogram_tester.ExpectUniqueSample(kOtherHistogramName, | 342 histogram_tester.ExpectUniqueSample(kOtherHistogramName, |
| 450 kResponseContentLength, 1); | 343 kResponseContentLength, 1); |
| 451 } else { | 344 } else { |
| 452 histogram_tester.ExpectTotalCount(kOtherHistogramName, 0); | 345 histogram_tester.ExpectTotalCount(kOtherHistogramName, 0); |
| 453 } | 346 } |
| 454 } | 347 } |
| 455 } | 348 } |
| 456 | 349 |
| 457 TEST_F(DataReductionProxyUsageStatsTest, RequestCompletionErrorCodes) { | 350 TEST_F(DataReductionProxyBypassStatsTest, RequestCompletionErrorCodes) { |
| 458 const std::string kPrimaryHistogramName = | 351 const std::string kPrimaryHistogramName = |
| 459 "DataReductionProxy.RequestCompletionErrorCodes.Primary"; | 352 "DataReductionProxy.RequestCompletionErrorCodes.Primary"; |
| 460 const std::string kFallbackHistogramName = | 353 const std::string kFallbackHistogramName = |
| 461 "DataReductionProxy.RequestCompletionErrorCodes.Fallback"; | 354 "DataReductionProxy.RequestCompletionErrorCodes.Fallback"; |
| 462 const std::string kPrimaryMainFrameHistogramName = | 355 const std::string kPrimaryMainFrameHistogramName = |
| 463 "DataReductionProxy.RequestCompletionErrorCodes.MainFrame.Primary"; | 356 "DataReductionProxy.RequestCompletionErrorCodes.MainFrame.Primary"; |
| 464 const std::string kFallbackMainFrameHistogramName = | 357 const std::string kFallbackMainFrameHistogramName = |
| 465 "DataReductionProxy.RequestCompletionErrorCodes.MainFrame.Fallback"; | 358 "DataReductionProxy.RequestCompletionErrorCodes.MainFrame.Fallback"; |
| 466 | 359 |
| 467 struct TestCase { | 360 struct TestCase { |
| 468 bool was_proxy_used; | 361 bool was_proxy_used; |
| 469 bool is_load_bypass_proxy; | 362 bool is_load_bypass_proxy; |
| 470 bool is_fallback; | 363 bool is_fallback; |
| 471 bool is_main_frame; | 364 bool is_main_frame; |
| 472 net::Error net_error; | 365 net::Error net_error; |
| 473 }; | 366 }; |
| 474 | 367 |
| 475 const TestCase test_cases[] = { | 368 const TestCase test_cases[] = { |
|
bengr
2015/03/24 15:47:27
And here. In this case the formatting is already a
zhuoyu.qian
2015/03/28 03:06:58
Done.
| |
| 476 {false, true, false, true, net::OK}, | 369 {false, true, false, true, net::OK}, |
| 477 {false, true, false, false, net::ERR_TOO_MANY_REDIRECTS}, | 370 {false, true, false, false, net::ERR_TOO_MANY_REDIRECTS}, |
| 478 {false, false, false, true, net::OK}, | 371 {false, false, false, true, net::OK}, |
| 479 {false, false, false, false, net::ERR_TOO_MANY_REDIRECTS}, | 372 {false, false, false, false, net::ERR_TOO_MANY_REDIRECTS}, |
| 480 {true, false, false, true, net::OK}, | 373 {true, false, false, true, net::OK}, |
| 481 {true, false, false, true, net::ERR_TOO_MANY_REDIRECTS}, | 374 {true, false, false, true, net::ERR_TOO_MANY_REDIRECTS}, |
| 482 {true, false, false, false, net::OK}, | 375 {true, false, false, false, net::OK}, |
| 483 {true, false, false, false, net::ERR_TOO_MANY_REDIRECTS}, | 376 {true, false, false, false, net::ERR_TOO_MANY_REDIRECTS}, |
| 484 {true, false, true, true, net::OK}, | 377 {true, false, true, true, net::OK}, |
| 485 {true, false, true, true, net::ERR_TOO_MANY_REDIRECTS}, | 378 {true, false, true, true, net::ERR_TOO_MANY_REDIRECTS}, |
| 486 {true, false, true, false, net::OK}, | 379 {true, false, true, false, net::OK}, |
| 487 {true, false, true, false, net::ERR_TOO_MANY_REDIRECTS} | 380 {true, false, true, false, net::ERR_TOO_MANY_REDIRECTS}}; |
| 488 }; | |
| 489 | 381 |
| 490 for (size_t i = 0; i < arraysize(test_cases); ++i) { | 382 for (size_t i = 0; i < arraysize(test_cases); ++i) { |
| 491 base::HistogramTester histogram_tester; | 383 base::HistogramTester histogram_tester; |
| 492 scoped_ptr<DataReductionProxyUsageStats> usage_stats = BuildUsageStats(); | 384 scoped_ptr<DataReductionProxyBypassStats> bypass_stats = BuildBypassStats(); |
| 493 | 385 |
| 494 std::string raw_headers("HTTP/1.1 200 OK\n" | 386 std::string raw_headers( |
| 495 "Via: 1.1 Chrome-Compression-Proxy\n"); | 387 "HTTP/1.1 200 OK\n" |
| 388 "Via: 1.1 Chrome-Compression-Proxy\n"); | |
| 496 HeadersToRaw(&raw_headers); | 389 HeadersToRaw(&raw_headers); |
| 497 scoped_ptr<net::URLRequest> fake_request( | 390 scoped_ptr<net::URLRequest> fake_request( |
| 498 CreateURLRequestWithResponseHeaders(GURL("http://www.google.com/"), | 391 CreateURLRequestWithResponseHeaders(GURL("http://www.google.com/"), |
| 499 raw_headers)); | 392 raw_headers)); |
| 500 if (test_cases[i].is_load_bypass_proxy) { | 393 if (test_cases[i].is_load_bypass_proxy) { |
| 501 fake_request->SetLoadFlags(fake_request->load_flags() | | 394 fake_request->SetLoadFlags(fake_request->load_flags() | |
| 502 net::LOAD_BYPASS_PROXY); | 395 net::LOAD_BYPASS_PROXY); |
| 503 } | 396 } |
| 504 if (test_cases[i].is_main_frame) { | 397 if (test_cases[i].is_main_frame) { |
| 505 fake_request->SetLoadFlags(fake_request->load_flags() | | 398 fake_request->SetLoadFlags(fake_request->load_flags() | |
| 506 net::LOAD_MAIN_FRAME); | 399 net::LOAD_MAIN_FRAME); |
| 507 } | 400 } |
| 508 | 401 |
| 509 int net_error_int = static_cast<int>(test_cases[i].net_error); | 402 int net_error_int = static_cast<int>(test_cases[i].net_error); |
| 510 if (test_cases[i].net_error != net::OK) { | 403 if (test_cases[i].net_error != net::OK) { |
| 511 fake_request->CancelWithError(net_error_int); | 404 fake_request->CancelWithError(net_error_int); |
| 512 } | 405 } |
| 513 | 406 |
| 514 DataReductionProxyTypeInfo proxy_info; | 407 DataReductionProxyTypeInfo proxy_info; |
| 515 proxy_info.is_fallback = test_cases[i].is_fallback; | 408 proxy_info.is_fallback = test_cases[i].is_fallback; |
| 516 EXPECT_CALL(*config(), WasDataReductionProxyUsed(fake_request.get(), | 409 EXPECT_CALL(*config(), WasDataReductionProxyUsed(fake_request.get(), |
| 517 testing::NotNull())) | 410 testing::NotNull())) |
| 518 .WillRepeatedly(testing::DoAll(testing::SetArgPointee<1>(proxy_info), | 411 .WillRepeatedly(testing::DoAll(testing::SetArgPointee<1>(proxy_info), |
| 519 Return(test_cases[i].was_proxy_used))); | 412 Return(test_cases[i].was_proxy_used))); |
| 520 | 413 |
| 521 usage_stats->OnUrlRequestCompleted(fake_request.get(), false); | 414 bypass_stats->OnUrlRequestCompleted(fake_request.get(), false); |
| 522 | 415 |
| 523 if (test_cases[i].was_proxy_used && !test_cases[i].is_load_bypass_proxy && | 416 if (test_cases[i].was_proxy_used && !test_cases[i].is_load_bypass_proxy && |
| 524 !test_cases[i].is_fallback) { | 417 !test_cases[i].is_fallback) { |
| 525 histogram_tester.ExpectUniqueSample( | 418 histogram_tester.ExpectUniqueSample(kPrimaryHistogramName, -net_error_int, |
| 526 kPrimaryHistogramName, -net_error_int, 1); | 419 1); |
| 527 } else { | 420 } else { |
| 528 histogram_tester.ExpectTotalCount(kPrimaryHistogramName, 0); | 421 histogram_tester.ExpectTotalCount(kPrimaryHistogramName, 0); |
| 529 } | 422 } |
| 530 if (test_cases[i].was_proxy_used && !test_cases[i].is_load_bypass_proxy && | 423 if (test_cases[i].was_proxy_used && !test_cases[i].is_load_bypass_proxy && |
| 531 test_cases[i].is_fallback) { | 424 test_cases[i].is_fallback) { |
| 532 histogram_tester.ExpectUniqueSample( | 425 histogram_tester.ExpectUniqueSample(kFallbackHistogramName, |
| 533 kFallbackHistogramName, -net_error_int, 1); | 426 -net_error_int, 1); |
| 534 } else { | 427 } else { |
| 535 histogram_tester.ExpectTotalCount(kFallbackHistogramName, 0); | 428 histogram_tester.ExpectTotalCount(kFallbackHistogramName, 0); |
| 536 } | 429 } |
| 537 if (test_cases[i].was_proxy_used && !test_cases[i].is_load_bypass_proxy && | 430 if (test_cases[i].was_proxy_used && !test_cases[i].is_load_bypass_proxy && |
| 538 !test_cases[i].is_fallback && test_cases[i].is_main_frame) { | 431 !test_cases[i].is_fallback && test_cases[i].is_main_frame) { |
| 539 histogram_tester.ExpectUniqueSample( | 432 histogram_tester.ExpectUniqueSample(kPrimaryMainFrameHistogramName, |
| 540 kPrimaryMainFrameHistogramName, -net_error_int, 1); | 433 -net_error_int, 1); |
| 541 } else { | 434 } else { |
| 542 histogram_tester.ExpectTotalCount(kPrimaryMainFrameHistogramName, 0); | 435 histogram_tester.ExpectTotalCount(kPrimaryMainFrameHistogramName, 0); |
| 543 } | 436 } |
| 544 if (test_cases[i].was_proxy_used && !test_cases[i].is_load_bypass_proxy && | 437 if (test_cases[i].was_proxy_used && !test_cases[i].is_load_bypass_proxy && |
| 545 test_cases[i].is_fallback && test_cases[i].is_main_frame) { | 438 test_cases[i].is_fallback && test_cases[i].is_main_frame) { |
| 546 histogram_tester.ExpectUniqueSample( | 439 histogram_tester.ExpectUniqueSample(kFallbackMainFrameHistogramName, |
| 547 kFallbackMainFrameHistogramName, -net_error_int, 1); | 440 -net_error_int, 1); |
| 548 } else { | 441 } else { |
| 549 histogram_tester.ExpectTotalCount(kFallbackMainFrameHistogramName, 0); | 442 histogram_tester.ExpectTotalCount(kFallbackMainFrameHistogramName, 0); |
| 550 } | 443 } |
| 551 } | 444 } |
| 552 } | 445 } |
| 553 | 446 |
| 554 // End-to-end tests for the DataReductionProxy.BypassedBytes histograms. | 447 // End-to-end tests for the DataReductionProxy.BypassedBytes histograms. |
| 555 class DataReductionProxyUsageStatsEndToEndTest : public testing::Test { | 448 class DataReductionProxyBypassStatsEndToEndTest : public testing::Test { |
| 556 public: | 449 public: |
| 557 DataReductionProxyUsageStatsEndToEndTest() | 450 DataReductionProxyBypassStatsEndToEndTest() |
| 558 : context_(true), context_storage_(&context_) {} | 451 : context_(true), context_storage_(&context_) {} |
| 559 | 452 |
| 560 ~DataReductionProxyUsageStatsEndToEndTest() override { | 453 ~DataReductionProxyBypassStatsEndToEndTest() override { |
| 561 drp_test_context_->io_data()->ShutdownOnUIThread(); | 454 drp_test_context_->io_data()->ShutdownOnUIThread(); |
| 562 drp_test_context_->RunUntilIdle(); | 455 drp_test_context_->RunUntilIdle(); |
| 563 } | 456 } |
| 564 | 457 |
| 565 void SetUp() override { | 458 void SetUp() override { |
| 566 // Only use the primary data reduction proxy in order to make it easier to | 459 // Only use the primary data reduction proxy in order to make it easier to |
| 567 // test bypassed bytes due to proxy fallbacks. This way, a test just needs | 460 // test bypassed bytes due to proxy fallbacks. This way, a test just needs |
| 568 // to cause one proxy fallback in order for the data reduction proxy to be | 461 // to cause one proxy fallback in order for the data reduction proxy to be |
| 569 // fully bypassed. | 462 // fully bypassed. |
| 570 drp_test_context_ = | 463 drp_test_context_ = |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 638 } | 531 } |
| 639 | 532 |
| 640 const DataReductionProxySettings* settings() const { | 533 const DataReductionProxySettings* settings() const { |
| 641 return drp_test_context_->settings(); | 534 return drp_test_context_->settings(); |
| 642 } | 535 } |
| 643 | 536 |
| 644 TestDataReductionProxyConfig* config() const { | 537 TestDataReductionProxyConfig* config() const { |
| 645 return drp_test_context_->config(); | 538 return drp_test_context_->config(); |
| 646 } | 539 } |
| 647 | 540 |
| 648 void ClearBadProxies() { | 541 void ClearBadProxies() { context_.proxy_service()->ClearBadProxiesCache(); } |
| 649 context_.proxy_service()->ClearBadProxiesCache(); | |
| 650 } | |
| 651 | 542 |
| 652 void InitializeContext() { | 543 void InitializeContext() { |
| 653 context_.Init(); | 544 context_.Init(); |
| 654 drp_test_context_->EnableDataReductionProxyWithSecureProxyCheckSuccess(); | 545 drp_test_context_->EnableDataReductionProxyWithSecureProxyCheckSuccess(); |
| 655 } | 546 } |
| 656 | 547 |
| 657 void ExpectOtherBypassedBytesHistogramsEmpty( | 548 void ExpectOtherBypassedBytesHistogramsEmpty( |
| 658 const base::HistogramTester& histogram_tester, | 549 const base::HistogramTester& histogram_tester, |
| 659 const std::set<std::string>& excluded_histograms) const { | 550 const std::set<std::string>& excluded_histograms) const { |
| 660 const std::string kHistograms[] = { | 551 const std::string kHistograms[] = { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 673 "DataReductionProxy.BypassedBytes.MissingViaHeader4xx", | 564 "DataReductionProxy.BypassedBytes.MissingViaHeader4xx", |
| 674 "DataReductionProxy.BypassedBytes.MissingViaHeaderOther", | 565 "DataReductionProxy.BypassedBytes.MissingViaHeaderOther", |
| 675 "DataReductionProxy.BypassedBytes.Malformed407", | 566 "DataReductionProxy.BypassedBytes.Malformed407", |
| 676 "DataReductionProxy.BypassedBytes.Status500HttpInternalServerError", | 567 "DataReductionProxy.BypassedBytes.Status500HttpInternalServerError", |
| 677 "DataReductionProxy.BypassedBytes.Status502HttpBadGateway", | 568 "DataReductionProxy.BypassedBytes.Status502HttpBadGateway", |
| 678 "DataReductionProxy.BypassedBytes.Status503HttpServiceUnavailable", | 569 "DataReductionProxy.BypassedBytes.Status503HttpServiceUnavailable", |
| 679 "DataReductionProxy.BypassedBytes.NetworkErrorOther", | 570 "DataReductionProxy.BypassedBytes.NetworkErrorOther", |
| 680 }; | 571 }; |
| 681 | 572 |
| 682 for (const std::string& histogram : kHistograms) { | 573 for (const std::string& histogram : kHistograms) { |
| 683 if (excluded_histograms.find(histogram) == | 574 if (excluded_histograms.find(histogram) == excluded_histograms.end()) { |
| 684 excluded_histograms.end()) { | |
| 685 histogram_tester.ExpectTotalCount(histogram, 0); | 575 histogram_tester.ExpectTotalCount(histogram, 0); |
| 686 } | 576 } |
| 687 } | 577 } |
| 688 } | 578 } |
| 689 | 579 |
| 690 void ExpectOtherBypassedBytesHistogramsEmpty( | 580 void ExpectOtherBypassedBytesHistogramsEmpty( |
| 691 const base::HistogramTester& histogram_tester, | 581 const base::HistogramTester& histogram_tester, |
| 692 const std::string& excluded_histogram) const { | 582 const std::string& excluded_histogram) const { |
| 693 std::set<std::string> excluded_histograms; | 583 std::set<std::string> excluded_histograms; |
| 694 excluded_histograms.insert(excluded_histogram); | 584 excluded_histograms.insert(excluded_histogram); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 708 } | 598 } |
| 709 | 599 |
| 710 private: | 600 private: |
| 711 net::TestDelegate delegate_; | 601 net::TestDelegate delegate_; |
| 712 net::MockClientSocketFactory mock_socket_factory_; | 602 net::MockClientSocketFactory mock_socket_factory_; |
| 713 net::TestURLRequestContext context_; | 603 net::TestURLRequestContext context_; |
| 714 net::URLRequestContextStorage context_storage_; | 604 net::URLRequestContextStorage context_storage_; |
| 715 scoped_ptr<DataReductionProxyTestContext> drp_test_context_; | 605 scoped_ptr<DataReductionProxyTestContext> drp_test_context_; |
| 716 }; | 606 }; |
| 717 | 607 |
| 718 TEST_F(DataReductionProxyUsageStatsEndToEndTest, BypassedBytesNoRetry) { | 608 TEST_F(DataReductionProxyBypassStatsEndToEndTest, BypassedBytesNoRetry) { |
| 719 struct TestCase { | 609 struct TestCase { |
| 720 GURL url; | 610 GURL url; |
| 721 const char* histogram_name; | 611 const char* histogram_name; |
| 722 const char* initial_response_headers; | 612 const char* initial_response_headers; |
| 723 }; | 613 }; |
| 724 const TestCase test_cases[] = { | 614 const TestCase test_cases[] = { |
| 725 { GURL("http://foo.com"), | 615 { |
| 726 "DataReductionProxy.BypassedBytes.NotBypassed", | 616 GURL("http://foo.com"), |
|
bengr
2015/03/24 15:47:27
Again, please revert the formatting change.
zhuoyu.qian
2015/03/28 03:06:58
Done.
| |
| 727 "HTTP/1.1 200 OK\r\n" | 617 "DataReductionProxy.BypassedBytes.NotBypassed", |
| 728 "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n", | 618 "HTTP/1.1 200 OK\r\n" |
| 729 }, | 619 "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n", |
| 730 { GURL("https://foo.com"), | 620 }, |
| 731 "DataReductionProxy.BypassedBytes.SSL", | 621 { |
| 732 "HTTP/1.1 200 OK\r\n\r\n", | 622 GURL("https://foo.com"), |
| 733 }, | 623 "DataReductionProxy.BypassedBytes.SSL", |
| 734 { GURL("http://localhost"), | 624 "HTTP/1.1 200 OK\r\n\r\n", |
| 735 "DataReductionProxy.BypassedBytes.LocalBypassRules", | 625 }, |
| 736 "HTTP/1.1 200 OK\r\n\r\n", | 626 { |
| 737 }, | 627 GURL("http://localhost"), |
| 628 "DataReductionProxy.BypassedBytes.LocalBypassRules", | |
| 629 "HTTP/1.1 200 OK\r\n\r\n", | |
| 630 }, | |
| 738 }; | 631 }; |
| 739 | 632 |
| 740 InitializeContext(); | 633 InitializeContext(); |
| 741 for (const TestCase& test_case : test_cases) { | 634 for (const TestCase& test_case : test_cases) { |
| 742 ClearBadProxies(); | 635 ClearBadProxies(); |
| 743 base::HistogramTester histogram_tester; | 636 base::HistogramTester histogram_tester; |
| 744 CreateAndExecuteRequest(test_case.url, test_case.initial_response_headers, | 637 CreateAndExecuteRequest(test_case.url, test_case.initial_response_headers, |
| 745 kBody.c_str(), nullptr, nullptr); | 638 kBody.c_str(), nullptr, nullptr); |
| 746 | 639 |
| 747 histogram_tester.ExpectUniqueSample(test_case.histogram_name, kBody.size(), | 640 histogram_tester.ExpectUniqueSample(test_case.histogram_name, kBody.size(), |
| 748 1); | 641 1); |
| 749 ExpectOtherBypassedBytesHistogramsEmpty(histogram_tester, | 642 ExpectOtherBypassedBytesHistogramsEmpty(histogram_tester, |
| 750 test_case.histogram_name); | 643 test_case.histogram_name); |
| 751 } | 644 } |
| 752 } | 645 } |
| 753 | 646 |
| 754 TEST_F(DataReductionProxyUsageStatsEndToEndTest, BypassedBytesProxyOverridden) { | 647 TEST_F(DataReductionProxyBypassStatsEndToEndTest, |
| 648 BypassedBytesProxyOverridden) { | |
| 755 scoped_ptr<net::ProxyService> proxy_service( | 649 scoped_ptr<net::ProxyService> proxy_service( |
| 756 net::ProxyService::CreateFixed("http://test.com:80")); | 650 net::ProxyService::CreateFixed("http://test.com:80")); |
| 757 set_proxy_service(proxy_service.get()); | 651 set_proxy_service(proxy_service.get()); |
| 758 InitializeContext(); | 652 InitializeContext(); |
| 759 | 653 |
| 760 base::HistogramTester histogram_tester; | 654 base::HistogramTester histogram_tester; |
| 761 CreateAndExecuteRequest(GURL("http://foo.com"), "HTTP/1.1 200 OK\r\n\r\n", | 655 CreateAndExecuteRequest(GURL("http://foo.com"), "HTTP/1.1 200 OK\r\n\r\n", |
| 762 kBody.c_str(), nullptr, nullptr); | 656 kBody.c_str(), nullptr, nullptr); |
| 763 | 657 |
| 764 histogram_tester.ExpectUniqueSample( | 658 histogram_tester.ExpectUniqueSample( |
| 765 "DataReductionProxy.BypassedBytes.ProxyOverridden", kBody.size(), 1); | 659 "DataReductionProxy.BypassedBytes.ProxyOverridden", kBody.size(), 1); |
| 766 ExpectOtherBypassedBytesHistogramsEmpty( | 660 ExpectOtherBypassedBytesHistogramsEmpty( |
| 767 histogram_tester, "DataReductionProxy.BypassedBytes.ProxyOverridden"); | 661 histogram_tester, "DataReductionProxy.BypassedBytes.ProxyOverridden"); |
| 768 } | 662 } |
| 769 | 663 |
| 770 TEST_F(DataReductionProxyUsageStatsEndToEndTest, BypassedBytesCurrent) { | 664 TEST_F(DataReductionProxyBypassStatsEndToEndTest, BypassedBytesCurrent) { |
| 771 InitializeContext(); | 665 InitializeContext(); |
| 772 base::HistogramTester histogram_tester; | 666 base::HistogramTester histogram_tester; |
| 773 CreateAndExecuteRequest(GURL("http://foo.com"), | 667 CreateAndExecuteRequest(GURL("http://foo.com"), |
| 774 "HTTP/1.1 502 Bad Gateway\r\n" | 668 "HTTP/1.1 502 Bad Gateway\r\n" |
| 775 "Via: 1.1 Chrome-Compression-Proxy\r\n" | 669 "Via: 1.1 Chrome-Compression-Proxy\r\n" |
| 776 "Chrome-Proxy: block-once\r\n\r\n", | 670 "Chrome-Proxy: block-once\r\n\r\n", |
| 777 kErrorBody.c_str(), "HTTP/1.1 200 OK\r\n\r\n", | 671 kErrorBody.c_str(), "HTTP/1.1 200 OK\r\n\r\n", |
| 778 kBody.c_str()); | 672 kBody.c_str()); |
| 779 | 673 |
| 780 histogram_tester.ExpectUniqueSample( | 674 histogram_tester.ExpectUniqueSample( |
| 781 "DataReductionProxy.BypassedBytes.Current", kBody.size(), 1); | 675 "DataReductionProxy.BypassedBytes.Current", kBody.size(), 1); |
| 782 ExpectOtherBypassedBytesHistogramsEmpty( | 676 ExpectOtherBypassedBytesHistogramsEmpty( |
| 783 histogram_tester, "DataReductionProxy.BypassedBytes.Current"); | 677 histogram_tester, "DataReductionProxy.BypassedBytes.Current"); |
| 784 } | 678 } |
| 785 | 679 |
| 786 TEST_F(DataReductionProxyUsageStatsEndToEndTest, BypassedBytesShortAudioVideo) { | 680 TEST_F(DataReductionProxyBypassStatsEndToEndTest, |
| 681 BypassedBytesShortAudioVideo) { | |
| 787 InitializeContext(); | 682 InitializeContext(); |
| 788 base::HistogramTester histogram_tester; | 683 base::HistogramTester histogram_tester; |
| 789 CreateAndExecuteRequest(GURL("http://foo.com"), | 684 CreateAndExecuteRequest(GURL("http://foo.com"), |
| 790 "HTTP/1.1 502 Bad Gateway\r\n" | 685 "HTTP/1.1 502 Bad Gateway\r\n" |
| 791 "Via: 1.1 Chrome-Compression-Proxy\r\n" | 686 "Via: 1.1 Chrome-Compression-Proxy\r\n" |
| 792 "Chrome-Proxy: block=1\r\n\r\n", | 687 "Chrome-Proxy: block=1\r\n\r\n", |
| 793 kErrorBody.c_str(), | 688 kErrorBody.c_str(), |
| 794 "HTTP/1.1 200 OK\r\n" | 689 "HTTP/1.1 200 OK\r\n" |
| 795 "Content-Type: video/mp4\r\n\r\n", | 690 "Content-Type: video/mp4\r\n\r\n", |
| 796 kBody.c_str()); | 691 kBody.c_str()); |
| 797 | 692 |
| 798 histogram_tester.ExpectUniqueSample( | 693 histogram_tester.ExpectUniqueSample( |
| 799 "DataReductionProxy.BypassedBytes.ShortAudioVideo", kBody.size(), 1); | 694 "DataReductionProxy.BypassedBytes.ShortAudioVideo", kBody.size(), 1); |
| 800 ExpectOtherBypassedBytesHistogramsEmpty( | 695 ExpectOtherBypassedBytesHistogramsEmpty( |
| 801 histogram_tester, "DataReductionProxy.BypassedBytes.ShortAudioVideo"); | 696 histogram_tester, "DataReductionProxy.BypassedBytes.ShortAudioVideo"); |
| 802 } | 697 } |
| 803 | 698 |
| 804 TEST_F(DataReductionProxyUsageStatsEndToEndTest, BypassedBytesExplicitBypass) { | 699 TEST_F(DataReductionProxyBypassStatsEndToEndTest, BypassedBytesExplicitBypass) { |
| 805 struct TestCase { | 700 struct TestCase { |
| 806 const char* triggering_histogram_name; | 701 const char* triggering_histogram_name; |
| 807 const char* all_histogram_name; | 702 const char* all_histogram_name; |
| 808 const char* initial_response_headers; | 703 const char* initial_response_headers; |
| 809 }; | 704 }; |
| 810 const TestCase test_cases[] = { | 705 const TestCase test_cases[] = { |
| 811 { "DataReductionProxy.BypassedBytes.ShortTriggeringRequest", | 706 { |
| 812 "DataReductionProxy.BypassedBytes.ShortAll", | 707 "DataReductionProxy.BypassedBytes.ShortTriggeringRequest", |
|
bengr
2015/03/24 15:47:27
Here too.
zhuoyu.qian
2015/03/28 03:06:58
Done.
| |
| 813 "HTTP/1.1 502 Bad Gateway\r\n" | 708 "DataReductionProxy.BypassedBytes.ShortAll", |
| 814 "Via: 1.1 Chrome-Compression-Proxy\r\n" | 709 "HTTP/1.1 502 Bad Gateway\r\n" |
| 815 "Chrome-Proxy: block=1\r\n\r\n", | 710 "Via: 1.1 Chrome-Compression-Proxy\r\n" |
| 816 }, | 711 "Chrome-Proxy: block=1\r\n\r\n", |
| 817 { "DataReductionProxy.BypassedBytes.MediumTriggeringRequest", | 712 }, |
| 818 "DataReductionProxy.BypassedBytes.MediumAll", | 713 { |
| 819 "HTTP/1.1 502 Bad Gateway\r\n" | 714 "DataReductionProxy.BypassedBytes.MediumTriggeringRequest", |
| 820 "Via: 1.1 Chrome-Compression-Proxy\r\n" | 715 "DataReductionProxy.BypassedBytes.MediumAll", |
| 821 "Chrome-Proxy: block=0\r\n\r\n", | 716 "HTTP/1.1 502 Bad Gateway\r\n" |
| 822 }, | 717 "Via: 1.1 Chrome-Compression-Proxy\r\n" |
| 823 { "DataReductionProxy.BypassedBytes.LongTriggeringRequest", | 718 "Chrome-Proxy: block=0\r\n\r\n", |
| 824 "DataReductionProxy.BypassedBytes.LongAll", | 719 }, |
| 825 "HTTP/1.1 502 Bad Gateway\r\n" | 720 { |
| 826 "Via: 1.1 Chrome-Compression-Proxy\r\n" | 721 "DataReductionProxy.BypassedBytes.LongTriggeringRequest", |
| 827 "Chrome-Proxy: block=3600\r\n\r\n", | 722 "DataReductionProxy.BypassedBytes.LongAll", |
| 828 }, | 723 "HTTP/1.1 502 Bad Gateway\r\n" |
| 724 "Via: 1.1 Chrome-Compression-Proxy\r\n" | |
| 725 "Chrome-Proxy: block=3600\r\n\r\n", | |
| 726 }, | |
| 829 }; | 727 }; |
| 830 | 728 |
| 831 InitializeContext(); | 729 InitializeContext(); |
| 832 for (const TestCase& test_case : test_cases) { | 730 for (const TestCase& test_case : test_cases) { |
| 833 ClearBadProxies(); | 731 ClearBadProxies(); |
| 834 base::HistogramTester histogram_tester; | 732 base::HistogramTester histogram_tester; |
| 835 | 733 |
| 836 CreateAndExecuteRequest( | 734 CreateAndExecuteRequest( |
| 837 GURL("http://foo.com"), test_case.initial_response_headers, | 735 GURL("http://foo.com"), test_case.initial_response_headers, |
| 838 kErrorBody.c_str(), "HTTP/1.1 200 OK\r\n\r\n", kBody.c_str()); | 736 kErrorBody.c_str(), "HTTP/1.1 200 OK\r\n\r\n", kBody.c_str()); |
| 839 // The first request caused the proxy to be marked as bad, so this second | 737 // The first request caused the proxy to be marked as bad, so this second |
| 840 // request should not come through the proxy. | 738 // request should not come through the proxy. |
| 841 CreateAndExecuteRequest(GURL("http://bar.com"), "HTTP/1.1 200 OK\r\n\r\n", | 739 CreateAndExecuteRequest(GURL("http://bar.com"), "HTTP/1.1 200 OK\r\n\r\n", |
| 842 kNextBody.c_str(), nullptr, nullptr); | 740 kNextBody.c_str(), nullptr, nullptr); |
| 843 | 741 |
| 844 histogram_tester.ExpectUniqueSample(test_case.triggering_histogram_name, | 742 histogram_tester.ExpectUniqueSample(test_case.triggering_histogram_name, |
| 845 kBody.size(), 1); | 743 kBody.size(), 1); |
| 846 histogram_tester.ExpectUniqueSample(test_case.all_histogram_name, | 744 histogram_tester.ExpectUniqueSample(test_case.all_histogram_name, |
| 847 kNextBody.size(), 1); | 745 kNextBody.size(), 1); |
| 848 ExpectOtherBypassedBytesHistogramsEmpty(histogram_tester, | 746 ExpectOtherBypassedBytesHistogramsEmpty(histogram_tester, |
| 849 test_case.triggering_histogram_name, | 747 test_case.triggering_histogram_name, |
| 850 test_case.all_histogram_name); | 748 test_case.all_histogram_name); |
| 851 } | 749 } |
| 852 } | 750 } |
| 853 | 751 |
| 854 TEST_F(DataReductionProxyUsageStatsEndToEndTest, | 752 TEST_F(DataReductionProxyBypassStatsEndToEndTest, |
| 855 BypassedBytesClientSideFallback) { | 753 BypassedBytesClientSideFallback) { |
| 856 struct TestCase { | 754 struct TestCase { |
| 857 const char* histogram_name; | 755 const char* histogram_name; |
| 858 const char* initial_response_headers; | 756 const char* initial_response_headers; |
| 859 }; | 757 }; |
| 860 const TestCase test_cases[] = { | 758 const TestCase test_cases[] = { |
| 861 { "DataReductionProxy.BypassedBytes.MissingViaHeader4xx", | 759 { |
| 862 "HTTP/1.1 414 Request-URI Too Long\r\n\r\n", | 760 "DataReductionProxy.BypassedBytes.MissingViaHeader4xx", |
|
bengr
2015/03/24 15:47:27
And here.
zhuoyu.qian
2015/03/28 03:06:58
Done.
| |
| 863 }, | 761 "HTTP/1.1 414 Request-URI Too Long\r\n\r\n", |
| 864 { "DataReductionProxy.BypassedBytes.MissingViaHeaderOther", | 762 }, |
| 865 "HTTP/1.1 200 OK\r\n\r\n", | 763 { |
| 866 }, | 764 "DataReductionProxy.BypassedBytes.MissingViaHeaderOther", |
| 867 { "DataReductionProxy.BypassedBytes.Malformed407", | 765 "HTTP/1.1 200 OK\r\n\r\n", |
| 868 "HTTP/1.1 407 Proxy Authentication Required\r\n\r\n", | 766 }, |
| 869 }, | 767 { |
| 870 { "DataReductionProxy.BypassedBytes.Status500HttpInternalServerError", | 768 "DataReductionProxy.BypassedBytes.Malformed407", |
| 871 "HTTP/1.1 500 Internal Server Error\r\n\r\n", | 769 "HTTP/1.1 407 Proxy Authentication Required\r\n\r\n", |
| 872 }, | 770 }, |
| 873 { "DataReductionProxy.BypassedBytes.Status502HttpBadGateway", | 771 { |
| 874 "HTTP/1.1 502 Bad Gateway\r\n\r\n", | 772 "DataReductionProxy.BypassedBytes.Status500HttpInternalServerError", |
| 875 }, | 773 "HTTP/1.1 500 Internal Server Error\r\n\r\n", |
| 876 { "DataReductionProxy.BypassedBytes.Status503HttpServiceUnavailable", | 774 }, |
| 877 "HTTP/1.1 503 Service Unavailable\r\n\r\n", | 775 { |
| 878 }, | 776 "DataReductionProxy.BypassedBytes.Status502HttpBadGateway", |
| 777 "HTTP/1.1 502 Bad Gateway\r\n\r\n", | |
| 778 }, | |
| 779 { | |
| 780 "DataReductionProxy.BypassedBytes.Status503HttpServiceUnavailable", | |
| 781 "HTTP/1.1 503 Service Unavailable\r\n\r\n", | |
| 782 }, | |
| 879 }; | 783 }; |
| 880 | 784 |
| 881 InitializeContext(); | 785 InitializeContext(); |
| 882 for (const TestCase& test_case : test_cases) { | 786 for (const TestCase& test_case : test_cases) { |
| 883 ClearBadProxies(); | 787 ClearBadProxies(); |
| 884 base::HistogramTester histogram_tester; | 788 base::HistogramTester histogram_tester; |
| 885 | 789 |
| 886 CreateAndExecuteRequest( | 790 CreateAndExecuteRequest( |
| 887 GURL("http://foo.com"), test_case.initial_response_headers, | 791 GURL("http://foo.com"), test_case.initial_response_headers, |
| 888 kErrorBody.c_str(), "HTTP/1.1 200 OK\r\n\r\n", kBody.c_str()); | 792 kErrorBody.c_str(), "HTTP/1.1 200 OK\r\n\r\n", kBody.c_str()); |
| 889 // The first request caused the proxy to be marked as bad, so this second | 793 // The first request caused the proxy to be marked as bad, so this second |
| 890 // request should not come through the proxy. | 794 // request should not come through the proxy. |
| 891 CreateAndExecuteRequest(GURL("http://bar.com"), "HTTP/1.1 200 OK\r\n\r\n", | 795 CreateAndExecuteRequest(GURL("http://bar.com"), "HTTP/1.1 200 OK\r\n\r\n", |
| 892 kNextBody.c_str(), nullptr, nullptr); | 796 kNextBody.c_str(), nullptr, nullptr); |
| 893 | 797 |
| 894 histogram_tester.ExpectTotalCount(test_case.histogram_name, 2); | 798 histogram_tester.ExpectTotalCount(test_case.histogram_name, 2); |
| 895 histogram_tester.ExpectBucketCount(test_case.histogram_name, kBody.size(), | 799 histogram_tester.ExpectBucketCount(test_case.histogram_name, kBody.size(), |
| 896 1); | 800 1); |
| 897 histogram_tester.ExpectBucketCount(test_case.histogram_name, | 801 histogram_tester.ExpectBucketCount(test_case.histogram_name, |
| 898 kNextBody.size(), 1); | 802 kNextBody.size(), 1); |
| 899 ExpectOtherBypassedBytesHistogramsEmpty(histogram_tester, | 803 ExpectOtherBypassedBytesHistogramsEmpty(histogram_tester, |
| 900 test_case.histogram_name); | 804 test_case.histogram_name); |
| 901 } | 805 } |
| 902 } | 806 } |
| 903 | 807 |
| 904 TEST_F(DataReductionProxyUsageStatsEndToEndTest, BypassedBytesNetErrorOther) { | 808 TEST_F(DataReductionProxyBypassStatsEndToEndTest, BypassedBytesNetErrorOther) { |
| 905 // Make the data reduction proxy host fail to resolve. | 809 // Make the data reduction proxy host fail to resolve. |
| 906 scoped_ptr<net::MockHostResolver> host_resolver(new net::MockHostResolver()); | 810 scoped_ptr<net::MockHostResolver> host_resolver(new net::MockHostResolver()); |
| 907 host_resolver->rules()->AddSimulatedFailure( | 811 host_resolver->rules()->AddSimulatedFailure( |
| 908 config()->test_params()->origin().host_port_pair().host()); | 812 config()->test_params()->origin().host_port_pair().host()); |
| 909 set_host_resolver(host_resolver.get()); | 813 set_host_resolver(host_resolver.get()); |
| 910 InitializeContext(); | 814 InitializeContext(); |
| 911 | 815 |
| 912 base::HistogramTester histogram_tester; | 816 base::HistogramTester histogram_tester; |
| 913 CreateAndExecuteRequest(GURL("http://foo.com"), "HTTP/1.1 200 OK\r\n\r\n", | 817 CreateAndExecuteRequest(GURL("http://foo.com"), "HTTP/1.1 200 OK\r\n\r\n", |
| 914 kBody.c_str(), nullptr, nullptr); | 818 kBody.c_str(), nullptr, nullptr); |
| 915 | 819 |
| 916 histogram_tester.ExpectUniqueSample( | 820 histogram_tester.ExpectUniqueSample( |
| 917 "DataReductionProxy.BypassedBytes.NetworkErrorOther", kBody.size(), 1); | 821 "DataReductionProxy.BypassedBytes.NetworkErrorOther", kBody.size(), 1); |
| 918 ExpectOtherBypassedBytesHistogramsEmpty( | 822 ExpectOtherBypassedBytesHistogramsEmpty( |
| 919 histogram_tester, "DataReductionProxy.BypassedBytes.NetworkErrorOther"); | 823 histogram_tester, "DataReductionProxy.BypassedBytes.NetworkErrorOther"); |
| 920 histogram_tester.ExpectUniqueSample( | 824 histogram_tester.ExpectUniqueSample( |
| 921 "DataReductionProxy.BypassOnNetworkErrorPrimary", | 825 "DataReductionProxy.BypassOnNetworkErrorPrimary", |
| 922 -net::ERR_PROXY_CONNECTION_FAILED, 1); | 826 -net::ERR_PROXY_CONNECTION_FAILED, 1); |
| 923 } | 827 } |
| 924 | 828 |
| 925 } // namespace data_reduction_proxy | 829 } // namespace data_reduction_proxy |
| OLD | NEW |