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/memory/scoped_ptr.h" | |
13 #include "base/metrics/histogram.h" | |
14 #include "base/metrics/histogram_samples.h" | |
15 #include "base/metrics/statistics_recorder.h" | |
16 #include "base/run_loop.h" | |
17 #include "base/stl_util.h" | |
18 #include "base/strings/stringprintf.h" | |
19 #include "content/public/browser/browser_thread.h" | |
20 #include "content/public/test/test_browser_thread_bundle.h" | |
21 #include "net/base/net_errors.h" | |
22 #include "net/base/test_completion_callback.h" | |
23 #include "net/test/spawned_test_server/spawned_test_server.h" | |
24 #include "net/url_request/url_request_context_getter.h" | |
25 #include "net/url_request/url_request_test_util.h" | |
26 #include "testing/gmock/include/gmock/gmock.h" | |
27 #include "testing/gtest/include/gtest/gtest.h" | |
28 | |
29 using base::HistogramBase; | |
30 using base::HistogramSamples; | |
31 | |
32 namespace chrome_browser_net { | |
33 | |
34 namespace { | |
35 | |
36 static const char* const kHistogramNames[] = { | |
37 "NetConnectivity.Pipeline.CanarySuccess", | |
38 "NetConnectivity.Pipeline.Depth", | |
39 "NetConnectivity.Pipeline.AllHTTP11", | |
40 "NetConnectivity.Pipeline.Success", | |
41 "NetConnectivity.Pipeline.0.NetworkError", | |
42 "NetConnectivity.Pipeline.0.ResponseCode", | |
43 "NetConnectivity.Pipeline.0.Status", | |
44 "NetConnectivity.Pipeline.1.NetworkError", | |
45 "NetConnectivity.Pipeline.1.ResponseCode", | |
46 "NetConnectivity.Pipeline.1.Status", | |
47 "NetConnectivity.Pipeline.2.NetworkError", | |
48 "NetConnectivity.Pipeline.2.ResponseCode", | |
49 "NetConnectivity.Pipeline.2.Status", | |
50 }; | |
51 | |
52 enum HistogramField { | |
53 FIELD_CANARY, | |
54 FIELD_DEPTH, | |
55 FIELD_HTTP_1_1, | |
56 FIELD_NETWORK_ERROR, | |
57 FIELD_RESPONSE_CODE, | |
58 FIELD_STATUS, | |
59 FIELD_SUCCESS, | |
60 }; | |
61 | |
62 class MockFactory : public internal::PipelineTestRequest::Factory { | |
63 public: | |
64 MOCK_METHOD6(NewRequest, internal::PipelineTestRequest*( | |
65 int, const std::string&, const RequestInfo&, | |
66 internal::PipelineTestRequest::Delegate*, net::URLRequestContext*, | |
67 internal::PipelineTestRequest::Type)); | |
68 }; | |
69 | |
70 class MockRequest : public internal::PipelineTestRequest { | |
71 public: | |
72 MOCK_METHOD0(Start, void()); | |
73 }; | |
74 | |
75 using content::BrowserThread; | |
76 using testing::_; | |
77 using testing::Field; | |
78 using testing::Invoke; | |
79 using testing::Return; | |
80 using testing::StrEq; | |
81 | |
82 class HttpPipeliningCompatibilityClientTest : public testing::Test { | |
83 public: | |
84 HttpPipeliningCompatibilityClientTest() | |
85 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), | |
86 test_server_(net::SpawnedTestServer::TYPE_HTTP, | |
87 net::SpawnedTestServer::kLocalhost, | |
88 base::FilePath(FILE_PATH_LITERAL( | |
89 "chrome/test/data/http_pipelining"))) { | |
90 } | |
91 | |
92 protected: | |
93 virtual void SetUp() OVERRIDE { | |
94 // Start up a histogram recorder. | |
95 // TODO(rtenneti): Leaks StatisticsRecorder and will update suppressions. | |
96 base::StatisticsRecorder::Initialize(); | |
97 ASSERT_TRUE(test_server_.Start()); | |
98 context_ = new net::TestURLRequestContextGetter( | |
99 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)); | |
100 context_->AddRef(); | |
101 | |
102 for (size_t i = 0; i < arraysize(kHistogramNames); ++i) { | |
103 const char* name = kHistogramNames[i]; | |
104 scoped_ptr<HistogramSamples> samples = GetHistogram(name); | |
105 if (samples.get() && samples->TotalCount() > 0) { | |
106 original_samples_[name] = samples.release(); | |
107 } | |
108 } | |
109 } | |
110 | |
111 virtual void TearDown() OVERRIDE { | |
112 BrowserThread::ReleaseSoon(BrowserThread::IO, FROM_HERE, context_); | |
113 base::RunLoop().RunUntilIdle(); | |
114 STLDeleteValues(&original_samples_); | |
115 } | |
116 | |
117 void RunTest( | |
118 std::vector<RequestInfo> requests, | |
119 HttpPipeliningCompatibilityClient::Options options) { | |
120 HttpPipeliningCompatibilityClient client(NULL); | |
121 net::TestCompletionCallback callback; | |
122 client.Start(test_server_.GetURL(std::string()).spec(), | |
123 requests, | |
124 options, | |
125 callback.callback(), | |
126 context_->GetURLRequestContext()); | |
127 callback.WaitForResult(); | |
128 } | |
129 | |
130 void ExpectHistogramCount(int expected_count, | |
131 int expected_value, | |
132 HistogramField field) { | |
133 const char* name; | |
134 | |
135 switch (field) { | |
136 case FIELD_CANARY: | |
137 name = "NetConnectivity.Pipeline.CanarySuccess"; | |
138 break; | |
139 | |
140 case FIELD_DEPTH: | |
141 name = "NetConnectivity.Pipeline.Depth"; | |
142 break; | |
143 | |
144 case FIELD_HTTP_1_1: | |
145 name = "NetConnectivity.Pipeline.AllHTTP11"; | |
146 break; | |
147 | |
148 case FIELD_SUCCESS: | |
149 name = "NetConnectivity.Pipeline.Success"; | |
150 break; | |
151 | |
152 default: | |
153 FAIL() << "Unexpected field: " << field; | |
154 } | |
155 | |
156 scoped_ptr<HistogramSamples> samples = GetHistogram(name); | |
157 if (!samples.get()) | |
158 return; | |
159 | |
160 if (ContainsKey(original_samples_, name)) { | |
161 samples->Subtract((*original_samples_[name])); | |
162 } | |
163 | |
164 EXPECT_EQ(expected_count, samples->TotalCount()) << name; | |
165 if (expected_count > 0) { | |
166 EXPECT_EQ(expected_count, samples->GetCount(expected_value)) << name; | |
167 } | |
168 } | |
169 | |
170 void ExpectRequestHistogramCount(int expected_count, | |
171 int expected_value, | |
172 int request_id, | |
173 HistogramField field) { | |
174 const char* field_str = ""; | |
175 switch (field) { | |
176 case FIELD_STATUS: | |
177 field_str = "Status"; | |
178 break; | |
179 | |
180 case FIELD_NETWORK_ERROR: | |
181 field_str = "NetworkError"; | |
182 break; | |
183 | |
184 case FIELD_RESPONSE_CODE: | |
185 field_str = "ResponseCode"; | |
186 break; | |
187 | |
188 default: | |
189 FAIL() << "Unexpected field: " << field; | |
190 } | |
191 | |
192 std::string name = base::StringPrintf("NetConnectivity.Pipeline.%d.%s", | |
193 request_id, field_str); | |
194 scoped_ptr<HistogramSamples> samples = GetHistogram(name.c_str()); | |
195 if (!samples.get()) | |
196 return; | |
197 | |
198 if (ContainsKey(original_samples_, name)) { | |
199 samples->Subtract(*(original_samples_[name])); | |
200 } | |
201 | |
202 EXPECT_EQ(expected_count, samples->TotalCount()) << name; | |
203 if (expected_count > 0) { | |
204 EXPECT_EQ(expected_count, samples->GetCount(expected_value)) << name; | |
205 } | |
206 } | |
207 | |
208 content::TestBrowserThreadBundle thread_bundle_; | |
209 net::SpawnedTestServer test_server_; | |
210 net::TestURLRequestContextGetter* context_; | |
211 | |
212 private: | |
213 scoped_ptr<HistogramSamples> GetHistogram(const char* name) { | |
214 scoped_ptr<HistogramSamples> samples; | |
215 HistogramBase* cached_histogram = NULL; | |
216 HistogramBase* current_histogram = | |
217 base::StatisticsRecorder::FindHistogram(name); | |
218 if (ContainsKey(histograms_, name)) { | |
219 cached_histogram = histograms_[name]; | |
220 } | |
221 | |
222 // This is to work around the CACHE_HISTOGRAM_* macros caching the last used | |
223 // histogram by name. So, even though we throw out the StatisticsRecorder | |
224 // between tests, the CACHE_HISTOGRAM_* might still write into the old | |
225 // Histogram if it has the same name as the last run. We keep a cache of the | |
226 // last used Histogram and then update the cache if it's different than the | |
227 // current Histogram. | |
228 if (cached_histogram && current_histogram) { | |
229 samples = cached_histogram->SnapshotSamples(); | |
230 if (cached_histogram != current_histogram) { | |
231 samples->Add(*(current_histogram->SnapshotSamples())); | |
232 histograms_[name] = current_histogram; | |
233 } | |
234 } else if (current_histogram) { | |
235 samples = current_histogram->SnapshotSamples(); | |
236 histograms_[name] = current_histogram; | |
237 } else if (cached_histogram) { | |
238 samples = cached_histogram->SnapshotSamples(); | |
239 } | |
240 return samples.Pass(); | |
241 } | |
242 | |
243 static std::map<std::string, HistogramBase*> histograms_; | |
244 std::map<std::string, HistogramSamples*> original_samples_; | |
245 }; | |
246 | |
247 // static | |
248 std::map<std::string, HistogramBase*> | |
249 HttpPipeliningCompatibilityClientTest::histograms_; | |
250 | |
251 TEST_F(HttpPipeliningCompatibilityClientTest, Success) { | |
252 RequestInfo info; | |
253 info.filename = "files/alphabet.txt"; | |
254 info.expected_response = "abcdefghijklmnopqrstuvwxyz"; | |
255 std::vector<RequestInfo> requests; | |
256 requests.push_back(info); | |
257 | |
258 RunTest(requests, HttpPipeliningCompatibilityClient::PIPE_TEST_DEFAULTS); | |
259 | |
260 ExpectHistogramCount(1, true, FIELD_SUCCESS); | |
261 ExpectHistogramCount(0, 0, FIELD_DEPTH); | |
262 ExpectHistogramCount(0, 0, FIELD_HTTP_1_1); | |
263 ExpectRequestHistogramCount( | |
264 1, internal::PipelineTestRequest::STATUS_SUCCESS, 0, FIELD_STATUS); | |
265 ExpectRequestHistogramCount(0, 0, 0, FIELD_NETWORK_ERROR); | |
266 ExpectRequestHistogramCount(1, 200, 0, FIELD_RESPONSE_CODE); | |
267 } | |
268 | |
269 TEST_F(HttpPipeliningCompatibilityClientTest, TooSmall) { | |
270 RequestInfo info; | |
271 info.filename = "files/alphabet.txt"; | |
272 info.expected_response = "abcdefghijklmnopqrstuvwxyz26"; | |
273 std::vector<RequestInfo> requests; | |
274 requests.push_back(info); | |
275 | |
276 RunTest(requests, HttpPipeliningCompatibilityClient::PIPE_TEST_DEFAULTS); | |
277 | |
278 ExpectHistogramCount(1, false, FIELD_SUCCESS); | |
279 ExpectRequestHistogramCount( | |
280 1, internal::PipelineTestRequest::STATUS_TOO_SMALL, 0, FIELD_STATUS); | |
281 ExpectRequestHistogramCount(0, 0, 0, FIELD_NETWORK_ERROR); | |
282 ExpectRequestHistogramCount(1, 200, 0, FIELD_RESPONSE_CODE); | |
283 } | |
284 | |
285 TEST_F(HttpPipeliningCompatibilityClientTest, TooLarge) { | |
286 RequestInfo info; | |
287 info.filename = "files/alphabet.txt"; | |
288 info.expected_response = "abc"; | |
289 std::vector<RequestInfo> requests; | |
290 requests.push_back(info); | |
291 | |
292 RunTest(requests, HttpPipeliningCompatibilityClient::PIPE_TEST_DEFAULTS); | |
293 | |
294 ExpectHistogramCount(1, false, FIELD_SUCCESS); | |
295 ExpectRequestHistogramCount( | |
296 1, internal::PipelineTestRequest::STATUS_TOO_LARGE, 0, FIELD_STATUS); | |
297 ExpectRequestHistogramCount(0, 0, 0, FIELD_NETWORK_ERROR); | |
298 ExpectRequestHistogramCount(1, 200, 0, FIELD_RESPONSE_CODE); | |
299 } | |
300 | |
301 TEST_F(HttpPipeliningCompatibilityClientTest, Mismatch) { | |
302 RequestInfo info; | |
303 info.filename = "files/alphabet.txt"; | |
304 info.expected_response = "zyxwvutsrqponmlkjihgfedcba"; | |
305 std::vector<RequestInfo> requests; | |
306 requests.push_back(info); | |
307 | |
308 RunTest(requests, HttpPipeliningCompatibilityClient::PIPE_TEST_DEFAULTS); | |
309 | |
310 ExpectHistogramCount(1, false, FIELD_SUCCESS); | |
311 ExpectRequestHistogramCount( | |
312 1, internal::PipelineTestRequest::STATUS_CONTENT_MISMATCH, | |
313 0, FIELD_STATUS); | |
314 ExpectRequestHistogramCount(0, 0, 0, FIELD_NETWORK_ERROR); | |
315 ExpectRequestHistogramCount(1, 200, 0, FIELD_RESPONSE_CODE); | |
316 } | |
317 | |
318 TEST_F(HttpPipeliningCompatibilityClientTest, Redirect) { | |
319 RequestInfo info; | |
320 info.filename = "server-redirect?http://foo.bar/asdf"; | |
321 info.expected_response = "shouldn't matter"; | |
322 std::vector<RequestInfo> requests; | |
323 requests.push_back(info); | |
324 | |
325 RunTest(requests, HttpPipeliningCompatibilityClient::PIPE_TEST_DEFAULTS); | |
326 | |
327 ExpectHistogramCount(1, false, FIELD_SUCCESS); | |
328 ExpectRequestHistogramCount( | |
329 1, internal::PipelineTestRequest::STATUS_REDIRECTED, 0, FIELD_STATUS); | |
330 ExpectRequestHistogramCount(0, 0, 0, FIELD_NETWORK_ERROR); | |
331 ExpectRequestHistogramCount(0, 0, 0, FIELD_RESPONSE_CODE); | |
332 } | |
333 | |
334 TEST_F(HttpPipeliningCompatibilityClientTest, AuthRequired) { | |
335 RequestInfo info; | |
336 info.filename = "auth-basic"; | |
337 info.expected_response = "shouldn't matter"; | |
338 std::vector<RequestInfo> requests; | |
339 requests.push_back(info); | |
340 | |
341 RunTest(requests, HttpPipeliningCompatibilityClient::PIPE_TEST_DEFAULTS); | |
342 | |
343 ExpectHistogramCount(1, false, FIELD_SUCCESS); | |
344 ExpectRequestHistogramCount( | |
345 1, internal::PipelineTestRequest::STATUS_BAD_RESPONSE_CODE, | |
346 0, FIELD_STATUS); | |
347 ExpectRequestHistogramCount(0, 0, 0, FIELD_NETWORK_ERROR); | |
348 ExpectRequestHistogramCount(1, 401, 0, FIELD_RESPONSE_CODE); | |
349 } | |
350 | |
351 TEST_F(HttpPipeliningCompatibilityClientTest, NoContent) { | |
352 RequestInfo info; | |
353 info.filename = "nocontent"; | |
354 info.expected_response = "shouldn't matter"; | |
355 std::vector<RequestInfo> requests; | |
356 requests.push_back(info); | |
357 | |
358 RunTest(requests, HttpPipeliningCompatibilityClient::PIPE_TEST_DEFAULTS); | |
359 | |
360 ExpectHistogramCount(1, false, FIELD_SUCCESS); | |
361 ExpectRequestHistogramCount( | |
362 1, internal::PipelineTestRequest::STATUS_BAD_RESPONSE_CODE, | |
363 0, FIELD_STATUS); | |
364 ExpectRequestHistogramCount(0, 0, 0, FIELD_NETWORK_ERROR); | |
365 ExpectRequestHistogramCount(1, 204, 0, FIELD_RESPONSE_CODE); | |
366 } | |
367 | |
368 TEST_F(HttpPipeliningCompatibilityClientTest, CloseSocket) { | |
369 RequestInfo info; | |
370 info.filename = "close-socket"; | |
371 info.expected_response = "shouldn't matter"; | |
372 std::vector<RequestInfo> requests; | |
373 requests.push_back(info); | |
374 | |
375 RunTest(requests, HttpPipeliningCompatibilityClient::PIPE_TEST_DEFAULTS); | |
376 | |
377 ExpectHistogramCount(1, false, FIELD_SUCCESS); | |
378 ExpectRequestHistogramCount( | |
379 1, internal::PipelineTestRequest::STATUS_NETWORK_ERROR, 0, FIELD_STATUS); | |
380 ExpectRequestHistogramCount( | |
381 1, -net::ERR_EMPTY_RESPONSE, 0, FIELD_NETWORK_ERROR); | |
382 ExpectRequestHistogramCount(0, 0, 0, FIELD_RESPONSE_CODE); | |
383 } | |
384 | |
385 TEST_F(HttpPipeliningCompatibilityClientTest, OldHttpVersion) { | |
386 RequestInfo info; | |
387 info.filename = "http-1.0"; | |
388 info.expected_response = "abcdefghijklmnopqrstuvwxyz"; | |
389 std::vector<RequestInfo> requests; | |
390 requests.push_back(info); | |
391 | |
392 RunTest(requests, HttpPipeliningCompatibilityClient::PIPE_TEST_DEFAULTS); | |
393 | |
394 ExpectHistogramCount(1, false, FIELD_SUCCESS); | |
395 ExpectRequestHistogramCount( | |
396 1, internal::PipelineTestRequest::STATUS_BAD_HTTP_VERSION, | |
397 0, FIELD_STATUS); | |
398 ExpectRequestHistogramCount(0, 0, 0, FIELD_NETWORK_ERROR); | |
399 ExpectRequestHistogramCount(1, 200, 0, FIELD_RESPONSE_CODE); | |
400 } | |
401 | |
402 #if defined(OS_CHROMEOS) | |
403 // http://crbug.com/147903: test fails on ChromeOS | |
404 #define MAYBE_MultipleRequests DISABLED_MultipleRequests | |
405 #else | |
406 #define MAYBE_MultipleRequests MultipleRequests | |
407 #endif | |
408 TEST_F(HttpPipeliningCompatibilityClientTest, MAYBE_MultipleRequests) { | |
409 std::vector<RequestInfo> requests; | |
410 | |
411 RequestInfo info1; | |
412 info1.filename = "files/alphabet.txt"; | |
413 info1.expected_response = "abcdefghijklmnopqrstuvwxyz"; | |
414 requests.push_back(info1); | |
415 | |
416 RequestInfo info2; | |
417 info2.filename = "close-socket"; | |
418 info2.expected_response = "shouldn't matter"; | |
419 requests.push_back(info2); | |
420 | |
421 RequestInfo info3; | |
422 info3.filename = "auth-basic"; | |
423 info3.expected_response = "shouldn't matter"; | |
424 requests.push_back(info3); | |
425 | |
426 RunTest(requests, | |
427 HttpPipeliningCompatibilityClient::PIPE_TEST_COLLECT_SERVER_STATS); | |
428 | |
429 ExpectHistogramCount(1, false, FIELD_SUCCESS); | |
430 | |
431 ExpectRequestHistogramCount( | |
432 1, internal::PipelineTestRequest::STATUS_SUCCESS, 0, FIELD_STATUS); | |
433 ExpectRequestHistogramCount(0, 0, 0, FIELD_NETWORK_ERROR); | |
434 ExpectRequestHistogramCount(1, 200, 0, FIELD_RESPONSE_CODE); | |
435 | |
436 ExpectRequestHistogramCount( | |
437 1, internal::PipelineTestRequest::STATUS_NETWORK_ERROR, 1, FIELD_STATUS); | |
438 ExpectRequestHistogramCount( | |
439 1, -net::ERR_PIPELINE_EVICTION, 1, FIELD_NETWORK_ERROR); | |
440 ExpectRequestHistogramCount(0, 0, 1, FIELD_RESPONSE_CODE); | |
441 | |
442 ExpectRequestHistogramCount( | |
443 1, internal::PipelineTestRequest::STATUS_NETWORK_ERROR, 2, FIELD_STATUS); | |
444 ExpectRequestHistogramCount( | |
445 1, -net::ERR_PIPELINE_EVICTION, 2, FIELD_NETWORK_ERROR); | |
446 ExpectRequestHistogramCount(0, 0, 2, FIELD_RESPONSE_CODE); | |
447 | |
448 ExpectRequestHistogramCount( | |
449 1, internal::PipelineTestRequest::STATUS_NETWORK_ERROR, 3, FIELD_STATUS); | |
450 ExpectRequestHistogramCount( | |
451 1, -net::ERR_PIPELINE_EVICTION, 3, FIELD_NETWORK_ERROR); | |
452 ExpectRequestHistogramCount(0, 0, 3, FIELD_RESPONSE_CODE); | |
453 } | |
454 | |
455 TEST_F(HttpPipeliningCompatibilityClientTest, StatsOk) { | |
456 EXPECT_EQ(internal::PipelineTestRequest::STATUS_SUCCESS, | |
457 internal::ProcessStatsResponse( | |
458 "max_pipeline_depth:3,were_all_requests_http_1_1:0")); | |
459 ExpectHistogramCount(1, 3, FIELD_DEPTH); | |
460 ExpectHistogramCount(1, 0, FIELD_HTTP_1_1); | |
461 } | |
462 | |
463 TEST_F(HttpPipeliningCompatibilityClientTest, StatsIndifferentToOrder) { | |
464 EXPECT_EQ(internal::PipelineTestRequest::STATUS_SUCCESS, | |
465 internal::ProcessStatsResponse( | |
466 "were_all_requests_http_1_1:1,max_pipeline_depth:2")); | |
467 ExpectHistogramCount(1, 2, FIELD_DEPTH); | |
468 ExpectHistogramCount(1, 1, FIELD_HTTP_1_1); | |
469 } | |
470 | |
471 #if defined(OS_CHROMEOS) | |
472 // http://crbug.com/147903: test fails on ChromeOS | |
473 #define MAYBE_StatsBadField DISABLED_StatsBadField | |
474 #else | |
475 #define MAYBE_StatsBadField StatsBadField | |
476 #endif | |
477 TEST_F(HttpPipeliningCompatibilityClientTest, MAYBE_StatsBadField) { | |
478 EXPECT_EQ(internal::PipelineTestRequest::STATUS_CORRUPT_STATS, | |
479 internal::ProcessStatsResponse( | |
480 "foo:3,were_all_requests_http_1_1:1")); | |
481 ExpectHistogramCount(0, 0, FIELD_DEPTH); | |
482 ExpectHistogramCount(0, 0, FIELD_HTTP_1_1); | |
483 } | |
484 | |
485 TEST_F(HttpPipeliningCompatibilityClientTest, StatsTooShort) { | |
486 EXPECT_EQ(internal::PipelineTestRequest::STATUS_CORRUPT_STATS, | |
487 internal::ProcessStatsResponse("were_all_requests_http_1_1:1")); | |
488 ExpectHistogramCount(0, 0, FIELD_DEPTH); | |
489 ExpectHistogramCount(0, 0, FIELD_HTTP_1_1); | |
490 } | |
491 | |
492 TEST_F(HttpPipeliningCompatibilityClientTest, WaitForCanary) { | |
493 MockFactory* factory = new MockFactory; | |
494 HttpPipeliningCompatibilityClient client(factory); | |
495 | |
496 MockRequest* request = new MockRequest; | |
497 base::Closure request_cb = base::Bind( | |
498 &internal::PipelineTestRequest::Delegate::OnRequestFinished, | |
499 base::Unretained(&client), 0, | |
500 internal::PipelineTestRequest::STATUS_SUCCESS); | |
501 | |
502 MockRequest* canary = new MockRequest; | |
503 base::Closure canary_cb = base::Bind( | |
504 &internal::PipelineTestRequest::Delegate::OnCanaryFinished, | |
505 base::Unretained(&client), internal::PipelineTestRequest::STATUS_SUCCESS); | |
506 | |
507 EXPECT_CALL(*factory, NewRequest( | |
508 0, _, Field(&RequestInfo::filename, StrEq("request.txt")), _, _, | |
509 internal::PipelineTestRequest::TYPE_PIPELINED)) | |
510 .Times(1) | |
511 .WillOnce(Return(request)); | |
512 EXPECT_CALL(*factory, NewRequest( | |
513 999, _, Field(&RequestInfo::filename, StrEq("index.html")), _, _, | |
514 internal::PipelineTestRequest::TYPE_CANARY)) | |
515 .Times(1) | |
516 .WillOnce(Return(canary)); | |
517 | |
518 EXPECT_CALL(*canary, Start()) | |
519 .Times(1) | |
520 .WillOnce(Invoke(&canary_cb, &base::Closure::Run)); | |
521 EXPECT_CALL(*request, Start()) | |
522 .Times(1) | |
523 .WillOnce(Invoke(&request_cb, &base::Closure::Run)); | |
524 | |
525 std::vector<RequestInfo> requests; | |
526 | |
527 RequestInfo info1; | |
528 info1.filename = "request.txt"; | |
529 requests.push_back(info1); | |
530 | |
531 net::TestCompletionCallback callback; | |
532 client.Start("http://base/", requests, | |
533 HttpPipeliningCompatibilityClient::PIPE_TEST_RUN_CANARY_REQUEST, | |
534 callback.callback(), context_->GetURLRequestContext()); | |
535 callback.WaitForResult(); | |
536 | |
537 ExpectHistogramCount(1, true, FIELD_CANARY); | |
538 ExpectHistogramCount(1, true, FIELD_SUCCESS); | |
539 ExpectRequestHistogramCount( | |
540 1, internal::PipelineTestRequest::STATUS_SUCCESS, 0, FIELD_STATUS); | |
541 } | |
542 | |
543 #if defined(OS_CHROMEOS) | |
544 // http://crbug.com/147903: test fails on ChromeOS | |
545 #define MAYBE_CanaryFailure DISABLED_CanaryFailure | |
546 #else | |
547 #define MAYBE_CanaryFailure CanaryFailure | |
548 #endif | |
549 TEST_F(HttpPipeliningCompatibilityClientTest, MAYBE_CanaryFailure) { | |
550 MockFactory* factory = new MockFactory; | |
551 HttpPipeliningCompatibilityClient client(factory); | |
552 | |
553 MockRequest* request = new MockRequest; | |
554 | |
555 MockRequest* canary = new MockRequest; | |
556 base::Closure canary_cb = base::Bind( | |
557 &internal::PipelineTestRequest::Delegate::OnCanaryFinished, | |
558 base::Unretained(&client), | |
559 internal::PipelineTestRequest::STATUS_REDIRECTED); | |
560 | |
561 EXPECT_CALL(*factory, NewRequest( | |
562 0, _, Field(&RequestInfo::filename, StrEq("request.txt")), _, _, | |
563 internal::PipelineTestRequest::TYPE_PIPELINED)) | |
564 .Times(1) | |
565 .WillOnce(Return(request)); | |
566 EXPECT_CALL(*factory, NewRequest( | |
567 999, _, Field(&RequestInfo::filename, StrEq("index.html")), _, _, | |
568 internal::PipelineTestRequest::TYPE_CANARY)) | |
569 .Times(1) | |
570 .WillOnce(Return(canary)); | |
571 | |
572 EXPECT_CALL(*canary, Start()) | |
573 .Times(1) | |
574 .WillOnce(Invoke(&canary_cb, &base::Closure::Run)); | |
575 EXPECT_CALL(*request, Start()) | |
576 .Times(0); | |
577 | |
578 std::vector<RequestInfo> requests; | |
579 | |
580 RequestInfo info1; | |
581 info1.filename = "request.txt"; | |
582 requests.push_back(info1); | |
583 | |
584 net::TestCompletionCallback callback; | |
585 client.Start("http://base/", requests, | |
586 HttpPipeliningCompatibilityClient::PIPE_TEST_RUN_CANARY_REQUEST, | |
587 callback.callback(), context_->GetURLRequestContext()); | |
588 callback.WaitForResult(); | |
589 | |
590 ExpectHistogramCount(1, false, FIELD_CANARY); | |
591 ExpectHistogramCount(0, false, FIELD_SUCCESS); | |
592 ExpectHistogramCount(0, true, FIELD_SUCCESS); | |
593 } | |
594 | |
595 } // anonymous namespace | |
596 | |
597 } // namespace chrome_browser_net | |
OLD | NEW |