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 26 matching lines...) Expand all Loading... |
37 namespace { | 37 namespace { |
38 | 38 |
39 const QuicStreamId kTestStreamId = 5u; | 39 const QuicStreamId kTestStreamId = 5u; |
40 | 40 |
41 class MockDelegate : public QuicChromiumClientStream::Delegate { | 41 class MockDelegate : public QuicChromiumClientStream::Delegate { |
42 public: | 42 public: |
43 MockDelegate() {} | 43 MockDelegate() {} |
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 OnHeadersAvailable(const SpdyHeaderBlock& headers, | 47 void OnInitialHeadersAvailable(const SpdyHeaderBlock& headers, |
48 size_t frame_len) override { | 48 size_t frame_len) override { |
49 headers_ = headers.Clone(); | 49 headers_ = headers.Clone(); |
50 OnHeadersAvailableMock(headers, frame_len); | 50 OnInitialHeadersAvailableMock(headers, frame_len); |
51 } | 51 } |
52 MOCK_METHOD2(OnHeadersAvailableMock, | 52 MOCK_METHOD2(OnInitialHeadersAvailableMock, |
| 53 void(const SpdyHeaderBlock& headers, size_t frame_len)); |
| 54 void OnTrailingHeadersAvailable(const SpdyHeaderBlock& headers, |
| 55 size_t frame_len) override { |
| 56 trailers_ = headers.Clone(); |
| 57 OnTrailingHeadersAvailableMock(headers, frame_len); |
| 58 } |
| 59 MOCK_METHOD2(OnTrailingHeadersAvailableMock, |
53 void(const SpdyHeaderBlock& headers, size_t frame_len)); | 60 void(const SpdyHeaderBlock& headers, size_t frame_len)); |
54 MOCK_METHOD2(OnDataReceived, int(const char*, int)); | 61 MOCK_METHOD2(OnDataReceived, int(const char*, int)); |
55 MOCK_METHOD0(OnDataAvailable, void()); | 62 MOCK_METHOD0(OnDataAvailable, void()); |
56 MOCK_METHOD0(OnClose, void()); | 63 MOCK_METHOD0(OnClose, void()); |
57 MOCK_METHOD1(OnError, void(int)); | 64 MOCK_METHOD1(OnError, void(int)); |
58 MOCK_METHOD0(HasSendHeadersComplete, bool()); | 65 MOCK_METHOD0(HasSendHeadersComplete, bool()); |
59 | 66 |
60 SpdyHeaderBlock headers_; | 67 SpdyHeaderBlock headers_; |
| 68 SpdyHeaderBlock trailers_; |
61 | 69 |
62 private: | 70 private: |
63 DISALLOW_COPY_AND_ASSIGN(MockDelegate); | 71 DISALLOW_COPY_AND_ASSIGN(MockDelegate); |
64 }; | 72 }; |
65 | 73 |
66 class TestQuicClientSessionBaseStream : public QuicSpdyStream { | 74 class TestQuicClientSessionBaseStream : public QuicSpdyStream { |
67 public: | 75 public: |
68 TestQuicClientSessionBaseStream(QuicStreamId id, QuicSpdySession* session) | 76 TestQuicClientSessionBaseStream(QuicStreamId id, QuicSpdySession* session) |
69 : QuicSpdyStream(id, session) {} | 77 : QuicSpdyStream(id, session) {} |
70 | 78 |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 } | 254 } |
247 | 255 |
248 QuicHeaderList ProcessTrailers(const SpdyHeaderBlock& headers) { | 256 QuicHeaderList ProcessTrailers(const SpdyHeaderBlock& headers) { |
249 QuicHeaderList h = AsHeaderList(headers); | 257 QuicHeaderList h = AsHeaderList(headers); |
250 stream_->OnStreamHeaderList(true, h.uncompressed_header_bytes(), h); | 258 stream_->OnStreamHeaderList(true, h.uncompressed_header_bytes(), h); |
251 return h; | 259 return h; |
252 } | 260 } |
253 | 261 |
254 QuicHeaderList ProcessHeadersFull(const SpdyHeaderBlock& headers) { | 262 QuicHeaderList ProcessHeadersFull(const SpdyHeaderBlock& headers) { |
255 QuicHeaderList h = ProcessHeaders(headers); | 263 QuicHeaderList h = ProcessHeaders(headers); |
256 EXPECT_CALL(delegate_, | 264 EXPECT_CALL(delegate_, OnInitialHeadersAvailableMock( |
257 OnHeadersAvailableMock(_, h.uncompressed_header_bytes())); | 265 _, h.uncompressed_header_bytes())); |
258 base::RunLoop().RunUntilIdle(); | 266 base::RunLoop().RunUntilIdle(); |
259 EXPECT_EQ(headers, delegate_.headers_); | 267 EXPECT_EQ(headers, delegate_.headers_); |
260 EXPECT_TRUE(stream_->header_list().empty()); | 268 EXPECT_TRUE(stream_->header_list().empty()); |
261 return h; | 269 return h; |
262 } | 270 } |
263 | 271 |
264 QuicStreamId GetNthClientInitiatedStreamId(int n) { | 272 QuicStreamId GetNthClientInitiatedStreamId(int n) { |
265 return QuicSpdySessionPeer::GetNthClientInitiatedStreamId(session_, n); | 273 return QuicSpdySessionPeer::GetNthClientInitiatedStreamId(session_, n); |
266 } | 274 } |
267 | 275 |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 &QuicChromiumClientStreamTest::ReadData, base::Unretained(this), | 378 &QuicChromiumClientStreamTest::ReadData, base::Unretained(this), |
371 QuicStringPiece(data, arraysize(data) - 1)))); | 379 QuicStringPiece(data, arraysize(data) - 1)))); |
372 | 380 |
373 SpdyHeaderBlock trailers; | 381 SpdyHeaderBlock trailers; |
374 trailers["bar"] = "foo"; | 382 trailers["bar"] = "foo"; |
375 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); | 383 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); |
376 | 384 |
377 auto t = ProcessTrailers(trailers); | 385 auto t = ProcessTrailers(trailers); |
378 base::RunLoop run_loop; | 386 base::RunLoop run_loop; |
379 EXPECT_CALL(delegate_, | 387 EXPECT_CALL(delegate_, |
380 OnHeadersAvailableMock(_, t.uncompressed_header_bytes())) | 388 OnTrailingHeadersAvailableMock(_, t.uncompressed_header_bytes())) |
381 .WillOnce(testing::InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); | 389 .WillOnce(testing::InvokeWithoutArgs([&run_loop]() { run_loop.Quit(); })); |
382 | 390 |
383 run_loop.Run(); | 391 run_loop.Run(); |
384 | 392 |
385 // OnDataAvailable callback should follow trailers notification. | 393 // OnDataAvailable callback should follow trailers notification. |
386 base::RunLoop run_loop3; | 394 base::RunLoop run_loop3; |
387 EXPECT_CALL(delegate_, OnDataAvailable()) | 395 EXPECT_CALL(delegate_, OnDataAvailable()) |
388 .Times(1) | 396 .Times(1) |
389 .WillOnce(testing::DoAll( | 397 .WillOnce(testing::DoAll( |
390 testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData, | 398 testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData, |
391 base::Unretained(this), | 399 base::Unretained(this), |
392 QuicStringPiece())), | 400 QuicStringPiece())), |
393 testing::InvokeWithoutArgs([&run_loop3]() { run_loop3.Quit(); }))); | 401 testing::InvokeWithoutArgs([&run_loop3]() { run_loop3.Quit(); }))); |
394 run_loop3.Run(); | 402 run_loop3.Run(); |
395 | 403 |
396 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. | 404 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. |
397 trailers.erase(kFinalOffsetHeaderKey); | 405 trailers.erase(kFinalOffsetHeaderKey); |
398 EXPECT_EQ(trailers, delegate_.headers_); | 406 EXPECT_EQ(trailers, delegate_.trailers_); |
399 base::RunLoop().RunUntilIdle(); | 407 base::RunLoop().RunUntilIdle(); |
400 EXPECT_CALL(delegate_, OnClose()); | 408 EXPECT_CALL(delegate_, OnClose()); |
401 } | 409 } |
402 | 410 |
403 // Tests that trailers are marked as consumed only before delegate is to be | 411 // Tests that trailers are marked as consumed only before delegate is to be |
404 // immediately notified about trailers. | 412 // immediately notified about trailers. |
405 TEST_P(QuicChromiumClientStreamTest, MarkTrailersConsumedWhenNotifyDelegate) { | 413 TEST_P(QuicChromiumClientStreamTest, MarkTrailersConsumedWhenNotifyDelegate) { |
406 InitializeHeaders(); | 414 InitializeHeaders(); |
407 ProcessHeadersFull(headers_); | 415 ProcessHeadersFull(headers_); |
408 | 416 |
(...skipping 18 matching lines...) Expand all Loading... |
427 EXPECT_THAT(stream_->Read(buffer.get(), 1), IsError(ERR_IO_PENDING)); | 435 EXPECT_THAT(stream_->Read(buffer.get(), 1), IsError(ERR_IO_PENDING)); |
428 | 436 |
429 SpdyHeaderBlock trailers; | 437 SpdyHeaderBlock trailers; |
430 trailers["bar"] = "foo"; | 438 trailers["bar"] = "foo"; |
431 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); | 439 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(data)); |
432 QuicHeaderList t = ProcessTrailers(trailers); | 440 QuicHeaderList t = ProcessTrailers(trailers); |
433 EXPECT_FALSE(stream_->IsDoneReading()); | 441 EXPECT_FALSE(stream_->IsDoneReading()); |
434 | 442 |
435 base::RunLoop run_loop2; | 443 base::RunLoop run_loop2; |
436 EXPECT_CALL(delegate_, | 444 EXPECT_CALL(delegate_, |
437 OnHeadersAvailableMock(_, t.uncompressed_header_bytes())) | 445 OnTrailingHeadersAvailableMock(_, t.uncompressed_header_bytes())) |
438 .WillOnce( | 446 .WillOnce( |
439 testing::InvokeWithoutArgs([&run_loop2]() { run_loop2.Quit(); })); | 447 testing::InvokeWithoutArgs([&run_loop2]() { run_loop2.Quit(); })); |
440 | 448 |
441 run_loop2.Run(); | 449 run_loop2.Run(); |
442 | 450 |
443 // OnDataAvailable callback should follow trailers notification. | 451 // OnDataAvailable callback should follow trailers notification. |
444 base::RunLoop run_loop3; | 452 base::RunLoop run_loop3; |
445 EXPECT_CALL(delegate_, OnDataAvailable()) | 453 EXPECT_CALL(delegate_, OnDataAvailable()) |
446 .Times(1) | 454 .Times(1) |
447 .WillOnce(testing::DoAll( | 455 .WillOnce(testing::DoAll( |
448 testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData, | 456 testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData, |
449 base::Unretained(this), | 457 base::Unretained(this), |
450 QuicStringPiece())), | 458 QuicStringPiece())), |
451 testing::InvokeWithoutArgs([&run_loop3]() { run_loop3.Quit(); }))); | 459 testing::InvokeWithoutArgs([&run_loop3]() { run_loop3.Quit(); }))); |
452 run_loop3.Run(); | 460 run_loop3.Run(); |
453 | 461 |
454 // Make sure the stream is properly closed since trailers and data are all | 462 // Make sure the stream is properly closed since trailers and data are all |
455 // consumed. | 463 // consumed. |
456 EXPECT_TRUE(stream_->IsDoneReading()); | 464 EXPECT_TRUE(stream_->IsDoneReading()); |
457 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. | 465 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. |
458 trailers.erase(kFinalOffsetHeaderKey); | 466 trailers.erase(kFinalOffsetHeaderKey); |
459 EXPECT_EQ(trailers, delegate_.headers_); | 467 EXPECT_EQ(trailers, delegate_.trailers_); |
460 | 468 |
461 base::RunLoop().RunUntilIdle(); | 469 base::RunLoop().RunUntilIdle(); |
462 EXPECT_CALL(delegate_, OnClose()); | 470 EXPECT_CALL(delegate_, OnClose()); |
463 } | 471 } |
464 | 472 |
465 // Test that if Read() is called after response body is read and after trailers | 473 // Test that if Read() is called after response body is read and after trailers |
466 // are received but not yet delivered, Read() will return ERR_IO_PENDING instead | 474 // are received but not yet delivered, Read() will return ERR_IO_PENDING instead |
467 // of 0 (EOF). | 475 // of 0 (EOF). |
468 TEST_P(QuicChromiumClientStreamTest, ReadAfterTrailersReceivedButNotDelivered) { | 476 TEST_P(QuicChromiumClientStreamTest, ReadAfterTrailersReceivedButNotDelivered) { |
469 InitializeHeaders(); | 477 InitializeHeaders(); |
(...skipping 24 matching lines...) Expand all Loading... |
494 | 502 |
495 // Read again, it return ERR_IO_PENDING. | 503 // Read again, it return ERR_IO_PENDING. |
496 scoped_refptr<IOBuffer> buffer(new IOBuffer(1)); | 504 scoped_refptr<IOBuffer> buffer(new IOBuffer(1)); |
497 EXPECT_THAT(stream_->Read(buffer.get(), 1), ERR_IO_PENDING); | 505 EXPECT_THAT(stream_->Read(buffer.get(), 1), ERR_IO_PENDING); |
498 | 506 |
499 // Trailers are not delivered | 507 // Trailers are not delivered |
500 EXPECT_FALSE(stream_->IsDoneReading()); | 508 EXPECT_FALSE(stream_->IsDoneReading()); |
501 | 509 |
502 base::RunLoop run_loop2; | 510 base::RunLoop run_loop2; |
503 EXPECT_CALL(delegate_, | 511 EXPECT_CALL(delegate_, |
504 OnHeadersAvailableMock(_, t.uncompressed_header_bytes())) | 512 OnTrailingHeadersAvailableMock(_, t.uncompressed_header_bytes())) |
505 .WillOnce( | 513 .WillOnce( |
506 testing::InvokeWithoutArgs([&run_loop2]() { run_loop2.Quit(); })); | 514 testing::InvokeWithoutArgs([&run_loop2]() { run_loop2.Quit(); })); |
507 | 515 |
508 run_loop2.Run(); | 516 run_loop2.Run(); |
509 | 517 |
510 base::RunLoop run_loop3; | 518 base::RunLoop run_loop3; |
511 // OnDataAvailable() should follow right after and Read() will return 0. | 519 // OnDataAvailable() should follow right after and Read() will return 0. |
512 EXPECT_CALL(delegate_, OnDataAvailable()) | 520 EXPECT_CALL(delegate_, OnDataAvailable()) |
513 .WillOnce(testing::DoAll( | 521 .WillOnce(testing::DoAll( |
514 testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData, | 522 testing::Invoke(CreateFunctor(&QuicChromiumClientStreamTest::ReadData, |
515 base::Unretained(this), | 523 base::Unretained(this), |
516 QuicStringPiece())), | 524 QuicStringPiece())), |
517 testing::Invoke([&run_loop3]() { run_loop3.Quit(); }))); | 525 testing::Invoke([&run_loop3]() { run_loop3.Quit(); }))); |
518 run_loop3.Run(); | 526 run_loop3.Run(); |
519 | 527 |
520 // Make sure the stream is properly closed since trailers and data are all | 528 // Make sure the stream is properly closed since trailers and data are all |
521 // consumed. | 529 // consumed. |
522 EXPECT_TRUE(stream_->IsDoneReading()); | 530 EXPECT_TRUE(stream_->IsDoneReading()); |
523 | 531 |
524 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. | 532 // Make sure kFinalOffsetHeaderKey is gone from the delivered actual trailers. |
525 trailers.erase(kFinalOffsetHeaderKey); | 533 trailers.erase(kFinalOffsetHeaderKey); |
526 EXPECT_EQ(trailers, delegate_.headers_); | 534 EXPECT_EQ(trailers, delegate_.trailers_); |
527 | 535 |
528 base::RunLoop().RunUntilIdle(); | 536 base::RunLoop().RunUntilIdle(); |
529 EXPECT_CALL(delegate_, OnClose()); | 537 EXPECT_CALL(delegate_, OnClose()); |
530 } | 538 } |
531 | 539 |
532 TEST_P(QuicChromiumClientStreamTest, WriteStreamData) { | 540 TEST_P(QuicChromiumClientStreamTest, WriteStreamData) { |
533 EXPECT_CALL(delegate_, OnClose()); | 541 EXPECT_CALL(delegate_, OnClose()); |
534 | 542 |
535 const char kData1[] = "hello world"; | 543 const char kData1[] = "hello world"; |
536 const size_t kDataLen = arraysize(kData1); | 544 const size_t kDataLen = arraysize(kData1); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 | 631 |
624 InitializeHeaders(); | 632 InitializeHeaders(); |
625 | 633 |
626 // Receive the headers before the delegate is set. | 634 // Receive the headers before the delegate is set. |
627 QuicHeaderList header_list = AsHeaderList(headers_); | 635 QuicHeaderList header_list = AsHeaderList(headers_); |
628 stream2->OnStreamHeaderList(true, header_list.uncompressed_header_bytes(), | 636 stream2->OnStreamHeaderList(true, header_list.uncompressed_header_bytes(), |
629 header_list); | 637 header_list); |
630 EXPECT_TRUE(delegate2_.headers_.empty()); | 638 EXPECT_TRUE(delegate2_.headers_.empty()); |
631 | 639 |
632 // Now set the delegate and verify that the headers are delivered. | 640 // Now set the delegate and verify that the headers are delivered. |
633 EXPECT_CALL(delegate2_, OnHeadersAvailableMock( | 641 EXPECT_CALL(delegate2_, OnInitialHeadersAvailableMock( |
634 _, header_list.uncompressed_header_bytes())); | 642 _, header_list.uncompressed_header_bytes())); |
635 stream2->SetDelegate(&delegate2_); | 643 stream2->SetDelegate(&delegate2_); |
636 base::RunLoop().RunUntilIdle(); | 644 base::RunLoop().RunUntilIdle(); |
637 EXPECT_EQ(headers_, delegate2_.headers_); | 645 EXPECT_EQ(headers_, delegate2_.headers_); |
638 | 646 |
639 // Both delegates should be notified that theirs streams are closed. | 647 // Both delegates should be notified that theirs streams are closed. |
640 EXPECT_CALL(delegate2_, OnClose()); | 648 EXPECT_CALL(delegate2_, OnClose()); |
641 EXPECT_CALL(delegate_, OnClose()); | 649 EXPECT_CALL(delegate_, OnClose()); |
642 } | 650 } |
643 | 651 |
(...skipping 11 matching lines...) Expand all Loading... |
655 QuicHeaderList header_list = AsHeaderList(headers_); | 663 QuicHeaderList header_list = AsHeaderList(headers_); |
656 stream2->OnStreamHeaderList(false, header_list.uncompressed_header_bytes(), | 664 stream2->OnStreamHeaderList(false, header_list.uncompressed_header_bytes(), |
657 header_list); | 665 header_list); |
658 EXPECT_TRUE(delegate2_.headers_.empty()); | 666 EXPECT_TRUE(delegate2_.headers_.empty()); |
659 const char data[] = "hello world!"; | 667 const char data[] = "hello world!"; |
660 stream2->OnStreamFrame(QuicStreamFrame(stream_id, /*fin=*/false, | 668 stream2->OnStreamFrame(QuicStreamFrame(stream_id, /*fin=*/false, |
661 /*offset=*/0, data)); | 669 /*offset=*/0, data)); |
662 | 670 |
663 // Now set the delegate and verify that the headers are delivered, but | 671 // Now set the delegate and verify that the headers are delivered, but |
664 // not the data, which needs to be read explicitly. | 672 // not the data, which needs to be read explicitly. |
665 EXPECT_CALL(delegate2_, OnHeadersAvailableMock( | 673 EXPECT_CALL(delegate2_, OnInitialHeadersAvailableMock( |
666 _, header_list.uncompressed_header_bytes())); | 674 _, header_list.uncompressed_header_bytes())); |
667 stream2->SetDelegate(&delegate2_); | 675 stream2->SetDelegate(&delegate2_); |
668 base::RunLoop().RunUntilIdle(); | 676 base::RunLoop().RunUntilIdle(); |
669 EXPECT_EQ(headers_, delegate2_.headers_); | 677 EXPECT_EQ(headers_, delegate2_.headers_); |
670 base::RunLoop().RunUntilIdle(); | 678 base::RunLoop().RunUntilIdle(); |
671 | 679 |
672 // Now explicitly read the data. | 680 // Now explicitly read the data. |
673 int data_len = arraysize(data) - 1; | 681 int data_len = arraysize(data) - 1; |
674 scoped_refptr<IOBuffer> buffer(new IOBuffer(data_len + 1)); | 682 scoped_refptr<IOBuffer> buffer(new IOBuffer(data_len + 1)); |
675 ASSERT_EQ(data_len, stream2->Read(buffer.get(), data_len + 1)); | 683 ASSERT_EQ(data_len, stream2->Read(buffer.get(), data_len + 1)); |
676 EXPECT_EQ(QuicStringPiece(data), QuicStringPiece(buffer->data(), data_len)); | 684 EXPECT_EQ(QuicStringPiece(data), QuicStringPiece(buffer->data(), data_len)); |
677 | 685 |
678 // Both delegates should be notified that theirs streams are closed. | 686 // Both delegates should be notified that theirs streams are closed. |
679 EXPECT_CALL(delegate2_, OnClose()); | 687 EXPECT_CALL(delegate2_, OnClose()); |
680 EXPECT_CALL(delegate_, OnClose()); | 688 EXPECT_CALL(delegate_, OnClose()); |
681 } | 689 } |
682 | 690 |
683 } // namespace | 691 } // namespace |
684 } // namespace test | 692 } // namespace test |
685 } // namespace net | 693 } // namespace net |
OLD | NEW |