OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/quic_headers_stream.h" | 5 #include "net/quic/quic_headers_stream.h" |
6 | 6 |
7 #include "net/quic/quic_utils.h" | 7 #include "net/quic/quic_utils.h" |
8 #include "net/quic/spdy_utils.h" | 8 #include "net/quic/spdy_utils.h" |
9 #include "net/quic/test_tools/quic_connection_peer.h" | 9 #include "net/quic/test_tools/quic_connection_peer.h" |
10 #include "net/quic/test_tools/quic_spdy_session_peer.h" | 10 #include "net/quic/test_tools/quic_spdy_session_peer.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 using std::vector; | 22 using std::vector; |
23 using testing::ElementsAre; | 23 using testing::ElementsAre; |
24 using testing::InSequence; | 24 using testing::InSequence; |
25 using testing::Invoke; | 25 using testing::Invoke; |
26 using testing::StrictMock; | 26 using testing::StrictMock; |
27 using testing::WithArgs; | 27 using testing::WithArgs; |
28 using testing::_; | 28 using testing::_; |
29 | 29 |
30 namespace net { | 30 namespace net { |
31 namespace test { | 31 namespace test { |
| 32 |
| 33 class MockHpackDebugVisitor : public QuicHeadersStream::HpackDebugVisitor { |
| 34 public: |
| 35 explicit MockHpackDebugVisitor() : HpackDebugVisitor() {} |
| 36 |
| 37 MOCK_METHOD1(OnUseEntry, void(QuicTime::Delta elapsed)); |
| 38 |
| 39 private: |
| 40 DISALLOW_COPY_AND_ASSIGN(MockHpackDebugVisitor); |
| 41 }; |
| 42 |
32 namespace { | 43 namespace { |
33 | 44 |
34 // TODO(ckrasic): this workaround is due to absence of std::initializer_list | 45 // TODO(ckrasic): this workaround is due to absence of std::initializer_list |
35 const bool kFins[] = {false, true}; | 46 const bool kFins[] = {false, true}; |
36 | 47 |
37 class MockVisitor : public SpdyFramerVisitorInterface { | 48 class MockVisitor : public SpdyFramerVisitorInterface { |
38 public: | 49 public: |
39 MOCK_METHOD1(OnError, void(SpdyFramer* framer)); | 50 MOCK_METHOD1(OnError, void(SpdyFramer* framer)); |
40 MOCK_METHOD3(OnDataFrameHeader, | 51 MOCK_METHOD3(OnDataFrameHeader, |
41 void(SpdyStreamId stream_id, size_t length, bool fin)); | 52 void(SpdyStreamId stream_id, size_t length, bool fin)); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParams> { | 134 class QuicHeadersStreamTest : public ::testing::TestWithParam<TestParams> { |
124 public: | 135 public: |
125 QuicHeadersStreamTest() | 136 QuicHeadersStreamTest() |
126 : connection_(new StrictMock<MockQuicConnection>(&helper_, | 137 : connection_(new StrictMock<MockQuicConnection>(&helper_, |
127 &alarm_factory_, | 138 &alarm_factory_, |
128 perspective(), | 139 perspective(), |
129 GetVersion())), | 140 GetVersion())), |
130 session_(connection_), | 141 session_(connection_), |
131 headers_stream_(QuicSpdySessionPeer::GetHeadersStream(&session_)), | 142 headers_stream_(QuicSpdySessionPeer::GetHeadersStream(&session_)), |
132 body_("hello world"), | 143 body_("hello world"), |
| 144 hpack_encoder_visitor_(new StrictMock<MockHpackDebugVisitor>), |
| 145 hpack_decoder_visitor_(new StrictMock<MockHpackDebugVisitor>), |
133 stream_frame_(kHeadersStreamId, /*fin=*/false, /*offset=*/0, ""), | 146 stream_frame_(kHeadersStreamId, /*fin=*/false, /*offset=*/0, ""), |
134 next_promised_stream_id_(2) { | 147 next_promised_stream_id_(2) { |
135 FLAGS_quic_always_log_bugs_for_tests = true; | 148 FLAGS_quic_always_log_bugs_for_tests = true; |
136 headers_[":version"] = "HTTP/1.1"; | 149 headers_[":version"] = "HTTP/1.1"; |
137 headers_[":status"] = "200 Ok"; | 150 headers_[":status"] = "200 Ok"; |
138 headers_["content-length"] = "11"; | 151 headers_["content-length"] = "11"; |
139 framer_ = std::unique_ptr<SpdyFramer>(new SpdyFramer(HTTP2)); | 152 framer_ = std::unique_ptr<SpdyFramer>(new SpdyFramer(HTTP2)); |
140 framer_->set_visitor(&visitor_); | 153 framer_->set_visitor(&visitor_); |
141 EXPECT_EQ(version(), session_.connection()->version()); | 154 EXPECT_EQ(version(), session_.connection()->version()); |
142 EXPECT_TRUE(headers_stream_ != nullptr); | 155 EXPECT_TRUE(headers_stream_ != nullptr); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 MockAlarmFactory alarm_factory_; | 253 MockAlarmFactory alarm_factory_; |
241 StrictMock<MockQuicConnection>* connection_; | 254 StrictMock<MockQuicConnection>* connection_; |
242 StrictMock<MockQuicSpdySession> session_; | 255 StrictMock<MockQuicSpdySession> session_; |
243 QuicHeadersStream* headers_stream_; | 256 QuicHeadersStream* headers_stream_; |
244 SpdyHeaderBlock headers_; | 257 SpdyHeaderBlock headers_; |
245 string body_; | 258 string body_; |
246 string saved_data_; | 259 string saved_data_; |
247 string saved_header_data_; | 260 string saved_header_data_; |
248 std::unique_ptr<SpdyFramer> framer_; | 261 std::unique_ptr<SpdyFramer> framer_; |
249 StrictMock<MockVisitor> visitor_; | 262 StrictMock<MockVisitor> visitor_; |
| 263 std::unique_ptr<StrictMock<MockHpackDebugVisitor>> hpack_encoder_visitor_; |
| 264 std::unique_ptr<StrictMock<MockHpackDebugVisitor>> hpack_decoder_visitor_; |
250 QuicStreamFrame stream_frame_; | 265 QuicStreamFrame stream_frame_; |
251 QuicStreamId next_promised_stream_id_; | 266 QuicStreamId next_promised_stream_id_; |
252 }; | 267 }; |
253 | 268 |
254 INSTANTIATE_TEST_CASE_P(Tests, | 269 INSTANTIATE_TEST_CASE_P(Tests, |
255 QuicHeadersStreamTest, | 270 QuicHeadersStreamTest, |
256 ::testing::ValuesIn(GetTestParams())); | 271 ::testing::ValuesIn(GetTestParams())); |
257 | 272 |
258 TEST_P(QuicHeadersStreamTest, StreamId) { | 273 TEST_P(QuicHeadersStreamTest, StreamId) { |
259 EXPECT_EQ(3u, headers_stream_->id()); | 274 EXPECT_EQ(3u, headers_stream_->id()); |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 stream_frame_.data_buffer = frame.data(); | 597 stream_frame_.data_buffer = frame.data(); |
583 stream_frame_.data_length = frame.size(); | 598 stream_frame_.data_length = frame.size(); |
584 headers_stream_->OnStreamFrame(stream_frame_); | 599 headers_stream_->OnStreamFrame(stream_frame_); |
585 } | 600 } |
586 | 601 |
587 TEST_P(QuicHeadersStreamTest, NoConnectionLevelFlowControl) { | 602 TEST_P(QuicHeadersStreamTest, NoConnectionLevelFlowControl) { |
588 EXPECT_FALSE(ReliableQuicStreamPeer::StreamContributesToConnectionFlowControl( | 603 EXPECT_FALSE(ReliableQuicStreamPeer::StreamContributesToConnectionFlowControl( |
589 headers_stream_)); | 604 headers_stream_)); |
590 } | 605 } |
591 | 606 |
| 607 TEST_P(QuicHeadersStreamTest, HpackDecoderDebugVisitor) { |
| 608 StrictMock<MockHpackDebugVisitor>* hpack_decoder_visitor = |
| 609 hpack_decoder_visitor_.get(); |
| 610 headers_stream_->SetHpackDecoderDebugVisitor( |
| 611 std::move(hpack_decoder_visitor_)); |
| 612 |
| 613 // Create some headers we expect to generate entries in HPACK's |
| 614 // dynamic table, in addition to content-length. |
| 615 headers_["key0"] = string(1 << 1, '.'); |
| 616 headers_["key1"] = string(1 << 2, '.'); |
| 617 headers_["key2"] = string(1 << 3, '.'); |
| 618 { |
| 619 testing::InSequence seq; |
| 620 // Number of indexed representations generated in headers below. |
| 621 for (int i = 1; i < 28; i++) { |
| 622 EXPECT_CALL(*hpack_decoder_visitor, |
| 623 OnUseEntry(QuicTime::Delta::FromMilliseconds(i))) |
| 624 .Times(4); |
| 625 } |
| 626 } |
| 627 for (QuicStreamId stream_id = kClientDataStreamId1; |
| 628 stream_id < kClientDataStreamId3; stream_id += 2) { |
| 629 for (bool fin : {false, true}) { |
| 630 for (SpdyPriority priority = 0; priority < 7; ++priority) { |
| 631 // Replace with "WriteHeadersAndSaveData" |
| 632 SpdySerializedFrame frame; |
| 633 if (perspective() == Perspective::IS_SERVER) { |
| 634 SpdyHeadersIR headers_frame(stream_id); |
| 635 headers_frame.set_header_block(headers_); |
| 636 headers_frame.set_fin(fin); |
| 637 headers_frame.set_has_priority(true); |
| 638 frame = framer_->SerializeFrame(headers_frame); |
| 639 EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0)); |
| 640 } else { |
| 641 SpdyHeadersIR headers_frame(stream_id); |
| 642 headers_frame.set_header_block(headers_); |
| 643 headers_frame.set_fin(fin); |
| 644 frame = framer_->SerializeFrame(headers_frame); |
| 645 } |
| 646 EXPECT_CALL(session_, OnStreamHeaders(stream_id, _)) |
| 647 .WillRepeatedly(WithArgs<1>(Invoke( |
| 648 this, &QuicHeadersStreamTest::SaveHeaderDataStringPiece))); |
| 649 EXPECT_CALL(session_, |
| 650 OnStreamHeadersComplete(stream_id, fin, frame.size())); |
| 651 stream_frame_.data_buffer = frame.data(); |
| 652 stream_frame_.data_length = frame.size(); |
| 653 connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); |
| 654 headers_stream_->OnStreamFrame(stream_frame_); |
| 655 stream_frame_.offset += frame.size(); |
| 656 CheckHeaders(); |
| 657 } |
| 658 } |
| 659 } |
| 660 } |
| 661 |
| 662 TEST_P(QuicHeadersStreamTest, HpackEncoderDebugVisitor) { |
| 663 StrictMock<MockHpackDebugVisitor>* hpack_encoder_visitor = |
| 664 hpack_encoder_visitor_.get(); |
| 665 headers_stream_->SetHpackEncoderDebugVisitor( |
| 666 std::move(hpack_encoder_visitor_)); |
| 667 |
| 668 if (perspective() == Perspective::IS_SERVER) { |
| 669 testing::InSequence seq; |
| 670 for (int i = 1; i < 4; i++) { |
| 671 EXPECT_CALL(*hpack_encoder_visitor, |
| 672 OnUseEntry(QuicTime::Delta::FromMilliseconds(i))); |
| 673 } |
| 674 } else { |
| 675 testing::InSequence seq; |
| 676 for (int i = 1; i < 28; i++) { |
| 677 EXPECT_CALL(*hpack_encoder_visitor, |
| 678 OnUseEntry(QuicTime::Delta::FromMilliseconds(i))); |
| 679 } |
| 680 } |
| 681 for (QuicStreamId stream_id = kClientDataStreamId1; |
| 682 stream_id < kClientDataStreamId3; stream_id += 2) { |
| 683 for (bool fin : {false, true}) { |
| 684 if (perspective() == Perspective::IS_SERVER) { |
| 685 WriteHeadersAndExpectSynReply(stream_id, fin); |
| 686 connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); |
| 687 } else { |
| 688 for (SpdyPriority priority = 0; priority < 7; ++priority) { |
| 689 // TODO(rch): implement priorities correctly. |
| 690 WriteHeadersAndExpectSynStream(stream_id, fin, 0); |
| 691 connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); |
| 692 } |
| 693 } |
| 694 } |
| 695 } |
| 696 } |
| 697 |
592 } // namespace | 698 } // namespace |
593 } // namespace test | 699 } // namespace test |
594 } // namespace net | 700 } // namespace net |
OLD | NEW |