| 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_spdy_stream.h" | 5 #include "net/quic/quic_spdy_stream.h" |
| 6 | 6 |
| 7 #include "net/quic/quic_connection.h" | 7 #include "net/quic/quic_connection.h" |
| 8 #include "net/quic/quic_utils.h" | 8 #include "net/quic/quic_utils.h" |
| 9 #include "net/quic/quic_write_blocked_list.h" | 9 #include "net/quic/quic_write_blocked_list.h" |
| 10 #include "net/quic/spdy_utils.h" | 10 #include "net/quic/spdy_utils.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 using ReliableQuicStream::WriteOrBufferData; | 51 using ReliableQuicStream::WriteOrBufferData; |
| 52 using ReliableQuicStream::CloseWriteSide; | 52 using ReliableQuicStream::CloseWriteSide; |
| 53 | 53 |
| 54 const string& data() const { return data_; } | 54 const string& data() const { return data_; } |
| 55 | 55 |
| 56 private: | 56 private: |
| 57 bool should_process_data_; | 57 bool should_process_data_; |
| 58 string data_; | 58 string data_; |
| 59 }; | 59 }; |
| 60 | 60 |
| 61 class QuicSpdyStreamTest : public ::testing::Test { | 61 class QuicSpdyStreamTest : public ::testing::TestWithParam<QuicVersion> { |
| 62 public: | 62 public: |
| 63 QuicSpdyStreamTest() { | 63 QuicSpdyStreamTest() { |
| 64 headers_[":host"] = "www.google.com"; | 64 headers_[":host"] = "www.google.com"; |
| 65 headers_[":path"] = "/index.hml"; | 65 headers_[":path"] = "/index.hml"; |
| 66 headers_[":scheme"] = "https"; | 66 headers_[":scheme"] = "https"; |
| 67 headers_["cookie"] = | 67 headers_["cookie"] = |
| 68 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; " | 68 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; " |
| 69 "__utmc=160408618; " | 69 "__utmc=160408618; " |
| 70 "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX" | 70 "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX" |
| 71 "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX" | 71 "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 85 "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6" | 85 "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6" |
| 86 "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG" | 86 "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG" |
| 87 "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk" | 87 "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk" |
| 88 "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn" | 88 "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn" |
| 89 "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr" | 89 "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr" |
| 90 "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo "; | 90 "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo "; |
| 91 } | 91 } |
| 92 | 92 |
| 93 void Initialize(bool stream_should_process_data) { | 93 void Initialize(bool stream_should_process_data) { |
| 94 connection_ = new testing::StrictMock<MockConnection>( | 94 connection_ = new testing::StrictMock<MockConnection>( |
| 95 &helper_, Perspective::IS_SERVER); | 95 &helper_, Perspective::IS_SERVER, SupportedVersions(GetParam())); |
| 96 session_.reset(new testing::StrictMock<MockQuicSpdySession>(connection_)); | 96 session_.reset(new testing::StrictMock<MockQuicSpdySession>(connection_)); |
| 97 stream_.reset(new TestStream(kClientDataStreamId1, session_.get(), | 97 stream_.reset(new TestStream(kClientDataStreamId1, session_.get(), |
| 98 stream_should_process_data)); | 98 stream_should_process_data)); |
| 99 stream2_.reset(new TestStream(kClientDataStreamId2, session_.get(), | 99 stream2_.reset(new TestStream(kClientDataStreamId2, session_.get(), |
| 100 stream_should_process_data)); | 100 stream_should_process_data)); |
| 101 write_blocked_list_ = | 101 write_blocked_list_ = |
| 102 QuicSessionPeer::GetWriteBlockedStreams(session_.get()); | 102 QuicSessionPeer::GetWriteBlockedStreams(session_.get()); |
| 103 } | 103 } |
| 104 | 104 |
| 105 protected: | 105 protected: |
| 106 MockHelper helper_; | 106 MockConnectionHelper helper_; |
| 107 MockConnection* connection_; | 107 MockConnection* connection_; |
| 108 scoped_ptr<MockQuicSpdySession> session_; | 108 scoped_ptr<MockQuicSpdySession> session_; |
| 109 scoped_ptr<TestStream> stream_; | 109 scoped_ptr<TestStream> stream_; |
| 110 scoped_ptr<TestStream> stream2_; | 110 scoped_ptr<TestStream> stream2_; |
| 111 SpdyHeaderBlock headers_; | 111 SpdyHeaderBlock headers_; |
| 112 QuicWriteBlockedList* write_blocked_list_; | 112 QuicWriteBlockedList* write_blocked_list_; |
| 113 }; | 113 }; |
| 114 | 114 |
| 115 TEST_F(QuicSpdyStreamTest, ProcessHeaders) { | 115 INSTANTIATE_TEST_CASE_P(Tests, |
| 116 QuicSpdyStreamTest, |
| 117 ::testing::ValuesIn(QuicSupportedVersions())); |
| 118 |
| 119 TEST_P(QuicSpdyStreamTest, ProcessHeaders) { |
| 116 Initialize(kShouldProcessData); | 120 Initialize(kShouldProcessData); |
| 117 | 121 |
| 118 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 122 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 119 stream_->OnStreamHeadersPriority(QuicUtils::HighestPriority()); | 123 stream_->OnStreamHeadersPriority(QuicUtils::HighestPriority()); |
| 120 stream_->OnStreamHeaders(headers); | 124 stream_->OnStreamHeaders(headers); |
| 121 EXPECT_EQ("", stream_->data()); | 125 EXPECT_EQ("", stream_->data()); |
| 122 EXPECT_EQ(headers, stream_->decompressed_headers()); | 126 EXPECT_EQ(headers, stream_->decompressed_headers()); |
| 123 stream_->OnStreamHeadersComplete(false, headers.size()); | 127 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 124 EXPECT_EQ(QuicUtils::HighestPriority(), stream_->EffectivePriority()); | 128 EXPECT_EQ(QuicUtils::HighestPriority(), stream_->EffectivePriority()); |
| 125 EXPECT_EQ("", stream_->data()); | 129 EXPECT_EQ("", stream_->data()); |
| 126 EXPECT_EQ(headers, stream_->decompressed_headers()); | 130 EXPECT_EQ(headers, stream_->decompressed_headers()); |
| 127 EXPECT_FALSE(stream_->IsDoneReading()); | 131 EXPECT_FALSE(stream_->IsDoneReading()); |
| 128 } | 132 } |
| 129 | 133 |
| 130 TEST_F(QuicSpdyStreamTest, ProcessHeadersWithFin) { | 134 TEST_P(QuicSpdyStreamTest, ProcessHeadersWithFin) { |
| 131 Initialize(kShouldProcessData); | 135 Initialize(kShouldProcessData); |
| 132 | 136 |
| 133 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 137 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 134 stream_->OnStreamHeadersPriority(QuicUtils::HighestPriority()); | 138 stream_->OnStreamHeadersPriority(QuicUtils::HighestPriority()); |
| 135 stream_->OnStreamHeaders(headers); | 139 stream_->OnStreamHeaders(headers); |
| 136 EXPECT_EQ("", stream_->data()); | 140 EXPECT_EQ("", stream_->data()); |
| 137 EXPECT_EQ(headers, stream_->decompressed_headers()); | 141 EXPECT_EQ(headers, stream_->decompressed_headers()); |
| 138 stream_->OnStreamHeadersComplete(true, headers.size()); | 142 stream_->OnStreamHeadersComplete(true, headers.size()); |
| 139 EXPECT_EQ(QuicUtils::HighestPriority(), stream_->EffectivePriority()); | 143 EXPECT_EQ(QuicUtils::HighestPriority(), stream_->EffectivePriority()); |
| 140 EXPECT_EQ("", stream_->data()); | 144 EXPECT_EQ("", stream_->data()); |
| 141 EXPECT_EQ(headers, stream_->decompressed_headers()); | 145 EXPECT_EQ(headers, stream_->decompressed_headers()); |
| 142 EXPECT_FALSE(stream_->IsDoneReading()); | 146 EXPECT_FALSE(stream_->IsDoneReading()); |
| 143 EXPECT_TRUE(stream_->HasFinalReceivedByteOffset()); | 147 EXPECT_TRUE(stream_->HasFinalReceivedByteOffset()); |
| 144 } | 148 } |
| 145 | 149 |
| 146 TEST_F(QuicSpdyStreamTest, MarkHeadersConsumed) { | 150 TEST_P(QuicSpdyStreamTest, MarkHeadersConsumed) { |
| 147 Initialize(kShouldProcessData); | 151 Initialize(kShouldProcessData); |
| 148 | 152 |
| 149 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 153 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 150 string body = "this is the body"; | 154 string body = "this is the body"; |
| 151 | 155 |
| 152 stream_->OnStreamHeaders(headers); | 156 stream_->OnStreamHeaders(headers); |
| 153 stream_->OnStreamHeadersComplete(false, headers.size()); | 157 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 154 EXPECT_EQ(headers, stream_->decompressed_headers()); | 158 EXPECT_EQ(headers, stream_->decompressed_headers()); |
| 155 | 159 |
| 156 headers.erase(0, 10); | 160 headers.erase(0, 10); |
| 157 stream_->MarkHeadersConsumed(10); | 161 stream_->MarkHeadersConsumed(10); |
| 158 EXPECT_EQ(headers, stream_->decompressed_headers()); | 162 EXPECT_EQ(headers, stream_->decompressed_headers()); |
| 159 | 163 |
| 160 stream_->MarkHeadersConsumed(headers.length()); | 164 stream_->MarkHeadersConsumed(headers.length()); |
| 161 EXPECT_EQ("", stream_->decompressed_headers()); | 165 EXPECT_EQ("", stream_->decompressed_headers()); |
| 162 } | 166 } |
| 163 | 167 |
| 164 TEST_F(QuicSpdyStreamTest, ProcessHeadersAndBody) { | 168 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBody) { |
| 165 Initialize(kShouldProcessData); | 169 Initialize(kShouldProcessData); |
| 166 | 170 |
| 167 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 171 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 168 string body = "this is the body"; | 172 string body = "this is the body"; |
| 169 | 173 |
| 170 stream_->OnStreamHeaders(headers); | 174 stream_->OnStreamHeaders(headers); |
| 171 EXPECT_EQ("", stream_->data()); | 175 EXPECT_EQ("", stream_->data()); |
| 172 EXPECT_EQ(headers, stream_->decompressed_headers()); | 176 EXPECT_EQ(headers, stream_->decompressed_headers()); |
| 173 stream_->OnStreamHeadersComplete(false, headers.size()); | 177 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 174 EXPECT_EQ(headers, stream_->decompressed_headers()); | 178 EXPECT_EQ(headers, stream_->decompressed_headers()); |
| 175 stream_->MarkHeadersConsumed(headers.length()); | 179 stream_->MarkHeadersConsumed(headers.length()); |
| 176 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 180 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
| 177 stream_->OnStreamFrame(frame); | 181 stream_->OnStreamFrame(frame); |
| 178 EXPECT_EQ("", stream_->decompressed_headers()); | 182 EXPECT_EQ("", stream_->decompressed_headers()); |
| 179 EXPECT_EQ(body, stream_->data()); | 183 EXPECT_EQ(body, stream_->data()); |
| 180 } | 184 } |
| 181 | 185 |
| 182 TEST_F(QuicSpdyStreamTest, ProcessHeadersAndBodyFragments) { | 186 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragments) { |
| 183 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 187 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 184 string body = "this is the body"; | 188 string body = "this is the body"; |
| 185 | 189 |
| 186 for (size_t fragment_size = 1; fragment_size < body.size(); ++fragment_size) { | 190 for (size_t fragment_size = 1; fragment_size < body.size(); ++fragment_size) { |
| 187 Initialize(kShouldProcessData); | 191 Initialize(kShouldProcessData); |
| 188 for (size_t offset = 0; offset < headers.size(); offset += fragment_size) { | 192 for (size_t offset = 0; offset < headers.size(); offset += fragment_size) { |
| 189 size_t remaining_data = headers.size() - offset; | 193 size_t remaining_data = headers.size() - offset; |
| 190 StringPiece fragment(headers.data() + offset, | 194 StringPiece fragment(headers.data() + offset, |
| 191 min(fragment_size, remaining_data)); | 195 min(fragment_size, remaining_data)); |
| 192 stream_->OnStreamHeaders(fragment); | 196 stream_->OnStreamHeaders(fragment); |
| 193 } | 197 } |
| 194 stream_->OnStreamHeadersComplete(false, headers.size()); | 198 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 195 ASSERT_EQ(headers, stream_->decompressed_headers()) << "fragment_size: " | 199 ASSERT_EQ(headers, stream_->decompressed_headers()) << "fragment_size: " |
| 196 << fragment_size; | 200 << fragment_size; |
| 197 stream_->MarkHeadersConsumed(headers.length()); | 201 stream_->MarkHeadersConsumed(headers.length()); |
| 198 for (size_t offset = 0; offset < body.size(); offset += fragment_size) { | 202 for (size_t offset = 0; offset < body.size(); offset += fragment_size) { |
| 199 size_t remaining_data = body.size() - offset; | 203 size_t remaining_data = body.size() - offset; |
| 200 StringPiece fragment(body.data() + offset, | 204 StringPiece fragment(body.data() + offset, |
| 201 min(fragment_size, remaining_data)); | 205 min(fragment_size, remaining_data)); |
| 202 QuicStreamFrame frame(kClientDataStreamId1, false, offset, | 206 QuicStreamFrame frame(kClientDataStreamId1, false, offset, |
| 203 StringPiece(fragment)); | 207 StringPiece(fragment)); |
| 204 stream_->OnStreamFrame(frame); | 208 stream_->OnStreamFrame(frame); |
| 205 } | 209 } |
| 206 ASSERT_EQ(body, stream_->data()) << "fragment_size: " << fragment_size; | 210 ASSERT_EQ(body, stream_->data()) << "fragment_size: " << fragment_size; |
| 207 } | 211 } |
| 208 } | 212 } |
| 209 | 213 |
| 210 TEST_F(QuicSpdyStreamTest, ProcessHeadersAndBodyFragmentsSplit) { | 214 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragmentsSplit) { |
| 211 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 215 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 212 string body = "this is the body"; | 216 string body = "this is the body"; |
| 213 | 217 |
| 214 for (size_t split_point = 1; split_point < body.size() - 1; ++split_point) { | 218 for (size_t split_point = 1; split_point < body.size() - 1; ++split_point) { |
| 215 Initialize(kShouldProcessData); | 219 Initialize(kShouldProcessData); |
| 216 StringPiece headers1(headers.data(), split_point); | 220 StringPiece headers1(headers.data(), split_point); |
| 217 stream_->OnStreamHeaders(headers1); | 221 stream_->OnStreamHeaders(headers1); |
| 218 | 222 |
| 219 StringPiece headers2(headers.data() + split_point, | 223 StringPiece headers2(headers.data() + split_point, |
| 220 headers.size() - split_point); | 224 headers.size() - split_point); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 231 | 235 |
| 232 StringPiece fragment2(body.data() + split_point, body.size() - split_point); | 236 StringPiece fragment2(body.data() + split_point, body.size() - split_point); |
| 233 QuicStreamFrame frame2(kClientDataStreamId1, false, split_point, | 237 QuicStreamFrame frame2(kClientDataStreamId1, false, split_point, |
| 234 StringPiece(fragment2)); | 238 StringPiece(fragment2)); |
| 235 stream_->OnStreamFrame(frame2); | 239 stream_->OnStreamFrame(frame2); |
| 236 | 240 |
| 237 ASSERT_EQ(body, stream_->data()) << "split_point: " << split_point; | 241 ASSERT_EQ(body, stream_->data()) << "split_point: " << split_point; |
| 238 } | 242 } |
| 239 } | 243 } |
| 240 | 244 |
| 241 TEST_F(QuicSpdyStreamTest, ProcessHeadersAndBodyReadv) { | 245 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyReadv) { |
| 242 Initialize(!kShouldProcessData); | 246 Initialize(!kShouldProcessData); |
| 243 | 247 |
| 244 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 248 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 245 string body = "this is the body"; | 249 string body = "this is the body"; |
| 246 | 250 |
| 247 stream_->OnStreamHeaders(headers); | 251 stream_->OnStreamHeaders(headers); |
| 248 stream_->OnStreamHeadersComplete(false, headers.size()); | 252 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 249 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 253 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
| 250 stream_->OnStreamFrame(frame); | 254 stream_->OnStreamFrame(frame); |
| 251 stream_->MarkHeadersConsumed(headers.length()); | 255 stream_->MarkHeadersConsumed(headers.length()); |
| 252 | 256 |
| 253 char buffer[2048]; | 257 char buffer[2048]; |
| 254 ASSERT_LT(body.length(), arraysize(buffer)); | 258 ASSERT_LT(body.length(), arraysize(buffer)); |
| 255 struct iovec vec; | 259 struct iovec vec; |
| 256 vec.iov_base = buffer; | 260 vec.iov_base = buffer; |
| 257 vec.iov_len = arraysize(buffer); | 261 vec.iov_len = arraysize(buffer); |
| 258 | 262 |
| 259 size_t bytes_read = stream_->Readv(&vec, 1); | 263 size_t bytes_read = stream_->Readv(&vec, 1); |
| 260 EXPECT_EQ(body.length(), bytes_read); | 264 EXPECT_EQ(body.length(), bytes_read); |
| 261 EXPECT_EQ(body, string(buffer, bytes_read)); | 265 EXPECT_EQ(body, string(buffer, bytes_read)); |
| 262 } | 266 } |
| 263 | 267 |
| 264 TEST_F(QuicSpdyStreamTest, ProcessHeadersAndBodyMarkConsumed) { | 268 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyMarkConsumed) { |
| 265 Initialize(!kShouldProcessData); | 269 Initialize(!kShouldProcessData); |
| 266 | 270 |
| 267 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 271 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 268 string body = "this is the body"; | 272 string body = "this is the body"; |
| 269 | 273 |
| 270 stream_->OnStreamHeaders(headers); | 274 stream_->OnStreamHeaders(headers); |
| 271 stream_->OnStreamHeadersComplete(false, headers.size()); | 275 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 272 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 276 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
| 273 stream_->OnStreamFrame(frame); | 277 stream_->OnStreamFrame(frame); |
| 274 stream_->MarkHeadersConsumed(headers.length()); | 278 stream_->MarkHeadersConsumed(headers.length()); |
| 275 | 279 |
| 276 struct iovec vec; | 280 struct iovec vec; |
| 277 | 281 |
| 278 EXPECT_EQ(1, stream_->GetReadableRegions(&vec, 1)); | 282 EXPECT_EQ(1, stream_->GetReadableRegions(&vec, 1)); |
| 279 EXPECT_EQ(body.length(), vec.iov_len); | 283 EXPECT_EQ(body.length(), vec.iov_len); |
| 280 EXPECT_EQ(body, string(static_cast<char*>(vec.iov_base), vec.iov_len)); | 284 EXPECT_EQ(body, string(static_cast<char*>(vec.iov_base), vec.iov_len)); |
| 281 | 285 |
| 282 stream_->MarkConsumed(body.length()); | 286 stream_->MarkConsumed(body.length()); |
| 283 EXPECT_EQ(body.length(), stream_->flow_controller()->bytes_consumed()); | 287 EXPECT_EQ(body.length(), stream_->flow_controller()->bytes_consumed()); |
| 284 } | 288 } |
| 285 | 289 |
| 286 TEST_F(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) { | 290 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) { |
| 287 Initialize(!kShouldProcessData); | 291 Initialize(!kShouldProcessData); |
| 288 | 292 |
| 289 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 293 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 290 string body = "this is the body"; | 294 string body = "this is the body"; |
| 291 stream_->OnStreamHeaders(headers); | 295 stream_->OnStreamHeaders(headers); |
| 292 stream_->OnStreamHeadersComplete(false, headers.size()); | 296 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 293 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 297 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
| 294 stream_->OnStreamFrame(frame); | 298 stream_->OnStreamFrame(frame); |
| 295 stream_->MarkHeadersConsumed(headers.length()); | 299 stream_->MarkHeadersConsumed(headers.length()); |
| 296 | 300 |
| 297 char buffer[1]; | 301 char buffer[1]; |
| 298 struct iovec vec; | 302 struct iovec vec; |
| 299 vec.iov_base = buffer; | 303 vec.iov_base = buffer; |
| 300 vec.iov_len = arraysize(buffer); | 304 vec.iov_len = arraysize(buffer); |
| 301 | 305 |
| 302 for (size_t i = 0; i < body.length(); ++i) { | 306 for (size_t i = 0; i < body.length(); ++i) { |
| 303 size_t bytes_read = stream_->Readv(&vec, 1); | 307 size_t bytes_read = stream_->Readv(&vec, 1); |
| 304 ASSERT_EQ(1u, bytes_read); | 308 ASSERT_EQ(1u, bytes_read); |
| 305 EXPECT_EQ(body.data()[i], buffer[0]); | 309 EXPECT_EQ(body.data()[i], buffer[0]); |
| 306 } | 310 } |
| 307 } | 311 } |
| 308 | 312 |
| 309 TEST_F(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) { | 313 TEST_P(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) { |
| 310 Initialize(!kShouldProcessData); | 314 Initialize(!kShouldProcessData); |
| 311 | 315 |
| 312 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 316 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 313 string body = "this is the body"; | 317 string body = "this is the body"; |
| 314 stream_->OnStreamHeaders(headers); | 318 stream_->OnStreamHeaders(headers); |
| 315 stream_->OnStreamHeadersComplete(false, headers.size()); | 319 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 316 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 320 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
| 317 stream_->OnStreamFrame(frame); | 321 stream_->OnStreamFrame(frame); |
| 318 stream_->MarkHeadersConsumed(headers.length()); | 322 stream_->MarkHeadersConsumed(headers.length()); |
| 319 | 323 |
| 320 char buffer1[1]; | 324 char buffer1[1]; |
| 321 char buffer2[1]; | 325 char buffer2[1]; |
| 322 struct iovec vec[2]; | 326 struct iovec vec[2]; |
| 323 vec[0].iov_base = buffer1; | 327 vec[0].iov_base = buffer1; |
| 324 vec[0].iov_len = arraysize(buffer1); | 328 vec[0].iov_len = arraysize(buffer1); |
| 325 vec[1].iov_base = buffer2; | 329 vec[1].iov_base = buffer2; |
| 326 vec[1].iov_len = arraysize(buffer2); | 330 vec[1].iov_len = arraysize(buffer2); |
| 327 | 331 |
| 328 for (size_t i = 0; i < body.length(); i += 2) { | 332 for (size_t i = 0; i < body.length(); i += 2) { |
| 329 size_t bytes_read = stream_->Readv(vec, 2); | 333 size_t bytes_read = stream_->Readv(vec, 2); |
| 330 ASSERT_EQ(2u, bytes_read) << i; | 334 ASSERT_EQ(2u, bytes_read) << i; |
| 331 ASSERT_EQ(body.data()[i], buffer1[0]) << i; | 335 ASSERT_EQ(body.data()[i], buffer1[0]) << i; |
| 332 ASSERT_EQ(body.data()[i + 1], buffer2[0]) << i; | 336 ASSERT_EQ(body.data()[i + 1], buffer2[0]) << i; |
| 333 } | 337 } |
| 334 } | 338 } |
| 335 | 339 |
| 336 TEST_F(QuicSpdyStreamTest, StreamFlowControlBlocked) { | 340 TEST_P(QuicSpdyStreamTest, StreamFlowControlBlocked) { |
| 337 // Tests that we send a BLOCKED frame to the peer when we attempt to write, | 341 // Tests that we send a BLOCKED frame to the peer when we attempt to write, |
| 338 // but are flow control blocked. | 342 // but are flow control blocked. |
| 339 Initialize(kShouldProcessData); | 343 Initialize(kShouldProcessData); |
| 340 | 344 |
| 341 // Set a small flow control limit. | 345 // Set a small flow control limit. |
| 342 const uint64 kWindow = 36; | 346 const uint64 kWindow = 36; |
| 343 QuicFlowControllerPeer::SetSendWindowOffset(stream_->flow_controller(), | 347 QuicFlowControllerPeer::SetSendWindowOffset(stream_->flow_controller(), |
| 344 kWindow); | 348 kWindow); |
| 345 EXPECT_EQ(kWindow, QuicFlowControllerPeer::SendWindowOffset( | 349 EXPECT_EQ(kWindow, QuicFlowControllerPeer::SendWindowOffset( |
| 346 stream_->flow_controller())); | 350 stream_->flow_controller())); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 357 stream_->WriteOrBufferData(body, false, nullptr); | 361 stream_->WriteOrBufferData(body, false, nullptr); |
| 358 | 362 |
| 359 // Should have sent as much as possible, resulting in no send window left. | 363 // Should have sent as much as possible, resulting in no send window left. |
| 360 EXPECT_EQ(0u, | 364 EXPECT_EQ(0u, |
| 361 QuicFlowControllerPeer::SendWindowSize(stream_->flow_controller())); | 365 QuicFlowControllerPeer::SendWindowSize(stream_->flow_controller())); |
| 362 | 366 |
| 363 // And we should have queued the overflowed data. | 367 // And we should have queued the overflowed data. |
| 364 EXPECT_EQ(kOverflow, ReliableQuicStreamPeer::SizeOfQueuedData(stream_.get())); | 368 EXPECT_EQ(kOverflow, ReliableQuicStreamPeer::SizeOfQueuedData(stream_.get())); |
| 365 } | 369 } |
| 366 | 370 |
| 367 TEST_F(QuicSpdyStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) { | 371 TEST_P(QuicSpdyStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) { |
| 368 // The flow control receive window decreases whenever we add new bytes to the | 372 // The flow control receive window decreases whenever we add new bytes to the |
| 369 // sequencer, whether they are consumed immediately or buffered. However we | 373 // sequencer, whether they are consumed immediately or buffered. However we |
| 370 // only send WINDOW_UPDATE frames based on increasing number of bytes | 374 // only send WINDOW_UPDATE frames based on increasing number of bytes |
| 371 // consumed. | 375 // consumed. |
| 372 | 376 |
| 373 // Don't process data - it will be buffered instead. | 377 // Don't process data - it will be buffered instead. |
| 374 Initialize(!kShouldProcessData); | 378 Initialize(!kShouldProcessData); |
| 375 | 379 |
| 376 // Expect no WINDOW_UPDATE frames to be sent. | 380 // Expect no WINDOW_UPDATE frames to be sent. |
| 377 EXPECT_CALL(*connection_, SendWindowUpdate(_, _)).Times(0); | 381 EXPECT_CALL(*connection_, SendWindowUpdate(_, _)).Times(0); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 401 // half full. This should all be buffered, decreasing the receive window but | 405 // half full. This should all be buffered, decreasing the receive window but |
| 402 // not sending WINDOW_UPDATE. | 406 // not sending WINDOW_UPDATE. |
| 403 QuicStreamFrame frame2(kClientDataStreamId1, false, kWindow / 3, | 407 QuicStreamFrame frame2(kClientDataStreamId1, false, kWindow / 3, |
| 404 StringPiece(body)); | 408 StringPiece(body)); |
| 405 stream_->OnStreamFrame(frame2); | 409 stream_->OnStreamFrame(frame2); |
| 406 EXPECT_EQ( | 410 EXPECT_EQ( |
| 407 kWindow - (2 * kWindow / 3), | 411 kWindow - (2 * kWindow / 3), |
| 408 QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller())); | 412 QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller())); |
| 409 } | 413 } |
| 410 | 414 |
| 411 TEST_F(QuicSpdyStreamTest, StreamFlowControlWindowUpdate) { | 415 TEST_P(QuicSpdyStreamTest, StreamFlowControlWindowUpdate) { |
| 412 // Tests that on receipt of data, the stream updates its receive window offset | 416 // Tests that on receipt of data, the stream updates its receive window offset |
| 413 // appropriately, and sends WINDOW_UPDATE frames when its receive window drops | 417 // appropriately, and sends WINDOW_UPDATE frames when its receive window drops |
| 414 // too low. | 418 // too low. |
| 415 Initialize(kShouldProcessData); | 419 Initialize(kShouldProcessData); |
| 416 | 420 |
| 417 // Set a small flow control limit. | 421 // Set a small flow control limit. |
| 418 const uint64 kWindow = 36; | 422 const uint64 kWindow = 36; |
| 419 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 423 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
| 420 kWindow); | 424 kWindow); |
| 421 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), | 425 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), |
| (...skipping 23 matching lines...) Expand all Loading... |
| 445 EXPECT_CALL(*connection_, | 449 EXPECT_CALL(*connection_, |
| 446 SendWindowUpdate(kClientDataStreamId1, | 450 SendWindowUpdate(kClientDataStreamId1, |
| 447 QuicFlowControllerPeer::ReceiveWindowOffset( | 451 QuicFlowControllerPeer::ReceiveWindowOffset( |
| 448 stream_->flow_controller()) + | 452 stream_->flow_controller()) + |
| 449 2 * kWindow / 3)); | 453 2 * kWindow / 3)); |
| 450 stream_->OnStreamFrame(frame2); | 454 stream_->OnStreamFrame(frame2); |
| 451 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowSize( | 455 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowSize( |
| 452 stream_->flow_controller())); | 456 stream_->flow_controller())); |
| 453 } | 457 } |
| 454 | 458 |
| 455 TEST_F(QuicSpdyStreamTest, ConnectionFlowControlWindowUpdate) { | 459 TEST_P(QuicSpdyStreamTest, ConnectionFlowControlWindowUpdate) { |
| 456 // Tests that on receipt of data, the connection updates its receive window | 460 // Tests that on receipt of data, the connection updates its receive window |
| 457 // offset appropriately, and sends WINDOW_UPDATE frames when its receive | 461 // offset appropriately, and sends WINDOW_UPDATE frames when its receive |
| 458 // window drops too low. | 462 // window drops too low. |
| 459 Initialize(kShouldProcessData); | 463 Initialize(kShouldProcessData); |
| 460 | 464 |
| 461 // Set a small flow control limit for streams and connection. | 465 // Set a small flow control limit for streams and connection. |
| 462 const uint64 kWindow = 36; | 466 const uint64 kWindow = 36; |
| 463 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 467 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
| 464 kWindow); | 468 kWindow); |
| 465 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), | 469 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 EXPECT_CALL(*connection_, SendWindowUpdate(kClientDataStreamId2, _)).Times(0); | 502 EXPECT_CALL(*connection_, SendWindowUpdate(kClientDataStreamId2, _)).Times(0); |
| 499 EXPECT_CALL(*connection_, | 503 EXPECT_CALL(*connection_, |
| 500 SendWindowUpdate(0, QuicFlowControllerPeer::ReceiveWindowOffset( | 504 SendWindowUpdate(0, QuicFlowControllerPeer::ReceiveWindowOffset( |
| 501 session_->flow_controller()) + | 505 session_->flow_controller()) + |
| 502 1 + kWindow / 2)); | 506 1 + kWindow / 2)); |
| 503 QuicStreamFrame frame3(kClientDataStreamId1, false, (kWindow / 4), | 507 QuicStreamFrame frame3(kClientDataStreamId1, false, (kWindow / 4), |
| 504 StringPiece("a")); | 508 StringPiece("a")); |
| 505 stream_->OnStreamFrame(frame3); | 509 stream_->OnStreamFrame(frame3); |
| 506 } | 510 } |
| 507 | 511 |
| 508 TEST_F(QuicSpdyStreamTest, StreamFlowControlViolation) { | 512 TEST_P(QuicSpdyStreamTest, StreamFlowControlViolation) { |
| 509 // Tests that on if the peer sends too much data (i.e. violates the flow | 513 // Tests that on if the peer sends too much data (i.e. violates the flow |
| 510 // control protocol), then we terminate the connection. | 514 // control protocol), then we terminate the connection. |
| 511 | 515 |
| 512 // Stream should not process data, so that data gets buffered in the | 516 // Stream should not process data, so that data gets buffered in the |
| 513 // sequencer, triggering flow control limits. | 517 // sequencer, triggering flow control limits. |
| 514 Initialize(!kShouldProcessData); | 518 Initialize(!kShouldProcessData); |
| 515 | 519 |
| 516 // Set a small flow control limit. | 520 // Set a small flow control limit. |
| 517 const uint64 kWindow = 50; | 521 const uint64 kWindow = 50; |
| 518 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 522 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
| 519 kWindow); | 523 kWindow); |
| 520 | 524 |
| 521 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 525 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 522 stream_->OnStreamHeaders(headers); | 526 stream_->OnStreamHeaders(headers); |
| 523 stream_->OnStreamHeadersComplete(false, headers.size()); | 527 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 524 | 528 |
| 525 // Receive data to overflow the window, violating flow control. | 529 // Receive data to overflow the window, violating flow control. |
| 526 string body; | 530 string body; |
| 527 GenerateBody(&body, kWindow + 1); | 531 GenerateBody(&body, kWindow + 1); |
| 528 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 532 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
| 529 EXPECT_CALL(*connection_, | 533 EXPECT_CALL(*connection_, |
| 530 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)); | 534 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)); |
| 531 stream_->OnStreamFrame(frame); | 535 stream_->OnStreamFrame(frame); |
| 532 } | 536 } |
| 533 | 537 |
| 534 TEST_F(QuicSpdyStreamTest, ConnectionFlowControlViolation) { | 538 TEST_P(QuicSpdyStreamTest, TestHandlingQuicRstStreamNoError) { |
| 539 Initialize(kShouldProcessData); |
| 540 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 541 stream_->OnStreamHeaders(headers); |
| 542 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 543 stream_->OnStreamReset( |
| 544 QuicRstStreamFrame(stream_->id(), QUIC_STREAM_NO_ERROR, 0)); |
| 545 EXPECT_TRUE(stream_->write_side_closed()); |
| 546 if (GetParam() > QUIC_VERSION_28) { |
| 547 EXPECT_FALSE(stream_->reading_stopped()); |
| 548 } else { |
| 549 EXPECT_TRUE(stream_->reading_stopped()); |
| 550 } |
| 551 } |
| 552 |
| 553 TEST_P(QuicSpdyStreamTest, ConnectionFlowControlViolation) { |
| 535 // Tests that on if the peer sends too much data (i.e. violates the flow | 554 // Tests that on if the peer sends too much data (i.e. violates the flow |
| 536 // control protocol), at the connection level (rather than the stream level) | 555 // control protocol), at the connection level (rather than the stream level) |
| 537 // then we terminate the connection. | 556 // then we terminate the connection. |
| 538 | 557 |
| 539 // Stream should not process data, so that data gets buffered in the | 558 // Stream should not process data, so that data gets buffered in the |
| 540 // sequencer, triggering flow control limits. | 559 // sequencer, triggering flow control limits. |
| 541 Initialize(!kShouldProcessData); | 560 Initialize(!kShouldProcessData); |
| 542 | 561 |
| 543 // Set a small flow control window on streams, and connection. | 562 // Set a small flow control window on streams, and connection. |
| 544 const uint64 kStreamWindow = 50; | 563 const uint64 kStreamWindow = 50; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 556 string body; | 575 string body; |
| 557 GenerateBody(&body, kConnectionWindow + 1); | 576 GenerateBody(&body, kConnectionWindow + 1); |
| 558 EXPECT_LT(body.size(), kStreamWindow); | 577 EXPECT_LT(body.size(), kStreamWindow); |
| 559 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 578 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
| 560 | 579 |
| 561 EXPECT_CALL(*connection_, | 580 EXPECT_CALL(*connection_, |
| 562 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)); | 581 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)); |
| 563 stream_->OnStreamFrame(frame); | 582 stream_->OnStreamFrame(frame); |
| 564 } | 583 } |
| 565 | 584 |
| 566 TEST_F(QuicSpdyStreamTest, StreamFlowControlFinNotBlocked) { | 585 TEST_P(QuicSpdyStreamTest, StreamFlowControlFinNotBlocked) { |
| 567 // An attempt to write a FIN with no data should not be flow control blocked, | 586 // An attempt to write a FIN with no data should not be flow control blocked, |
| 568 // even if the send window is 0. | 587 // even if the send window is 0. |
| 569 | 588 |
| 570 Initialize(kShouldProcessData); | 589 Initialize(kShouldProcessData); |
| 571 | 590 |
| 572 // Set a flow control limit of zero. | 591 // Set a flow control limit of zero. |
| 573 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), 0); | 592 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), 0); |
| 574 EXPECT_EQ(0u, QuicFlowControllerPeer::ReceiveWindowOffset( | 593 EXPECT_EQ(0u, QuicFlowControllerPeer::ReceiveWindowOffset( |
| 575 stream_->flow_controller())); | 594 stream_->flow_controller())); |
| 576 | 595 |
| 577 // Send a frame with a FIN but no data. This should not be blocked. | 596 // Send a frame with a FIN but no data. This should not be blocked. |
| 578 string body = ""; | 597 string body = ""; |
| 579 bool fin = true; | 598 bool fin = true; |
| 580 | 599 |
| 581 EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1)).Times(0); | 600 EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1)).Times(0); |
| 582 EXPECT_CALL(*session_, WritevData(kClientDataStreamId1, _, _, _, _, _)) | 601 EXPECT_CALL(*session_, WritevData(kClientDataStreamId1, _, _, _, _, _)) |
| 583 .WillOnce(Return(QuicConsumedData(0, fin))); | 602 .WillOnce(Return(QuicConsumedData(0, fin))); |
| 584 | 603 |
| 585 stream_->WriteOrBufferData(body, fin, nullptr); | 604 stream_->WriteOrBufferData(body, fin, nullptr); |
| 586 } | 605 } |
| 587 | 606 |
| 588 } // namespace | 607 } // namespace |
| 589 } // namespace test | 608 } // namespace test |
| 590 } // namespace net | 609 } // namespace net |
| OLD | NEW |