| 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_METHOD0(OnDataAvailable, void()); | |
| 55 MOCK_METHOD0(OnClose, void()); | 54 MOCK_METHOD0(OnClose, void()); |
| 56 MOCK_METHOD1(OnError, void(int)); | 55 MOCK_METHOD1(OnError, void(int)); |
| 57 MOCK_METHOD0(HasSendHeadersComplete, bool()); | 56 MOCK_METHOD0(HasSendHeadersComplete, bool()); |
| 58 | 57 |
| 59 SpdyHeaderBlock headers_; | 58 SpdyHeaderBlock headers_; |
| 60 SpdyHeaderBlock trailers_; | 59 SpdyHeaderBlock trailers_; |
| 61 | 60 |
| 62 private: | 61 private: |
| 63 DISALLOW_COPY_AND_ASSIGN(MockDelegate); | 62 DISALLOW_COPY_AND_ASSIGN(MockDelegate); |
| 64 }; | 63 }; |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 } | 255 } |
| 257 | 256 |
| 258 QuicStreamId GetNthClientInitiatedStreamId(int n) { | 257 QuicStreamId GetNthClientInitiatedStreamId(int n) { |
| 259 return QuicSpdySessionPeer::GetNthClientInitiatedStreamId(session_, n); | 258 return QuicSpdySessionPeer::GetNthClientInitiatedStreamId(session_, n); |
| 260 } | 259 } |
| 261 | 260 |
| 262 QuicStreamId GetNthServerInitiatedStreamId(int n) { | 261 QuicStreamId GetNthServerInitiatedStreamId(int n) { |
| 263 return QuicSpdySessionPeer::GetNthServerInitiatedStreamId(session_, n); | 262 return QuicSpdySessionPeer::GetNthServerInitiatedStreamId(session_, n); |
| 264 } | 263 } |
| 265 | 264 |
| 265 void ResetStreamCallback(QuicChromiumClientStream* stream, int /*rv*/) { |
| 266 stream->Reset(QUIC_STREAM_CANCELLED); |
| 267 } |
| 268 |
| 266 QuicCryptoClientConfig crypto_config_; | 269 QuicCryptoClientConfig crypto_config_; |
| 267 std::unique_ptr<QuicChromiumClientStream::Handle> handle_; | 270 std::unique_ptr<QuicChromiumClientStream::Handle> handle_; |
| 268 testing::StrictMock<MockDelegate> delegate_; | 271 testing::StrictMock<MockDelegate> delegate_; |
| 269 std::unique_ptr<QuicChromiumClientStream::Handle> handle2_; | 272 std::unique_ptr<QuicChromiumClientStream::Handle> handle2_; |
| 270 testing::StrictMock<MockDelegate> delegate2_; | 273 testing::StrictMock<MockDelegate> delegate2_; |
| 271 MockQuicConnectionHelper helper_; | 274 MockQuicConnectionHelper helper_; |
| 272 MockAlarmFactory alarm_factory_; | 275 MockAlarmFactory alarm_factory_; |
| 273 MockQuicClientSessionBase session_; | 276 MockQuicClientSessionBase session_; |
| 274 QuicChromiumClientStream* stream_; | 277 QuicChromiumClientStream* stream_; |
| 275 SpdyHeaderBlock headers_; | 278 SpdyHeaderBlock headers_; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 | 384 |
| 382 TEST_P(QuicChromiumClientStreamTest, OnFinRead) { | 385 TEST_P(QuicChromiumClientStreamTest, OnFinRead) { |
| 383 InitializeHeaders(); | 386 InitializeHeaders(); |
| 384 QuicStreamOffset offset = 0; | 387 QuicStreamOffset offset = 0; |
| 385 ProcessHeadersFull(headers_); | 388 ProcessHeadersFull(headers_); |
| 386 QuicStreamFrame frame2(kTestStreamId, true, offset, QuicStringPiece()); | 389 QuicStreamFrame frame2(kTestStreamId, true, offset, QuicStringPiece()); |
| 387 EXPECT_CALL(delegate_, OnClose()); | 390 EXPECT_CALL(delegate_, OnClose()); |
| 388 stream_->OnStreamFrame(frame2); | 391 stream_->OnStreamFrame(frame2); |
| 389 } | 392 } |
| 390 | 393 |
| 391 TEST_P(QuicChromiumClientStreamTest, OnDataAvailableBeforeHeaders) { | |
| 392 EXPECT_CALL(delegate_, OnClose()); | |
| 393 | |
| 394 EXPECT_CALL(delegate_, OnDataAvailable()).Times(0); | |
| 395 stream_->OnDataAvailable(); | |
| 396 } | |
| 397 | |
| 398 TEST_P(QuicChromiumClientStreamTest, OnDataAvailable) { | 394 TEST_P(QuicChromiumClientStreamTest, OnDataAvailable) { |
| 399 InitializeHeaders(); | 395 InitializeHeaders(); |
| 400 ProcessHeadersFull(headers_); | 396 ProcessHeadersFull(headers_); |
| 401 | 397 |
| 402 const char data[] = "hello world!"; | 398 const char data[] = "hello world!"; |
| 399 int data_len = strlen(data); |
| 403 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, | 400 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, |
| 404 /*offset=*/0, data)); | 401 /*offset=*/0, data)); |
| 405 | 402 |
| 406 EXPECT_CALL(delegate_, OnDataAvailable()) | 403 // Read the body and verify that it arrives correctly. |
| 407 .WillOnce(testing::Invoke(CreateFunctor( | 404 TestCompletionCallback callback; |
| 408 &QuicChromiumClientStreamTest::ReadData, base::Unretained(this), | 405 scoped_refptr<IOBuffer> buffer(new IOBuffer(2 * data_len)); |
| 409 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, OnDataAvailableAfterReadBody) { |
| 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)); |
| 410 base::RunLoop().RunUntilIdle(); | 431 base::RunLoop().RunUntilIdle(); |
| 411 | 432 |
| 412 EXPECT_CALL(delegate_, OnClose()); | 433 EXPECT_CALL(delegate_, OnClose()); |
| 413 } | 434 } |
| 414 | 435 |
| 415 TEST_P(QuicChromiumClientStreamTest, ProcessHeadersWithError) { | 436 TEST_P(QuicChromiumClientStreamTest, ProcessHeadersWithError) { |
| 416 SpdyHeaderBlock bad_headers; | 437 SpdyHeaderBlock bad_headers; |
| 417 bad_headers["NAME"] = "..."; | 438 bad_headers["NAME"] = "..."; |
| 418 EXPECT_CALL(session_, | 439 EXPECT_CALL(session_, |
| 419 SendRstStream(kTestStreamId, QUIC_BAD_APPLICATION_PAYLOAD, 0)); | 440 SendRstStream(kTestStreamId, QUIC_BAD_APPLICATION_PAYLOAD, 0)); |
| 420 | 441 |
| 421 auto headers = AsHeaderList(bad_headers); | 442 auto headers = AsHeaderList(bad_headers); |
| 422 stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), | 443 stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), |
| 423 headers); | 444 headers); |
| 424 | 445 |
| 425 base::RunLoop().RunUntilIdle(); | 446 base::RunLoop().RunUntilIdle(); |
| 426 | 447 |
| 427 EXPECT_CALL(delegate_, OnClose()); | 448 EXPECT_CALL(delegate_, OnClose()); |
| 428 } | 449 } |
| 429 | 450 |
| 430 TEST_P(QuicChromiumClientStreamTest, OnDataAvailableWithError) { | 451 TEST_P(QuicChromiumClientStreamTest, OnDataAvailableWithError) { |
| 431 InitializeHeaders(); | 452 InitializeHeaders(); |
| 432 auto headers = AsHeaderList(headers_); | 453 auto headers = AsHeaderList(headers_); |
| 433 ProcessHeadersFull(headers_); | 454 ProcessHeadersFull(headers_); |
| 434 EXPECT_CALL(session_, SendRstStream(kTestStreamId, QUIC_STREAM_CANCELLED, 0)); | 455 EXPECT_CALL(session_, SendRstStream(kTestStreamId, QUIC_STREAM_CANCELLED, 0)); |
| 435 | 456 |
| 436 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. |
| 437 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, | 470 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, |
| 438 /*offset=*/0, data)); | 471 /*offset=*/0, data)); |
| 439 EXPECT_CALL(delegate_, OnDataAvailable()) | 472 |
| 440 .WillOnce(testing::Invoke(CreateFunctor( | |
| 441 &QuicChromiumClientStream::Reset, | |
| 442 base::Unretained(stream_), QUIC_STREAM_CANCELLED))); | |
| 443 base::RunLoop().RunUntilIdle(); | 473 base::RunLoop().RunUntilIdle(); |
| 444 | 474 |
| 445 EXPECT_CALL(delegate_, OnClose()); | 475 EXPECT_CALL(delegate_, OnClose()); |
| 446 } | 476 } |
| 447 | 477 |
| 448 TEST_P(QuicChromiumClientStreamTest, OnError) { | 478 TEST_P(QuicChromiumClientStreamTest, OnError) { |
| 449 EXPECT_CALL(delegate_, OnError(ERR_INTERNET_DISCONNECTED)).Times(1); | 479 EXPECT_CALL(delegate_, OnError(ERR_INTERNET_DISCONNECTED)).Times(1); |
| 450 | 480 |
| 451 stream_->OnError(ERR_INTERNET_DISCONNECTED); | 481 stream_->OnError(ERR_INTERNET_DISCONNECTED); |
| 452 stream_->OnError(ERR_INTERNET_DISCONNECTED); | 482 stream_->OnError(ERR_INTERNET_DISCONNECTED); |
| 453 } | 483 } |
| 454 | 484 |
| 455 TEST_P(QuicChromiumClientStreamTest, OnTrailers) { | 485 TEST_P(QuicChromiumClientStreamTest, OnTrailers) { |
| 456 InitializeHeaders(); | 486 InitializeHeaders(); |
| 457 ProcessHeadersFull(headers_); | 487 ProcessHeadersFull(headers_); |
| 458 | 488 |
| 459 const char data[] = "hello world!"; | 489 const char data[] = "hello world!"; |
| 490 int data_len = strlen(data); |
| 460 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, | 491 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, |
| 461 /*offset=*/0, data)); | 492 /*offset=*/0, data)); |
| 462 | 493 |
| 463 EXPECT_CALL(delegate_, OnDataAvailable()) | 494 // Read the body and verify that it arrives correctly. |
| 464 .WillOnce(testing::Invoke(CreateFunctor( | 495 TestCompletionCallback callback; |
| 465 &QuicChromiumClientStreamTest::ReadData, base::Unretained(this), | 496 scoped_refptr<IOBuffer> buffer(new IOBuffer(2 * data_len)); |
| 466 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)); |
| 467 | 500 |
| 468 SpdyHeaderBlock trailers; | 501 SpdyHeaderBlock trailers; |
| 469 trailers["bar"] = "foo"; | 502 trailers["bar"] = "foo"; |
| 470 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); | 503 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); |
| 471 | 504 |
| 472 auto t = ProcessTrailers(trailers); | 505 auto t = ProcessTrailers(trailers); |
| 473 base::RunLoop run_loop; | 506 base::RunLoop run_loop; |
| 474 EXPECT_CALL(delegate_, | 507 EXPECT_CALL(delegate_, |
| 475 OnTrailingHeadersAvailableMock(_, t.uncompressed_header_bytes())) | 508 OnTrailingHeadersAvailableMock(_, t.uncompressed_header_bytes())) |
| 476 .WillOnce(testing::InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); | 509 .WillOnce(testing::InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); |
| 477 | 510 |
| 478 run_loop.Run(); | 511 run_loop.Run(); |
| 479 | 512 |
| 480 // OnDataAvailable callback should follow trailers notification. | 513 // Read the body and verify that it arrives correctly. |
| 481 base::RunLoop run_loop3; | 514 EXPECT_EQ(0, |
| 482 EXPECT_CALL(delegate_, OnDataAvailable()) | 515 handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback())); |
| 483 .Times(1) | |
| 484 .WillOnce(testing::DoAll( | |
| 485 testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData, | |
| 486 base::Unretained(this), | |
| 487 QuicStringPiece())), | |
| 488 testing::InvokeWithoutArgs([&run_loop3]() { run_loop3.Quit(); }))); | |
| 489 run_loop3.Run(); | |
| 490 | 516 |
| 491 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. | 517 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. |
| 492 trailers.erase(kFinalOffsetHeaderKey); | 518 trailers.erase(kFinalOffsetHeaderKey); |
| 493 EXPECT_EQ(trailers, delegate_.trailers_); | 519 EXPECT_EQ(trailers, delegate_.trailers_); |
| 494 base::RunLoop().RunUntilIdle(); | 520 base::RunLoop().RunUntilIdle(); |
| 495 EXPECT_CALL(delegate_, OnClose()); | 521 EXPECT_CALL(delegate_, OnClose()); |
| 496 } | 522 } |
| 497 | 523 |
| 498 // 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 |
| 499 // immediately notified about trailers. | 525 // immediately notified about trailers. |
| 500 TEST_P(QuicChromiumClientStreamTest, MarkTrailersConsumedWhenNotifyDelegate) { | 526 TEST_P(QuicChromiumClientStreamTest, MarkTrailersConsumedWhenNotifyDelegate) { |
| 501 InitializeHeaders(); | 527 InitializeHeaders(); |
| 502 ProcessHeadersFull(headers_); | 528 ProcessHeadersFull(headers_); |
| 503 | 529 |
| 504 const char data[] = "hello world!"; | 530 const char data[] = "hello world!"; |
| 531 int data_len = strlen(data); |
| 505 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, | 532 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, |
| 506 /*offset=*/0, data)); | 533 /*offset=*/0, data)); |
| 507 | 534 |
| 508 base::RunLoop run_loop; | 535 // Read the body and verify that it arrives correctly. |
| 509 EXPECT_CALL(delegate_, OnDataAvailable()) | 536 TestCompletionCallback callback; |
| 510 .Times(1) | 537 scoped_refptr<IOBuffer> buffer(new IOBuffer(2 * data_len)); |
| 511 .WillOnce(testing::DoAll( | 538 EXPECT_EQ(data_len, |
| 512 testing::Invoke(CreateFunctor( | 539 handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback())); |
| 513 &QuicChromiumClientStreamTest::ReadData, base::Unretained(this), | 540 EXPECT_EQ(QuicStringPiece(data), QuicStringPiece(buffer->data(), data_len)); |
| 514 QuicStringPiece(data, arraysize(data) - 1))), | |
| 515 testing::Invoke([&run_loop]() { run_loop.Quit(); }))); | |
| 516 | |
| 517 // Wait for the read to complete. | |
| 518 run_loop.Run(); | |
| 519 | 541 |
| 520 // Read again, and it will be pending. | 542 // Read again, and it will be pending. |
| 521 scoped_refptr<IOBuffer> buffer(new IOBuffer(1)); | 543 EXPECT_THAT( |
| 522 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)); |
| 523 | 546 |
| 524 SpdyHeaderBlock trailers; | 547 SpdyHeaderBlock trailers; |
| 525 trailers["bar"] = "foo"; | 548 trailers["bar"] = "foo"; |
| 526 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); | 549 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); |
| 527 QuicHeaderList t = ProcessTrailers(trailers); | 550 QuicHeaderList t = ProcessTrailers(trailers); |
| 528 EXPECT_FALSE(stream_->IsDoneReading()); | 551 EXPECT_FALSE(stream_->IsDoneReading()); |
| 529 | 552 |
| 530 base::RunLoop run_loop2; | 553 base::RunLoop run_loop2; |
| 531 EXPECT_CALL(delegate_, | 554 EXPECT_CALL(delegate_, |
| 532 OnTrailingHeadersAvailableMock(_, t.uncompressed_header_bytes())) | 555 OnTrailingHeadersAvailableMock(_, t.uncompressed_header_bytes())) |
| 533 .WillOnce( | 556 .WillOnce( |
| 534 testing::InvokeWithoutArgs([&run_loop2]() { run_loop2.Quit(); })); | 557 testing::InvokeWithoutArgs([&run_loop2]() { run_loop2.Quit(); })); |
| 535 | 558 |
| 536 run_loop2.Run(); | 559 run_loop2.Run(); |
| 537 | 560 |
| 538 // OnDataAvailable callback should follow trailers notification. | 561 // Read the body and verify that it arrives correctly. |
| 539 base::RunLoop run_loop3; | 562 EXPECT_EQ(0, callback.WaitForResult()); |
| 540 EXPECT_CALL(delegate_, OnDataAvailable()) | |
| 541 .Times(1) | |
| 542 .WillOnce(testing::DoAll( | |
| 543 testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData, | |
| 544 base::Unretained(this), | |
| 545 QuicStringPiece())), | |
| 546 testing::InvokeWithoutArgs([&run_loop3]() { run_loop3.Quit(); }))); | |
| 547 run_loop3.Run(); | |
| 548 | 563 |
| 549 // 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 |
| 550 // consumed. | 565 // consumed. |
| 551 EXPECT_TRUE(stream_->IsDoneReading()); | 566 EXPECT_TRUE(stream_->IsDoneReading()); |
| 552 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. | 567 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. |
| 553 trailers.erase(kFinalOffsetHeaderKey); | 568 trailers.erase(kFinalOffsetHeaderKey); |
| 554 EXPECT_EQ(trailers, delegate_.trailers_); | 569 EXPECT_EQ(trailers, delegate_.trailers_); |
| 555 | 570 |
| 556 base::RunLoop().RunUntilIdle(); | 571 base::RunLoop().RunUntilIdle(); |
| 557 EXPECT_CALL(delegate_, OnClose()); | 572 EXPECT_CALL(delegate_, OnClose()); |
| 558 } | 573 } |
| 559 | 574 |
| 560 // 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 |
| 561 // 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 |
| 562 // of 0 (EOF). | 577 // of 0 (EOF). |
| 563 TEST_P(QuicChromiumClientStreamTest, ReadAfterTrailersReceivedButNotDelivered) { | 578 TEST_P(QuicChromiumClientStreamTest, ReadAfterTrailersReceivedButNotDelivered) { |
| 564 InitializeHeaders(); | 579 InitializeHeaders(); |
| 565 ProcessHeadersFull(headers_); | 580 ProcessHeadersFull(headers_); |
| 566 | 581 |
| 567 const char data[] = "hello world!"; | 582 const char data[] = "hello world!"; |
| 583 int data_len = strlen(data); |
| 568 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, | 584 stream_->OnStreamFrame(QuicStreamFrame(kTestStreamId, /*fin=*/false, |
| 569 /*offset=*/0, data)); | 585 /*offset=*/0, data)); |
| 570 | 586 |
| 571 base::RunLoop run_loop; | 587 // Read the body and verify that it arrives correctly. |
| 572 EXPECT_CALL(delegate_, OnDataAvailable()) | 588 TestCompletionCallback callback; |
| 573 .Times(1) | 589 scoped_refptr<IOBuffer> buffer(new IOBuffer(2 * data_len)); |
| 574 .WillOnce(testing::DoAll( | 590 EXPECT_EQ(data_len, |
| 575 testing::Invoke(CreateFunctor( | 591 handle_->ReadBody(buffer.get(), 2 * data_len, callback.callback())); |
| 576 &QuicChromiumClientStreamTest::ReadData, base::Unretained(this), | 592 EXPECT_EQ(QuicStringPiece(data), QuicStringPiece(buffer->data(), data_len)); |
| 577 QuicStringPiece(data, arraysize(data) - 1))), | |
| 578 testing::Invoke([&run_loop]() { run_loop.Quit(); }))); | |
| 579 | |
| 580 // Wait for the read to complete. | |
| 581 run_loop.Run(); | |
| 582 | 593 |
| 583 // Deliver trailers. Delegate notification is posted asynchronously. | 594 // Deliver trailers. Delegate notification is posted asynchronously. |
| 584 SpdyHeaderBlock trailers; | 595 SpdyHeaderBlock trailers; |
| 585 trailers["bar"] = "foo"; | 596 trailers["bar"] = "foo"; |
| 586 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); | 597 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); |
| 587 | 598 |
| 588 QuicHeaderList t = ProcessTrailers(trailers); | 599 QuicHeaderList t = ProcessTrailers(trailers); |
| 589 | 600 |
| 601 EXPECT_FALSE(stream_->IsDoneReading()); |
| 590 // Read again, it return ERR_IO_PENDING. | 602 // Read again, it return ERR_IO_PENDING. |
| 591 scoped_refptr<IOBuffer> buffer(new IOBuffer(1)); | 603 EXPECT_THAT( |
| 592 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)); |
| 593 | 606 |
| 594 // Trailers are not delivered | 607 // Trailers are not delivered |
| 595 EXPECT_FALSE(stream_->IsDoneReading()); | 608 EXPECT_FALSE(stream_->IsDoneReading()); |
| 596 | 609 |
| 597 base::RunLoop run_loop2; | 610 base::RunLoop run_loop2; |
| 598 EXPECT_CALL(delegate_, | 611 EXPECT_CALL(delegate_, |
| 599 OnTrailingHeadersAvailableMock(_, t.uncompressed_header_bytes())) | 612 OnTrailingHeadersAvailableMock(_, t.uncompressed_header_bytes())) |
| 600 .WillOnce( | 613 .WillOnce( |
| 601 testing::InvokeWithoutArgs([&run_loop2]() { run_loop2.Quit(); })); | 614 testing::InvokeWithoutArgs([&run_loop2]() { run_loop2.Quit(); })); |
| 602 | 615 |
| 603 run_loop2.Run(); | 616 run_loop2.Run(); |
| 604 | 617 |
| 605 base::RunLoop run_loop3; | 618 // Read the body and verify that it arrives correctly. |
| 606 // OnDataAvailable() should follow right after and Read() will return 0. | 619 // OnDataAvailable() should follow right after and Read() will return 0. |
| 607 EXPECT_CALL(delegate_, OnDataAvailable()) | 620 EXPECT_EQ(0, callback.WaitForResult()); |
| 608 .WillOnce(testing::DoAll( | |
| 609 testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData, | |
| 610 base::Unretained(this), | |
| 611 QuicStringPiece())), | |
| 612 testing::Invoke([&run_loop3]() { run_loop3.Quit(); }))); | |
| 613 run_loop3.Run(); | |
| 614 | 621 |
| 615 // 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 |
| 616 // consumed. | 623 // consumed. |
| 617 EXPECT_TRUE(stream_->IsDoneReading()); | 624 EXPECT_TRUE(stream_->IsDoneReading()); |
| 618 | 625 |
| 619 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. | 626 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. |
| 620 trailers.erase(kFinalOffsetHeaderKey); | 627 trailers.erase(kFinalOffsetHeaderKey); |
| 621 EXPECT_EQ(trailers, delegate_.trailers_); | 628 EXPECT_EQ(trailers, delegate_.trailers_); |
| 622 | 629 |
| 623 base::RunLoop().RunUntilIdle(); | 630 base::RunLoop().RunUntilIdle(); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 EXPECT_EQ(QuicStringPiece(data), QuicStringPiece(buffer->data(), data_len)); | 780 EXPECT_EQ(QuicStringPiece(data), QuicStringPiece(buffer->data(), data_len)); |
| 774 | 781 |
| 775 // Both delegates should be notified that theirs streams are closed. | 782 // Both delegates should be notified that theirs streams are closed. |
| 776 EXPECT_CALL(delegate2_, OnClose()); | 783 EXPECT_CALL(delegate2_, OnClose()); |
| 777 EXPECT_CALL(delegate_, OnClose()); | 784 EXPECT_CALL(delegate_, OnClose()); |
| 778 } | 785 } |
| 779 | 786 |
| 780 } // namespace | 787 } // namespace |
| 781 } // namespace test | 788 } // namespace test |
| 782 } // namespace net | 789 } // namespace net |
| OLD | NEW |