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/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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |