Chromium Code Reviews| 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 |