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

Side by Side Diff: net/http/http_pipelined_connection_impl_unittest.cc

Issue 7289006: Basic HTTP pipelining support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Use linked_ptr Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
willchan no longer on Chromium 2011/10/13 02:29:17 I should really read this file. I'm not going to r
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, OnPipelineHasCapacity) {
970 MockWrite writes[] = {
971 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
972 };
973 Initialize(NULL, 0, writes, arraysize(writes));
974
975 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(0);
976 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
977
978 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(1);
979 HttpRequestHeaders headers;
980 HttpResponseInfo response;
981 EXPECT_EQ(OK, stream->SendRequest(headers, NULL, &response, &callback_));
982
983 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(0);
984 MessageLoop::current()->RunAllPending();
985
986 stream->Close(false);
987 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(1);
988 stream.reset(NULL);
989 }
990
991 TEST_F(HttpPipelinedConnectionImplTest, OnPipelineHasCapacityWithoutSend) {
992 MockWrite writes[] = {
993 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
994 };
995 Initialize(NULL, 0, writes, arraysize(writes));
996
997 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(0);
998 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
999
1000 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(1);
1001 MessageLoop::current()->RunAllPending();
1002
1003 stream->Close(false);
1004 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(1);
1005 stream.reset(NULL);
1006 }
1007
1008 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698