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

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

Issue 577343002: 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: Addressed comments 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/request_priority.h" 14 #include "net/base/request_priority.h"
15 #include "net/http/http_response_headers.h"
16 #include "net/http/http_util.h"
10 #include "net/url_request/url_request.h" 17 #include "net/url_request/url_request.h"
18 #include "net/url_request/url_request_job_factory_impl.h"
11 #include "net/url_request/url_request_status.h" 19 #include "net/url_request/url_request_status.h"
20 #include "net/url_request/url_request_test_job.h"
12 #include "net/url_request/url_request_test_util.h" 21 #include "net/url_request/url_request_test_util.h"
13 #include "testing/gmock/include/gmock/gmock.h" 22 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h" 23 #include "testing/gtest/include/gtest/gtest.h"
15 24
16 using base::MessageLoop; 25 using base::MessageLoop;
17 using base::MessageLoopProxy; 26 using base::MessageLoopProxy;
18 using data_reduction_proxy::DataReductionProxyParams; 27 using data_reduction_proxy::DataReductionProxyParams;
19 using net::TestDelegate; 28 using net::TestDelegate;
20 using net::TestURLRequestContext; 29 using net::TestURLRequestContext;
21 using net::URLRequest; 30 using net::URLRequest;
(...skipping 21 matching lines...) Expand all
43 52
44 namespace data_reduction_proxy { 53 namespace data_reduction_proxy {
45 54
46 class DataReductionProxyUsageStatsTest : public testing::Test { 55 class DataReductionProxyUsageStatsTest : public testing::Test {
47 public: 56 public:
48 DataReductionProxyUsageStatsTest() 57 DataReductionProxyUsageStatsTest()
49 : loop_proxy_(MessageLoopProxy::current().get()), 58 : loop_proxy_(MessageLoopProxy::current().get()),
50 context_(true), 59 context_(true),
51 unavailable_(false) { 60 unavailable_(false) {
52 context_.Init(); 61 context_.Init();
62
63 // The |test_job_factory_| takes ownership of the interceptor.
64 test_job_interceptor_ = new net::TestJobInterceptor();
65 DCHECK(test_job_factory_.SetProtocolHandler(url::kHttpScheme,
66 test_job_interceptor_));
67 context_.set_job_factory(&test_job_factory_);
68
53 mock_url_request_ = context_.CreateRequest(GURL(), net::IDLE, &delegate_, 69 mock_url_request_ = context_.CreateRequest(GURL(), net::IDLE, &delegate_,
54 NULL); 70 NULL);
55 } 71 }
56 72
57 void NotifyUnavailable(bool unavailable) { 73 void NotifyUnavailable(bool unavailable) {
58 unavailable_ = unavailable; 74 unavailable_ = unavailable;
59 } 75 }
60 76
77 scoped_ptr<URLRequest> CreateURLRequestWithResponseHeaders(
78 const GURL& url,
79 const std::string& raw_response_headers) {
80 scoped_ptr<URLRequest> fake_request = context_.CreateRequest(url, net::IDLE,
81 &delegate_,
82 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 MessageLoop::current()->RunUntilIdle();
95
96 DCHECK(fake_request->response_headers() != NULL);
97 return fake_request.Pass();
98 }
99
61 // Required for MessageLoopProxy::current(). 100 // Required for MessageLoopProxy::current().
62 base::MessageLoopForUI loop_; 101 base::MessageLoopForUI loop_;
63 MessageLoopProxy* loop_proxy_; 102 MessageLoopProxy* loop_proxy_;
64 103
65 protected: 104 protected:
66 TestURLRequestContext context_; 105 TestURLRequestContext context_;
67 TestDelegate delegate_; 106 TestDelegate delegate_;
68 DataReductionProxyParamsMock mock_params_; 107 DataReductionProxyParamsMock mock_params_;
69 scoped_ptr<URLRequest> mock_url_request_; 108 scoped_ptr<URLRequest> mock_url_request_;
109 net::TestJobInterceptor* test_job_interceptor_;
Alexei Svitkine (slow) 2014/09/23 18:20:06 Nit: Add a comment that this is owned by |test_job
sclittle 2014/09/23 19:58:31 Done.
110 net::URLRequestJobFactoryImpl test_job_factory_;
70 bool unavailable_; 111 bool unavailable_;
71 }; 112 };
72 113
73 TEST_F(DataReductionProxyUsageStatsTest, IsDataReductionProxyUnreachable) { 114 TEST_F(DataReductionProxyUsageStatsTest, IsDataReductionProxyUnreachable) {
74 struct TestCase { 115 struct TestCase {
75 bool is_proxy_eligible; 116 bool is_proxy_eligible;
76 bool was_proxy_used; 117 bool was_proxy_used;
77 bool is_unreachable; 118 bool is_unreachable;
78 }; 119 };
79 const TestCase test_cases[] = { 120 const TestCase test_cases[] = {
(...skipping 30 matching lines...) Expand all
110 base::Bind(&DataReductionProxyUsageStatsTest::NotifyUnavailable, 151 base::Bind(&DataReductionProxyUsageStatsTest::NotifyUnavailable,
111 base::Unretained(this))); 152 base::Unretained(this)));
112 153
113 usage_stats->OnUrlRequestCompleted(mock_url_request_.get(), false); 154 usage_stats->OnUrlRequestCompleted(mock_url_request_.get(), false);
114 MessageLoop::current()->RunUntilIdle(); 155 MessageLoop::current()->RunUntilIdle();
115 156
116 EXPECT_EQ(test_case.is_unreachable, unavailable_); 157 EXPECT_EQ(test_case.is_unreachable, unavailable_);
117 } 158 }
118 } 159 }
119 160
161 TEST_F(DataReductionProxyUsageStatsTest,
162 DetectAndRecordMissingViaHeaderResponseCode) {
163 const std::string kPrimaryHistogramName =
164 "DataReductionProxy.MissingViaHeader.ResponseCode.Primary";
165 const std::string kFallbackHistogramName =
166 "DataReductionProxy.MissingViaHeader.ResponseCode.Fallback";
167
168 struct TestCase {
169 bool is_primary;
170 const char* headers;
171 int expected_primary_sample; // -1 indicates no expected sample.
172 int expected_fallback_sample; // -1 indicates no expected sample.
173 };
174 const TestCase test_cases[] = {
175 {
176 true,
177 "HTTP/1.1 200 OK\n"
178 "Via: 1.1 Chrome-Compression-Proxy\n",
179 -1,
180 -1
181 },
182 {
183 false,
184 "HTTP/1.1 200 OK\n"
185 "Via: 1.1 Chrome-Compression-Proxy\n",
186 -1,
187 -1
188 },
189 {
190 true,
191 "HTTP/1.1 200 OK\n",
192 200,
193 -1
194 },
195 {
196 false,
197 "HTTP/1.1 200 OK\n",
198 -1,
199 200
200 },
201 {
202 true,
203 "HTTP/1.1 304 Not Modified\n",
204 304,
205 -1
206 },
207 {
208 false,
209 "HTTP/1.1 304 Not Modified\n",
210 -1,
211 304
212 },
213 {
214 true,
215 "HTTP/1.1 404 Not Found\n",
216 404,
217 -1
218 },
219 {
220 false,
221 "HTTP/1.1 404 Not Found\n",
222 -1,
223 404
224 }
225 };
226
227 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
228 base::HistogramTester histogram_tester;
229 std::string raw_headers(test_cases[i].headers);
230 HeadersToRaw(&raw_headers);
231 scoped_refptr<net::HttpResponseHeaders> headers(
232 new net::HttpResponseHeaders(raw_headers));
233
234 DataReductionProxyUsageStats::DetectAndRecordMissingViaHeaderResponseCode(
235 test_cases[i].is_primary, headers.get());
236
237 if (test_cases[i].expected_primary_sample == -1) {
238 histogram_tester.ExpectTotalCount(kPrimaryHistogramName, 0);
239 } else {
240 histogram_tester.ExpectUniqueSample(
241 kPrimaryHistogramName, test_cases[i].expected_primary_sample, 1);
242 }
243
244 if (test_cases[i].expected_fallback_sample == -1) {
245 histogram_tester.ExpectTotalCount(kFallbackHistogramName, 0);
246 } else {
247 histogram_tester.ExpectUniqueSample(
248 kFallbackHistogramName, test_cases[i].expected_fallback_sample, 1);
249 }
250 }
251 }
252
253 TEST_F(DataReductionProxyUsageStatsTest, RecordMissingViaHeaderBytes) {
254 const std::string k4xxHistogramName =
255 "DataReductionProxy.MissingViaHeader.Bytes.4xx";
256 const std::string kOtherHistogramName =
257 "DataReductionProxy.MissingViaHeader.Bytes.Other";
258 const int64 kResponseContentLength = 100;
259
260 struct TestCase {
261 bool was_proxy_used;
262 const char* headers;
263 bool is_4xx_sample_expected;
264 bool is_other_sample_expected;
265 };
266 const TestCase test_cases[] = {
267 // Nothing should be recorded for requests that don't use the proxy.
268 {
269 false,
270 "HTTP/1.1 404 Not Found\n",
271 false,
272 false
273 },
274 {
275 false,
276 "HTTP/1.1 200 OK\n",
277 false,
278 false
279 },
280 // Nothing should be recorded for responses that have the via header.
281 {
282 true,
283 "HTTP/1.1 404 Not Found\n"
284 "Via: 1.1 Chrome-Compression-Proxy\n",
285 false,
286 false
287 },
288 {
289 true,
290 "HTTP/1.1 200 OK\n"
291 "Via: 1.1 Chrome-Compression-Proxy\n",
292 false,
293 false
294 },
295 // 4xx responses that used the proxy and don't have the via header should be
296 // recorded.
297 {
298 true,
299 "HTTP/1.1 404 Not Found\n",
300 true,
301 false
302 },
303 {
304 true,
305 "HTTP/1.1 400 Bad Request\n",
306 true,
307 false
308 },
309 {
310 true,
311 "HTTP/1.1 499 Big Client Error Response Code\n",
312 true,
313 false
314 },
315 // Non-4xx responses that used the proxy and don't have the via header
316 // should be recorded.
317 {
318 true,
319 "HTTP/1.1 200 OK\n",
320 false,
321 true
322 },
323 {
324 true,
325 "HTTP/1.1 399 Big Redirection Response Code\n",
326 false,
327 true
328 },
329 {
330 true,
331 "HTTP/1.1 500 Internal Server Error\n",
332 false,
333 true
334 }
335 };
336
337 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
338 base::HistogramTester histogram_tester;
339 scoped_ptr<DataReductionProxyUsageStats> usage_stats(
340 new DataReductionProxyUsageStats(&mock_params_, loop_proxy_));
341
342 std::string raw_headers(test_cases[i].headers);
343 HeadersToRaw(&raw_headers);
344
345 scoped_ptr<URLRequest> fake_request(
346 CreateURLRequestWithResponseHeaders(GURL("http://www.google.com/"),
347 raw_headers));
348 fake_request->set_received_response_content_length(kResponseContentLength);
349
350 EXPECT_CALL(mock_params_,
351 WasDataReductionProxyUsed(fake_request.get(), NULL))
352 .WillRepeatedly(Return(test_cases[i].was_proxy_used));
353
354 usage_stats->RecordMissingViaHeaderBytes(fake_request.get());
355
356 if (test_cases[i].is_4xx_sample_expected) {
357 histogram_tester.ExpectUniqueSample(k4xxHistogramName,
358 kResponseContentLength, 1);
359 } else {
360 histogram_tester.ExpectTotalCount(k4xxHistogramName, 0);
361 }
362
363 if (test_cases[i].is_other_sample_expected) {
364 histogram_tester.ExpectUniqueSample(kOtherHistogramName,
365 kResponseContentLength, 1);
366 } else {
367 histogram_tester.ExpectTotalCount(kOtherHistogramName, 0);
368 }
369 }
370 }
371
120 } // namespace data_reduction_proxy 372 } // namespace data_reduction_proxy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698