Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(405)

Side by Side Diff: components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats_unittest.cc

Issue 602503002: Adds UMA to measure when the data reduction proxy via header is missing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/browser/data_reduction_proxy_usage_sta ts.h" 5 #include "components/data_reduction_proxy/browser/data_reduction_proxy_usage_sta ts.h"
6 6
7 #include <string>
8
7 #include "base/bind.h" 9 #include "base/bind.h"
8 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/metrics/histogram.h"
12 #include "base/test/histogram_tester.h"
13 #include "components/data_reduction_proxy/common/data_reduction_proxy_headers_te st_utils.h"
9 #include "net/base/host_port_pair.h" 14 #include "net/base/host_port_pair.h"
10 #include "net/base/request_priority.h" 15 #include "net/base/request_priority.h"
16 #include "net/http/http_response_headers.h"
17 #include "net/http/http_util.h"
11 #include "net/url_request/url_request.h" 18 #include "net/url_request/url_request.h"
19 #include "net/url_request/url_request_job_factory_impl.h"
12 #include "net/url_request/url_request_status.h" 20 #include "net/url_request/url_request_status.h"
21 #include "net/url_request/url_request_test_job.h"
13 #include "net/url_request/url_request_test_util.h" 22 #include "net/url_request/url_request_test_util.h"
14 #include "testing/gmock/include/gmock/gmock.h" 23 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h" 24 #include "testing/gtest/include/gtest/gtest.h"
16 25
17 using testing::Return; 26 using testing::Return;
18 27
19 namespace { 28 namespace {
20 29
21 class DataReductionProxyParamsMock : 30 class DataReductionProxyParamsMock :
22 public data_reduction_proxy::DataReductionProxyParams { 31 public data_reduction_proxy::DataReductionProxyParams {
(...skipping 19 matching lines...) Expand all
42 51
43 namespace data_reduction_proxy { 52 namespace data_reduction_proxy {
44 53
45 class DataReductionProxyUsageStatsTest : public testing::Test { 54 class DataReductionProxyUsageStatsTest : public testing::Test {
46 public: 55 public:
47 DataReductionProxyUsageStatsTest() 56 DataReductionProxyUsageStatsTest()
48 : loop_proxy_(base::MessageLoopProxy::current().get()), 57 : loop_proxy_(base::MessageLoopProxy::current().get()),
49 context_(true), 58 context_(true),
50 unavailable_(false) { 59 unavailable_(false) {
51 context_.Init(); 60 context_.Init();
61
62 // The |test_job_factory_| takes ownership of the interceptor.
63 test_job_interceptor_ = new net::TestJobInterceptor();
64 // This must be a CHECK, and not a DCHECK, so that Valgrind doesn't complain
65 // that the |test_job_interceptor_| is never freed.
66 CHECK(test_job_factory_.SetProtocolHandler(url::kHttpScheme,
sclittle 2014/09/24 04:22:58 This line (and the comment above it) are the only
67 test_job_interceptor_));
mmenke 2014/09/24 15:31:12 I think it's still a bad idea to put code with sid
sclittle 2014/09/24 17:41:44 Unfortunately, changing this to ASSERT_TRUE doesn'
bengr 2014/09/24 17:46:47 You shouldn't be using DCHECK in tests. See: http:
sclittle 2014/09/24 18:05:14 OK, I've changed it to use EXPECT_TRUE.
68 context_.set_job_factory(&test_job_factory_);
69
52 mock_url_request_ = context_.CreateRequest(GURL(), net::IDLE, &delegate_, 70 mock_url_request_ = context_.CreateRequest(GURL(), net::IDLE, &delegate_,
53 NULL); 71 NULL);
54 } 72 }
55 73
56 void NotifyUnavailable(bool unavailable) { 74 void NotifyUnavailable(bool unavailable) {
57 unavailable_ = unavailable; 75 unavailable_ = unavailable;
58 } 76 }
59 77
78 scoped_ptr<net::URLRequest> CreateURLRequestWithResponseHeaders(
79 const GURL& url,
80 const std::string& raw_response_headers) {
81 scoped_ptr<net::URLRequest> fake_request = context_.CreateRequest(
82 url, net::IDLE, &delegate_, NULL);
83
84 // Create a test job that will fill in the given response headers for the
85 // |fake_request|.
86 scoped_refptr<net::URLRequestTestJob> test_job(
87 new net::URLRequestTestJob(fake_request.get(),
88 context_.network_delegate(),
89 raw_response_headers, std::string(), true));
90
91 // Configure the interceptor to use the test job to handle the next request.
92 test_job_interceptor_->set_main_intercept_job(test_job.get());
93 fake_request->Start();
94 base::MessageLoop::current()->RunUntilIdle();
95
96 DCHECK(fake_request->response_headers() != NULL);
97 return fake_request.Pass();
98 }
99
60 // Required for base::MessageLoopProxy::current(). 100 // Required for base::MessageLoopProxy::current().
61 base::MessageLoopForUI loop_; 101 base::MessageLoopForUI loop_;
62 base::MessageLoopProxy* loop_proxy_; 102 base::MessageLoopProxy* loop_proxy_;
63 103
64 protected: 104 protected:
65 net::TestURLRequestContext context_; 105 net::TestURLRequestContext context_;
66 net::TestDelegate delegate_; 106 net::TestDelegate delegate_;
67 DataReductionProxyParamsMock mock_params_; 107 DataReductionProxyParamsMock mock_params_;
68 scoped_ptr<net::URLRequest> mock_url_request_; 108 scoped_ptr<net::URLRequest> mock_url_request_;
109 // |test_job_interceptor_| is owned by |test_job_factory_|.
110 net::TestJobInterceptor* test_job_interceptor_;
111 net::URLRequestJobFactoryImpl test_job_factory_;
69 bool unavailable_; 112 bool unavailable_;
70 }; 113 };
71 114
72 TEST_F(DataReductionProxyUsageStatsTest, IsDataReductionProxyUnreachable) { 115 TEST_F(DataReductionProxyUsageStatsTest, IsDataReductionProxyUnreachable) {
73 net::ProxyServer fallback_proxy_server = 116 net::ProxyServer fallback_proxy_server =
74 net::ProxyServer::FromURI("foo.com", net::ProxyServer::SCHEME_HTTP); 117 net::ProxyServer::FromURI("foo.com", net::ProxyServer::SCHEME_HTTP);
75 data_reduction_proxy::DataReductionProxyTypeInfo proxy_info; 118 data_reduction_proxy::DataReductionProxyTypeInfo proxy_info;
76 struct TestCase { 119 struct TestCase {
77 bool fallback_proxy_server_is_data_reduction_proxy; 120 bool fallback_proxy_server_is_data_reduction_proxy;
78 bool was_proxy_used; 121 bool was_proxy_used;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 usage_stats->OnProxyFallback(fallback_proxy_server, 223 usage_stats->OnProxyFallback(fallback_proxy_server,
181 net::ERR_PROXY_CONNECTION_FAILED); 224 net::ERR_PROXY_CONNECTION_FAILED);
182 usage_stats->OnProxyFallback(fallback_proxy_server, 225 usage_stats->OnProxyFallback(fallback_proxy_server,
183 net::ERR_PROXY_CONNECTION_FAILED); 226 net::ERR_PROXY_CONNECTION_FAILED);
184 usage_stats->OnProxyFallback(fallback_proxy_server, 227 usage_stats->OnProxyFallback(fallback_proxy_server,
185 net::ERR_PROXY_CONNECTION_FAILED); 228 net::ERR_PROXY_CONNECTION_FAILED);
186 base::MessageLoop::current()->RunUntilIdle(); 229 base::MessageLoop::current()->RunUntilIdle();
187 EXPECT_TRUE(unavailable_); 230 EXPECT_TRUE(unavailable_);
188 } 231 }
189 232
233 TEST_F(DataReductionProxyUsageStatsTest,
234 DetectAndRecordMissingViaHeaderResponseCode) {
235 const std::string kPrimaryHistogramName =
236 "DataReductionProxy.MissingViaHeader.ResponseCode.Primary";
237 const std::string kFallbackHistogramName =
238 "DataReductionProxy.MissingViaHeader.ResponseCode.Fallback";
239
240 struct TestCase {
241 bool is_primary;
242 const char* headers;
243 int expected_primary_sample; // -1 indicates no expected sample.
244 int expected_fallback_sample; // -1 indicates no expected sample.
245 };
246 const TestCase test_cases[] = {
247 {
248 true,
249 "HTTP/1.1 200 OK\n"
250 "Via: 1.1 Chrome-Compression-Proxy\n",
251 -1,
252 -1
253 },
254 {
255 false,
256 "HTTP/1.1 200 OK\n"
257 "Via: 1.1 Chrome-Compression-Proxy\n",
258 -1,
259 -1
260 },
261 {
262 true,
263 "HTTP/1.1 200 OK\n",
264 200,
265 -1
266 },
267 {
268 false,
269 "HTTP/1.1 200 OK\n",
270 -1,
271 200
272 },
273 {
274 true,
275 "HTTP/1.1 304 Not Modified\n",
276 304,
277 -1
278 },
279 {
280 false,
281 "HTTP/1.1 304 Not Modified\n",
282 -1,
283 304
284 },
285 {
286 true,
287 "HTTP/1.1 404 Not Found\n",
288 404,
289 -1
290 },
291 {
292 false,
293 "HTTP/1.1 404 Not Found\n",
294 -1,
295 404
296 }
297 };
298
299 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
300 base::HistogramTester histogram_tester;
301 std::string raw_headers(test_cases[i].headers);
302 HeadersToRaw(&raw_headers);
303 scoped_refptr<net::HttpResponseHeaders> headers(
304 new net::HttpResponseHeaders(raw_headers));
305
306 DataReductionProxyUsageStats::DetectAndRecordMissingViaHeaderResponseCode(
307 test_cases[i].is_primary, headers.get());
308
309 if (test_cases[i].expected_primary_sample == -1) {
310 histogram_tester.ExpectTotalCount(kPrimaryHistogramName, 0);
311 } else {
312 histogram_tester.ExpectUniqueSample(
313 kPrimaryHistogramName, test_cases[i].expected_primary_sample, 1);
314 }
315
316 if (test_cases[i].expected_fallback_sample == -1) {
317 histogram_tester.ExpectTotalCount(kFallbackHistogramName, 0);
318 } else {
319 histogram_tester.ExpectUniqueSample(
320 kFallbackHistogramName, test_cases[i].expected_fallback_sample, 1);
321 }
322 }
323 }
324
325 TEST_F(DataReductionProxyUsageStatsTest, RecordMissingViaHeaderBytes) {
326 const std::string k4xxHistogramName =
327 "DataReductionProxy.MissingViaHeader.Bytes.4xx";
328 const std::string kOtherHistogramName =
329 "DataReductionProxy.MissingViaHeader.Bytes.Other";
330 const int64 kResponseContentLength = 100;
331
332 struct TestCase {
333 bool was_proxy_used;
334 const char* headers;
335 bool is_4xx_sample_expected;
336 bool is_other_sample_expected;
337 };
338 const TestCase test_cases[] = {
339 // Nothing should be recorded for requests that don't use the proxy.
340 {
341 false,
342 "HTTP/1.1 404 Not Found\n",
343 false,
344 false
345 },
346 {
347 false,
348 "HTTP/1.1 200 OK\n",
349 false,
350 false
351 },
352 // Nothing should be recorded for responses that have the via header.
353 {
354 true,
355 "HTTP/1.1 404 Not Found\n"
356 "Via: 1.1 Chrome-Compression-Proxy\n",
357 false,
358 false
359 },
360 {
361 true,
362 "HTTP/1.1 200 OK\n"
363 "Via: 1.1 Chrome-Compression-Proxy\n",
364 false,
365 false
366 },
367 // 4xx responses that used the proxy and don't have the via header should be
368 // recorded.
369 {
370 true,
371 "HTTP/1.1 404 Not Found\n",
372 true,
373 false
374 },
375 {
376 true,
377 "HTTP/1.1 400 Bad Request\n",
378 true,
379 false
380 },
381 {
382 true,
383 "HTTP/1.1 499 Big Client Error Response Code\n",
384 true,
385 false
386 },
387 // Non-4xx responses that used the proxy and don't have the via header
388 // should be recorded.
389 {
390 true,
391 "HTTP/1.1 200 OK\n",
392 false,
393 true
394 },
395 {
396 true,
397 "HTTP/1.1 399 Big Redirection Response Code\n",
398 false,
399 true
400 },
401 {
402 true,
403 "HTTP/1.1 500 Internal Server Error\n",
404 false,
405 true
406 }
407 };
408
409 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
410 base::HistogramTester histogram_tester;
411 scoped_ptr<DataReductionProxyUsageStats> usage_stats(
412 new DataReductionProxyUsageStats(&mock_params_, loop_proxy_));
413
414 std::string raw_headers(test_cases[i].headers);
415 HeadersToRaw(&raw_headers);
416
417 scoped_ptr<net::URLRequest> fake_request(
418 CreateURLRequestWithResponseHeaders(GURL("http://www.google.com/"),
419 raw_headers));
420 fake_request->set_received_response_content_length(kResponseContentLength);
421
422 EXPECT_CALL(mock_params_,
423 WasDataReductionProxyUsed(fake_request.get(), NULL))
424 .WillRepeatedly(Return(test_cases[i].was_proxy_used));
425
426 usage_stats->RecordMissingViaHeaderBytes(fake_request.get());
427
428 if (test_cases[i].is_4xx_sample_expected) {
429 histogram_tester.ExpectUniqueSample(k4xxHistogramName,
430 kResponseContentLength, 1);
431 } else {
432 histogram_tester.ExpectTotalCount(k4xxHistogramName, 0);
433 }
434
435 if (test_cases[i].is_other_sample_expected) {
436 histogram_tester.ExpectUniqueSample(kOtherHistogramName,
437 kResponseContentLength, 1);
438 } else {
439 histogram_tester.ExpectTotalCount(kOtherHistogramName, 0);
440 }
441 }
442 }
443
190 } // namespace data_reduction_proxy 444 } // namespace data_reduction_proxy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698