OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/chromium/quic_chromium_client_stream.h" | 5 #include "net/quic/chromium/quic_chromium_client_stream.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
44 | 44 |
45 MOCK_METHOD0(OnSendData, int()); | 45 MOCK_METHOD0(OnSendData, int()); |
46 MOCK_METHOD2(OnSendDataComplete, int(int, bool*)); | 46 MOCK_METHOD2(OnSendDataComplete, int(int, bool*)); |
47 void OnTrailingHeadersAvailable(const SpdyHeaderBlock& headers, | 47 void OnTrailingHeadersAvailable(const SpdyHeaderBlock& headers, |
48 size_t frame_len) override { | 48 size_t frame_len) override { |
49 trailers_ = headers.Clone(); | 49 trailers_ = headers.Clone(); |
50 OnTrailingHeadersAvailableMock(headers, frame_len); | 50 OnTrailingHeadersAvailableMock(headers, frame_len); |
51 } | 51 } |
52 MOCK_METHOD2(OnTrailingHeadersAvailableMock, | 52 MOCK_METHOD2(OnTrailingHeadersAvailableMock, |
53 void(const SpdyHeaderBlock& headers, size_t frame_len)); | 53 void(const SpdyHeaderBlock& headers, size_t frame_len)); |
54 MOCK_METHOD2(OnDataReceived, int(const char*, int)); | |
55 MOCK_METHOD0(OnDataAvailable, void()); | |
56 MOCK_METHOD0(OnClose, void()); | 54 MOCK_METHOD0(OnClose, void()); |
57 MOCK_METHOD1(OnError, void(int)); | 55 MOCK_METHOD1(OnError, void(int)); |
58 MOCK_METHOD0(HasSendHeadersComplete, bool()); | 56 MOCK_METHOD0(HasSendHeadersComplete, bool()); |
59 | 57 |
60 SpdyHeaderBlock headers_; | 58 SpdyHeaderBlock headers_; |
61 SpdyHeaderBlock trailers_; | 59 SpdyHeaderBlock trailers_; |
62 | 60 |
63 private: | 61 private: |
64 DISALLOW_COPY_AND_ASSIGN(MockDelegate); | 62 DISALLOW_COPY_AND_ASSIGN(MockDelegate); |
65 }; | 63 }; |
66 | 64 |
67 class TestQuicClientSessionBaseStream : public QuicSpdyStream { | |
68 public: | |
69 TestQuicClientSessionBaseStream(QuicStreamId id, QuicSpdySession* session) | |
70 : QuicSpdyStream(id, session) {} | |
71 | |
72 void OnDataAvailable() override {} | |
73 }; | |
74 | |
75 class MockQuicClientSessionBase : public QuicClientSessionBase { | 65 class MockQuicClientSessionBase : public QuicClientSessionBase { |
76 public: | 66 public: |
77 explicit MockQuicClientSessionBase(QuicConnection* connection, | 67 explicit MockQuicClientSessionBase(QuicConnection* connection, |
78 QuicClientPushPromiseIndex* index); | 68 QuicClientPushPromiseIndex* index); |
79 ~MockQuicClientSessionBase() override; | 69 ~MockQuicClientSessionBase() override; |
80 | 70 |
81 const QuicCryptoStream* GetCryptoStream() const override { | 71 const QuicCryptoStream* GetCryptoStream() const override { |
82 return crypto_stream_.get(); | 72 return crypto_stream_.get(); |
83 } | 73 } |
84 | 74 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
135 WriteHeadersMock, | 125 WriteHeadersMock, |
136 size_t(QuicStreamId id, | 126 size_t(QuicStreamId id, |
137 const SpdyHeaderBlock& headers, | 127 const SpdyHeaderBlock& headers, |
138 bool fin, | 128 bool fin, |
139 SpdyPriority priority, | 129 SpdyPriority priority, |
140 const QuicReferenceCountedPointer<QuicAckListenerInterface>& | 130 const QuicReferenceCountedPointer<QuicAckListenerInterface>& |
141 ack_listener)); | 131 ack_listener)); |
142 MOCK_METHOD1(OnHeadersHeadOfLineBlocking, void(QuicTime::Delta delta)); | 132 MOCK_METHOD1(OnHeadersHeadOfLineBlocking, void(QuicTime::Delta delta)); |
143 | 133 |
144 std::unique_ptr<QuicStream> CreateStream(QuicStreamId id) { | 134 std::unique_ptr<QuicStream> CreateStream(QuicStreamId id) { |
145 return QuicMakeUnique<TestQuicClientSessionBaseStream>(id, this); | 135 return QuicMakeUnique<QuicChromiumClientStream>(id, this, |
136 NetLogWithSource()); | |
146 } | 137 } |
147 | 138 |
148 using QuicSession::ActivateStream; | 139 using QuicSession::ActivateStream; |
149 | 140 |
150 // Returns a QuicConsumedData that indicates all of |data| (and |fin| if set) | 141 // Returns a QuicConsumedData that indicates all of |data| (and |fin| if set) |
151 // has been consumed. | 142 // has been consumed. |
152 static QuicConsumedData ConsumeAllData( | 143 static QuicConsumedData ConsumeAllData( |
153 QuicStreamId id, | 144 QuicStreamId id, |
154 const QuicIOVector& data, | 145 const QuicIOVector& data, |
155 QuicStreamOffset offset, | 146 QuicStreamOffset offset, |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
264 } | 255 } |
265 | 256 |
266 QuicStreamId GetNthClientInitiatedStreamId(int n) { | 257 QuicStreamId GetNthClientInitiatedStreamId(int n) { |
267 return QuicSpdySessionPeer::GetNthClientInitiatedStreamId(session_, n); | 258 return QuicSpdySessionPeer::GetNthClientInitiatedStreamId(session_, n); |
268 } | 259 } |
269 | 260 |
270 QuicStreamId GetNthServerInitiatedStreamId(int n) { | 261 QuicStreamId GetNthServerInitiatedStreamId(int n) { |
271 return QuicSpdySessionPeer::GetNthServerInitiatedStreamId(session_, n); | 262 return QuicSpdySessionPeer::GetNthServerInitiatedStreamId(session_, n); |
272 } | 263 } |
273 | 264 |
265 void ResetStreamCallback(QuicChromiumClientStream* stream, int /*rv*/) { | |
266 stream->Reset(QUIC_STREAM_CANCELLED); | |
267 } | |
268 | |
274 QuicCryptoClientConfig crypto_config_; | 269 QuicCryptoClientConfig crypto_config_; |
275 std::unique_ptr<QuicChromiumClientStream::Handle> handle_; | 270 std::unique_ptr<QuicChromiumClientStream::Handle> handle_; |
276 testing::StrictMock<MockDelegate> delegate_; | 271 testing::StrictMock<MockDelegate> delegate_; |
277 std::unique_ptr<QuicChromiumClientStream::Handle> handle2_; | 272 std::unique_ptr<QuicChromiumClientStream::Handle> handle2_; |
278 testing::StrictMock<MockDelegate> delegate2_; | 273 testing::StrictMock<MockDelegate> delegate2_; |
279 MockQuicConnectionHelper helper_; | 274 MockQuicConnectionHelper helper_; |
280 MockAlarmFactory alarm_factory_; | 275 MockAlarmFactory alarm_factory_; |
281 MockQuicClientSessionBase session_; | 276 MockQuicClientSessionBase session_; |
282 QuicChromiumClientStream* stream_; | 277 QuicChromiumClientStream* stream_; |
283 SpdyHeaderBlock headers_; | 278 SpdyHeaderBlock headers_; |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
389 | 384 |
390 TEST_P(QuicChromiumClientStreamTest, OnFinRead) { | 385 TEST_P(QuicChromiumClientStreamTest, OnFinRead) { |
391 InitializeHeaders(); | 386 InitializeHeaders(); |
392 QuicStreamOffset offset = 0; | 387 QuicStreamOffset offset = 0; |
393 ProcessHeadersFull(headers_); | 388 ProcessHeadersFull(headers_); |
394 QuicStreamFrame frame2(kTestStreamId, true, offset, QuicStringPiece()); | 389 QuicStreamFrame frame2(kTestStreamId, true, offset, QuicStringPiece()); |
395 EXPECT_CALL(delegate_, OnClose()); | 390 EXPECT_CALL(delegate_, OnClose()); |
396 stream_->OnStreamFrame(frame2); | 391 stream_->OnStreamFrame(frame2); |
397 } | 392 } |
398 | 393 |
399 TEST_P(QuicChromiumClientStreamTest, OnDataAvailableBeforeHeaders) { | |
400 EXPECT_CALL(delegate_, OnClose()); | |
401 | |
402 EXPECT_CALL(delegate_, OnDataAvailable()).Times(0); | |
403 stream_->OnDataAvailable(); | |
404 } | |
405 | |
406 TEST_P(QuicChromiumClientStreamTest, OnDataAvailable) { | 394 TEST_P(QuicChromiumClientStreamTest, OnDataAvailable) { |
407 InitializeHeaders(); | 395 InitializeHeaders(); |
408 ProcessHeadersFull(headers_); | 396 ProcessHeadersFull(headers_); |
409 | 397 |
410 const char data[] = "hello world!"; | 398 const char data[] = "hello world!"; |
399 int data_len = strlen(data); | |
411 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, | 400 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, |
412 /*offset=*/0, data)); | 401 /*offset=*/0, data)); |
413 | 402 |
414 EXPECT_CALL(delegate_, OnDataAvailable()) | 403 // Read the body and verify that it arrives correctly. |
415 .WillOnce(testing::Invoke(CreateFunctor( | 404 TestCompletionCallback callback; |
416 &QuicChromiumClientStreamTest::ReadData, base::Unretained(this), | 405 scoped_refptr<IOBuffer> buffer(new IOBuffer(2 * data_len)); |
417 QuicStringPiece(data, arraysize(data) - 1)))); | 406 EXPECT_EQ(data_len, |
407 handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback())); | |
408 EXPECT_EQ(QuicStringPiece(data), QuicStringPiece(buffer->data(), data_len)); | |
409 | |
410 EXPECT_CALL(delegate_, OnClose()); | |
411 } | |
412 | |
413 TEST_P(QuicChromiumClientStreamTest, OnDataAvailableEarly) { | |
xunjieli
2017/05/12 15:22:22
Why is this testing OnDataAvailable Early?
The OnS
Ryan Hamilton
2017/05/12 17:26:24
Good point. Done.
| |
414 InitializeHeaders(); | |
415 ProcessHeadersFull(headers_); | |
416 | |
417 const char data[] = "hello world!"; | |
418 int data_len = strlen(data); | |
419 | |
420 // Start to read the body. | |
421 TestCompletionCallback callback; | |
422 scoped_refptr<IOBuffer> buffer(new IOBuffer(2 * data_len)); | |
423 EXPECT_EQ(ERR_IO_PENDING, | |
424 handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback())); | |
425 | |
426 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, | |
427 /*offset=*/0, data)); | |
428 | |
429 EXPECT_EQ(data_len, callback.WaitForResult()); | |
430 EXPECT_EQ(QuicStringPiece(data), QuicStringPiece(buffer->data(), data_len)); | |
418 base::RunLoop().RunUntilIdle(); | 431 base::RunLoop().RunUntilIdle(); |
419 | 432 |
420 EXPECT_CALL(delegate_, OnClose()); | 433 EXPECT_CALL(delegate_, OnClose()); |
421 } | 434 } |
422 | 435 |
423 TEST_P(QuicChromiumClientStreamTest, ProcessHeadersWithError) { | 436 TEST_P(QuicChromiumClientStreamTest, ProcessHeadersWithError) { |
424 SpdyHeaderBlock bad_headers; | 437 SpdyHeaderBlock bad_headers; |
425 bad_headers["NAME"] = "..."; | 438 bad_headers["NAME"] = "..."; |
426 EXPECT_CALL(session_, | 439 EXPECT_CALL(session_, |
427 SendRstStream(kTestStreamId, QUIC_BAD_APPLICATION_PAYLOAD, 0)); | 440 SendRstStream(kTestStreamId, QUIC_BAD_APPLICATION_PAYLOAD, 0)); |
428 | 441 |
429 auto headers = AsHeaderList(bad_headers); | 442 auto headers = AsHeaderList(bad_headers); |
430 stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), | 443 stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), |
431 headers); | 444 headers); |
432 | 445 |
433 base::RunLoop().RunUntilIdle(); | 446 base::RunLoop().RunUntilIdle(); |
434 | 447 |
435 EXPECT_CALL(delegate_, OnClose()); | 448 EXPECT_CALL(delegate_, OnClose()); |
436 } | 449 } |
437 | 450 |
438 TEST_P(QuicChromiumClientStreamTest, OnDataAvailableWithError) { | 451 TEST_P(QuicChromiumClientStreamTest, OnDataAvailableWithError) { |
439 InitializeHeaders(); | 452 InitializeHeaders(); |
440 auto headers = AsHeaderList(headers_); | 453 auto headers = AsHeaderList(headers_); |
441 ProcessHeadersFull(headers_); | 454 ProcessHeadersFull(headers_); |
442 EXPECT_CALL(session_, SendRstStream(kTestStreamId, QUIC_STREAM_CANCELLED, 0)); | 455 EXPECT_CALL(session_, SendRstStream(kTestStreamId, QUIC_STREAM_CANCELLED, 0)); |
443 | 456 |
444 const char data[] = "hello world!"; | 457 const char data[] = "hello world!"; |
458 int data_len = strlen(data); | |
459 | |
460 // Start to read the body. | |
461 TestCompletionCallback callback; | |
462 scoped_refptr<IOBuffer> buffer(new IOBuffer(2 * data_len)); | |
463 EXPECT_EQ(ERR_IO_PENDING, | |
464 handle_->ReadBody( | |
465 buffer.get(), 2 * data_len, | |
466 base::Bind(&QuicChromiumClientStreamTest::ResetStreamCallback, | |
467 base::Unretained(this), stream_))); | |
468 | |
469 // Receive the data and close the stream during the callback. | |
445 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, | 470 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, |
446 /*offset=*/0, data)); | 471 /*offset=*/0, data)); |
447 EXPECT_CALL(delegate_, OnDataAvailable()) | 472 |
448 .WillOnce(testing::Invoke(CreateFunctor( | |
449 &QuicChromiumClientStream::Reset, | |
450 base::Unretained(stream_), QUIC_STREAM_CANCELLED))); | |
451 base::RunLoop().RunUntilIdle(); | 473 base::RunLoop().RunUntilIdle(); |
452 | 474 |
453 EXPECT_CALL(delegate_, OnClose()); | 475 EXPECT_CALL(delegate_, OnClose()); |
454 } | 476 } |
455 | 477 |
456 TEST_P(QuicChromiumClientStreamTest, OnError) { | 478 TEST_P(QuicChromiumClientStreamTest, OnError) { |
457 EXPECT_CALL(delegate_, OnError(ERR_INTERNET_DISCONNECTED)).Times(1); | 479 EXPECT_CALL(delegate_, OnError(ERR_INTERNET_DISCONNECTED)).Times(1); |
458 | 480 |
459 stream_->OnError(ERR_INTERNET_DISCONNECTED); | 481 stream_->OnError(ERR_INTERNET_DISCONNECTED); |
460 stream_->OnError(ERR_INTERNET_DISCONNECTED); | 482 stream_->OnError(ERR_INTERNET_DISCONNECTED); |
461 } | 483 } |
462 | 484 |
463 TEST_P(QuicChromiumClientStreamTest, OnTrailers) { | 485 TEST_P(QuicChromiumClientStreamTest, OnTrailers) { |
464 InitializeHeaders(); | 486 InitializeHeaders(); |
465 ProcessHeadersFull(headers_); | 487 ProcessHeadersFull(headers_); |
466 | 488 |
467 const char data[] = "hello world!"; | 489 const char data[] = "hello world!"; |
490 int data_len = strlen(data); | |
468 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, | 491 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, |
469 /*offset=*/0, data)); | 492 /*offset=*/0, data)); |
470 | 493 |
471 EXPECT_CALL(delegate_, OnDataAvailable()) | 494 // Read the body and verify that it arrives correctly. |
472 .WillOnce(testing::Invoke(CreateFunctor( | 495 TestCompletionCallback callback; |
473 &QuicChromiumClientStreamTest::ReadData, base::Unretained(this), | 496 scoped_refptr<IOBuffer> buffer(new IOBuffer(2 * data_len)); |
474 QuicStringPiece(data, arraysize(data) - 1)))); | 497 EXPECT_EQ(data_len, |
498 handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback())); | |
499 EXPECT_EQ(QuicStringPiece(data), QuicStringPiece(buffer->data(), data_len)); | |
475 | 500 |
476 SpdyHeaderBlock trailers; | 501 SpdyHeaderBlock trailers; |
477 trailers["bar"] = "foo"; | 502 trailers["bar"] = "foo"; |
478 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); | 503 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); |
479 | 504 |
480 auto t = ProcessTrailers(trailers); | 505 auto t = ProcessTrailers(trailers); |
481 base::RunLoop run_loop; | 506 base::RunLoop run_loop; |
482 EXPECT_CALL(delegate_, | 507 EXPECT_CALL(delegate_, |
483 OnTrailingHeadersAvailableMock(_, t.uncompressed_header_bytes())) | 508 OnTrailingHeadersAvailableMock(_, t.uncompressed_header_bytes())) |
484 .WillOnce(testing::InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); | 509 .WillOnce(testing::InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); |
485 | 510 |
486 run_loop.Run(); | 511 run_loop.Run(); |
487 | 512 |
488 // OnDataAvailable callback should follow trailers notification. | 513 // Read the body and verify that it arrives correctly. |
489 base::RunLoop run_loop3; | 514 EXPECT_EQ(0, |
490 EXPECT_CALL(delegate_, OnDataAvailable()) | 515 handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback())); |
491 .Times(1) | |
492 .WillOnce(testing::DoAll( | |
493 testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData, | |
494 base::Unretained(this), | |
495 QuicStringPiece())), | |
496 testing::InvokeWithoutArgs([&run_loop3]() { run_loop3.Quit(); }))); | |
497 run_loop3.Run(); | |
498 | 516 |
499 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. | 517 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. |
500 trailers.erase(kFinalOffsetHeaderKey); | 518 trailers.erase(kFinalOffsetHeaderKey); |
501 EXPECT_EQ(trailers, delegate_.trailers_); | 519 EXPECT_EQ(trailers, delegate_.trailers_); |
502 base::RunLoop().RunUntilIdle(); | 520 base::RunLoop().RunUntilIdle(); |
503 EXPECT_CALL(delegate_, OnClose()); | 521 EXPECT_CALL(delegate_, OnClose()); |
504 } | 522 } |
505 | 523 |
506 // Tests that trailers are marked as consumed only before delegate is to be | 524 // Tests that trailers are marked as consumed only before delegate is to be |
507 // immediately notified about trailers. | 525 // immediately notified about trailers. |
508 TEST_P(QuicChromiumClientStreamTest, MarkTrailersConsumedWhenNotifyDelegate) { | 526 TEST_P(QuicChromiumClientStreamTest, MarkTrailersConsumedWhenNotifyDelegate) { |
509 InitializeHeaders(); | 527 InitializeHeaders(); |
510 ProcessHeadersFull(headers_); | 528 ProcessHeadersFull(headers_); |
511 | 529 |
512 const char data[] = "hello world!"; | 530 const char data[] = "hello world!"; |
531 int data_len = strlen(data); | |
513 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, | 532 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, |
514 /*offset=*/0, data)); | 533 /*offset=*/0, data)); |
515 | 534 |
516 base::RunLoop run_loop; | 535 // Read the body and verify that it arrives correctly. |
517 EXPECT_CALL(delegate_, OnDataAvailable()) | 536 TestCompletionCallback callback; |
518 .Times(1) | 537 scoped_refptr<IOBuffer> buffer(new IOBuffer(2 * data_len)); |
519 .WillOnce(testing::DoAll( | 538 EXPECT_EQ(data_len, |
520 testing::Invoke(CreateFunctor( | 539 handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback())); |
521 &QuicChromiumClientStreamTest::ReadData, base::Unretained(this), | 540 EXPECT_EQ(QuicStringPiece(data), QuicStringPiece(buffer->data(), data_len)); |
522 QuicStringPiece(data, arraysize(data) - 1))), | |
523 testing::Invoke([&run_loop]() { run_loop.Quit(); }))); | |
524 | |
525 // Wait for the read to complete. | |
526 run_loop.Run(); | |
527 | 541 |
528 // Read again, and it will be pending. | 542 // Read again, and it will be pending. |
529 scoped_refptr<IOBuffer> buffer(new IOBuffer(1)); | 543 EXPECT_THAT( |
530 EXPECT_THAT(stream_->Read(buffer.get(), 1), IsError(ERR_IO_PENDING)); | 544 handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback()), |
545 IsError(ERR_IO_PENDING)); | |
531 | 546 |
532 SpdyHeaderBlock trailers; | 547 SpdyHeaderBlock trailers; |
533 trailers["bar"] = "foo"; | 548 trailers["bar"] = "foo"; |
534 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); | 549 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); |
535 QuicHeaderList t = ProcessTrailers(trailers); | 550 QuicHeaderList t = ProcessTrailers(trailers); |
536 EXPECT_FALSE(stream_->IsDoneReading()); | 551 EXPECT_FALSE(stream_->IsDoneReading()); |
537 | 552 |
538 base::RunLoop run_loop2; | 553 base::RunLoop run_loop2; |
539 EXPECT_CALL(delegate_, | 554 EXPECT_CALL(delegate_, |
540 OnTrailingHeadersAvailableMock(_, t.uncompressed_header_bytes())) | 555 OnTrailingHeadersAvailableMock(_, t.uncompressed_header_bytes())) |
541 .WillOnce( | 556 .WillOnce( |
542 testing::InvokeWithoutArgs([&run_loop2]() { run_loop2.Quit(); })); | 557 testing::InvokeWithoutArgs([&run_loop2]() { run_loop2.Quit(); })); |
543 | 558 |
544 run_loop2.Run(); | 559 run_loop2.Run(); |
545 | 560 |
546 // OnDataAvailable callback should follow trailers notification. | 561 // Read the body and verify that it arrives correctly. |
547 base::RunLoop run_loop3; | 562 EXPECT_EQ(0, callback.WaitForResult()); |
548 EXPECT_CALL(delegate_, OnDataAvailable()) | |
549 .Times(1) | |
550 .WillOnce(testing::DoAll( | |
551 testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData, | |
552 base::Unretained(this), | |
553 QuicStringPiece())), | |
554 testing::InvokeWithoutArgs([&run_loop3]() { run_loop3.Quit(); }))); | |
555 run_loop3.Run(); | |
556 | 563 |
557 // Make sure the stream is properly closed since trailers and data are all | 564 // Make sure the stream is properly closed since trailers and data are all |
558 // consumed. | 565 // consumed. |
559 EXPECT_TRUE(stream_->IsDoneReading()); | 566 EXPECT_TRUE(stream_->IsDoneReading()); |
560 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. | 567 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. |
561 trailers.erase(kFinalOffsetHeaderKey); | 568 trailers.erase(kFinalOffsetHeaderKey); |
562 EXPECT_EQ(trailers, delegate_.trailers_); | 569 EXPECT_EQ(trailers, delegate_.trailers_); |
563 | 570 |
564 base::RunLoop().RunUntilIdle(); | 571 base::RunLoop().RunUntilIdle(); |
565 EXPECT_CALL(delegate_, OnClose()); | 572 EXPECT_CALL(delegate_, OnClose()); |
566 } | 573 } |
567 | 574 |
568 // Test that if Read() is called after response body is read and after trailers | 575 // Test that if Read() is called after response body is read and after trailers |
569 // are received but not yet delivered, Read() will return ERR_IO_PENDING instead | 576 // are received but not yet delivered, Read() will return ERR_IO_PENDING instead |
570 // of 0 (EOF). | 577 // of 0 (EOF). |
571 TEST_P(QuicChromiumClientStreamTest, ReadAfterTrailersReceivedButNotDelivered) { | 578 TEST_P(QuicChromiumClientStreamTest, ReadAfterTrailersReceivedButNotDelivered) { |
572 InitializeHeaders(); | 579 InitializeHeaders(); |
573 ProcessHeadersFull(headers_); | 580 ProcessHeadersFull(headers_); |
574 | 581 |
575 const char data[] = "hello world!"; | 582 const char data[] = "hello world!"; |
583 int data_len = strlen(data); | |
576 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, | 584 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, |
577 /*offset=*/0, data)); | 585 /*offset=*/0, data)); |
578 | 586 |
579 base::RunLoop run_loop; | 587 // Read the body and verify that it arrives correctly. |
580 EXPECT_CALL(delegate_, OnDataAvailable()) | 588 TestCompletionCallback callback; |
581 .Times(1) | 589 scoped_refptr<IOBuffer> buffer(new IOBuffer(2 * data_len)); |
582 .WillOnce(testing::DoAll( | 590 EXPECT_EQ(data_len, |
583 testing::Invoke(CreateFunctor( | 591 handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback())); |
584 &QuicChromiumClientStreamTest::ReadData, base::Unretained(this), | 592 EXPECT_EQ(QuicStringPiece(data), QuicStringPiece(buffer->data(), data_len)); |
585 QuicStringPiece(data, arraysize(data) - 1))), | |
586 testing::Invoke([&run_loop]() { run_loop.Quit(); }))); | |
587 | |
588 // Wait for the read to complete. | |
589 run_loop.Run(); | |
590 | 593 |
591 // Deliver trailers. Delegate notification is posted asynchronously. | 594 // Deliver trailers. Delegate notification is posted asynchronously. |
592 SpdyHeaderBlock trailers; | 595 SpdyHeaderBlock trailers; |
593 trailers["bar"] = "foo"; | 596 trailers["bar"] = "foo"; |
594 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); | 597 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); |
595 | 598 |
596 QuicHeaderList t = ProcessTrailers(trailers); | 599 QuicHeaderList t = ProcessTrailers(trailers); |
597 | 600 |
601 EXPECT_FALSE(stream_->IsDoneReading()); | |
598 // Read again, it return ERR_IO_PENDING. | 602 // Read again, it return ERR_IO_PENDING. |
599 scoped_refptr<IOBuffer> buffer(new IOBuffer(1)); | 603 EXPECT_THAT( |
600 EXPECT_THAT(stream_->Read(buffer.get(), 1), ERR_IO_PENDING); | 604 handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback()), |
605 IsError(ERR_IO_PENDING)); | |
601 | 606 |
602 // Trailers are not delivered | 607 // Trailers are not delivered |
603 EXPECT_FALSE(stream_->IsDoneReading()); | 608 EXPECT_FALSE(stream_->IsDoneReading()); |
604 | 609 |
605 base::RunLoop run_loop2; | 610 base::RunLoop run_loop2; |
606 EXPECT_CALL(delegate_, | 611 EXPECT_CALL(delegate_, |
607 OnTrailingHeadersAvailableMock(_, t.uncompressed_header_bytes())) | 612 OnTrailingHeadersAvailableMock(_, t.uncompressed_header_bytes())) |
608 .WillOnce( | 613 .WillOnce( |
609 testing::InvokeWithoutArgs([&run_loop2]() { run_loop2.Quit(); })); | 614 testing::InvokeWithoutArgs([&run_loop2]() { run_loop2.Quit(); })); |
610 | 615 |
611 run_loop2.Run(); | 616 run_loop2.Run(); |
612 | 617 |
613 base::RunLoop run_loop3; | 618 // Read the body and verify that it arrives correctly. |
614 // OnDataAvailable() should follow right after and Read() will return 0. | 619 // OnDataAvailable() should follow right after and Read() will return 0. |
615 EXPECT_CALL(delegate_, OnDataAvailable()) | 620 EXPECT_EQ(0, callback.WaitForResult()); |
616 .WillOnce(testing::DoAll( | |
617 testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData, | |
618 base::Unretained(this), | |
619 QuicStringPiece())), | |
620 testing::Invoke([&run_loop3]() { run_loop3.Quit(); }))); | |
621 run_loop3.Run(); | |
622 | 621 |
623 // Make sure the stream is properly closed since trailers and data are all | 622 // Make sure the stream is properly closed since trailers and data are all |
624 // consumed. | 623 // consumed. |
625 EXPECT_TRUE(stream_->IsDoneReading()); | 624 EXPECT_TRUE(stream_->IsDoneReading()); |
626 | 625 |
627 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. | 626 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. |
628 trailers.erase(kFinalOffsetHeaderKey); | 627 trailers.erase(kFinalOffsetHeaderKey); |
629 EXPECT_EQ(trailers, delegate_.trailers_); | 628 EXPECT_EQ(trailers, delegate_.trailers_); |
630 | 629 |
631 base::RunLoop().RunUntilIdle(); | 630 base::RunLoop().RunUntilIdle(); |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
781 EXPECT_EQ(QuicStringPiece(data), QuicStringPiece(buffer->data(), data_len)); | 780 EXPECT_EQ(QuicStringPiece(data), QuicStringPiece(buffer->data(), data_len)); |
782 | 781 |
783 // Both delegates should be notified that theirs streams are closed. | 782 // Both delegates should be notified that theirs streams are closed. |
784 EXPECT_CALL(delegate2_, OnClose()); | 783 EXPECT_CALL(delegate2_, OnClose()); |
785 EXPECT_CALL(delegate_, OnClose()); | 784 EXPECT_CALL(delegate_, OnClose()); |
786 } | 785 } |
787 | 786 |
788 } // namespace | 787 } // namespace |
789 } // namespace test | 788 } // namespace test |
790 } // namespace net | 789 } // namespace net |
OLD | NEW |