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 |