| 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_data_stream.h" | 5 #include "net/quic/quic_data_stream.h" |
| 6 | 6 |
| 7 #include "net/quic/quic_ack_notifier.h" | 7 #include "net/quic/quic_ack_notifier.h" |
| 8 #include "net/quic/quic_connection.h" | 8 #include "net/quic/quic_connection.h" |
| 9 #include "net/quic/quic_flags.h" | 9 #include "net/quic/quic_flags.h" |
| 10 #include "net/quic/quic_utils.h" | 10 #include "net/quic/quic_utils.h" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 namespace net { | 29 namespace net { |
| 30 namespace test { | 30 namespace test { |
| 31 namespace { | 31 namespace { |
| 32 | 32 |
| 33 const QuicConnectionId kStreamId = 3; | 33 const QuicConnectionId kStreamId = 3; |
| 34 const bool kIsServer = true; | 34 const bool kIsServer = true; |
| 35 const bool kShouldProcessData = true; | 35 const bool kShouldProcessData = true; |
| 36 | 36 |
| 37 class TestStream : public QuicDataStream { | 37 class TestStream : public QuicDataStream { |
| 38 public: | 38 public: |
| 39 TestStream(QuicStreamId id, | 39 TestStream(QuicStreamId id, QuicSession* session, bool should_process_data) |
| 40 QuicSession* session, | |
| 41 bool should_process_data) | |
| 42 : QuicDataStream(id, session), | 40 : QuicDataStream(id, session), |
| 43 should_process_data_(should_process_data) {} | 41 should_process_data_(should_process_data) {} |
| 44 | 42 |
| 45 virtual uint32 ProcessData(const char* data, uint32 data_len) OVERRIDE { | 43 virtual uint32 ProcessData(const char* data, uint32 data_len) OVERRIDE { |
| 46 EXPECT_NE(0u, data_len); | 44 EXPECT_NE(0u, data_len); |
| 47 DVLOG(1) << "ProcessData data_len: " << data_len; | 45 DVLOG(1) << "ProcessData data_len: " << data_len; |
| 48 data_ += string(data, data_len); | 46 data_ += string(data, data_len); |
| 49 return should_process_data_ ? data_len : 0; | 47 return should_process_data_ ? data_len : 0; |
| 50 } | 48 } |
| 51 | 49 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk" | 87 "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk" |
| 90 "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn" | 88 "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn" |
| 91 "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr" | 89 "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr" |
| 92 "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo "; | 90 "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo "; |
| 93 } | 91 } |
| 94 | 92 |
| 95 void Initialize(bool stream_should_process_data) { | 93 void Initialize(bool stream_should_process_data) { |
| 96 connection_ = new testing::StrictMock<MockConnection>( | 94 connection_ = new testing::StrictMock<MockConnection>( |
| 97 kIsServer, SupportedVersions(GetParam())); | 95 kIsServer, SupportedVersions(GetParam())); |
| 98 session_.reset(new testing::StrictMock<MockSession>(connection_)); | 96 session_.reset(new testing::StrictMock<MockSession>(connection_)); |
| 99 stream_.reset(new TestStream(kStreamId, session_.get(), | 97 stream_.reset( |
| 100 stream_should_process_data)); | 98 new TestStream(kStreamId, session_.get(), stream_should_process_data)); |
| 101 stream2_.reset(new TestStream(kStreamId + 2, session_.get(), | 99 stream2_.reset(new TestStream( |
| 102 stream_should_process_data)); | 100 kStreamId + 2, session_.get(), stream_should_process_data)); |
| 103 write_blocked_list_ = | 101 write_blocked_list_ = |
| 104 QuicSessionPeer::GetWriteblockedStreams(session_.get()); | 102 QuicSessionPeer::GetWriteblockedStreams(session_.get()); |
| 105 } | 103 } |
| 106 | 104 |
| 107 protected: | 105 protected: |
| 108 MockConnection* connection_; | 106 MockConnection* connection_; |
| 109 scoped_ptr<MockSession> session_; | 107 scoped_ptr<MockSession> session_; |
| 110 scoped_ptr<TestStream> stream_; | 108 scoped_ptr<TestStream> stream_; |
| 111 scoped_ptr<TestStream> stream2_; | 109 scoped_ptr<TestStream> stream2_; |
| 112 SpdyHeaderBlock headers_; | 110 SpdyHeaderBlock headers_; |
| 113 QuicWriteBlockedList* write_blocked_list_; | 111 QuicWriteBlockedList* write_blocked_list_; |
| 114 }; | 112 }; |
| 115 | 113 |
| 116 INSTANTIATE_TEST_CASE_P(Tests, QuicDataStreamTest, | 114 INSTANTIATE_TEST_CASE_P(Tests, |
| 115 QuicDataStreamTest, |
| 117 ::testing::ValuesIn(QuicSupportedVersions())); | 116 ::testing::ValuesIn(QuicSupportedVersions())); |
| 118 | 117 |
| 119 TEST_P(QuicDataStreamTest, ProcessHeaders) { | 118 TEST_P(QuicDataStreamTest, ProcessHeaders) { |
| 120 Initialize(kShouldProcessData); | 119 Initialize(kShouldProcessData); |
| 121 | 120 |
| 122 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 121 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 123 stream_->OnStreamHeadersPriority(QuicUtils::HighestPriority()); | 122 stream_->OnStreamHeadersPriority(QuicUtils::HighestPriority()); |
| 124 stream_->OnStreamHeaders(headers); | 123 stream_->OnStreamHeaders(headers); |
| 125 EXPECT_EQ(headers, stream_->data()); | 124 EXPECT_EQ(headers, stream_->data()); |
| 126 stream_->OnStreamHeadersComplete(false, headers.size()); | 125 stream_->OnStreamHeadersComplete(false, headers.size()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 141 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(body)); | 140 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(body)); |
| 142 stream_->OnStreamFrame(frame); | 141 stream_->OnStreamFrame(frame); |
| 143 | 142 |
| 144 EXPECT_EQ(headers + body, stream_->data()); | 143 EXPECT_EQ(headers + body, stream_->data()); |
| 145 } | 144 } |
| 146 | 145 |
| 147 TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragments) { | 146 TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragments) { |
| 148 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 147 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 149 string body = "this is the body"; | 148 string body = "this is the body"; |
| 150 | 149 |
| 151 for (size_t fragment_size = 1; fragment_size < body.size(); | 150 for (size_t fragment_size = 1; fragment_size < body.size(); ++fragment_size) { |
| 152 ++fragment_size) { | |
| 153 Initialize(kShouldProcessData); | 151 Initialize(kShouldProcessData); |
| 154 for (size_t offset = 0; offset < headers.size(); | 152 for (size_t offset = 0; offset < headers.size(); offset += fragment_size) { |
| 155 offset += fragment_size) { | |
| 156 size_t remaining_data = headers.size() - offset; | 153 size_t remaining_data = headers.size() - offset; |
| 157 StringPiece fragment(headers.data() + offset, | 154 StringPiece fragment(headers.data() + offset, |
| 158 min(fragment_size, remaining_data)); | 155 min(fragment_size, remaining_data)); |
| 159 stream_->OnStreamHeaders(fragment); | 156 stream_->OnStreamHeaders(fragment); |
| 160 } | 157 } |
| 161 stream_->OnStreamHeadersComplete(false, headers.size()); | 158 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 162 for (size_t offset = 0; offset < body.size(); offset += fragment_size) { | 159 for (size_t offset = 0; offset < body.size(); offset += fragment_size) { |
| 163 size_t remaining_data = body.size() - offset; | 160 size_t remaining_data = body.size() - offset; |
| 164 StringPiece fragment(body.data() + offset, | 161 StringPiece fragment(body.data() + offset, |
| 165 min(fragment_size, remaining_data)); | 162 min(fragment_size, remaining_data)); |
| 166 QuicStreamFrame frame(kStreamId, false, offset, MakeIOVector(fragment)); | 163 QuicStreamFrame frame(kStreamId, false, offset, MakeIOVector(fragment)); |
| 167 stream_->OnStreamFrame(frame); | 164 stream_->OnStreamFrame(frame); |
| 168 } | 165 } |
| 169 ASSERT_EQ(headers + body, | 166 ASSERT_EQ(headers + body, stream_->data()) |
| 170 stream_->data()) << "fragment_size: " << fragment_size; | 167 << "fragment_size: " << fragment_size; |
| 171 } | 168 } |
| 172 } | 169 } |
| 173 | 170 |
| 174 TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragmentsSplit) { | 171 TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragmentsSplit) { |
| 175 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 172 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 176 string body = "this is the body"; | 173 string body = "this is the body"; |
| 177 | 174 |
| 178 for (size_t split_point = 1; split_point < body.size() - 1; ++split_point) { | 175 for (size_t split_point = 1; split_point < body.size() - 1; ++split_point) { |
| 179 Initialize(kShouldProcessData); | 176 Initialize(kShouldProcessData); |
| 180 StringPiece headers1(headers.data(), split_point); | 177 StringPiece headers1(headers.data(), split_point); |
| 181 stream_->OnStreamHeaders(headers1); | 178 stream_->OnStreamHeaders(headers1); |
| 182 | 179 |
| 183 StringPiece headers2(headers.data() + split_point, | 180 StringPiece headers2(headers.data() + split_point, |
| 184 headers.size() - split_point); | 181 headers.size() - split_point); |
| 185 stream_->OnStreamHeaders(headers2); | 182 stream_->OnStreamHeaders(headers2); |
| 186 stream_->OnStreamHeadersComplete(false, headers.size()); | 183 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 187 | 184 |
| 188 StringPiece fragment1(body.data(), split_point); | 185 StringPiece fragment1(body.data(), split_point); |
| 189 QuicStreamFrame frame1(kStreamId, false, 0, MakeIOVector(fragment1)); | 186 QuicStreamFrame frame1(kStreamId, false, 0, MakeIOVector(fragment1)); |
| 190 stream_->OnStreamFrame(frame1); | 187 stream_->OnStreamFrame(frame1); |
| 191 | 188 |
| 192 StringPiece fragment2(body.data() + split_point, | 189 StringPiece fragment2(body.data() + split_point, body.size() - split_point); |
| 193 body.size() - split_point); | |
| 194 QuicStreamFrame frame2( | 190 QuicStreamFrame frame2( |
| 195 kStreamId, false, split_point, MakeIOVector(fragment2)); | 191 kStreamId, false, split_point, MakeIOVector(fragment2)); |
| 196 stream_->OnStreamFrame(frame2); | 192 stream_->OnStreamFrame(frame2); |
| 197 | 193 |
| 198 ASSERT_EQ(headers + body, | 194 ASSERT_EQ(headers + body, stream_->data()) |
| 199 stream_->data()) << "split_point: " << split_point; | 195 << "split_point: " << split_point; |
| 200 } | 196 } |
| 201 } | 197 } |
| 202 | 198 |
| 203 TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyReadv) { | 199 TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyReadv) { |
| 204 Initialize(!kShouldProcessData); | 200 Initialize(!kShouldProcessData); |
| 205 | 201 |
| 206 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 202 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 207 string body = "this is the body"; | 203 string body = "this is the body"; |
| 208 | 204 |
| 209 stream_->OnStreamHeaders(headers); | 205 stream_->OnStreamHeaders(headers); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 231 Initialize(!kShouldProcessData); | 227 Initialize(!kShouldProcessData); |
| 232 | 228 |
| 233 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 229 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 234 string body = "this is the body"; | 230 string body = "this is the body"; |
| 235 stream_->OnStreamHeaders(headers); | 231 stream_->OnStreamHeaders(headers); |
| 236 EXPECT_EQ(headers, stream_->data()); | 232 EXPECT_EQ(headers, stream_->data()); |
| 237 stream_->OnStreamHeadersComplete(false, headers.size()); | 233 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 238 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(body)); | 234 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(body)); |
| 239 stream_->OnStreamFrame(frame); | 235 stream_->OnStreamFrame(frame); |
| 240 | 236 |
| 241 | |
| 242 char buffer[1]; | 237 char buffer[1]; |
| 243 struct iovec vec; | 238 struct iovec vec; |
| 244 vec.iov_base = buffer; | 239 vec.iov_base = buffer; |
| 245 vec.iov_len = arraysize(buffer); | 240 vec.iov_len = arraysize(buffer); |
| 246 | 241 |
| 247 string data = headers + body; | 242 string data = headers + body; |
| 248 for (size_t i = 0; i < data.length(); ++i) { | 243 for (size_t i = 0; i < data.length(); ++i) { |
| 249 size_t bytes_read = stream_->Readv(&vec, 1); | 244 size_t bytes_read = stream_->Readv(&vec, 1); |
| 250 ASSERT_EQ(1u, bytes_read); | 245 ASSERT_EQ(1u, bytes_read); |
| 251 EXPECT_EQ(data.data()[i], buffer[0]); | 246 EXPECT_EQ(data.data()[i], buffer[0]); |
| 252 } | 247 } |
| 253 } | 248 } |
| 254 | 249 |
| 255 TEST_P(QuicDataStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) { | 250 TEST_P(QuicDataStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) { |
| 256 Initialize(!kShouldProcessData); | 251 Initialize(!kShouldProcessData); |
| 257 | 252 |
| 258 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 253 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 259 string body = "this is the body"; | 254 string body = "this is the body"; |
| 260 stream_->OnStreamHeaders(headers); | 255 stream_->OnStreamHeaders(headers); |
| 261 EXPECT_EQ(headers, stream_->data()); | 256 EXPECT_EQ(headers, stream_->data()); |
| 262 stream_->OnStreamHeadersComplete(false, headers.size()); | 257 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 263 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(body)); | 258 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(body)); |
| 264 stream_->OnStreamFrame(frame); | 259 stream_->OnStreamFrame(frame); |
| 265 | 260 |
| 266 | |
| 267 char buffer1[1]; | 261 char buffer1[1]; |
| 268 char buffer2[1]; | 262 char buffer2[1]; |
| 269 struct iovec vec[2]; | 263 struct iovec vec[2]; |
| 270 vec[0].iov_base = buffer1; | 264 vec[0].iov_base = buffer1; |
| 271 vec[0].iov_len = arraysize(buffer1); | 265 vec[0].iov_len = arraysize(buffer1); |
| 272 vec[1].iov_base = buffer2; | 266 vec[1].iov_base = buffer2; |
| 273 vec[1].iov_len = arraysize(buffer2); | 267 vec[1].iov_len = arraysize(buffer2); |
| 274 string data = headers + body; | 268 string data = headers + body; |
| 275 for (size_t i = 0; i < data.length(); i += 2) { | 269 for (size_t i = 0; i < data.length(); i += 2) { |
| 276 size_t bytes_read = stream_->Readv(vec, 2); | 270 size_t bytes_read = stream_->Readv(vec, 2); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 287 return; | 281 return; |
| 288 } | 282 } |
| 289 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true); | 283 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true); |
| 290 | 284 |
| 291 Initialize(kShouldProcessData); | 285 Initialize(kShouldProcessData); |
| 292 | 286 |
| 293 // Set a small flow control limit. | 287 // Set a small flow control limit. |
| 294 const uint64 kWindow = 36; | 288 const uint64 kWindow = 36; |
| 295 QuicFlowControllerPeer::SetSendWindowOffset(stream_->flow_controller(), | 289 QuicFlowControllerPeer::SetSendWindowOffset(stream_->flow_controller(), |
| 296 kWindow); | 290 kWindow); |
| 297 EXPECT_EQ(kWindow, QuicFlowControllerPeer::SendWindowOffset( | 291 EXPECT_EQ( |
| 298 stream_->flow_controller())); | 292 kWindow, |
| 293 QuicFlowControllerPeer::SendWindowOffset(stream_->flow_controller())); |
| 299 | 294 |
| 300 // Try to send more data than the flow control limit allows. | 295 // Try to send more data than the flow control limit allows. |
| 301 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 296 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 302 string body; | 297 string body; |
| 303 const uint64 kOverflow = 15; | 298 const uint64 kOverflow = 15; |
| 304 GenerateBody(&body, kWindow + kOverflow); | 299 GenerateBody(&body, kWindow + kOverflow); |
| 305 | 300 |
| 306 EXPECT_CALL(*connection_, SendBlocked(kStreamId)); | 301 EXPECT_CALL(*connection_, SendBlocked(kStreamId)); |
| 307 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( | 302 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)) |
| 308 Return(QuicConsumedData(kWindow, true))); | 303 .WillOnce(Return(QuicConsumedData(kWindow, true))); |
| 309 stream_->WriteOrBufferData(body, false, NULL); | 304 stream_->WriteOrBufferData(body, false, NULL); |
| 310 | 305 |
| 311 // Should have sent as much as possible, resulting in no send window left. | 306 // Should have sent as much as possible, resulting in no send window left. |
| 312 EXPECT_EQ(0u, | 307 EXPECT_EQ(0u, |
| 313 QuicFlowControllerPeer::SendWindowSize(stream_->flow_controller())); | 308 QuicFlowControllerPeer::SendWindowSize(stream_->flow_controller())); |
| 314 | 309 |
| 315 // And we should have queued the overflowed data. | 310 // And we should have queued the overflowed data. |
| 316 EXPECT_EQ(kOverflow, | 311 EXPECT_EQ(kOverflow, ReliableQuicStreamPeer::SizeOfQueuedData(stream_.get())); |
| 317 ReliableQuicStreamPeer::SizeOfQueuedData(stream_.get())); | |
| 318 } | 312 } |
| 319 | 313 |
| 320 TEST_P(QuicDataStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) { | 314 TEST_P(QuicDataStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) { |
| 321 // The flow control receive window decreases whenever we add new bytes to the | 315 // The flow control receive window decreases whenever we add new bytes to the |
| 322 // sequencer, whether they are consumed immediately or buffered. However we | 316 // sequencer, whether they are consumed immediately or buffered. However we |
| 323 // only send WINDOW_UPDATE frames based on increasing number of bytes | 317 // only send WINDOW_UPDATE frames based on increasing number of bytes |
| 324 // consumed. | 318 // consumed. |
| 325 if (GetParam() < QUIC_VERSION_17) { | 319 if (GetParam() < QUIC_VERSION_17) { |
| 326 return; | 320 return; |
| 327 } | 321 } |
| 328 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true); | 322 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true); |
| 329 | 323 |
| 330 // Don't process data - it will be buffered instead. | 324 // Don't process data - it will be buffered instead. |
| 331 Initialize(!kShouldProcessData); | 325 Initialize(!kShouldProcessData); |
| 332 | 326 |
| 333 // Expect no WINDOW_UPDATE frames to be sent. | 327 // Expect no WINDOW_UPDATE frames to be sent. |
| 334 EXPECT_CALL(*connection_, SendWindowUpdate(_, _)).Times(0); | 328 EXPECT_CALL(*connection_, SendWindowUpdate(_, _)).Times(0); |
| 335 | 329 |
| 336 // Set a small flow control receive window. | 330 // Set a small flow control receive window. |
| 337 const uint64 kWindow = 36; | 331 const uint64 kWindow = 36; |
| 338 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 332 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
| 339 kWindow); | 333 kWindow); |
| 340 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), | 334 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), |
| 341 kWindow); | 335 kWindow); |
| 342 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset( | 336 EXPECT_EQ( |
| 343 stream_->flow_controller())); | 337 kWindow, |
| 338 QuicFlowControllerPeer::ReceiveWindowOffset(stream_->flow_controller())); |
| 344 | 339 |
| 345 // Stream receives enough data to fill a fraction of the receive window. | 340 // Stream receives enough data to fill a fraction of the receive window. |
| 346 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 341 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 347 string body; | 342 string body; |
| 348 GenerateBody(&body, kWindow / 3); | 343 GenerateBody(&body, kWindow / 3); |
| 349 stream_->OnStreamHeaders(headers); | 344 stream_->OnStreamHeaders(headers); |
| 350 EXPECT_EQ(headers, stream_->data()); | 345 EXPECT_EQ(headers, stream_->data()); |
| 351 stream_->OnStreamHeadersComplete(false, headers.size()); | 346 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 352 | 347 |
| 353 QuicStreamFrame frame1(kStreamId, false, 0, MakeIOVector(body)); | 348 QuicStreamFrame frame1(kStreamId, false, 0, MakeIOVector(body)); |
| 354 stream_->OnStreamFrame(frame1); | 349 stream_->OnStreamFrame(frame1); |
| 355 EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize( | 350 EXPECT_EQ( |
| 356 stream_->flow_controller())); | 351 kWindow - (kWindow / 3), |
| 352 QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller())); |
| 357 | 353 |
| 358 // Now receive another frame which results in the receive window being over | 354 // Now receive another frame which results in the receive window being over |
| 359 // half full. This should all be buffered, decreasing the receive window but | 355 // half full. This should all be buffered, decreasing the receive window but |
| 360 // not sending WINDOW_UPDATE. | 356 // not sending WINDOW_UPDATE. |
| 361 QuicStreamFrame frame2(kStreamId, false, kWindow / 3, MakeIOVector(body)); | 357 QuicStreamFrame frame2(kStreamId, false, kWindow / 3, MakeIOVector(body)); |
| 362 stream_->OnStreamFrame(frame2); | 358 stream_->OnStreamFrame(frame2); |
| 363 EXPECT_EQ( | 359 EXPECT_EQ( |
| 364 kWindow - (2 * kWindow / 3), | 360 kWindow - (2 * kWindow / 3), |
| 365 QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller())); | 361 QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller())); |
| 366 } | 362 } |
| 367 | 363 |
| 368 TEST_P(QuicDataStreamTest, StreamFlowControlWindowUpdate) { | 364 TEST_P(QuicDataStreamTest, StreamFlowControlWindowUpdate) { |
| 369 // Tests that on receipt of data, the stream updates its receive window offset | 365 // Tests that on receipt of data, the stream updates its receive window offset |
| 370 // appropriately, and sends WINDOW_UPDATE frames when its receive window drops | 366 // appropriately, and sends WINDOW_UPDATE frames when its receive window drops |
| 371 // too low. | 367 // too low. |
| 372 if (GetParam() < QUIC_VERSION_17) { | 368 if (GetParam() < QUIC_VERSION_17) { |
| 373 return; | 369 return; |
| 374 } | 370 } |
| 375 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true); | 371 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true); |
| 376 | 372 |
| 377 Initialize(kShouldProcessData); | 373 Initialize(kShouldProcessData); |
| 378 | 374 |
| 379 // Set a small flow control limit. | 375 // Set a small flow control limit. |
| 380 const uint64 kWindow = 36; | 376 const uint64 kWindow = 36; |
| 381 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 377 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
| 382 kWindow); | 378 kWindow); |
| 383 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), | 379 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), |
| 384 kWindow); | 380 kWindow); |
| 385 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset( | 381 EXPECT_EQ( |
| 386 stream_->flow_controller())); | 382 kWindow, |
| 383 QuicFlowControllerPeer::ReceiveWindowOffset(stream_->flow_controller())); |
| 387 | 384 |
| 388 // Stream receives enough data to fill a fraction of the receive window. | 385 // Stream receives enough data to fill a fraction of the receive window. |
| 389 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 386 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
| 390 string body; | 387 string body; |
| 391 GenerateBody(&body, kWindow / 3); | 388 GenerateBody(&body, kWindow / 3); |
| 392 stream_->OnStreamHeaders(headers); | 389 stream_->OnStreamHeaders(headers); |
| 393 EXPECT_EQ(headers, stream_->data()); | 390 EXPECT_EQ(headers, stream_->data()); |
| 394 stream_->OnStreamHeadersComplete(false, headers.size()); | 391 stream_->OnStreamHeadersComplete(false, headers.size()); |
| 395 | 392 |
| 396 QuicStreamFrame frame1(kStreamId, false, 0, MakeIOVector(body)); | 393 QuicStreamFrame frame1(kStreamId, false, 0, MakeIOVector(body)); |
| 397 stream_->OnStreamFrame(frame1); | 394 stream_->OnStreamFrame(frame1); |
| 398 EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize( | 395 EXPECT_EQ( |
| 399 stream_->flow_controller())); | 396 kWindow - (kWindow / 3), |
| 397 QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller())); |
| 400 | 398 |
| 401 // Now receive another frame which results in the receive window being over | 399 // Now receive another frame which results in the receive window being over |
| 402 // half full. This will trigger the stream to increase its receive window | 400 // half full. This will trigger the stream to increase its receive window |
| 403 // offset and send a WINDOW_UPDATE. The result will be again an available | 401 // offset and send a WINDOW_UPDATE. The result will be again an available |
| 404 // window of kWindow bytes. | 402 // window of kWindow bytes. |
| 405 QuicStreamFrame frame2(kStreamId, false, kWindow / 3, MakeIOVector(body)); | 403 QuicStreamFrame frame2(kStreamId, false, kWindow / 3, MakeIOVector(body)); |
| 406 EXPECT_CALL( | 404 EXPECT_CALL(*connection_, |
| 407 *connection_, | 405 SendWindowUpdate(kStreamId, |
| 408 SendWindowUpdate(kStreamId, QuicFlowControllerPeer::ReceiveWindowOffset( | 406 QuicFlowControllerPeer::ReceiveWindowOffset( |
| 409 stream_->flow_controller()) + | 407 stream_->flow_controller()) + |
| 410 2 * kWindow / 3)); | 408 2 * kWindow / 3)); |
| 411 stream_->OnStreamFrame(frame2); | 409 stream_->OnStreamFrame(frame2); |
| 412 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowSize( | 410 EXPECT_EQ( |
| 413 stream_->flow_controller())); | 411 kWindow, |
| 412 QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller())); |
| 414 } | 413 } |
| 415 | 414 |
| 416 TEST_P(QuicDataStreamTest, StreamFlowControlViolation) { | 415 TEST_P(QuicDataStreamTest, StreamFlowControlViolation) { |
| 417 // Tests that on if the peer sends too much data (i.e. violates the flow | 416 // Tests that on if the peer sends too much data (i.e. violates the flow |
| 418 // control protocol), then we terminate the connection. | 417 // control protocol), then we terminate the connection. |
| 419 if (GetParam() < QUIC_VERSION_17) { | 418 if (GetParam() < QUIC_VERSION_17) { |
| 420 return; | 419 return; |
| 421 } | 420 } |
| 422 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true); | 421 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true); |
| 423 | 422 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 448 // even if the send window is 0. | 447 // even if the send window is 0. |
| 449 if (GetParam() < QUIC_VERSION_17) { | 448 if (GetParam() < QUIC_VERSION_17) { |
| 450 return; | 449 return; |
| 451 } | 450 } |
| 452 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true); | 451 ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true); |
| 453 | 452 |
| 454 Initialize(kShouldProcessData); | 453 Initialize(kShouldProcessData); |
| 455 | 454 |
| 456 // Set a flow control limit of zero. | 455 // Set a flow control limit of zero. |
| 457 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), 0); | 456 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), 0); |
| 458 EXPECT_EQ(0u, QuicFlowControllerPeer::ReceiveWindowOffset( | 457 EXPECT_EQ( |
| 459 stream_->flow_controller())); | 458 0u, |
| 459 QuicFlowControllerPeer::ReceiveWindowOffset(stream_->flow_controller())); |
| 460 | 460 |
| 461 // Send a frame with a FIN but no data. This should not be blocked. | 461 // Send a frame with a FIN but no data. This should not be blocked. |
| 462 string body = ""; | 462 string body = ""; |
| 463 bool fin = true; | 463 bool fin = true; |
| 464 | 464 |
| 465 EXPECT_CALL(*connection_, SendBlocked(kStreamId)).Times(0); | 465 EXPECT_CALL(*connection_, SendBlocked(kStreamId)).Times(0); |
| 466 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce( | 466 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)) |
| 467 Return(QuicConsumedData(0, fin))); | 467 .WillOnce(Return(QuicConsumedData(0, fin))); |
| 468 | 468 |
| 469 stream_->WriteOrBufferData(body, fin, NULL); | 469 stream_->WriteOrBufferData(body, fin, NULL); |
| 470 } | 470 } |
| 471 | 471 |
| 472 } // namespace | 472 } // namespace |
| 473 } // namespace test | 473 } // namespace test |
| 474 } // namespace net | 474 } // namespace net |
| OLD | NEW |