OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/net/http_pipelining_compatibility_client.h" | |
6 | |
7 #include <map> | |
8 #include <string> | |
9 #include <vector> | |
10 | |
11 #include "base/basictypes.h" | |
12 #include "base/message_loop.h" | |
13 #include "base/metrics/histogram.h" | |
14 #include "base/stl_util.h" | |
15 #include "base/stringprintf.h" | |
16 #include "chrome/test/base/test_url_request_context_getter.h" | |
17 #include "content/test/test_browser_thread.h" | |
18 #include "net/base/net_errors.h" | |
19 #include "net/base/test_completion_callback.h" | |
20 #include "net/url_request/url_request_context_getter.h" | |
21 #include "net/test/test_server.h" | |
22 #include "testing/gtest/include/gtest/gtest.h" | |
23 | |
24 namespace chrome_browser_net { | |
25 | |
26 namespace { | |
27 | |
28 static const char* const kHistogramNames[] = { | |
29 "NetConnectivity.Pipeline.0.NetworkError", | |
30 "NetConnectivity.Pipeline.0.ResponseCode", | |
31 "NetConnectivity.Pipeline.0.Status", | |
32 "NetConnectivity.Pipeline.1.NetworkError", | |
33 "NetConnectivity.Pipeline.1.ResponseCode", | |
34 "NetConnectivity.Pipeline.1.Status", | |
35 "NetConnectivity.Pipeline.2.NetworkError", | |
36 "NetConnectivity.Pipeline.2.ResponseCode", | |
37 "NetConnectivity.Pipeline.2.Status", | |
38 }; | |
39 | |
40 enum HistogramField { | |
41 FIELD_NETWORK_ERROR, | |
42 FIELD_RESPONSE_CODE, | |
43 FIELD_STATUS, | |
44 }; | |
45 | |
46 class HttpPipeliningCompatibilityClientTest : public testing::Test { | |
47 public: | |
48 HttpPipeliningCompatibilityClientTest() | |
49 : test_server_( | |
50 net::TestServer::TYPE_HTTP, | |
51 FilePath(FILE_PATH_LITERAL("chrome/test/data/http_pipelining"))) { | |
52 } | |
53 | |
54 protected: | |
55 virtual void SetUp() OVERRIDE { | |
56 ASSERT_TRUE(test_server_.Start()); | |
57 context_ = new TestURLRequestContextGetter; | |
58 context_->AddRef(); | |
59 | |
60 for (size_t i = 0; i < arraysize(kHistogramNames); ++i) { | |
61 const char* name = kHistogramNames[i]; | |
62 base::Histogram::SampleSet sample = GetHistogram(name); | |
63 if (sample.TotalCount() > 0) { | |
64 original_samples_[name] = sample; | |
65 } | |
66 } | |
67 } | |
68 | |
69 virtual void TearDown() OVERRIDE { | |
70 content::BrowserThread::ReleaseSoon(content::BrowserThread::IO, | |
71 FROM_HERE, context_); | |
72 message_loop_.RunAllPending(); | |
73 } | |
74 | |
75 void RunTest( | |
76 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests) { | |
77 HttpPipeliningCompatibilityClient client; | |
78 net::TestCompletionCallback callback; | |
79 client.Start(test_server_.GetURL("").spec(), | |
80 requests, callback.callback(), | |
81 context_->GetURLRequestContext()); | |
82 callback.WaitForResult(); | |
83 | |
84 for (size_t i = 0; i < arraysize(kHistogramNames); ++i) { | |
85 const char* name = kHistogramNames[i]; | |
86 base::Histogram::SampleSet sample = GetHistogram(name); | |
87 if (ContainsKey(original_samples_, name)) { | |
88 sample.Subtract(original_samples_[name]); | |
89 } | |
90 samples_[name] = sample; | |
91 } | |
92 } | |
93 | |
94 base::Histogram::SampleSet GetHistogramValue(int request_id, | |
95 HistogramField field) { | |
96 const char* field_str = ""; | |
97 switch (field) { | |
98 case FIELD_STATUS: | |
99 field_str = "Status"; | |
100 break; | |
101 | |
102 case FIELD_NETWORK_ERROR: | |
103 field_str = "NetworkError"; | |
104 break; | |
105 | |
106 case FIELD_RESPONSE_CODE: | |
107 field_str = "ResponseCode"; | |
108 break; | |
109 | |
110 default: | |
111 NOTREACHED(); | |
112 break; | |
113 } | |
114 | |
115 std::string name = base::StringPrintf("NetConnectivity.Pipeline.%d.%s", | |
116 request_id, field_str); | |
117 return samples_[name]; | |
118 } | |
119 | |
120 MessageLoopForIO message_loop_; | |
121 net::TestServer test_server_; | |
122 TestURLRequestContextGetter* context_; | |
123 | |
124 private: | |
125 base::Histogram::SampleSet GetHistogram(const char* name) { | |
126 base::Histogram::SampleSet sample; | |
127 base::Histogram* histogram; | |
128 if (ContainsKey(histograms_, name)) { | |
129 histogram = histograms_[name]; | |
130 histogram->SnapshotSample(&sample); | |
131 } else if (base::StatisticsRecorder::FindHistogram(name, &histogram)) { | |
132 histograms_[name] = histogram; | |
133 histogram->SnapshotSample(&sample); | |
134 } | |
135 return sample; | |
136 } | |
137 | |
138 static std::map<std::string, base::Histogram*> histograms_; | |
139 std::map<std::string, base::Histogram::SampleSet> samples_; | |
140 std::map<std::string, base::Histogram::SampleSet> original_samples_; | |
141 base::StatisticsRecorder recorder_; | |
142 }; | |
143 | |
144 // static | |
145 std::map<std::string, base::Histogram*> | |
146 HttpPipeliningCompatibilityClientTest::histograms_; | |
147 | |
148 TEST_F(HttpPipeliningCompatibilityClientTest, Success) { | |
149 HttpPipeliningCompatibilityClient::RequestInfo info; | |
150 info.filename = "files/alphabet.txt"; | |
151 info.expected_response = "abcdefghijklmnopqrstuvwxyz"; | |
152 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
153 requests.push_back(info); | |
154 | |
155 RunTest(requests); | |
156 | |
157 base::Histogram::SampleSet status_sample = | |
158 GetHistogramValue(0, FIELD_STATUS); | |
159 EXPECT_EQ(1, status_sample.TotalCount()); | |
160 EXPECT_EQ(1, status_sample.counts( | |
161 HttpPipeliningCompatibilityClient::SUCCESS)); | |
162 | |
163 base::Histogram::SampleSet network_sample = | |
164 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
165 EXPECT_EQ(0, network_sample.TotalCount()); | |
166 | |
167 base::Histogram::SampleSet response_sample = | |
168 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
169 EXPECT_EQ(1, response_sample.TotalCount()); | |
170 EXPECT_EQ(1, response_sample.counts(200)); | |
171 } | |
172 | |
173 TEST_F(HttpPipeliningCompatibilityClientTest, TooSmall) { | |
174 HttpPipeliningCompatibilityClient::RequestInfo info; | |
175 info.filename = "files/alphabet.txt"; | |
176 info.expected_response = "abcdefghijklmnopqrstuvwxyz26"; | |
177 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
178 requests.push_back(info); | |
179 | |
180 RunTest(requests); | |
181 | |
182 base::Histogram::SampleSet status_sample = | |
183 GetHistogramValue(0, FIELD_STATUS); | |
184 EXPECT_EQ(1, status_sample.TotalCount()); | |
185 EXPECT_EQ(1, status_sample.counts( | |
186 HttpPipeliningCompatibilityClient::TOO_SMALL)); | |
187 | |
188 base::Histogram::SampleSet network_sample = | |
189 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
190 EXPECT_EQ(0, network_sample.TotalCount()); | |
191 | |
192 base::Histogram::SampleSet response_sample = | |
193 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
194 EXPECT_EQ(1, response_sample.TotalCount()); | |
195 EXPECT_EQ(1, response_sample.counts(200)); | |
196 } | |
197 | |
198 TEST_F(HttpPipeliningCompatibilityClientTest, TooLarge) { | |
199 HttpPipeliningCompatibilityClient::RequestInfo info; | |
200 info.filename = "files/alphabet.txt"; | |
201 info.expected_response = "abc"; | |
202 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
203 requests.push_back(info); | |
204 | |
205 RunTest(requests); | |
206 | |
207 base::Histogram::SampleSet status_sample = | |
208 GetHistogramValue(0, FIELD_STATUS); | |
209 EXPECT_EQ(1, status_sample.TotalCount()); | |
210 EXPECT_EQ(1, status_sample.counts( | |
211 HttpPipeliningCompatibilityClient::TOO_LARGE)); | |
212 | |
213 base::Histogram::SampleSet network_sample = | |
214 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
215 EXPECT_EQ(0, network_sample.TotalCount()); | |
216 | |
217 base::Histogram::SampleSet response_sample = | |
218 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
219 EXPECT_EQ(1, response_sample.TotalCount()); | |
220 EXPECT_EQ(1, response_sample.counts(200)); | |
221 } | |
222 | |
223 TEST_F(HttpPipeliningCompatibilityClientTest, Mismatch) { | |
224 HttpPipeliningCompatibilityClient::RequestInfo info; | |
225 info.filename = "files/alphabet.txt"; | |
226 info.expected_response = "zyxwvutsrqponmlkjihgfedcba"; | |
227 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
228 requests.push_back(info); | |
229 | |
230 RunTest(requests); | |
231 | |
232 base::Histogram::SampleSet status_sample = | |
233 GetHistogramValue(0, FIELD_STATUS); | |
234 EXPECT_EQ(1, status_sample.TotalCount()); | |
235 EXPECT_EQ(1, status_sample.counts( | |
236 HttpPipeliningCompatibilityClient::CONTENT_MISMATCH)); | |
237 | |
238 base::Histogram::SampleSet network_sample = | |
239 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
240 EXPECT_EQ(0, network_sample.TotalCount()); | |
241 | |
242 base::Histogram::SampleSet response_sample = | |
243 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
244 EXPECT_EQ(1, response_sample.TotalCount()); | |
245 EXPECT_EQ(1, response_sample.counts(200)); | |
246 } | |
247 | |
248 TEST_F(HttpPipeliningCompatibilityClientTest, Redirect) { | |
249 HttpPipeliningCompatibilityClient::RequestInfo info; | |
250 info.filename = "server-redirect?http://foo.bar/asdf"; | |
251 info.expected_response = "shouldn't matter"; | |
252 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
253 requests.push_back(info); | |
254 | |
255 RunTest(requests); | |
256 | |
257 base::Histogram::SampleSet status_sample = | |
258 GetHistogramValue(0, FIELD_STATUS); | |
259 EXPECT_EQ(1, status_sample.TotalCount()); | |
260 EXPECT_EQ(1, status_sample.counts( | |
261 HttpPipeliningCompatibilityClient::REDIRECTED)); | |
262 | |
263 base::Histogram::SampleSet network_sample = | |
264 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
265 EXPECT_EQ(0, network_sample.TotalCount()); | |
266 | |
267 base::Histogram::SampleSet response_sample = | |
268 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
269 EXPECT_EQ(0, response_sample.TotalCount()); | |
270 } | |
271 | |
272 TEST_F(HttpPipeliningCompatibilityClientTest, AuthRequired) { | |
273 HttpPipeliningCompatibilityClient::RequestInfo info; | |
274 info.filename = "auth-basic"; | |
275 info.expected_response = "shouldn't matter"; | |
276 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
277 requests.push_back(info); | |
278 | |
279 RunTest(requests); | |
280 | |
281 base::Histogram::SampleSet status_sample = | |
282 GetHistogramValue(0, FIELD_STATUS); | |
283 EXPECT_EQ(1, status_sample.TotalCount()); | |
284 EXPECT_EQ(1, status_sample.counts( | |
285 HttpPipeliningCompatibilityClient::BAD_RESPONSE_CODE)); | |
286 | |
287 base::Histogram::SampleSet network_sample = | |
288 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
289 EXPECT_EQ(0, network_sample.TotalCount()); | |
290 | |
291 base::Histogram::SampleSet response_sample = | |
292 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
293 EXPECT_EQ(1, response_sample.TotalCount()); | |
294 EXPECT_EQ(1, response_sample.counts(401)); | |
295 } | |
296 | |
297 TEST_F(HttpPipeliningCompatibilityClientTest, NoContent) { | |
298 HttpPipeliningCompatibilityClient::RequestInfo info; | |
299 info.filename = "nocontent"; | |
300 info.expected_response = "shouldn't matter"; | |
301 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
302 requests.push_back(info); | |
303 | |
304 RunTest(requests); | |
305 | |
306 base::Histogram::SampleSet status_sample = | |
307 GetHistogramValue(0, FIELD_STATUS); | |
308 EXPECT_EQ(1, status_sample.TotalCount()); | |
309 EXPECT_EQ(1, status_sample.counts( | |
310 HttpPipeliningCompatibilityClient::BAD_RESPONSE_CODE)); | |
311 | |
312 base::Histogram::SampleSet network_sample = | |
313 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
314 EXPECT_EQ(0, network_sample.TotalCount()); | |
315 | |
316 base::Histogram::SampleSet response_sample = | |
317 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
318 EXPECT_EQ(1, response_sample.TotalCount()); | |
319 EXPECT_EQ(1, response_sample.counts(204)); | |
320 } | |
321 | |
322 TEST_F(HttpPipeliningCompatibilityClientTest, CloseSocket) { | |
323 HttpPipeliningCompatibilityClient::RequestInfo info; | |
324 info.filename = "close-socket"; | |
325 info.expected_response = "shouldn't matter"; | |
326 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
327 requests.push_back(info); | |
328 | |
329 RunTest(requests); | |
330 | |
331 base::Histogram::SampleSet status_sample = | |
332 GetHistogramValue(0, FIELD_STATUS); | |
333 EXPECT_EQ(1, status_sample.TotalCount()); | |
334 EXPECT_EQ(1, status_sample.counts( | |
335 HttpPipeliningCompatibilityClient::NETWORK_ERROR)); | |
336 | |
337 base::Histogram::SampleSet network_sample = | |
338 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
339 EXPECT_EQ(1, network_sample.TotalCount()); | |
340 EXPECT_EQ(1, network_sample.counts(-net::ERR_EMPTY_RESPONSE)); | |
341 | |
342 base::Histogram::SampleSet response_sample = | |
343 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
344 EXPECT_EQ(0, response_sample.TotalCount()); | |
345 } | |
346 | |
347 TEST_F(HttpPipeliningCompatibilityClientTest, OldHttpVersion) { | |
348 HttpPipeliningCompatibilityClient::RequestInfo info; | |
349 info.filename = "http-1.0"; | |
350 info.expected_response = "abcdefghijklmnopqrstuvwxyz"; | |
351 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
352 requests.push_back(info); | |
353 | |
354 RunTest(requests); | |
355 | |
356 base::Histogram::SampleSet status_sample = | |
357 GetHistogramValue(0, FIELD_STATUS); | |
358 EXPECT_EQ(1, status_sample.TotalCount()); | |
359 EXPECT_EQ(1, status_sample.counts( | |
360 HttpPipeliningCompatibilityClient::BAD_HTTP_VERSION)); | |
361 | |
362 base::Histogram::SampleSet network_sample = | |
363 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
364 EXPECT_EQ(0, network_sample.TotalCount()); | |
365 | |
366 base::Histogram::SampleSet response_sample = | |
367 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
368 EXPECT_EQ(1, response_sample.TotalCount()); | |
369 EXPECT_EQ(1, response_sample.counts(200)); | |
370 } | |
371 | |
372 TEST_F(HttpPipeliningCompatibilityClientTest, MultipleRequests) { | |
373 std::vector<HttpPipeliningCompatibilityClient::RequestInfo> requests; | |
374 | |
375 HttpPipeliningCompatibilityClient::RequestInfo info1; | |
376 info1.filename = "files/alphabet.txt"; | |
377 info1.expected_response = "abcdefghijklmnopqrstuvwxyz"; | |
378 requests.push_back(info1); | |
379 | |
380 HttpPipeliningCompatibilityClient::RequestInfo info2; | |
381 info2.filename = "close-socket"; | |
382 info2.expected_response = "shouldn't matter"; | |
383 requests.push_back(info2); | |
384 | |
385 HttpPipeliningCompatibilityClient::RequestInfo info3; | |
386 info3.filename = "auth-basic"; | |
387 info3.expected_response = "shouldn't matter"; | |
388 requests.push_back(info3); | |
389 | |
390 RunTest(requests); | |
391 | |
392 base::Histogram::SampleSet status_sample1 = | |
393 GetHistogramValue(0, FIELD_STATUS); | |
394 EXPECT_EQ(1, status_sample1.TotalCount()); | |
395 EXPECT_EQ(1, status_sample1.counts( | |
396 HttpPipeliningCompatibilityClient::SUCCESS)); | |
397 | |
398 base::Histogram::SampleSet network_sample1 = | |
399 GetHistogramValue(0, FIELD_NETWORK_ERROR); | |
400 EXPECT_EQ(0, network_sample1.TotalCount()); | |
401 | |
402 base::Histogram::SampleSet response_sample1 = | |
403 GetHistogramValue(0, FIELD_RESPONSE_CODE); | |
404 EXPECT_EQ(1, response_sample1.TotalCount()); | |
405 EXPECT_EQ(1, response_sample1.counts(200)); | |
406 | |
407 base::Histogram::SampleSet status_sample2 = | |
408 GetHistogramValue(1, FIELD_STATUS); | |
409 EXPECT_EQ(1, status_sample2.TotalCount()); | |
410 EXPECT_EQ(1, status_sample2.counts( | |
411 HttpPipeliningCompatibilityClient::NETWORK_ERROR)); | |
412 | |
413 base::Histogram::SampleSet network_sample2 = | |
414 GetHistogramValue(1, FIELD_NETWORK_ERROR); | |
415 EXPECT_EQ(1, network_sample2.TotalCount()); | |
416 EXPECT_EQ(1, network_sample2.counts(-net::ERR_EMPTY_RESPONSE)); | |
417 | |
418 base::Histogram::SampleSet response_sample2 = | |
419 GetHistogramValue(1, FIELD_RESPONSE_CODE); | |
420 EXPECT_EQ(0, response_sample2.TotalCount()); | |
421 | |
422 base::Histogram::SampleSet status_sample3 = | |
423 GetHistogramValue(2, FIELD_STATUS); | |
424 EXPECT_EQ(1, status_sample3.TotalCount()); | |
425 EXPECT_EQ(1, status_sample3.counts( | |
426 HttpPipeliningCompatibilityClient::BAD_RESPONSE_CODE)); | |
427 | |
428 base::Histogram::SampleSet network_sample3 = | |
429 GetHistogramValue(2, FIELD_NETWORK_ERROR); | |
430 EXPECT_EQ(0, network_sample3.TotalCount()); | |
431 | |
432 base::Histogram::SampleSet response_sample3 = | |
433 GetHistogramValue(2, FIELD_RESPONSE_CODE); | |
434 EXPECT_EQ(1, response_sample3.TotalCount()); | |
435 EXPECT_EQ(1, response_sample3.counts(401)); | |
436 } | |
437 | |
438 } // anonymous namespace | |
439 | |
440 } // namespace chrome_browser_net | |
OLD | NEW |