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

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: Added unit 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>
mmenke 2011/08/23 19:05:25 nit: Add blank link.
James Simonsen 2011/08/26 22:19:07 Done.
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/scoped_vector.h"
10 #include "net/base/io_buffer.h"
11 #include "net/base/net_errors.h"
12 #include "net/base/request_priority.h"
13 #include "net/http/http_pipelined_stream.h"
14 #include "net/socket/client_socket_handle.h"
15 #include "net/socket/client_socket_pool_histograms.h"
16 #include "net/socket/socket_test_util.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 using testing::NiceMock;
21 using testing::Ref;
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 MockPipelineOwner : public HttpPipelinedConnectionImpl::Owner {
35 public:
36 MOCK_METHOD1(OnPipelineHasCapacity, void(HttpPipelinedConnection* pipeline));
37 };
38
39 class HttpPipelinedConnectionImplTest : public testing::Test {
40 public:
41 HttpPipelinedConnectionImplTest()
42 : histograms_("a"),
43 pool_(1, 1, &histograms_, &factory_) {
44 }
45
46 void Initialize(MockRead* reads, size_t reads_count,
47 MockWrite* writes, size_t writes_count) {
48 data_ = new DeterministicSocketData(reads, reads_count,
49 writes, writes_count);
50 data_->set_connect_data(MockConnect(false, 0));
51 if (reads_count || writes_count) {
52 data_->StopAfter(reads_count + writes_count);
53 }
54 factory_.AddSocketDataProvider(data_.get());
55 scoped_refptr<DummySocketParams> params;
56 ClientSocketHandle* connection = new ClientSocketHandle;
57 connection->Init("a", params, MEDIUM, NULL, &pool_, BoundNetLog());
58 pipeline_.reset(new HttpPipelinedConnectionImpl(connection, &owner_,
59 ssl_config_, proxy_info_,
60 BoundNetLog(), false));
61 }
62
63 HttpRequestInfo* GetRequestInfo(const std::string& filename) {
64 HttpRequestInfo* request_info = new HttpRequestInfo;
65 request_info->url = GURL("http://localhost/" + filename);
66 request_info->method = "GET";
67 request_info_vector_.push_back(request_info);
68 return request_info;
69 }
70
71 HttpStream* NewTestStream(const std::string& filename) {
72 HttpStream* stream = pipeline_->CreateNewStream();
73 HttpRequestInfo* request_info = GetRequestInfo(filename);
74 int rv = stream->InitializeStream(request_info, BoundNetLog(), NULL);
75 DCHECK_EQ(OK, rv);
76 return stream;
77 }
78
79 void ExpectResponse(const std::string& expected,
80 scoped_ptr<HttpStream>& stream, bool async) {
81 scoped_refptr<IOBuffer> buffer(new IOBuffer(expected.size()));
82
83 if (async) {
84 EXPECT_EQ(ERR_IO_PENDING,
85 stream->ReadResponseBody(buffer.get(), expected.size(),
86 &callback_));
87 data_->RunFor(1);
88 EXPECT_EQ(static_cast<int>(expected.size()), callback_.WaitForResult());
89 } else {
90 EXPECT_EQ(static_cast<int>(expected.size()),
91 stream->ReadResponseBody(buffer.get(), expected.size(),
92 &callback_));
93 }
94 std::string actual(buffer->data(), expected.size());
95 EXPECT_THAT(actual, StrEq(expected));
96 }
97
98 void TestSyncRequest(scoped_ptr<HttpStream>& stream,
99 const std::string& filename) {
100 HttpRequestHeaders headers;
101 HttpResponseInfo response;
102 EXPECT_EQ(OK, stream->SendRequest(headers, NULL, &response, &callback_));
103 EXPECT_EQ(OK, stream->ReadResponseHeaders(&callback_));
104 ExpectResponse(filename, stream, false);
105
106 stream->Close(false);
107 }
108
109 DeterministicMockClientSocketFactory factory_;
110 ClientSocketPoolHistograms histograms_;
111 MockTransportClientSocketPool pool_;
112 scoped_refptr<DeterministicSocketData> data_;
113
114 SSLConfig ssl_config_;
115 ProxyInfo proxy_info_;
116 NiceMock<MockPipelineOwner> owner_;
117 TestCompletionCallback callback_;
118 scoped_ptr<HttpPipelinedConnectionImpl> pipeline_;
119 ScopedVector<HttpRequestInfo> request_info_vector_;
120 };
121
122 TEST_F(HttpPipelinedConnectionImplTest, SyncSingleRequest) {
123 MockWrite writes[] = {
124 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
125 };
126 MockRead reads[] = {
127 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"),
128 MockRead(false, 2, "Content-Length: 7\r\n\r\n"),
129 MockRead(false, 3, "ok.html"),
130 };
131 Initialize(reads, arraysize(reads), writes, arraysize(writes));
132
133 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
134 TestSyncRequest(stream, "ok.html");
135 }
136
137 TEST_F(HttpPipelinedConnectionImplTest, AsyncSingleRequest) {
138 MockWrite writes[] = {
139 MockWrite(true, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
140 };
141 MockRead reads[] = {
142 MockRead(true, 1, "HTTP/1.1 200 OK\r\n"),
143 MockRead(true, 2, "Content-Length: 7\r\n\r\n"),
144 MockRead(true, 3, "ok.html"),
145 };
146 Initialize(reads, arraysize(reads), writes, arraysize(writes));
147
148 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
149
150 HttpRequestHeaders headers;
151 HttpResponseInfo response;
152 EXPECT_EQ(ERR_IO_PENDING,
153 stream->SendRequest(headers, NULL, &response, &callback_));
154 data_->RunFor(1);
155 EXPECT_LE(OK, callback_.WaitForResult());
156
157 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(&callback_));
158 data_->RunFor(2);
159 EXPECT_LE(OK, callback_.WaitForResult());
160
161 ExpectResponse("ok.html", stream, true);
162
163 stream->Close(false);
164 }
165
166 TEST_F(HttpPipelinedConnectionImplTest, LockStepAsyncRequests) {
167 MockWrite writes[] = {
168 MockWrite(true, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
169 MockWrite(true, 1, "GET /ko.html HTTP/1.1\r\n\r\n"),
170 };
171 MockRead reads[] = {
172 MockRead(true, 2, "HTTP/1.1 200 OK\r\n"),
173 MockRead(true, 3, "Content-Length: 7\r\n\r\n"),
174 MockRead(true, 4, "ok.html"),
175 MockRead(true, 5, "HTTP/1.1 200 OK\r\n"),
176 MockRead(true, 6, "Content-Length: 7\r\n\r\n"),
177 MockRead(true, 7, "ko.html"),
178 };
179 Initialize(reads, arraysize(reads), writes, arraysize(writes));
180
181 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html"));
182 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html"));
183
184 HttpRequestHeaders headers1;
185 HttpResponseInfo response1;
186 EXPECT_EQ(ERR_IO_PENDING,
187 stream1->SendRequest(headers1, NULL, &response1, &callback_));
188
189 HttpRequestHeaders headers2;
190 HttpResponseInfo response2;
191 EXPECT_EQ(ERR_IO_PENDING,
192 stream2->SendRequest(headers2, NULL, &response2, &callback_));
193
194 data_->RunFor(1);
195 EXPECT_LE(OK, callback_.WaitForResult());
196 data_->RunFor(1);
197 EXPECT_LE(OK, callback_.WaitForResult());
198
199 EXPECT_EQ(ERR_IO_PENDING, stream1->ReadResponseHeaders(&callback_));
200 EXPECT_EQ(ERR_IO_PENDING, stream2->ReadResponseHeaders(&callback_));
201
202 data_->RunFor(2);
203 EXPECT_LE(OK, callback_.WaitForResult());
204
205 ExpectResponse("ok.html", stream1, true);
206
207 stream1->Close(false);
208
209 data_->RunFor(2);
210 EXPECT_LE(OK, callback_.WaitForResult());
211
212 ExpectResponse("ko.html", stream2, true);
213
214 stream2->Close(false);
215 }
216
217 TEST_F(HttpPipelinedConnectionImplTest, TwoResponsesInOnePacket) {
218 MockWrite writes[] = {
219 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
220 MockWrite(false, 1, "GET /ko.html HTTP/1.1\r\n\r\n"),
221 };
222 MockRead reads[] = {
223 MockRead(false, 2,
224 "HTTP/1.1 200 OK\r\n"
225 "Content-Length: 7\r\n\r\n"
226 "ok.html"
227 "HTTP/1.1 200 OK\r\n"
228 "Content-Length: 7\r\n\r\n"
229 "ko.html"),
230 };
231 Initialize(reads, arraysize(reads), writes, arraysize(writes));
232
233 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html"));
234 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html"));
235
236 HttpRequestHeaders headers1;
237 HttpResponseInfo response1;
238 EXPECT_EQ(OK, stream1->SendRequest(headers1, NULL, &response1, &callback_));
239 HttpRequestHeaders headers2;
240 HttpResponseInfo response2;
241 EXPECT_EQ(OK, stream2->SendRequest(headers2, NULL, &response2, &callback_));
242
243 EXPECT_EQ(OK, stream1->ReadResponseHeaders(&callback_));
244 ExpectResponse("ok.html", stream1, false);
245 stream1->Close(false);
246
247 EXPECT_EQ(OK, stream2->ReadResponseHeaders(&callback_));
248 ExpectResponse("ko.html", stream2, false);
249 stream2->Close(false);
250 }
251
252 TEST_F(HttpPipelinedConnectionImplTest, InitializeOrderSwapped) {
253 MockWrite writes[] = {
254 MockWrite(false, 0, "GET /ko.html HTTP/1.1\r\n\r\n"),
255 MockWrite(false, 4, "GET /ok.html HTTP/1.1\r\n\r\n"),
256 };
257 MockRead reads[] = {
258 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"),
259 MockRead(false, 2, "Content-Length: 7\r\n\r\n"),
260 MockRead(false, 3, "ko.html"),
261 MockRead(false, 5, "HTTP/1.1 200 OK\r\n"),
262 MockRead(false, 6, "Content-Length: 7\r\n\r\n"),
263 MockRead(false, 7, "ok.html"),
264 };
265 Initialize(reads, arraysize(reads), writes, arraysize(writes));
266
267 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html"));
268 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html"));
269
270 TestSyncRequest(stream2, "ko.html");
271 TestSyncRequest(stream1, "ok.html");
272 }
273
274 TEST_F(HttpPipelinedConnectionImplTest, SendOrderSwapped) {
mmenke 2011/08/23 19:05:25 How is this different from the previous test?
James Simonsen 2011/08/26 22:19:07 Hmm. It was different at one point, but I oversimp
275 MockWrite writes[] = {
276 MockWrite(false, 0, "GET /ko.html HTTP/1.1\r\n\r\n"),
277 MockWrite(false, 4, "GET /ok.html HTTP/1.1\r\n\r\n"),
278 };
279 MockRead reads[] = {
280 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"),
281 MockRead(false, 2, "Content-Length: 7\r\n\r\n"),
282 MockRead(false, 3, "ko.html"),
283 MockRead(false, 5, "HTTP/1.1 200 OK\r\n"),
284 MockRead(false, 6, "Content-Length: 7\r\n\r\n"),
285 MockRead(false, 7, "ok.html"),
286 };
287 Initialize(reads, arraysize(reads), writes, arraysize(writes));
288
289 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html"));
290 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html"));
291
292 HttpRequestHeaders headers2;
293 HttpResponseInfo response2;
294 EXPECT_EQ(OK, stream2->SendRequest(headers2, NULL, &response2, &callback_));
295 EXPECT_EQ(OK, stream2->ReadResponseHeaders(&callback_));
296 ExpectResponse("ko.html", stream2, false);
297
298 stream2->Close(false);
299
300 HttpRequestHeaders headers1;
301 HttpResponseInfo response1;
302 EXPECT_EQ(OK, stream1->SendRequest(headers1, NULL, &response1, &callback_));
303 EXPECT_EQ(OK, stream1->ReadResponseHeaders(&callback_));
304 ExpectResponse("ok.html", stream1, false);
305
306 stream1->Close(false);
307 }
308
309 TEST_F(HttpPipelinedConnectionImplTest, ReadOrderSwapped) {
310 MockWrite writes[] = {
311 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
312 MockWrite(false, 1, "GET /ko.html HTTP/1.1\r\n\r\n"),
313 };
314 MockRead reads[] = {
315 MockRead(false, 2, "HTTP/1.1 200 OK\r\n"),
316 MockRead(false, 3, "Content-Length: 7\r\n\r\n"),
317 MockRead(false, 4, "ok.html"),
318 MockRead(false, 5, "HTTP/1.1 200 OK\r\n"),
319 MockRead(false, 6, "Content-Length: 7\r\n\r\n"),
320 MockRead(false, 7, "ko.html"),
321 };
322 Initialize(reads, arraysize(reads), writes, arraysize(writes));
323
324 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html"));
325 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html"));
326
327 HttpRequestHeaders headers1;
328 HttpResponseInfo response1;
329 EXPECT_EQ(OK, stream1->SendRequest(headers1, NULL, &response1, &callback_));
330
331 HttpRequestHeaders headers2;
332 HttpResponseInfo response2;
333 EXPECT_EQ(OK, stream2->SendRequest(headers2, NULL, &response2, &callback_));
334
335 EXPECT_EQ(ERR_IO_PENDING, stream2->ReadResponseHeaders(&callback_));
336
337 EXPECT_EQ(OK, stream1->ReadResponseHeaders(&callback_));
338 ExpectResponse("ok.html", stream1, false);
339
340 stream1->Close(false);
341
342 EXPECT_LE(OK, callback_.WaitForResult());
343 ExpectResponse("ko.html", stream2, false);
344
345 stream2->Close(false);
346 }
347
348 TEST_F(HttpPipelinedConnectionImplTest, SendWhileReading) {
349 MockWrite writes[] = {
350 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
351 MockWrite(false, 3, "GET /ko.html HTTP/1.1\r\n\r\n"),
352 };
353 MockRead reads[] = {
354 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"),
355 MockRead(false, 2, "Content-Length: 7\r\n\r\n"),
356 MockRead(false, 4, "ok.html"),
357 MockRead(false, 5, "HTTP/1.1 200 OK\r\n"),
358 MockRead(false, 6, "Content-Length: 7\r\n\r\n"),
359 MockRead(false, 7, "ko.html"),
360 };
361 Initialize(reads, arraysize(reads), writes, arraysize(writes));
362
363 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html"));
364 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html"));
365
366 HttpRequestHeaders headers1;
367 HttpResponseInfo response1;
368 EXPECT_EQ(OK, stream1->SendRequest(headers1, NULL, &response1, &callback_));
369 EXPECT_EQ(OK, stream1->ReadResponseHeaders(&callback_));
370
371 HttpRequestHeaders headers2;
372 HttpResponseInfo response2;
373 EXPECT_EQ(OK, stream2->SendRequest(headers2, NULL, &response2, &callback_));
374
375 ExpectResponse("ok.html", stream1, false);
376 stream1->Close(false);
377
378 EXPECT_EQ(OK, stream2->ReadResponseHeaders(&callback_));
379 ExpectResponse("ko.html", stream2, false);
380 stream2->Close(false);
381 }
382
383 TEST_F(HttpPipelinedConnectionImplTest, AsyncSendWhileAsyncReadBlocked) {
384 MockWrite writes[] = {
385 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
386 MockWrite(true, 3, "GET /ko.html HTTP/1.1\r\n\r\n"),
387 };
388 MockRead reads[] = {
389 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"),
390 MockRead(false, 2, "Content-Length: 7\r\n\r\n"),
391 MockRead(true, 4, "ok.html"),
392 MockRead(false, 5, "HTTP/1.1 200 OK\r\n"),
393 MockRead(false, 6, "Content-Length: 7\r\n\r\n"),
394 MockRead(false, 7, "ko.html"),
395 };
396 Initialize(reads, arraysize(reads), writes, arraysize(writes));
397
398 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html"));
399 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html"));
400
401 HttpRequestHeaders headers1;
402 HttpResponseInfo response1;
403 EXPECT_EQ(OK, stream1->SendRequest(headers1, NULL, &response1, &callback_));
404 EXPECT_EQ(OK, stream1->ReadResponseHeaders(&callback_));
405 TestCompletionCallback callback1;
406 std::string expected = "ok.html";
407 scoped_refptr<IOBuffer> buffer(new IOBuffer(expected.size()));
408 EXPECT_EQ(ERR_IO_PENDING,
409 stream1->ReadResponseBody(buffer.get(), expected.size(),
410 &callback1));
411
412 HttpRequestHeaders headers2;
413 HttpResponseInfo response2;
414 TestCompletionCallback callback2;
415 EXPECT_EQ(ERR_IO_PENDING,
416 stream2->SendRequest(headers2, NULL, &response2, &callback2));
417
418 data_->RunFor(1);
419 EXPECT_LE(OK, callback2.WaitForResult());
420 EXPECT_EQ(ERR_IO_PENDING, stream2->ReadResponseHeaders(&callback2));
421
422 data_->RunFor(1);
423 EXPECT_EQ(static_cast<int>(expected.size()), callback1.WaitForResult());
424 std::string actual(buffer->data(), expected.size());
425 EXPECT_THAT(actual, StrEq(expected));
426 stream1->Close(false);
427
428 data_->StopAfter(8);
429 EXPECT_LE(OK, callback2.WaitForResult());
430 ExpectResponse("ko.html", stream2, false);
431 stream2->Close(false);
432 }
433
434 TEST_F(HttpPipelinedConnectionImplTest, PipelineNotUsed) {
mmenke 2011/08/23 19:05:25 nit: Might want to put this test as well as the n
James Simonsen 2011/08/26 22:19:07 Done.
435 MockWrite writes[] = {};
mmenke 2011/08/23 19:05:25 MSVC doesn't like 0-length arrays like this.
James Simonsen 2011/08/26 22:19:07 Lame. Fixed.
436 MockRead reads[] = {};
437 Initialize(reads, 0, writes, 0);
438 }
439
440 TEST_F(HttpPipelinedConnectionImplTest, StreamNotUsed) {
441 MockWrite writes[] = {};
442 MockRead reads[] = {};
443 Initialize(reads, 0, writes, 0);
444
445 scoped_ptr<HttpStream> stream(pipeline_->CreateNewStream());
446
447 stream->Close(false);
448 }
449
450 TEST_F(HttpPipelinedConnectionImplTest, StreamBoundButNotUsed) {
451 MockWrite writes[] = {};
452 MockRead reads[] = {};
453 Initialize(reads, 0, writes, 0);
454
455 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
456
457 stream->Close(false);
458 }
459
460 TEST_F(HttpPipelinedConnectionImplTest, UnusedStreamAllowsLaterUse) {
461 MockWrite writes[] = {
462 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
463 };
464 MockRead reads[] = {
465 MockRead(false, 1, "HTTP/1.1 200 OK\r\n"),
466 MockRead(false, 2, "Content-Length: 7\r\n\r\n"),
467 MockRead(false, 3, "ok.html"),
468 };
469 Initialize(reads, arraysize(reads), writes, arraysize(writes));
470
471 scoped_ptr<HttpStream> unused_stream(NewTestStream("unused.html"));
472 unused_stream->Close(false);
473
474 scoped_ptr<HttpStream> later_stream(NewTestStream("ok.html"));
475 TestSyncRequest(later_stream, "ok.html");
476 }
477
478 TEST_F(HttpPipelinedConnectionImplTest, UnsentStreamAllowsLaterUse) {
479 MockWrite writes[] = {
480 MockWrite(true, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
481 MockWrite(false, 4, "GET /ko.html HTTP/1.1\r\n\r\n"),
482 };
483 MockRead reads[] = {
484 MockRead(true, 1, "HTTP/1.1 200 OK\r\n"),
485 MockRead(true, 2, "Content-Length: 7\r\n\r\n"),
486 MockRead(true, 3, "ok.html"),
487 MockRead(false, 5, "HTTP/1.1 200 OK\r\n"),
488 MockRead(false, 6, "Content-Length: 7\r\n\r\n"),
489 MockRead(false, 7, "ko.html"),
490 };
491 Initialize(reads, arraysize(reads), writes, arraysize(writes));
492
493 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
494
495 HttpRequestHeaders headers;
496 HttpResponseInfo response;
497 EXPECT_EQ(ERR_IO_PENDING,
498 stream->SendRequest(headers, NULL, &response, &callback_));
499
500 scoped_ptr<HttpStream> unsent_stream(NewTestStream("unsent.html"));
501 HttpRequestHeaders unsent_headers;
502 HttpResponseInfo unsent_response;
503 EXPECT_EQ(ERR_IO_PENDING,
504 unsent_stream->SendRequest(unsent_headers, NULL, &unsent_response,
505 &callback_));
506 unsent_stream->Close(false);
507
508 data_->RunFor(1);
509 EXPECT_LE(OK, callback_.WaitForResult());
510
511 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(&callback_));
512 data_->RunFor(2);
513 EXPECT_LE(OK, callback_.WaitForResult());
514
515 ExpectResponse("ok.html", stream, true);
516
517 stream->Close(false);
518
519 data_->StopAfter(8);
520 scoped_ptr<HttpStream> later_stream(NewTestStream("ko.html"));
521 TestSyncRequest(later_stream, "ko.html");
522 }
523
524 TEST_F(HttpPipelinedConnectionImplTest, FailedSend) {
525 MockWrite writes[] = {
526 MockWrite(true, ERR_FAILED),
527 };
528 MockRead reads[] = {};
529 Initialize(reads, 0, writes, arraysize(writes));
530
531 scoped_ptr<HttpStream> failed_stream(NewTestStream("ok.html"));
532 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html"));
533 scoped_ptr<HttpStream> closed_stream(NewTestStream("closed.html"));
534 scoped_ptr<HttpStream> rejected_stream(NewTestStream("rejected.html"));
535
536 HttpRequestHeaders headers;
537 HttpResponseInfo response;
538 TestCompletionCallback failed_callback;
539 EXPECT_EQ(ERR_IO_PENDING,
540 failed_stream->SendRequest(headers, NULL, &response,
541 &failed_callback));
542 TestCompletionCallback evicted_callback;
543 EXPECT_EQ(ERR_IO_PENDING,
544 evicted_stream->SendRequest(headers, NULL, &response,
545 &evicted_callback));
546 EXPECT_EQ(ERR_IO_PENDING,
547 closed_stream->SendRequest(headers, NULL, &response,
548 &callback_));
549 closed_stream->Close(false);
550
551 data_->RunFor(1);
552 EXPECT_EQ(ERR_FAILED, failed_callback.WaitForResult());
553 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult());
554 EXPECT_EQ(ERR_PIPELINE_EVICTION,
555 rejected_stream->SendRequest(headers, NULL, &response,
556 &callback_));
557
558 failed_stream->Close(true);
559 evicted_stream->Close(true);
560 rejected_stream->Close(true);
561 }
562
563 TEST_F(HttpPipelinedConnectionImplTest, ConnectionSuddenlyClosedAfterResponse) {
564 MockWrite writes[] = {
565 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
566 MockWrite(false, 1, "GET /read_evicted.html HTTP/1.1\r\n\r\n"),
567 MockWrite(false, 2, "GET /read_rejected.html HTTP/1.1\r\n\r\n"),
568 MockWrite(true, ERR_SOCKET_NOT_CONNECTED, 5),
569 };
570 MockRead reads[] = {
571 MockRead(false, 3, "HTTP/1.1 200 OK\r\n\r\n"),
572 MockRead(false, 4, "ok.html"),
573 };
574 Initialize(reads, arraysize(reads), writes, arraysize(writes));
575
576 scoped_ptr<HttpStream> closed_stream(NewTestStream("ok.html"));
577 scoped_ptr<HttpStream> read_evicted_stream(
578 NewTestStream("read_evicted.html"));
579 scoped_ptr<HttpStream> read_rejected_stream(
580 NewTestStream("read_rejected.html"));
581 scoped_ptr<HttpStream> send_closed_stream(
582 NewTestStream("send_closed.html"));
583 scoped_ptr<HttpStream> send_evicted_stream(
584 NewTestStream("send_evicted.html"));
585 scoped_ptr<HttpStream> send_rejected_stream(
586 NewTestStream("send_rejected.html"));
587
588 HttpRequestHeaders headers;
589 HttpResponseInfo response;
590 EXPECT_EQ(OK, closed_stream->SendRequest(headers, NULL, &response,
591 &callback_));
592 EXPECT_EQ(OK, read_evicted_stream->SendRequest(headers, NULL, &response,
593 &callback_));
594 EXPECT_EQ(OK, read_rejected_stream->SendRequest(headers, NULL, &response,
595 &callback_));
596 TestCompletionCallback send_closed_callback;
597 EXPECT_EQ(ERR_IO_PENDING,
598 send_closed_stream->SendRequest(headers, NULL, &response,
599 &send_closed_callback));
600 TestCompletionCallback send_evicted_callback;
601 EXPECT_EQ(ERR_IO_PENDING,
602 send_evicted_stream->SendRequest(headers, NULL, &response,
603 &send_evicted_callback));
604
605 TestCompletionCallback read_evicted_callback;
606 EXPECT_EQ(ERR_IO_PENDING,
607 read_evicted_stream->ReadResponseHeaders(&read_evicted_callback));
608
609 EXPECT_EQ(OK, closed_stream->ReadResponseHeaders(&callback_));
610 std::string expected = "ok.html";
611 scoped_refptr<IOBuffer> buffer(new IOBuffer(expected.size() + 10));
612 EXPECT_EQ(static_cast<int>(expected.size()),
613 closed_stream->ReadResponseBody(buffer.get(), expected.size() + 10,
614 &callback_));
615 std::string actual(buffer->data(), expected.size());
616 EXPECT_THAT(actual, StrEq(expected));
mmenke 2011/08/23 19:05:25 nit: Instead of the above lines, could just use:
James Simonsen 2011/08/26 22:19:07 Good eye. Fixed.
617 closed_stream->Close(true);
618
619 EXPECT_EQ(ERR_PIPELINE_EVICTION, read_evicted_callback.WaitForResult());
620 read_evicted_stream->Close(true);
621
622 EXPECT_EQ(ERR_PIPELINE_EVICTION,
623 read_rejected_stream->ReadResponseHeaders(&callback_));
624 read_rejected_stream->Close(true);
625
626 data_->RunFor(1);
627 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, send_closed_callback.WaitForResult());
628 send_closed_stream->Close(true);
629
630 EXPECT_EQ(ERR_PIPELINE_EVICTION, send_evicted_callback.WaitForResult());
631 send_evicted_stream->Close(true);
632
633 EXPECT_EQ(ERR_PIPELINE_EVICTION,
634 send_rejected_stream->SendRequest(headers, NULL, &response,
635 &callback_));
636 send_rejected_stream->Close(true);
637 }
638
639 TEST_F(HttpPipelinedConnectionImplTest, AbortWhileReadingHeaders) {
640 MockWrite writes[] = {
641 MockWrite(false, 0, "GET /aborts.html HTTP/1.1\r\n\r\n"),
642 MockWrite(false, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"),
643 };
644 MockRead reads[] = {
645 MockRead(true, ERR_FAILED, 2),
646 };
647 Initialize(reads, arraysize(reads), writes, arraysize(writes));
648
649 scoped_ptr<HttpStream> aborted_stream(NewTestStream("aborts.html"));
650 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html"));
651 scoped_ptr<HttpStream> rejected_stream(NewTestStream(
652 "rejected.html"));
653
654 HttpRequestHeaders headers;
655 HttpResponseInfo response;
656 EXPECT_EQ(OK, aborted_stream->SendRequest(headers, NULL, &response,
657 &callback_));
658 EXPECT_EQ(OK, evicted_stream->SendRequest(headers, NULL, &response,
659 &callback_));
660
661 EXPECT_EQ(ERR_IO_PENDING, aborted_stream->ReadResponseHeaders(&callback_));
662 TestCompletionCallback evicted_callback;
663 EXPECT_EQ(ERR_IO_PENDING,
664 evicted_stream->ReadResponseHeaders(&evicted_callback));
665
666 aborted_stream->Close(true);
667 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult());
668 evicted_stream->Close(true);
669
670 EXPECT_EQ(ERR_PIPELINE_EVICTION,
671 rejected_stream->SendRequest(headers, NULL, &response, &callback_));
672 rejected_stream->Close(true);
673 }
674
675 TEST_F(HttpPipelinedConnectionImplTest, PendingResponseAbandoned) {
mmenke 2011/08/23 19:05:25 Out of general paranoia, should also have tests wh
James Simonsen 2011/08/26 22:19:07 Nice. Caught a bug too.
676 MockWrite writes[] = {
677 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
678 MockWrite(false, 1, "GET /abandoned.html HTTP/1.1\r\n\r\n"),
679 MockWrite(false, 2, "GET /evicted.html HTTP/1.1\r\n\r\n"),
680 };
681 MockRead reads[] = {
682 MockRead(false, 3, "HTTP/1.1 200 OK\r\n"),
683 MockRead(false, 4, "Content-Length: 7\r\n\r\n"),
684 MockRead(false, 5, "ok.html"),
685 };
686 Initialize(reads, arraysize(reads), writes, arraysize(writes));
687
688 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html"));
689 scoped_ptr<HttpStream> abandoned_stream(
690 NewTestStream("abandoned.html"));
691 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html"));
692
693 HttpRequestHeaders headers;
694 HttpResponseInfo response;
695 EXPECT_EQ(OK, ok_stream->SendRequest(headers, NULL, &response, &callback_));
696 EXPECT_EQ(OK, abandoned_stream->SendRequest(headers, NULL, &response,
697 &callback_));
698 EXPECT_EQ(OK, evicted_stream->SendRequest(headers, NULL, &response,
699 &callback_));
700
701 EXPECT_EQ(OK, ok_stream->ReadResponseHeaders(&callback_));
702 TestCompletionCallback abandoned_callback;
703 EXPECT_EQ(ERR_IO_PENDING,
704 abandoned_stream->ReadResponseHeaders(&abandoned_callback));
705 TestCompletionCallback evicted_callback;
706 EXPECT_EQ(ERR_IO_PENDING,
707 evicted_stream->ReadResponseHeaders(&evicted_callback));
708
709 abandoned_stream->Close(false);
710
711 ExpectResponse("ok.html", ok_stream, false);
712 ok_stream->Close(false);
713
714 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult());
715 evicted_stream->Close(true);
716 EXPECT_FALSE(evicted_stream->IsConnectionReusable());
717 }
718
719 TEST_F(HttpPipelinedConnectionImplTest, OnPipelineHasCapacity) {
720 MockWrite writes[] = {
721 MockWrite(false, 0, "GET /ok.html HTTP/1.1\r\n\r\n"),
722 };
723 MockRead reads[] = {};
724 Initialize(reads, 0, writes, arraysize(writes));
725
726 scoped_ptr<HttpStream> stream(NewTestStream("ok.html"));
727
728 EXPECT_CALL(owner_, OnPipelineHasCapacity(pipeline_.get())).Times(1);
729 HttpRequestHeaders headers;
730 HttpResponseInfo response;
731 EXPECT_EQ(OK, stream->SendRequest(headers, NULL, &response, &callback_));
732 MessageLoop::current()->RunAllPending();
733
734 stream->Close(false);
735 EXPECT_CALL(owner_, OnPipelineHasCapacity(pipeline_.get())).Times(1);
736 stream.reset(NULL);
737 MessageLoop::current()->RunAllPending();
738 }
739
740 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698