OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 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 "net/http/http_pipelined_connection_impl.h" | |
6 | |
7 #include <string> | |
8 | |
9 #include "base/memory/ref_counted.h" | |
10 #include "base/memory/scoped_vector.h" | |
11 #include "net/base/io_buffer.h" | |
12 #include "net/base/net_errors.h" | |
13 #include "net/base/request_priority.h" | |
14 #include "net/http/http_pipelined_stream.h" | |
15 #include "net/socket/client_socket_handle.h" | |
16 #include "net/socket/client_socket_pool_histograms.h" | |
17 #include "net/socket/socket_test_util.h" | |
18 #include "testing/gmock/include/gmock/gmock.h" | |
19 #include "testing/gtest/include/gtest/gtest.h" | |
20 | |
21 using testing::NiceMock; | |
22 using testing::StrEq; | |
23 | |
24 namespace net { | |
25 | |
26 class DummySocketParams : public base::RefCounted<DummySocketParams> { | |
27 private: | |
28 friend class base::RefCounted<DummySocketParams>; | |
29 }; | |
30 | |
31 REGISTER_SOCKET_PARAMS_FOR_POOL(MockTransportClientSocketPool, | |
32 DummySocketParams); | |
33 | |
34 class MockPipelineDelegate : public HttpPipelinedConnectionImpl::Delegate { | |
35 public: | |
36 MOCK_METHOD1(OnPipelineHasCapacity, void(HttpPipelinedConnection* pipeline)); | |
37 }; | |
38 | |
39 class SuddenCloseObserver : public MessageLoop::TaskObserver { | |
40 public: | |
41 SuddenCloseObserver(HttpStream* stream, int close_before_task) | |
42 : stream_(stream), | |
43 close_before_task_(close_before_task), | |
44 current_task_(0) { } | |
45 | |
46 virtual void WillProcessTask(base::TimeTicks) OVERRIDE { | |
47 ++current_task_; | |
48 if (current_task_ == close_before_task_) { | |
49 stream_->Close(false); | |
50 MessageLoop::current()->RemoveTaskObserver(this); | |
51 } | |
52 } | |
53 | |
54 virtual void DidProcessTask(base::TimeTicks) OVERRIDE { } | |
55 | |
56 private: | |
57 HttpStream* stream_; | |
58 int close_before_task_; | |
59 int current_task_; | |
60 }; | |
61 | |
62 class HttpPipelinedConnectionImplTest : public testing::Test { | |
63 public: | |
64 HttpPipelinedConnectionImplTest() | |
65 : histograms_("a"), | |
66 pool_(1, 1, &histograms_, &factory_) { | |
67 } | |
68 | |
69 void TearDown() { | |
70 MessageLoop::current()->RunAllPending(); | |
71 } | |
72 | |
73 void Initialize(MockRead* reads, size_t reads_count, | |
74 MockWrite* writes, size_t writes_count) { | |
75 data_ = new DeterministicSocketData(reads, reads_count, | |
76 writes, writes_count); | |
77 data_->set_connect_data(MockConnect(false, 0)); | |
78 if (reads_count || writes_count) { | |
79 data_->StopAfter(reads_count + writes_count); | |
80 } | |
81 factory_.AddSocketDataProvider(data_.get()); | |
82 scoped_refptr<DummySocketParams> params; | |
83 ClientSocketHandle* connection = new ClientSocketHandle; | |
84 connection->Init("a", params, MEDIUM, NULL, &pool_, BoundNetLog()); | |
85 pipeline_.reset(new HttpPipelinedConnectionImpl(connection, &delegate_, | |
86 ssl_config_, proxy_info_, | |
87 BoundNetLog(), false)); | |
88 } | |
89 | |
90 HttpRequestInfo* GetRequestInfo(const std::string& filename) { | |
91 HttpRequestInfo* request_info = new HttpRequestInfo; | |
92 request_info->url = GURL("http://localhost/" + filename); | |
93 request_info->method = "GET"; | |
94 request_info_vector_.push_back(request_info); | |
95 return request_info; | |
96 } | |
97 | |
98 HttpStream* NewTestStream(const std::string& filename) { | |
99 HttpStream* stream = pipeline_->CreateNewStream(); | |
100 HttpRequestInfo* request_info = GetRequestInfo(filename); | |
101 int rv = stream->InitializeStream(request_info, BoundNetLog(), NULL); | |
102 DCHECK_EQ(OK, rv); | |
103 return stream; | |
104 } | |
105 | |
106 void ExpectResponse(const std::string& expected, | |
107 scoped_ptr<HttpStream>& stream, bool async) { | |
108 scoped_refptr<IOBuffer> buffer(new IOBuffer(expected.size())); | |
109 | |
110 if (async) { | |
111 EXPECT_EQ(ERR_IO_PENDING, | |
112 stream->ReadResponseBody(buffer.get(), expected.size(), | |
113 &callback_)); | |
114 data_->RunFor(1); | |
115 EXPECT_EQ(static_cast<int>(expected.size()), callback_.WaitForResult()); | |
116 } else { | |
117 EXPECT_EQ(static_cast<int>(expected.size()), | |
118 stream->ReadResponseBody(buffer.get(), expected.size(), | |
119 &callback_)); | |
120 } | |
121 std::string actual(buffer->data(), expected.size()); | |
122 EXPECT_THAT(actual, StrEq(expected)); | |
123 } | |
124 | |
125 void TestSyncRequest(scoped_ptr<HttpStream>& stream, | |
126 const std::string& filename) { | |
127 HttpRequestHeaders headers; | |
128 HttpResponseInfo response; | |
129 EXPECT_EQ(OK, stream->SendRequest(headers, NULL, &response, &callback_)); | |
130 EXPECT_EQ(OK, stream->ReadResponseHeaders(&callback_)); | |
131 ExpectResponse(filename, stream, false); | |
132 | |
133 stream->Close(false); | |
134 } | |
135 | |
136 DeterministicMockClientSocketFactory factory_; | |
137 ClientSocketPoolHistograms histograms_; | |
138 MockTransportClientSocketPool pool_; | |
139 scoped_refptr<DeterministicSocketData> data_; | |
140 | |
141 SSLConfig ssl_config_; | |
142 ProxyInfo proxy_info_; | |
143 NiceMock<MockPipelineDelegate> delegate_; | |
144 TestOldCompletionCallback callback_; | |
145 scoped_ptr<HttpPipelinedConnectionImpl> pipeline_; | |
146 ScopedVector<HttpRequestInfo> request_info_vector_; | |
147 }; | |
148 | |
149 TEST_F(HttpPipelinedConnectionImplTest, PipelineNotUsed) { | |
150 Initialize(NULL, 0, NULL, 0); | |
151 } | |
152 | |
153 TEST_F(HttpPipelinedConnectionImplTest, StreamNotUsed) { | |
154 Initialize(NULL, 0, NULL, 0); | |
155 | |
156 scoped_ptr<HttpStream> stream(pipeline_->CreateNewStream()); | |
157 | |
158 stream->Close(false); | |
159 } | |
160 | |
161 TEST_F(HttpPipelinedConnectionImplTest, StreamBoundButNotUsed) { | |
162 Initialize(NULL, 0, NULL, 0); | |
163 | |
164 scoped_ptr<HttpStream> stream(NewTestStream("ok.html")); | |
165 | |
166 stream->Close(false); | |
167 } | |
168 | |
169 TEST_F(HttpPipelinedConnectionImplTest, SyncSingleRequest) { | |
170 MockWrite writes[] = { | |
171 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
172 }; | |
173 MockRead reads[] = { | |
174 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
175 MockRead(false, 2, "Content-Length: 7\r\n\r\n"), | |
176 MockRead(false, 3, "ok.html"), | |
177 }; | |
178 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
179 | |
180 scoped_ptr<HttpStream> stream(NewTestStream("ok.html")); | |
181 TestSyncRequest(stream, "ok.html"); | |
182 } | |
183 | |
184 TEST_F(HttpPipelinedConnectionImplTest, AsyncSingleRequest) { | |
185 MockWrite writes[] = { | |
186 MockWrite(true, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
187 }; | |
188 MockRead reads[] = { | |
189 MockRead(true, 1, "HTTP/1.1 200 OK\r\n"), | |
190 MockRead(true, 2, "Content-Length: 7\r\n\r\n"), | |
191 MockRead(true, 3, "ok.html"), | |
192 }; | |
193 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
194 | |
195 scoped_ptr<HttpStream> stream(NewTestStream("ok.html")); | |
196 | |
197 HttpRequestHeaders headers; | |
198 HttpResponseInfo response; | |
199 EXPECT_EQ(ERR_IO_PENDING, | |
200 stream->SendRequest(headers, NULL, &response, &callback_)); | |
201 data_->RunFor(1); | |
202 EXPECT_LE(OK, callback_.WaitForResult()); | |
203 | |
204 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(&callback_)); | |
205 data_->RunFor(2); | |
206 EXPECT_LE(OK, callback_.WaitForResult()); | |
207 | |
208 ExpectResponse("ok.html", stream, true); | |
209 | |
210 stream->Close(false); | |
211 } | |
212 | |
213 TEST_F(HttpPipelinedConnectionImplTest, LockStepAsyncRequests) { | |
214 MockWrite writes[] = { | |
215 MockWrite(true, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
216 MockWrite(true, 1, "GET /ko.html HTTP/1.1\r\n\r\n"), | |
217 }; | |
218 MockRead reads[] = { | |
219 MockRead(true, 2, "HTTP/1.1 200 OK\r\n"), | |
220 MockRead(true, 3, "Content-Length: 7\r\n\r\n"), | |
221 MockRead(true, 4, "ok.html"), | |
222 MockRead(true, 5, "HTTP/1.1 200 OK\r\n"), | |
223 MockRead(true, 6, "Content-Length: 7\r\n\r\n"), | |
224 MockRead(true, 7, "ko.html"), | |
225 }; | |
226 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
227 | |
228 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html")); | |
229 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html")); | |
230 | |
231 HttpRequestHeaders headers1; | |
232 HttpResponseInfo response1; | |
233 EXPECT_EQ(ERR_IO_PENDING, | |
234 stream1->SendRequest(headers1, NULL, &response1, &callback_)); | |
235 | |
236 HttpRequestHeaders headers2; | |
237 HttpResponseInfo response2; | |
238 EXPECT_EQ(ERR_IO_PENDING, | |
239 stream2->SendRequest(headers2, NULL, &response2, &callback_)); | |
240 | |
241 data_->RunFor(1); | |
242 EXPECT_LE(OK, callback_.WaitForResult()); | |
243 data_->RunFor(1); | |
244 EXPECT_LE(OK, callback_.WaitForResult()); | |
245 | |
246 EXPECT_EQ(ERR_IO_PENDING, stream1->ReadResponseHeaders(&callback_)); | |
247 EXPECT_EQ(ERR_IO_PENDING, stream2->ReadResponseHeaders(&callback_)); | |
248 | |
249 data_->RunFor(2); | |
250 EXPECT_LE(OK, callback_.WaitForResult()); | |
251 | |
252 ExpectResponse("ok.html", stream1, true); | |
253 | |
254 stream1->Close(false); | |
255 | |
256 data_->RunFor(2); | |
257 EXPECT_LE(OK, callback_.WaitForResult()); | |
258 | |
259 ExpectResponse("ko.html", stream2, true); | |
260 | |
261 stream2->Close(false); | |
262 } | |
263 | |
264 TEST_F(HttpPipelinedConnectionImplTest, TwoResponsesInOnePacket) { | |
265 MockWrite writes[] = { | |
266 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
267 MockWrite(false, 1, "GET /ko.html HTTP/1.1\r\n\r\n"), | |
268 }; | |
269 MockRead reads[] = { | |
270 MockRead(false, 2, | |
271 "HTTP/1.1 200 OK\r\n" | |
272 "Content-Length: 7\r\n\r\n" | |
273 "ok.html" | |
274 "HTTP/1.1 200 OK\r\n" | |
275 "Content-Length: 7\r\n\r\n" | |
276 "ko.html"), | |
277 }; | |
278 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
279 | |
280 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html")); | |
281 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html")); | |
282 | |
283 HttpRequestHeaders headers1; | |
284 HttpResponseInfo response1; | |
285 EXPECT_EQ(OK, stream1->SendRequest(headers1, NULL, &response1, &callback_)); | |
286 HttpRequestHeaders headers2; | |
287 HttpResponseInfo response2; | |
288 EXPECT_EQ(OK, stream2->SendRequest(headers2, NULL, &response2, &callback_)); | |
289 | |
290 EXPECT_EQ(OK, stream1->ReadResponseHeaders(&callback_)); | |
291 ExpectResponse("ok.html", stream1, false); | |
292 stream1->Close(false); | |
293 | |
294 EXPECT_EQ(OK, stream2->ReadResponseHeaders(&callback_)); | |
295 ExpectResponse("ko.html", stream2, false); | |
296 stream2->Close(false); | |
297 } | |
298 | |
299 TEST_F(HttpPipelinedConnectionImplTest, SendOrderSwapped) { | |
300 MockWrite writes[] = { | |
301 MockWrite(false, 0, "GET /ko.html HTTP/1.1\r\n\r\n"), | |
302 MockWrite(false, 4, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
303 }; | |
304 MockRead reads[] = { | |
305 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
306 MockRead(false, 2, "Content-Length: 7\r\n\r\n"), | |
307 MockRead(false, 3, "ko.html"), | |
308 MockRead(false, 5, "HTTP/1.1 200 OK\r\n"), | |
309 MockRead(false, 6, "Content-Length: 7\r\n\r\n"), | |
310 MockRead(false, 7, "ok.html"), | |
311 }; | |
312 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
313 | |
314 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html")); | |
315 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html")); | |
316 | |
317 TestSyncRequest(stream2, "ko.html"); | |
318 TestSyncRequest(stream1, "ok.html"); | |
319 } | |
320 | |
321 TEST_F(HttpPipelinedConnectionImplTest, ReadOrderSwapped) { | |
322 MockWrite writes[] = { | |
323 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
324 MockWrite(false, 1, "GET /ko.html HTTP/1.1\r\n\r\n"), | |
325 }; | |
326 MockRead reads[] = { | |
327 MockRead(false, 2, "HTTP/1.1 200 OK\r\n"), | |
328 MockRead(false, 3, "Content-Length: 7\r\n\r\n"), | |
329 MockRead(false, 4, "ok.html"), | |
330 MockRead(false, 5, "HTTP/1.1 200 OK\r\n"), | |
331 MockRead(false, 6, "Content-Length: 7\r\n\r\n"), | |
332 MockRead(false, 7, "ko.html"), | |
333 }; | |
334 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
335 | |
336 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html")); | |
337 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html")); | |
338 | |
339 HttpRequestHeaders headers1; | |
340 HttpResponseInfo response1; | |
341 EXPECT_EQ(OK, stream1->SendRequest(headers1, NULL, &response1, &callback_)); | |
342 | |
343 HttpRequestHeaders headers2; | |
344 HttpResponseInfo response2; | |
345 EXPECT_EQ(OK, stream2->SendRequest(headers2, NULL, &response2, &callback_)); | |
346 | |
347 EXPECT_EQ(ERR_IO_PENDING, stream2->ReadResponseHeaders(&callback_)); | |
348 | |
349 EXPECT_EQ(OK, stream1->ReadResponseHeaders(&callback_)); | |
350 ExpectResponse("ok.html", stream1, false); | |
351 | |
352 stream1->Close(false); | |
353 | |
354 EXPECT_LE(OK, callback_.WaitForResult()); | |
355 ExpectResponse("ko.html", stream2, false); | |
356 | |
357 stream2->Close(false); | |
358 } | |
359 | |
360 TEST_F(HttpPipelinedConnectionImplTest, SendWhileReading) { | |
361 MockWrite writes[] = { | |
362 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
363 MockWrite(false, 3, "GET /ko.html HTTP/1.1\r\n\r\n"), | |
364 }; | |
365 MockRead reads[] = { | |
366 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
367 MockRead(false, 2, "Content-Length: 7\r\n\r\n"), | |
368 MockRead(false, 4, "ok.html"), | |
369 MockRead(false, 5, "HTTP/1.1 200 OK\r\n"), | |
370 MockRead(false, 6, "Content-Length: 7\r\n\r\n"), | |
371 MockRead(false, 7, "ko.html"), | |
372 }; | |
373 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
374 | |
375 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html")); | |
376 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html")); | |
377 | |
378 HttpRequestHeaders headers1; | |
379 HttpResponseInfo response1; | |
380 EXPECT_EQ(OK, stream1->SendRequest(headers1, NULL, &response1, &callback_)); | |
381 EXPECT_EQ(OK, stream1->ReadResponseHeaders(&callback_)); | |
382 | |
383 HttpRequestHeaders headers2; | |
384 HttpResponseInfo response2; | |
385 EXPECT_EQ(OK, stream2->SendRequest(headers2, NULL, &response2, &callback_)); | |
386 | |
387 ExpectResponse("ok.html", stream1, false); | |
388 stream1->Close(false); | |
389 | |
390 EXPECT_EQ(OK, stream2->ReadResponseHeaders(&callback_)); | |
391 ExpectResponse("ko.html", stream2, false); | |
392 stream2->Close(false); | |
393 } | |
394 | |
395 TEST_F(HttpPipelinedConnectionImplTest, AsyncSendWhileAsyncReadBlocked) { | |
396 MockWrite writes[] = { | |
397 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
398 MockWrite(true, 3, "GET /ko.html HTTP/1.1\r\n\r\n"), | |
399 }; | |
400 MockRead reads[] = { | |
401 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
402 MockRead(false, 2, "Content-Length: 7\r\n\r\n"), | |
403 MockRead(true, 4, "ok.html"), | |
404 MockRead(false, 5, "HTTP/1.1 200 OK\r\n"), | |
405 MockRead(false, 6, "Content-Length: 7\r\n\r\n"), | |
406 MockRead(false, 7, "ko.html"), | |
407 }; | |
408 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
409 | |
410 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html")); | |
411 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html")); | |
412 | |
413 HttpRequestHeaders headers1; | |
414 HttpResponseInfo response1; | |
415 EXPECT_EQ(OK, stream1->SendRequest(headers1, NULL, &response1, &callback_)); | |
416 EXPECT_EQ(OK, stream1->ReadResponseHeaders(&callback_)); | |
417 TestOldCompletionCallback callback1; | |
418 std::string expected = "ok.html"; | |
419 scoped_refptr<IOBuffer> buffer(new IOBuffer(expected.size())); | |
420 EXPECT_EQ(ERR_IO_PENDING, | |
421 stream1->ReadResponseBody(buffer.get(), expected.size(), | |
422 &callback1)); | |
423 | |
424 HttpRequestHeaders headers2; | |
425 HttpResponseInfo response2; | |
426 TestOldCompletionCallback callback2; | |
427 EXPECT_EQ(ERR_IO_PENDING, | |
428 stream2->SendRequest(headers2, NULL, &response2, &callback2)); | |
429 | |
430 data_->RunFor(1); | |
431 EXPECT_LE(OK, callback2.WaitForResult()); | |
432 EXPECT_EQ(ERR_IO_PENDING, stream2->ReadResponseHeaders(&callback2)); | |
433 | |
434 data_->RunFor(1); | |
435 EXPECT_EQ(static_cast<int>(expected.size()), callback1.WaitForResult()); | |
436 std::string actual(buffer->data(), expected.size()); | |
437 EXPECT_THAT(actual, StrEq(expected)); | |
438 stream1->Close(false); | |
439 | |
440 data_->StopAfter(8); | |
441 EXPECT_LE(OK, callback2.WaitForResult()); | |
442 ExpectResponse("ko.html", stream2, false); | |
443 stream2->Close(false); | |
444 } | |
445 | |
446 TEST_F(HttpPipelinedConnectionImplTest, UnusedStreamAllowsLaterUse) { | |
447 MockWrite writes[] = { | |
448 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
449 }; | |
450 MockRead reads[] = { | |
451 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
452 MockRead(false, 2, "Content-Length: 7\r\n\r\n"), | |
453 MockRead(false, 3, "ok.html"), | |
454 }; | |
455 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
456 | |
457 scoped_ptr<HttpStream> unused_stream(NewTestStream("unused.html")); | |
458 unused_stream->Close(false); | |
459 | |
460 scoped_ptr<HttpStream> later_stream(NewTestStream("ok.html")); | |
461 TestSyncRequest(later_stream, "ok.html"); | |
462 } | |
463 | |
464 TEST_F(HttpPipelinedConnectionImplTest, UnsentStreamAllowsLaterUse) { | |
465 MockWrite writes[] = { | |
466 MockWrite(true, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
467 MockWrite(false, 4, "GET /ko.html HTTP/1.1\r\n\r\n"), | |
468 }; | |
469 MockRead reads[] = { | |
470 MockRead(true, 1, "HTTP/1.1 200 OK\r\n"), | |
471 MockRead(true, 2, "Content-Length: 7\r\n\r\n"), | |
472 MockRead(true, 3, "ok.html"), | |
473 MockRead(false, 5, "HTTP/1.1 200 OK\r\n"), | |
474 MockRead(false, 6, "Content-Length: 7\r\n\r\n"), | |
475 MockRead(false, 7, "ko.html"), | |
476 }; | |
477 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
478 | |
479 scoped_ptr<HttpStream> stream(NewTestStream("ok.html")); | |
480 | |
481 HttpRequestHeaders headers; | |
482 HttpResponseInfo response; | |
483 EXPECT_EQ(ERR_IO_PENDING, | |
484 stream->SendRequest(headers, NULL, &response, &callback_)); | |
485 | |
486 scoped_ptr<HttpStream> unsent_stream(NewTestStream("unsent.html")); | |
487 HttpRequestHeaders unsent_headers; | |
488 HttpResponseInfo unsent_response; | |
489 EXPECT_EQ(ERR_IO_PENDING, | |
490 unsent_stream->SendRequest(unsent_headers, NULL, &unsent_response, | |
491 &callback_)); | |
492 unsent_stream->Close(false); | |
493 | |
494 data_->RunFor(1); | |
495 EXPECT_LE(OK, callback_.WaitForResult()); | |
496 | |
497 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(&callback_)); | |
498 data_->RunFor(2); | |
499 EXPECT_LE(OK, callback_.WaitForResult()); | |
500 | |
501 ExpectResponse("ok.html", stream, true); | |
502 | |
503 stream->Close(false); | |
504 | |
505 data_->StopAfter(8); | |
506 scoped_ptr<HttpStream> later_stream(NewTestStream("ko.html")); | |
507 TestSyncRequest(later_stream, "ko.html"); | |
508 } | |
509 | |
510 TEST_F(HttpPipelinedConnectionImplTest, FailedSend) { | |
511 MockWrite writes[] = { | |
512 MockWrite(true, ERR_FAILED), | |
513 }; | |
514 Initialize(NULL, 0, writes, arraysize(writes)); | |
515 | |
516 scoped_ptr<HttpStream> failed_stream(NewTestStream("ok.html")); | |
517 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html")); | |
518 scoped_ptr<HttpStream> closed_stream(NewTestStream("closed.html")); | |
519 scoped_ptr<HttpStream> rejected_stream(NewTestStream("rejected.html")); | |
520 | |
521 HttpRequestHeaders headers; | |
522 HttpResponseInfo response; | |
523 TestOldCompletionCallback failed_callback; | |
524 EXPECT_EQ(ERR_IO_PENDING, | |
525 failed_stream->SendRequest(headers, NULL, &response, | |
526 &failed_callback)); | |
527 TestOldCompletionCallback evicted_callback; | |
528 EXPECT_EQ(ERR_IO_PENDING, | |
529 evicted_stream->SendRequest(headers, NULL, &response, | |
530 &evicted_callback)); | |
531 EXPECT_EQ(ERR_IO_PENDING, | |
532 closed_stream->SendRequest(headers, NULL, &response, | |
533 &callback_)); | |
534 closed_stream->Close(false); | |
535 | |
536 data_->RunFor(1); | |
537 EXPECT_EQ(ERR_FAILED, failed_callback.WaitForResult()); | |
538 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult()); | |
539 EXPECT_EQ(ERR_PIPELINE_EVICTION, | |
540 rejected_stream->SendRequest(headers, NULL, &response, | |
541 &callback_)); | |
542 | |
543 failed_stream->Close(true); | |
544 evicted_stream->Close(true); | |
545 rejected_stream->Close(true); | |
546 } | |
547 | |
548 TEST_F(HttpPipelinedConnectionImplTest, ConnectionSuddenlyClosedAfterResponse) { | |
549 MockWrite writes[] = { | |
550 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
551 MockWrite(false, 1, "GET /read_evicted.html HTTP/1.1\r\n\r\n"), | |
552 MockWrite(false, 2, "GET /read_rejected.html HTTP/1.1\r\n\r\n"), | |
553 MockWrite(true, ERR_SOCKET_NOT_CONNECTED, 5), | |
554 }; | |
555 MockRead reads[] = { | |
556 MockRead(false, 3, "HTTP/1.1 200 OK\r\n\r\n"), | |
557 MockRead(false, 4, "ok.html"), | |
558 }; | |
559 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
560 | |
561 scoped_ptr<HttpStream> closed_stream(NewTestStream("ok.html")); | |
562 scoped_ptr<HttpStream> read_evicted_stream( | |
563 NewTestStream("read_evicted.html")); | |
564 scoped_ptr<HttpStream> read_rejected_stream( | |
565 NewTestStream("read_rejected.html")); | |
566 scoped_ptr<HttpStream> send_closed_stream( | |
567 NewTestStream("send_closed.html")); | |
568 scoped_ptr<HttpStream> send_evicted_stream( | |
569 NewTestStream("send_evicted.html")); | |
570 scoped_ptr<HttpStream> send_rejected_stream( | |
571 NewTestStream("send_rejected.html")); | |
572 | |
573 HttpRequestHeaders headers; | |
574 HttpResponseInfo response; | |
575 EXPECT_EQ(OK, closed_stream->SendRequest(headers, NULL, &response, | |
576 &callback_)); | |
577 EXPECT_EQ(OK, read_evicted_stream->SendRequest(headers, NULL, &response, | |
578 &callback_)); | |
579 EXPECT_EQ(OK, read_rejected_stream->SendRequest(headers, NULL, &response, | |
580 &callback_)); | |
581 TestOldCompletionCallback send_closed_callback; | |
582 EXPECT_EQ(ERR_IO_PENDING, | |
583 send_closed_stream->SendRequest(headers, NULL, &response, | |
584 &send_closed_callback)); | |
585 TestOldCompletionCallback send_evicted_callback; | |
586 EXPECT_EQ(ERR_IO_PENDING, | |
587 send_evicted_stream->SendRequest(headers, NULL, &response, | |
588 &send_evicted_callback)); | |
589 | |
590 TestOldCompletionCallback read_evicted_callback; | |
591 EXPECT_EQ(ERR_IO_PENDING, | |
592 read_evicted_stream->ReadResponseHeaders(&read_evicted_callback)); | |
593 | |
594 EXPECT_EQ(OK, closed_stream->ReadResponseHeaders(&callback_)); | |
595 ExpectResponse("ok.html", closed_stream, false); | |
596 closed_stream->Close(true); | |
597 | |
598 EXPECT_EQ(ERR_PIPELINE_EVICTION, read_evicted_callback.WaitForResult()); | |
599 read_evicted_stream->Close(true); | |
600 | |
601 EXPECT_EQ(ERR_PIPELINE_EVICTION, | |
602 read_rejected_stream->ReadResponseHeaders(&callback_)); | |
603 read_rejected_stream->Close(true); | |
604 | |
605 data_->RunFor(1); | |
606 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, send_closed_callback.WaitForResult()); | |
607 send_closed_stream->Close(true); | |
608 | |
609 EXPECT_EQ(ERR_PIPELINE_EVICTION, send_evicted_callback.WaitForResult()); | |
610 send_evicted_stream->Close(true); | |
611 | |
612 EXPECT_EQ(ERR_PIPELINE_EVICTION, | |
613 send_rejected_stream->SendRequest(headers, NULL, &response, | |
614 &callback_)); | |
615 send_rejected_stream->Close(true); | |
616 } | |
617 | |
618 TEST_F(HttpPipelinedConnectionImplTest, AbortWhileSending) { | |
619 MockWrite writes[] = { | |
620 MockWrite(true, 0, "GET /aborts.html HTTP/1.1\r\n\r\n"), | |
621 }; | |
622 Initialize(NULL, 0, writes, arraysize(writes)); | |
623 | |
624 scoped_ptr<HttpStream> aborted_stream(NewTestStream("aborts.html")); | |
625 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html")); | |
626 | |
627 HttpRequestHeaders headers; | |
628 HttpResponseInfo response; | |
629 TestOldCompletionCallback aborted_callback; | |
630 EXPECT_EQ(ERR_IO_PENDING, | |
631 aborted_stream->SendRequest(headers, NULL, &response, | |
632 &aborted_callback)); | |
633 TestOldCompletionCallback evicted_callback; | |
634 EXPECT_EQ(ERR_IO_PENDING, | |
635 evicted_stream->SendRequest(headers, NULL, &response, | |
636 &evicted_callback)); | |
637 | |
638 aborted_stream->Close(true); | |
639 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult()); | |
640 evicted_stream->Close(true); | |
641 EXPECT_FALSE(aborted_callback.have_result()); | |
642 } | |
643 | |
644 TEST_F(HttpPipelinedConnectionImplTest, AbortWhileSendingSecondRequest) { | |
645 MockWrite writes[] = { | |
646 MockWrite(true, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
647 MockWrite(true, 1, "GET /aborts.html HTTP/1.1\r\n\r\n"), | |
648 }; | |
649 Initialize(NULL, 0, writes, arraysize(writes)); | |
650 | |
651 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html")); | |
652 scoped_ptr<HttpStream> aborted_stream(NewTestStream("aborts.html")); | |
653 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html")); | |
654 | |
655 HttpRequestHeaders headers; | |
656 HttpResponseInfo response; | |
657 TestOldCompletionCallback ok_callback; | |
658 EXPECT_EQ(ERR_IO_PENDING, | |
659 ok_stream->SendRequest(headers, NULL, &response, | |
660 &ok_callback)); | |
661 TestOldCompletionCallback aborted_callback; | |
662 EXPECT_EQ(ERR_IO_PENDING, | |
663 aborted_stream->SendRequest(headers, NULL, &response, | |
664 &aborted_callback)); | |
665 TestOldCompletionCallback evicted_callback; | |
666 EXPECT_EQ(ERR_IO_PENDING, | |
667 evicted_stream->SendRequest(headers, NULL, &response, | |
668 &evicted_callback)); | |
669 | |
670 data_->RunFor(1); | |
671 EXPECT_LE(OK, ok_callback.WaitForResult()); | |
672 MessageLoop::current()->RunAllPending(); | |
673 aborted_stream->Close(true); | |
674 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult()); | |
675 evicted_stream->Close(true); | |
676 EXPECT_FALSE(aborted_callback.have_result()); | |
677 ok_stream->Close(true); | |
678 } | |
679 | |
680 TEST_F(HttpPipelinedConnectionImplTest, AbortWhileReadingHeaders) { | |
681 MockWrite writes[] = { | |
682 MockWrite(false, 0, "GET /aborts.html HTTP/1.1\r\n\r\n"), | |
683 MockWrite(false, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"), | |
684 }; | |
685 MockRead reads[] = { | |
686 MockRead(true, ERR_FAILED, 2), | |
687 }; | |
688 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
689 | |
690 scoped_ptr<HttpStream> aborted_stream(NewTestStream("aborts.html")); | |
691 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html")); | |
692 scoped_ptr<HttpStream> rejected_stream(NewTestStream("rejected.html")); | |
693 | |
694 HttpRequestHeaders headers; | |
695 HttpResponseInfo response; | |
696 EXPECT_EQ(OK, aborted_stream->SendRequest(headers, NULL, &response, | |
697 &callback_)); | |
698 EXPECT_EQ(OK, evicted_stream->SendRequest(headers, NULL, &response, | |
699 &callback_)); | |
700 | |
701 EXPECT_EQ(ERR_IO_PENDING, aborted_stream->ReadResponseHeaders(&callback_)); | |
702 TestOldCompletionCallback evicted_callback; | |
703 EXPECT_EQ(ERR_IO_PENDING, | |
704 evicted_stream->ReadResponseHeaders(&evicted_callback)); | |
705 | |
706 aborted_stream->Close(true); | |
707 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult()); | |
708 evicted_stream->Close(true); | |
709 | |
710 EXPECT_EQ(ERR_PIPELINE_EVICTION, | |
711 rejected_stream->SendRequest(headers, NULL, &response, &callback_)); | |
712 rejected_stream->Close(true); | |
713 } | |
714 | |
715 TEST_F(HttpPipelinedConnectionImplTest, PendingResponseAbandoned) { | |
716 MockWrite writes[] = { | |
717 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
718 MockWrite(false, 1, "GET /abandoned.html HTTP/1.1\r\n\r\n"), | |
719 MockWrite(false, 2, "GET /evicted.html HTTP/1.1\r\n\r\n"), | |
720 }; | |
721 MockRead reads[] = { | |
722 MockRead(false, 3, "HTTP/1.1 200 OK\r\n"), | |
723 MockRead(false, 4, "Content-Length: 7\r\n\r\n"), | |
724 MockRead(false, 5, "ok.html"), | |
725 }; | |
726 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
727 | |
728 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html")); | |
729 scoped_ptr<HttpStream> abandoned_stream(NewTestStream("abandoned.html")); | |
730 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html")); | |
731 | |
732 HttpRequestHeaders headers; | |
733 HttpResponseInfo response; | |
734 EXPECT_EQ(OK, ok_stream->SendRequest(headers, NULL, &response, &callback_)); | |
735 EXPECT_EQ(OK, abandoned_stream->SendRequest(headers, NULL, &response, | |
736 &callback_)); | |
737 EXPECT_EQ(OK, evicted_stream->SendRequest(headers, NULL, &response, | |
738 &callback_)); | |
739 | |
740 EXPECT_EQ(OK, ok_stream->ReadResponseHeaders(&callback_)); | |
741 TestOldCompletionCallback abandoned_callback; | |
742 EXPECT_EQ(ERR_IO_PENDING, | |
743 abandoned_stream->ReadResponseHeaders(&abandoned_callback)); | |
744 TestOldCompletionCallback evicted_callback; | |
745 EXPECT_EQ(ERR_IO_PENDING, | |
746 evicted_stream->ReadResponseHeaders(&evicted_callback)); | |
747 | |
748 abandoned_stream->Close(false); | |
749 | |
750 ExpectResponse("ok.html", ok_stream, false); | |
751 ok_stream->Close(false); | |
752 | |
753 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult()); | |
754 evicted_stream->Close(true); | |
755 EXPECT_FALSE(evicted_stream->IsConnectionReusable()); | |
756 } | |
757 | |
758 TEST_F(HttpPipelinedConnectionImplTest, DisconnectedAfterOneRequestRecovery) { | |
759 MockWrite writes[] = { | |
760 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
761 MockWrite(false, 1, "GET /rejected.html HTTP/1.1\r\n\r\n"), | |
762 MockWrite(true, ERR_SOCKET_NOT_CONNECTED, 5), | |
763 MockWrite(false, ERR_SOCKET_NOT_CONNECTED, 7), | |
764 }; | |
765 MockRead reads[] = { | |
766 MockRead(false, 2, "HTTP/1.1 200 OK\r\n"), | |
767 MockRead(false, 3, "Content-Length: 7\r\n\r\n"), | |
768 MockRead(false, 4, "ok.html"), | |
769 MockRead(false, ERR_SOCKET_NOT_CONNECTED, 6), | |
770 }; | |
771 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
772 | |
773 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html")); | |
774 scoped_ptr<HttpStream> rejected_read_stream(NewTestStream("rejected.html")); | |
775 scoped_ptr<HttpStream> evicted_send_stream(NewTestStream("evicted.html")); | |
776 scoped_ptr<HttpStream> rejected_send_stream(NewTestStream("rejected.html")); | |
777 | |
778 HttpRequestHeaders headers; | |
779 HttpResponseInfo response; | |
780 EXPECT_EQ(OK, ok_stream->SendRequest(headers, NULL, &response, &callback_)); | |
781 EXPECT_EQ(OK, rejected_read_stream->SendRequest( | |
782 headers, NULL, &response, &callback_)); | |
783 | |
784 EXPECT_EQ(OK, ok_stream->ReadResponseHeaders(&callback_)); | |
785 ExpectResponse("ok.html", ok_stream, false); | |
786 ok_stream->Close(false); | |
787 | |
788 TestOldCompletionCallback read_callback; | |
789 EXPECT_EQ(ERR_IO_PENDING, | |
790 evicted_send_stream->SendRequest(headers, NULL, &response, | |
791 &read_callback)); | |
792 data_->RunFor(1); | |
793 EXPECT_EQ(ERR_PIPELINE_EVICTION, read_callback.WaitForResult()); | |
794 | |
795 EXPECT_EQ(ERR_PIPELINE_EVICTION, | |
796 rejected_read_stream->ReadResponseHeaders(&callback_)); | |
797 EXPECT_EQ(ERR_PIPELINE_EVICTION, | |
798 rejected_send_stream->SendRequest(headers, NULL, &response, | |
799 &callback_)); | |
800 | |
801 rejected_read_stream->Close(true); | |
802 rejected_send_stream->Close(true); | |
803 } | |
804 | |
805 TEST_F(HttpPipelinedConnectionImplTest, DisconnectedPendingReadRecovery) { | |
806 MockWrite writes[] = { | |
807 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
808 MockWrite(false, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"), | |
809 }; | |
810 MockRead reads[] = { | |
811 MockRead(false, 2, "HTTP/1.1 200 OK\r\n"), | |
812 MockRead(false, 3, "Content-Length: 7\r\n\r\n"), | |
813 MockRead(false, 4, "ok.html"), | |
814 MockRead(false, ERR_SOCKET_NOT_CONNECTED, 5), | |
815 }; | |
816 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
817 | |
818 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html")); | |
819 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html")); | |
820 | |
821 HttpRequestHeaders headers; | |
822 HttpResponseInfo response; | |
823 EXPECT_EQ(OK, ok_stream->SendRequest(headers, NULL, &response, &callback_)); | |
824 EXPECT_EQ(OK, evicted_stream->SendRequest( | |
825 headers, NULL, &response, &callback_)); | |
826 | |
827 EXPECT_EQ(OK, ok_stream->ReadResponseHeaders(&callback_)); | |
828 ExpectResponse("ok.html", ok_stream, false); | |
829 | |
830 TestOldCompletionCallback evicted_callback; | |
831 EXPECT_EQ(ERR_IO_PENDING, | |
832 evicted_stream->ReadResponseHeaders(&evicted_callback)); | |
833 | |
834 ok_stream->Close(false); | |
835 | |
836 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult()); | |
837 evicted_stream->Close(false); | |
838 } | |
839 | |
840 TEST_F(HttpPipelinedConnectionImplTest, CloseCalledBeforeNextReadLoop) { | |
841 MockWrite writes[] = { | |
842 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
843 MockWrite(false, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"), | |
844 }; | |
845 MockRead reads[] = { | |
846 MockRead(false, 2, "HTTP/1.1 200 OK\r\n"), | |
847 MockRead(false, 3, "Content-Length: 7\r\n\r\n"), | |
848 MockRead(false, 4, "ok.html"), | |
849 MockRead(false, ERR_SOCKET_NOT_CONNECTED, 5), | |
850 }; | |
851 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
852 | |
853 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html")); | |
854 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html")); | |
855 | |
856 HttpRequestHeaders headers; | |
857 HttpResponseInfo response; | |
858 EXPECT_EQ(OK, ok_stream->SendRequest(headers, NULL, &response, &callback_)); | |
859 EXPECT_EQ(OK, evicted_stream->SendRequest( | |
860 headers, NULL, &response, &callback_)); | |
861 | |
862 EXPECT_EQ(OK, ok_stream->ReadResponseHeaders(&callback_)); | |
863 ExpectResponse("ok.html", ok_stream, false); | |
864 | |
865 TestOldCompletionCallback evicted_callback; | |
866 EXPECT_EQ(ERR_IO_PENDING, | |
867 evicted_stream->ReadResponseHeaders(&evicted_callback)); | |
868 | |
869 ok_stream->Close(false); | |
870 evicted_stream->Close(false); | |
871 } | |
872 | |
873 TEST_F(HttpPipelinedConnectionImplTest, CloseCalledBeforeReadCallback) { | |
874 MockWrite writes[] = { | |
875 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
876 MockWrite(false, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"), | |
877 }; | |
878 MockRead reads[] = { | |
879 MockRead(false, 2, "HTTP/1.1 200 OK\r\n"), | |
880 MockRead(false, 3, "Content-Length: 7\r\n\r\n"), | |
881 MockRead(false, 4, "ok.html"), | |
882 MockRead(false, ERR_SOCKET_NOT_CONNECTED, 5), | |
883 }; | |
884 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
885 | |
886 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html")); | |
887 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html")); | |
888 | |
889 HttpRequestHeaders headers; | |
890 HttpResponseInfo response; | |
891 EXPECT_EQ(OK, ok_stream->SendRequest(headers, NULL, &response, &callback_)); | |
892 EXPECT_EQ(OK, evicted_stream->SendRequest( | |
893 headers, NULL, &response, &callback_)); | |
894 | |
895 EXPECT_EQ(OK, ok_stream->ReadResponseHeaders(&callback_)); | |
896 ExpectResponse("ok.html", ok_stream, false); | |
897 | |
898 TestOldCompletionCallback evicted_callback; | |
899 EXPECT_EQ(ERR_IO_PENDING, | |
900 evicted_stream->ReadResponseHeaders(&evicted_callback)); | |
901 | |
902 ok_stream->Close(false); | |
903 | |
904 // The posted tasks should be: | |
905 // 1. DoReadHeadersLoop, which will post: | |
906 // 2. InvokeUserCallback | |
907 SuddenCloseObserver observer(evicted_stream.get(), 2); | |
908 MessageLoop::current()->AddTaskObserver(&observer); | |
909 MessageLoop::current()->RunAllPending(); | |
910 EXPECT_FALSE(evicted_callback.have_result()); | |
911 } | |
912 | |
913 class StreamDeleter { | |
914 public: | |
915 StreamDeleter(HttpStream* stream) : | |
916 stream_(stream), | |
917 ALLOW_THIS_IN_INITIALIZER_LIST( | |
918 callback_(this, &StreamDeleter::OnIOComplete)) { | |
919 } | |
920 | |
921 OldCompletionCallbackImpl<StreamDeleter>* callback() { return &callback_; } | |
922 | |
923 private: | |
924 void OnIOComplete(int result) { | |
925 delete stream_; | |
926 } | |
927 | |
928 HttpStream* stream_; | |
929 OldCompletionCallbackImpl<StreamDeleter> callback_; | |
930 }; | |
931 | |
932 TEST_F(HttpPipelinedConnectionImplTest, CloseCalledDuringSendCallback) { | |
933 MockWrite writes[] = { | |
934 MockWrite(true, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
935 }; | |
936 Initialize(NULL, 0, writes, arraysize(writes)); | |
937 | |
938 HttpStream* stream(NewTestStream("ok.html")); | |
939 | |
940 StreamDeleter deleter(stream); | |
941 HttpRequestHeaders headers; | |
942 HttpResponseInfo response; | |
943 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(headers, NULL, &response, | |
944 deleter.callback())); | |
945 data_->RunFor(1); | |
946 } | |
947 | |
948 TEST_F(HttpPipelinedConnectionImplTest, CloseCalledDuringReadCallback) { | |
949 MockWrite writes[] = { | |
950 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
951 }; | |
952 MockRead reads[] = { | |
953 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"), | |
954 MockRead(true, 2, "Content-Length: 7\r\n\r\n"), | |
955 }; | |
956 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
957 | |
958 HttpStream* stream(NewTestStream("ok.html")); | |
959 | |
960 HttpRequestHeaders headers; | |
961 HttpResponseInfo response; | |
962 EXPECT_EQ(OK, stream->SendRequest(headers, NULL, &response, &callback_)); | |
963 | |
964 StreamDeleter deleter(stream); | |
965 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(deleter.callback())); | |
966 data_->RunFor(1); | |
967 } | |
968 | |
969 TEST_F(HttpPipelinedConnectionImplTest, | |
970 CloseCalledDuringReadCallbackWithPendingRead) { | |
971 MockWrite writes[] = { | |
972 MockWrite(false, 0, "GET /failed.html HTTP/1.1\r\n\r\n"), | |
973 MockWrite(false, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"), | |
974 }; | |
975 MockRead reads[] = { | |
976 MockRead(false, 2, "HTTP/1.1 200 OK\r\n"), | |
977 MockRead(true, 3, "Content-Length: 7\r\n\r\n"), | |
978 }; | |
979 Initialize(reads, arraysize(reads), writes, arraysize(writes)); | |
980 | |
981 HttpStream* failed_stream(NewTestStream("failed.html")); | |
982 HttpStream* evicted_stream(NewTestStream("evicted.html")); | |
983 | |
984 HttpRequestHeaders headers; | |
985 HttpResponseInfo response; | |
986 EXPECT_EQ(OK, | |
987 failed_stream->SendRequest(headers, NULL, &response, &callback_)); | |
988 EXPECT_EQ(OK, | |
989 evicted_stream->SendRequest(headers, NULL, &response, &callback_)); | |
990 | |
991 StreamDeleter failed_deleter(failed_stream); | |
992 EXPECT_EQ(ERR_IO_PENDING, | |
993 failed_stream->ReadResponseHeaders(failed_deleter.callback())); | |
994 StreamDeleter evicted_deleter(evicted_stream); | |
995 EXPECT_EQ(ERR_IO_PENDING, | |
996 evicted_stream->ReadResponseHeaders(evicted_deleter.callback())); | |
997 data_->RunFor(1); | |
998 } | |
mmenke
2011/10/14 16:21:26
nit: Missing blank line.
| |
999 TEST_F(HttpPipelinedConnectionImplTest, OnPipelineHasCapacity) { | |
1000 MockWrite writes[] = { | |
1001 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
1002 }; | |
1003 Initialize(NULL, 0, writes, arraysize(writes)); | |
1004 | |
1005 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(0); | |
1006 scoped_ptr<HttpStream> stream(NewTestStream("ok.html")); | |
1007 | |
1008 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(1); | |
1009 HttpRequestHeaders headers; | |
1010 HttpResponseInfo response; | |
1011 EXPECT_EQ(OK, stream->SendRequest(headers, NULL, &response, &callback_)); | |
1012 | |
1013 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(0); | |
1014 MessageLoop::current()->RunAllPending(); | |
1015 | |
1016 stream->Close(false); | |
1017 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(1); | |
1018 stream.reset(NULL); | |
1019 } | |
1020 | |
1021 TEST_F(HttpPipelinedConnectionImplTest, OnPipelineHasCapacityWithoutSend) { | |
1022 MockWrite writes[] = { | |
1023 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), | |
1024 }; | |
1025 Initialize(NULL, 0, writes, arraysize(writes)); | |
1026 | |
1027 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(0); | |
1028 scoped_ptr<HttpStream> stream(NewTestStream("ok.html")); | |
1029 | |
1030 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(1); | |
1031 MessageLoop::current()->RunAllPending(); | |
1032 | |
1033 stream->Close(false); | |
1034 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(1); | |
1035 stream.reset(NULL); | |
1036 } | |
1037 | |
1038 } // namespace net | |
OLD | NEW |