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

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

Powered by Google App Engine
This is Rietveld 408576698