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/core/quic_spdy_stream.h" | 5 #include "net/quic/core/quic_spdy_stream.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "net/quic/core/quic_connection.h" | 10 #include "net/quic/core/quic_connection.h" |
11 #include "net/quic/core/quic_utils.h" | 11 #include "net/quic/core/quic_utils.h" |
12 #include "net/quic/core/quic_write_blocked_list.h" | 12 #include "net/quic/core/quic_write_blocked_list.h" |
13 #include "net/quic/core/spdy_utils.h" | 13 #include "net/quic/core/spdy_utils.h" |
14 #include "net/quic/platform/api/quic_ptr_util.h" | 14 #include "net/quic/platform/api/quic_ptr_util.h" |
15 #include "net/quic/platform/api/quic_string_piece.h" | 15 #include "net/quic/platform/api/quic_string_piece.h" |
16 #include "net/quic/platform/api/quic_test.h" | 16 #include "net/quic/platform/api/quic_test.h" |
17 #include "net/quic/platform/api/quic_text_utils.h" | 17 #include "net/quic/platform/api/quic_text_utils.h" |
18 #include "net/quic/test_tools/quic_flow_controller_peer.h" | 18 #include "net/quic/test_tools/quic_flow_controller_peer.h" |
19 #include "net/quic/test_tools/quic_spdy_session_peer.h" | 19 #include "net/quic/test_tools/quic_session_peer.h" |
20 #include "net/quic/test_tools/quic_stream_peer.h" | 20 #include "net/quic/test_tools/quic_stream_peer.h" |
21 #include "net/quic/test_tools/quic_test_utils.h" | 21 #include "net/quic/test_tools/quic_test_utils.h" |
22 | 22 |
23 using std::string; | 23 using std::string; |
24 using testing::AnyNumber; | 24 using testing::AnyNumber; |
25 using testing::Invoke; | 25 using testing::Invoke; |
26 using testing::Return; | 26 using testing::Return; |
27 using testing::StrictMock; | 27 using testing::StrictMock; |
28 using testing::_; | 28 using testing::_; |
29 | 29 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn" | 93 "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn" |
94 "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr" | 94 "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr" |
95 "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo "; | 95 "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo "; |
96 } | 96 } |
97 | 97 |
98 void Initialize(bool stream_should_process_data) { | 98 void Initialize(bool stream_should_process_data) { |
99 connection_ = new testing::StrictMock<MockQuicConnection>( | 99 connection_ = new testing::StrictMock<MockQuicConnection>( |
100 &helper_, &alarm_factory_, Perspective::IS_SERVER, | 100 &helper_, &alarm_factory_, Perspective::IS_SERVER, |
101 SupportedVersions(GetParam())); | 101 SupportedVersions(GetParam())); |
102 session_.reset(new testing::StrictMock<MockQuicSpdySession>(connection_)); | 102 session_.reset(new testing::StrictMock<MockQuicSpdySession>(connection_)); |
103 stream_ = new TestStream(GetNthClientInitiatedId(0), session_.get(), | 103 stream_ = new TestStream(kClientDataStreamId1, session_.get(), |
104 stream_should_process_data); | 104 stream_should_process_data); |
105 session_->ActivateStream(QuicWrapUnique(stream_)); | 105 session_->ActivateStream(QuicWrapUnique(stream_)); |
106 stream2_ = new TestStream(GetNthClientInitiatedId(1), session_.get(), | 106 stream2_ = new TestStream(kClientDataStreamId2, session_.get(), |
107 stream_should_process_data); | 107 stream_should_process_data); |
108 session_->ActivateStream(QuicWrapUnique(stream2_)); | 108 session_->ActivateStream(QuicWrapUnique(stream2_)); |
109 } | 109 } |
110 | 110 |
111 QuicHeaderList ProcessHeaders(bool fin, const SpdyHeaderBlock& headers) { | 111 QuicHeaderList ProcessHeaders(bool fin, const SpdyHeaderBlock& headers) { |
112 QuicHeaderList h = AsHeaderList(headers); | 112 QuicHeaderList h = AsHeaderList(headers); |
113 stream_->OnStreamHeaderList(fin, h.uncompressed_header_bytes(), h); | 113 stream_->OnStreamHeaderList(fin, h.uncompressed_header_bytes(), h); |
114 return h; | 114 return h; |
115 } | 115 } |
116 | 116 |
117 QuicStreamId GetNthClientInitiatedId(int n) { | |
118 return QuicSpdySessionPeer::GetNthClientInitiatedStreamId(*session_, n); | |
119 } | |
120 | |
121 protected: | 117 protected: |
122 MockQuicConnectionHelper helper_; | 118 MockQuicConnectionHelper helper_; |
123 MockAlarmFactory alarm_factory_; | 119 MockAlarmFactory alarm_factory_; |
124 MockQuicConnection* connection_; | 120 MockQuicConnection* connection_; |
125 std::unique_ptr<MockQuicSpdySession> session_; | 121 std::unique_ptr<MockQuicSpdySession> session_; |
126 | 122 |
127 // Owned by the |session_|. | 123 // Owned by the |session_|. |
128 TestStream* stream_; | 124 TestStream* stream_; |
129 TestStream* stream2_; | 125 TestStream* stream2_; |
130 | 126 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 | 241 |
246 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBody) { | 242 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBody) { |
247 Initialize(kShouldProcessData); | 243 Initialize(kShouldProcessData); |
248 | 244 |
249 string body = "this is the body"; | 245 string body = "this is the body"; |
250 | 246 |
251 EXPECT_EQ("", stream_->data()); | 247 EXPECT_EQ("", stream_->data()); |
252 QuicHeaderList headers = ProcessHeaders(false, headers_); | 248 QuicHeaderList headers = ProcessHeaders(false, headers_); |
253 EXPECT_EQ(headers, stream_->header_list()); | 249 EXPECT_EQ(headers, stream_->header_list()); |
254 stream_->ConsumeHeaderList(); | 250 stream_->ConsumeHeaderList(); |
255 QuicStreamFrame frame(GetNthClientInitiatedId(0), false, 0, | 251 QuicStreamFrame frame(kClientDataStreamId1, false, 0, QuicStringPiece(body)); |
256 QuicStringPiece(body)); | |
257 stream_->OnStreamFrame(frame); | 252 stream_->OnStreamFrame(frame); |
258 EXPECT_EQ(QuicHeaderList(), stream_->header_list()); | 253 EXPECT_EQ(QuicHeaderList(), stream_->header_list()); |
259 EXPECT_EQ(body, stream_->data()); | 254 EXPECT_EQ(body, stream_->data()); |
260 } | 255 } |
261 | 256 |
262 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragments) { | 257 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragments) { |
263 string body = "this is the body"; | 258 string body = "this is the body"; |
264 | 259 |
265 for (size_t fragment_size = 1; fragment_size < body.size(); ++fragment_size) { | 260 for (size_t fragment_size = 1; fragment_size < body.size(); ++fragment_size) { |
266 Initialize(kShouldProcessData); | 261 Initialize(kShouldProcessData); |
267 QuicHeaderList headers = ProcessHeaders(false, headers_); | 262 QuicHeaderList headers = ProcessHeaders(false, headers_); |
268 ASSERT_EQ(headers, stream_->header_list()); | 263 ASSERT_EQ(headers, stream_->header_list()); |
269 stream_->ConsumeHeaderList(); | 264 stream_->ConsumeHeaderList(); |
270 for (size_t offset = 0; offset < body.size(); offset += fragment_size) { | 265 for (size_t offset = 0; offset < body.size(); offset += fragment_size) { |
271 size_t remaining_data = body.size() - offset; | 266 size_t remaining_data = body.size() - offset; |
272 QuicStringPiece fragment(body.data() + offset, | 267 QuicStringPiece fragment(body.data() + offset, |
273 std::min(fragment_size, remaining_data)); | 268 std::min(fragment_size, remaining_data)); |
274 QuicStreamFrame frame(GetNthClientInitiatedId(0), false, offset, | 269 QuicStreamFrame frame(kClientDataStreamId1, false, offset, |
275 QuicStringPiece(fragment)); | 270 QuicStringPiece(fragment)); |
276 stream_->OnStreamFrame(frame); | 271 stream_->OnStreamFrame(frame); |
277 } | 272 } |
278 ASSERT_EQ(body, stream_->data()) << "fragment_size: " << fragment_size; | 273 ASSERT_EQ(body, stream_->data()) << "fragment_size: " << fragment_size; |
279 } | 274 } |
280 } | 275 } |
281 | 276 |
282 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragmentsSplit) { | 277 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyFragmentsSplit) { |
283 string body = "this is the body"; | 278 string body = "this is the body"; |
284 | 279 |
285 for (size_t split_point = 1; split_point < body.size() - 1; ++split_point) { | 280 for (size_t split_point = 1; split_point < body.size() - 1; ++split_point) { |
286 Initialize(kShouldProcessData); | 281 Initialize(kShouldProcessData); |
287 QuicHeaderList headers = ProcessHeaders(false, headers_); | 282 QuicHeaderList headers = ProcessHeaders(false, headers_); |
288 ASSERT_EQ(headers, stream_->header_list()); | 283 ASSERT_EQ(headers, stream_->header_list()); |
289 stream_->ConsumeHeaderList(); | 284 stream_->ConsumeHeaderList(); |
290 | 285 |
291 QuicStringPiece fragment1(body.data(), split_point); | 286 QuicStringPiece fragment1(body.data(), split_point); |
292 QuicStreamFrame frame1(GetNthClientInitiatedId(0), false, 0, | 287 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, |
293 QuicStringPiece(fragment1)); | 288 QuicStringPiece(fragment1)); |
294 stream_->OnStreamFrame(frame1); | 289 stream_->OnStreamFrame(frame1); |
295 | 290 |
296 QuicStringPiece fragment2(body.data() + split_point, | 291 QuicStringPiece fragment2(body.data() + split_point, |
297 body.size() - split_point); | 292 body.size() - split_point); |
298 QuicStreamFrame frame2(GetNthClientInitiatedId(0), false, split_point, | 293 QuicStreamFrame frame2(kClientDataStreamId1, false, split_point, |
299 QuicStringPiece(fragment2)); | 294 QuicStringPiece(fragment2)); |
300 stream_->OnStreamFrame(frame2); | 295 stream_->OnStreamFrame(frame2); |
301 | 296 |
302 ASSERT_EQ(body, stream_->data()) << "split_point: " << split_point; | 297 ASSERT_EQ(body, stream_->data()) << "split_point: " << split_point; |
303 } | 298 } |
304 } | 299 } |
305 | 300 |
306 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyReadv) { | 301 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyReadv) { |
307 Initialize(!kShouldProcessData); | 302 Initialize(!kShouldProcessData); |
308 | 303 |
309 string body = "this is the body"; | 304 string body = "this is the body"; |
310 | 305 |
311 ProcessHeaders(false, headers_); | 306 ProcessHeaders(false, headers_); |
312 QuicStreamFrame frame(GetNthClientInitiatedId(0), false, 0, | 307 QuicStreamFrame frame(kClientDataStreamId1, false, 0, QuicStringPiece(body)); |
313 QuicStringPiece(body)); | |
314 stream_->OnStreamFrame(frame); | 308 stream_->OnStreamFrame(frame); |
315 stream_->ConsumeHeaderList(); | 309 stream_->ConsumeHeaderList(); |
316 | 310 |
317 char buffer[2048]; | 311 char buffer[2048]; |
318 ASSERT_LT(body.length(), arraysize(buffer)); | 312 ASSERT_LT(body.length(), arraysize(buffer)); |
319 struct iovec vec; | 313 struct iovec vec; |
320 vec.iov_base = buffer; | 314 vec.iov_base = buffer; |
321 vec.iov_len = arraysize(buffer); | 315 vec.iov_len = arraysize(buffer); |
322 | 316 |
323 size_t bytes_read = stream_->Readv(&vec, 1); | 317 size_t bytes_read = stream_->Readv(&vec, 1); |
324 EXPECT_EQ(body.length(), bytes_read); | 318 EXPECT_EQ(body.length(), bytes_read); |
325 EXPECT_EQ(body, string(buffer, bytes_read)); | 319 EXPECT_EQ(body, string(buffer, bytes_read)); |
326 } | 320 } |
327 | 321 |
328 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyMarkConsumed) { | 322 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyMarkConsumed) { |
329 Initialize(!kShouldProcessData); | 323 Initialize(!kShouldProcessData); |
330 | 324 |
331 string body = "this is the body"; | 325 string body = "this is the body"; |
332 | 326 |
333 ProcessHeaders(false, headers_); | 327 ProcessHeaders(false, headers_); |
334 QuicStreamFrame frame(GetNthClientInitiatedId(0), false, 0, | 328 QuicStreamFrame frame(kClientDataStreamId1, false, 0, QuicStringPiece(body)); |
335 QuicStringPiece(body)); | |
336 stream_->OnStreamFrame(frame); | 329 stream_->OnStreamFrame(frame); |
337 stream_->ConsumeHeaderList(); | 330 stream_->ConsumeHeaderList(); |
338 | 331 |
339 struct iovec vec; | 332 struct iovec vec; |
340 | 333 |
341 EXPECT_EQ(1, stream_->GetReadableRegions(&vec, 1)); | 334 EXPECT_EQ(1, stream_->GetReadableRegions(&vec, 1)); |
342 EXPECT_EQ(body.length(), vec.iov_len); | 335 EXPECT_EQ(body.length(), vec.iov_len); |
343 EXPECT_EQ(body, string(static_cast<char*>(vec.iov_base), vec.iov_len)); | 336 EXPECT_EQ(body, string(static_cast<char*>(vec.iov_base), vec.iov_len)); |
344 | 337 |
345 stream_->MarkConsumed(body.length()); | 338 stream_->MarkConsumed(body.length()); |
346 EXPECT_EQ(body.length(), stream_->flow_controller()->bytes_consumed()); | 339 EXPECT_EQ(body.length(), stream_->flow_controller()->bytes_consumed()); |
347 } | 340 } |
348 | 341 |
349 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) { | 342 TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) { |
350 Initialize(!kShouldProcessData); | 343 Initialize(!kShouldProcessData); |
351 | 344 |
352 string body = "this is the body"; | 345 string body = "this is the body"; |
353 ProcessHeaders(false, headers_); | 346 ProcessHeaders(false, headers_); |
354 QuicStreamFrame frame(GetNthClientInitiatedId(0), false, 0, | 347 QuicStreamFrame frame(kClientDataStreamId1, false, 0, QuicStringPiece(body)); |
355 QuicStringPiece(body)); | |
356 stream_->OnStreamFrame(frame); | 348 stream_->OnStreamFrame(frame); |
357 stream_->ConsumeHeaderList(); | 349 stream_->ConsumeHeaderList(); |
358 | 350 |
359 char buffer[1]; | 351 char buffer[1]; |
360 struct iovec vec; | 352 struct iovec vec; |
361 vec.iov_base = buffer; | 353 vec.iov_base = buffer; |
362 vec.iov_len = arraysize(buffer); | 354 vec.iov_len = arraysize(buffer); |
363 | 355 |
364 for (size_t i = 0; i < body.length(); ++i) { | 356 for (size_t i = 0; i < body.length(); ++i) { |
365 size_t bytes_read = stream_->Readv(&vec, 1); | 357 size_t bytes_read = stream_->Readv(&vec, 1); |
366 ASSERT_EQ(1u, bytes_read); | 358 ASSERT_EQ(1u, bytes_read); |
367 EXPECT_EQ(body.data()[i], buffer[0]); | 359 EXPECT_EQ(body.data()[i], buffer[0]); |
368 } | 360 } |
369 } | 361 } |
370 | 362 |
371 TEST_P(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) { | 363 TEST_P(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) { |
372 Initialize(!kShouldProcessData); | 364 Initialize(!kShouldProcessData); |
373 | 365 |
374 string body = "this is the body"; | 366 string body = "this is the body"; |
375 ProcessHeaders(false, headers_); | 367 ProcessHeaders(false, headers_); |
376 QuicStreamFrame frame(GetNthClientInitiatedId(0), false, 0, | 368 QuicStreamFrame frame(kClientDataStreamId1, false, 0, QuicStringPiece(body)); |
377 QuicStringPiece(body)); | |
378 stream_->OnStreamFrame(frame); | 369 stream_->OnStreamFrame(frame); |
379 stream_->ConsumeHeaderList(); | 370 stream_->ConsumeHeaderList(); |
380 | 371 |
381 char buffer1[1]; | 372 char buffer1[1]; |
382 char buffer2[1]; | 373 char buffer2[1]; |
383 struct iovec vec[2]; | 374 struct iovec vec[2]; |
384 vec[0].iov_base = buffer1; | 375 vec[0].iov_base = buffer1; |
385 vec[0].iov_len = arraysize(buffer1); | 376 vec[0].iov_len = arraysize(buffer1); |
386 vec[1].iov_base = buffer2; | 377 vec[1].iov_base = buffer2; |
387 vec[1].iov_len = arraysize(buffer2); | 378 vec[1].iov_len = arraysize(buffer2); |
(...skipping 16 matching lines...) Expand all Loading... |
404 QuicFlowControllerPeer::SetSendWindowOffset(stream_->flow_controller(), | 395 QuicFlowControllerPeer::SetSendWindowOffset(stream_->flow_controller(), |
405 kWindow); | 396 kWindow); |
406 EXPECT_EQ(kWindow, QuicFlowControllerPeer::SendWindowOffset( | 397 EXPECT_EQ(kWindow, QuicFlowControllerPeer::SendWindowOffset( |
407 stream_->flow_controller())); | 398 stream_->flow_controller())); |
408 | 399 |
409 // Try to send more data than the flow control limit allows. | 400 // Try to send more data than the flow control limit allows. |
410 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 401 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
411 const uint64_t kOverflow = 15; | 402 const uint64_t kOverflow = 15; |
412 string body(kWindow + kOverflow, 'a'); | 403 string body(kWindow + kOverflow, 'a'); |
413 | 404 |
414 EXPECT_CALL(*connection_, SendBlocked(GetNthClientInitiatedId(0))); | 405 EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1)); |
415 EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) | 406 EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) |
416 .WillOnce(Return(QuicConsumedData(kWindow, true))); | 407 .WillOnce(Return(QuicConsumedData(kWindow, true))); |
417 stream_->WriteOrBufferData(body, false, nullptr); | 408 stream_->WriteOrBufferData(body, false, nullptr); |
418 | 409 |
419 // Should have sent as much as possible, resulting in no send window left. | 410 // Should have sent as much as possible, resulting in no send window left. |
420 EXPECT_EQ(0u, | 411 EXPECT_EQ(0u, |
421 QuicFlowControllerPeer::SendWindowSize(stream_->flow_controller())); | 412 QuicFlowControllerPeer::SendWindowSize(stream_->flow_controller())); |
422 | 413 |
423 // And we should have queued the overflowed data. | 414 // And we should have queued the overflowed data. |
424 EXPECT_EQ(kOverflow, QuicStreamPeer::SizeOfQueuedData(stream_)); | 415 EXPECT_EQ(kOverflow, QuicStreamPeer::SizeOfQueuedData(stream_)); |
(...skipping 17 matching lines...) Expand all Loading... |
442 kWindow); | 433 kWindow); |
443 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), | 434 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), |
444 kWindow); | 435 kWindow); |
445 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset( | 436 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset( |
446 stream_->flow_controller())); | 437 stream_->flow_controller())); |
447 | 438 |
448 // Stream receives enough data to fill a fraction of the receive window. | 439 // Stream receives enough data to fill a fraction of the receive window. |
449 string body(kWindow / 3, 'a'); | 440 string body(kWindow / 3, 'a'); |
450 ProcessHeaders(false, headers_); | 441 ProcessHeaders(false, headers_); |
451 | 442 |
452 QuicStreamFrame frame1(GetNthClientInitiatedId(0), false, 0, | 443 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, QuicStringPiece(body)); |
453 QuicStringPiece(body)); | |
454 stream_->OnStreamFrame(frame1); | 444 stream_->OnStreamFrame(frame1); |
455 EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize( | 445 EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize( |
456 stream_->flow_controller())); | 446 stream_->flow_controller())); |
457 | 447 |
458 // Now receive another frame which results in the receive window being over | 448 // Now receive another frame which results in the receive window being over |
459 // half full. This should all be buffered, decreasing the receive window but | 449 // half full. This should all be buffered, decreasing the receive window but |
460 // not sending WINDOW_UPDATE. | 450 // not sending WINDOW_UPDATE. |
461 QuicStreamFrame frame2(GetNthClientInitiatedId(0), false, kWindow / 3, | 451 QuicStreamFrame frame2(kClientDataStreamId1, false, kWindow / 3, |
462 QuicStringPiece(body)); | 452 QuicStringPiece(body)); |
463 stream_->OnStreamFrame(frame2); | 453 stream_->OnStreamFrame(frame2); |
464 EXPECT_EQ( | 454 EXPECT_EQ( |
465 kWindow - (2 * kWindow / 3), | 455 kWindow - (2 * kWindow / 3), |
466 QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller())); | 456 QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller())); |
467 } | 457 } |
468 | 458 |
469 TEST_P(QuicSpdyStreamTest, StreamFlowControlWindowUpdate) { | 459 TEST_P(QuicSpdyStreamTest, StreamFlowControlWindowUpdate) { |
470 // Tests that on receipt of data, the stream updates its receive window offset | 460 // Tests that on receipt of data, the stream updates its receive window offset |
471 // appropriately, and sends WINDOW_UPDATE frames when its receive window drops | 461 // appropriately, and sends WINDOW_UPDATE frames when its receive window drops |
472 // too low. | 462 // too low. |
473 Initialize(kShouldProcessData); | 463 Initialize(kShouldProcessData); |
474 | 464 |
475 // Set a small flow control limit. | 465 // Set a small flow control limit. |
476 const uint64_t kWindow = 36; | 466 const uint64_t kWindow = 36; |
477 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 467 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
478 kWindow); | 468 kWindow); |
479 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), | 469 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), |
480 kWindow); | 470 kWindow); |
481 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset( | 471 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset( |
482 stream_->flow_controller())); | 472 stream_->flow_controller())); |
483 | 473 |
484 // Stream receives enough data to fill a fraction of the receive window. | 474 // Stream receives enough data to fill a fraction of the receive window. |
485 string body(kWindow / 3, 'a'); | 475 string body(kWindow / 3, 'a'); |
486 ProcessHeaders(false, headers_); | 476 ProcessHeaders(false, headers_); |
487 stream_->ConsumeHeaderList(); | 477 stream_->ConsumeHeaderList(); |
488 | 478 |
489 QuicStreamFrame frame1(GetNthClientInitiatedId(0), false, 0, | 479 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, QuicStringPiece(body)); |
490 QuicStringPiece(body)); | |
491 stream_->OnStreamFrame(frame1); | 480 stream_->OnStreamFrame(frame1); |
492 EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize( | 481 EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize( |
493 stream_->flow_controller())); | 482 stream_->flow_controller())); |
494 | 483 |
495 // Now receive another frame which results in the receive window being over | 484 // Now receive another frame which results in the receive window being over |
496 // half full. This will trigger the stream to increase its receive window | 485 // half full. This will trigger the stream to increase its receive window |
497 // offset and send a WINDOW_UPDATE. The result will be again an available | 486 // offset and send a WINDOW_UPDATE. The result will be again an available |
498 // window of kWindow bytes. | 487 // window of kWindow bytes. |
499 QuicStreamFrame frame2(GetNthClientInitiatedId(0), false, kWindow / 3, | 488 QuicStreamFrame frame2(kClientDataStreamId1, false, kWindow / 3, |
500 QuicStringPiece(body)); | 489 QuicStringPiece(body)); |
501 EXPECT_CALL(*connection_, | 490 EXPECT_CALL(*connection_, |
502 SendWindowUpdate(GetNthClientInitiatedId(0), | 491 SendWindowUpdate(kClientDataStreamId1, |
503 QuicFlowControllerPeer::ReceiveWindowOffset( | 492 QuicFlowControllerPeer::ReceiveWindowOffset( |
504 stream_->flow_controller()) + | 493 stream_->flow_controller()) + |
505 2 * kWindow / 3)); | 494 2 * kWindow / 3)); |
506 stream_->OnStreamFrame(frame2); | 495 stream_->OnStreamFrame(frame2); |
507 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowSize( | 496 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowSize( |
508 stream_->flow_controller())); | 497 stream_->flow_controller())); |
509 } | 498 } |
510 | 499 |
511 TEST_P(QuicSpdyStreamTest, ConnectionFlowControlWindowUpdate) { | 500 TEST_P(QuicSpdyStreamTest, ConnectionFlowControlWindowUpdate) { |
512 // Tests that on receipt of data, the connection updates its receive window | 501 // Tests that on receipt of data, the connection updates its receive window |
(...skipping 21 matching lines...) Expand all Loading... |
534 stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), | 523 stream_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), |
535 headers); | 524 headers); |
536 stream_->ConsumeHeaderList(); | 525 stream_->ConsumeHeaderList(); |
537 stream2_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), | 526 stream2_->OnStreamHeaderList(false, headers.uncompressed_header_bytes(), |
538 headers); | 527 headers); |
539 stream2_->ConsumeHeaderList(); | 528 stream2_->ConsumeHeaderList(); |
540 | 529 |
541 // Each stream gets a quarter window of data. This should not trigger a | 530 // Each stream gets a quarter window of data. This should not trigger a |
542 // WINDOW_UPDATE for either stream, nor for the connection. | 531 // WINDOW_UPDATE for either stream, nor for the connection. |
543 string body(kWindow / 4, 'a'); | 532 string body(kWindow / 4, 'a'); |
544 QuicStreamFrame frame1(GetNthClientInitiatedId(0), false, 0, | 533 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, QuicStringPiece(body)); |
545 QuicStringPiece(body)); | |
546 stream_->OnStreamFrame(frame1); | 534 stream_->OnStreamFrame(frame1); |
547 QuicStreamFrame frame2(GetNthClientInitiatedId(1), false, 0, | 535 QuicStreamFrame frame2(kClientDataStreamId2, false, 0, QuicStringPiece(body)); |
548 QuicStringPiece(body)); | |
549 stream2_->OnStreamFrame(frame2); | 536 stream2_->OnStreamFrame(frame2); |
550 | 537 |
551 // Now receive a further single byte on one stream - again this does not | 538 // Now receive a further single byte on one stream - again this does not |
552 // trigger a stream WINDOW_UPDATE, but now the connection flow control window | 539 // trigger a stream WINDOW_UPDATE, but now the connection flow control window |
553 // is over half full and thus a connection WINDOW_UPDATE is sent. | 540 // is over half full and thus a connection WINDOW_UPDATE is sent. |
554 EXPECT_CALL(*connection_, SendWindowUpdate(GetNthClientInitiatedId(0), _)) | 541 EXPECT_CALL(*connection_, SendWindowUpdate(kClientDataStreamId1, _)).Times(0); |
555 .Times(0); | 542 EXPECT_CALL(*connection_, SendWindowUpdate(kClientDataStreamId2, _)).Times(0); |
556 EXPECT_CALL(*connection_, SendWindowUpdate(GetNthClientInitiatedId(1), _)) | |
557 .Times(0); | |
558 EXPECT_CALL(*connection_, | 543 EXPECT_CALL(*connection_, |
559 SendWindowUpdate(0, QuicFlowControllerPeer::ReceiveWindowOffset( | 544 SendWindowUpdate(0, |
560 session_->flow_controller()) + | 545 QuicFlowControllerPeer::ReceiveWindowOffset( |
561 1 + kWindow / 2)); | 546 session_->flow_controller()) + |
562 QuicStreamFrame frame3(GetNthClientInitiatedId(0), false, (kWindow / 4), | 547 1 + kWindow / 2)); |
| 548 QuicStreamFrame frame3(kClientDataStreamId1, false, (kWindow / 4), |
563 QuicStringPiece("a")); | 549 QuicStringPiece("a")); |
564 stream_->OnStreamFrame(frame3); | 550 stream_->OnStreamFrame(frame3); |
565 } | 551 } |
566 | 552 |
567 TEST_P(QuicSpdyStreamTest, StreamFlowControlViolation) { | 553 TEST_P(QuicSpdyStreamTest, StreamFlowControlViolation) { |
568 // 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 |
569 // control protocol), then we terminate the connection. | 555 // control protocol), then we terminate the connection. |
570 | 556 |
571 // Stream should not process data, so that data gets buffered in the | 557 // Stream should not process data, so that data gets buffered in the |
572 // sequencer, triggering flow control limits. | 558 // sequencer, triggering flow control limits. |
573 Initialize(!kShouldProcessData); | 559 Initialize(!kShouldProcessData); |
574 | 560 |
575 // Set a small flow control limit. | 561 // Set a small flow control limit. |
576 const uint64_t kWindow = 50; | 562 const uint64_t kWindow = 50; |
577 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 563 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
578 kWindow); | 564 kWindow); |
579 | 565 |
580 ProcessHeaders(false, headers_); | 566 ProcessHeaders(false, headers_); |
581 | 567 |
582 // Receive data to overflow the window, violating flow control. | 568 // Receive data to overflow the window, violating flow control. |
583 string body(kWindow + 1, 'a'); | 569 string body(kWindow + 1, 'a'); |
584 QuicStreamFrame frame(GetNthClientInitiatedId(0), false, 0, | 570 QuicStreamFrame frame(kClientDataStreamId1, false, 0, QuicStringPiece(body)); |
585 QuicStringPiece(body)); | |
586 EXPECT_CALL(*connection_, | 571 EXPECT_CALL(*connection_, |
587 CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _)); | 572 CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _)); |
588 stream_->OnStreamFrame(frame); | 573 stream_->OnStreamFrame(frame); |
589 } | 574 } |
590 | 575 |
591 TEST_P(QuicSpdyStreamTest, TestHandlingQuicRstStreamNoError) { | 576 TEST_P(QuicSpdyStreamTest, TestHandlingQuicRstStreamNoError) { |
592 Initialize(kShouldProcessData); | 577 Initialize(kShouldProcessData); |
593 ProcessHeaders(false, headers_); | 578 ProcessHeaders(false, headers_); |
594 | 579 |
595 stream_->OnStreamReset( | 580 stream_->OnStreamReset( |
(...skipping 17 matching lines...) Expand all Loading... |
613 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 598 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
614 kStreamWindow); | 599 kStreamWindow); |
615 QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(), | 600 QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(), |
616 kConnectionWindow); | 601 kConnectionWindow); |
617 | 602 |
618 ProcessHeaders(false, headers_); | 603 ProcessHeaders(false, headers_); |
619 | 604 |
620 // Send enough data to overflow the connection level flow control window. | 605 // Send enough data to overflow the connection level flow control window. |
621 string body(kConnectionWindow + 1, 'a'); | 606 string body(kConnectionWindow + 1, 'a'); |
622 EXPECT_LT(body.size(), kStreamWindow); | 607 EXPECT_LT(body.size(), kStreamWindow); |
623 QuicStreamFrame frame(GetNthClientInitiatedId(0), false, 0, | 608 QuicStreamFrame frame(kClientDataStreamId1, false, 0, QuicStringPiece(body)); |
624 QuicStringPiece(body)); | |
625 | 609 |
626 EXPECT_CALL(*connection_, | 610 EXPECT_CALL(*connection_, |
627 CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _)); | 611 CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _)); |
628 stream_->OnStreamFrame(frame); | 612 stream_->OnStreamFrame(frame); |
629 } | 613 } |
630 | 614 |
631 TEST_P(QuicSpdyStreamTest, StreamFlowControlFinNotBlocked) { | 615 TEST_P(QuicSpdyStreamTest, StreamFlowControlFinNotBlocked) { |
632 // An attempt to write a FIN with no data should not be flow control blocked, | 616 // An attempt to write a FIN with no data should not be flow control blocked, |
633 // even if the send window is 0. | 617 // even if the send window is 0. |
634 | 618 |
635 Initialize(kShouldProcessData); | 619 Initialize(kShouldProcessData); |
636 | 620 |
637 // Set a flow control limit of zero. | 621 // Set a flow control limit of zero. |
638 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), 0); | 622 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), 0); |
639 EXPECT_EQ(0u, QuicFlowControllerPeer::ReceiveWindowOffset( | 623 EXPECT_EQ(0u, QuicFlowControllerPeer::ReceiveWindowOffset( |
640 stream_->flow_controller())); | 624 stream_->flow_controller())); |
641 | 625 |
642 // Send a frame with a FIN but no data. This should not be blocked. | 626 // Send a frame with a FIN but no data. This should not be blocked. |
643 string body = ""; | 627 string body = ""; |
644 bool fin = true; | 628 bool fin = true; |
645 | 629 |
646 EXPECT_CALL(*connection_, SendBlocked(GetNthClientInitiatedId(0))).Times(0); | 630 EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1)).Times(0); |
647 EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) | 631 EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) |
648 .WillOnce(Return(QuicConsumedData(0, fin))); | 632 .WillOnce(Return(QuicConsumedData(0, fin))); |
649 | 633 |
650 stream_->WriteOrBufferData(body, fin, nullptr); | 634 stream_->WriteOrBufferData(body, fin, nullptr); |
651 } | 635 } |
652 | 636 |
653 TEST_P(QuicSpdyStreamTest, ReceivingTrailersViaHeaderList) { | 637 TEST_P(QuicSpdyStreamTest, ReceivingTrailersViaHeaderList) { |
654 // Test that receiving trailing headers from the peer via | 638 // Test that receiving trailing headers from the peer via |
655 // OnStreamHeaderList() works, and can be read from the stream and consumed. | 639 // OnStreamHeaderList() works, and can be read from the stream and consumed. |
656 Initialize(kShouldProcessData); | 640 Initialize(kShouldProcessData); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 // The final offset trailer will be consumed by QUIC. | 702 // The final offset trailer will be consumed by QUIC. |
719 trailers_block.erase(kFinalOffsetHeaderKey); | 703 trailers_block.erase(kFinalOffsetHeaderKey); |
720 EXPECT_EQ(trailers_block, stream_->received_trailers()); | 704 EXPECT_EQ(trailers_block, stream_->received_trailers()); |
721 | 705 |
722 // Consuming the trailers erases them from the stream. | 706 // Consuming the trailers erases them from the stream. |
723 stream_->MarkTrailersConsumed(); | 707 stream_->MarkTrailersConsumed(); |
724 EXPECT_TRUE(stream_->FinishedReadingTrailers()); | 708 EXPECT_TRUE(stream_->FinishedReadingTrailers()); |
725 | 709 |
726 EXPECT_FALSE(stream_->IsDoneReading()); | 710 EXPECT_FALSE(stream_->IsDoneReading()); |
727 // Receive and consume body. | 711 // Receive and consume body. |
728 QuicStreamFrame frame(GetNthClientInitiatedId(0), /*fin=*/false, 0, body); | 712 QuicStreamFrame frame(kClientDataStreamId1, /*fin=*/false, 0, body); |
729 stream_->OnStreamFrame(frame); | 713 stream_->OnStreamFrame(frame); |
730 EXPECT_EQ(body, stream_->data()); | 714 EXPECT_EQ(body, stream_->data()); |
731 EXPECT_TRUE(stream_->IsDoneReading()); | 715 EXPECT_TRUE(stream_->IsDoneReading()); |
732 } | 716 } |
733 | 717 |
734 TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutOffset) { | 718 TEST_P(QuicSpdyStreamTest, ReceivingTrailersWithoutOffset) { |
735 // Test that receiving trailers without a final offset field is an error. | 719 // Test that receiving trailers without a final offset field is an error. |
736 Initialize(kShouldProcessData); | 720 Initialize(kShouldProcessData); |
737 | 721 |
738 // Receive initial headers. | 722 // Receive initial headers. |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
799 | 783 |
800 TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterBodyWithFin) { | 784 TEST_P(QuicSpdyStreamTest, ReceivingTrailersAfterBodyWithFin) { |
801 // If body data are received with a FIN, no trailers should then arrive. | 785 // If body data are received with a FIN, no trailers should then arrive. |
802 Initialize(kShouldProcessData); | 786 Initialize(kShouldProcessData); |
803 | 787 |
804 // Receive initial headers without FIN set. | 788 // Receive initial headers without FIN set. |
805 ProcessHeaders(false, headers_); | 789 ProcessHeaders(false, headers_); |
806 stream_->ConsumeHeaderList(); | 790 stream_->ConsumeHeaderList(); |
807 | 791 |
808 // Receive body data, with FIN. | 792 // Receive body data, with FIN. |
809 QuicStreamFrame frame(GetNthClientInitiatedId(0), /*fin=*/true, 0, "body"); | 793 QuicStreamFrame frame(kClientDataStreamId1, /*fin=*/true, 0, "body"); |
810 stream_->OnStreamFrame(frame); | 794 stream_->OnStreamFrame(frame); |
811 | 795 |
812 // Receive trailing headers after FIN already received. | 796 // Receive trailing headers after FIN already received. |
813 SpdyHeaderBlock trailers_block; | 797 SpdyHeaderBlock trailers_block; |
814 trailers_block["foo"] = "bar"; | 798 trailers_block["foo"] = "bar"; |
815 EXPECT_CALL(*connection_, | 799 EXPECT_CALL(*connection_, |
816 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _)) | 800 CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA, _, _)) |
817 .Times(1); | 801 .Times(1); |
818 ProcessHeaders(true, trailers_block); | 802 ProcessHeaders(true, trailers_block); |
819 } | 803 } |
820 | 804 |
821 TEST_P(QuicSpdyStreamTest, ClosingStreamWithNoTrailers) { | 805 TEST_P(QuicSpdyStreamTest, ClosingStreamWithNoTrailers) { |
822 // Verify that a stream receiving headers, body, and no trailers is correctly | 806 // Verify that a stream receiving headers, body, and no trailers is correctly |
823 // marked as done reading on consumption of headers and body. | 807 // marked as done reading on consumption of headers and body. |
824 Initialize(kShouldProcessData); | 808 Initialize(kShouldProcessData); |
825 | 809 |
826 // Receive and consume initial headers with FIN not set. | 810 // Receive and consume initial headers with FIN not set. |
827 auto h = AsHeaderList(headers_); | 811 auto h = AsHeaderList(headers_); |
828 stream_->OnStreamHeaderList(/*fin=*/false, h.uncompressed_header_bytes(), h); | 812 stream_->OnStreamHeaderList(/*fin=*/false, h.uncompressed_header_bytes(), h); |
829 stream_->ConsumeHeaderList(); | 813 stream_->ConsumeHeaderList(); |
830 | 814 |
831 // Receive and consume body with FIN set, and no trailers. | 815 // Receive and consume body with FIN set, and no trailers. |
832 const string kBody = string(1024, 'x'); | 816 const string kBody = string(1024, 'x'); |
833 QuicStreamFrame frame(GetNthClientInitiatedId(0), /*fin=*/true, 0, kBody); | 817 QuicStreamFrame frame(kClientDataStreamId1, /*fin=*/true, 0, kBody); |
834 stream_->OnStreamFrame(frame); | 818 stream_->OnStreamFrame(frame); |
835 | 819 |
836 EXPECT_TRUE(stream_->IsDoneReading()); | 820 EXPECT_TRUE(stream_->IsDoneReading()); |
837 } | 821 } |
838 | 822 |
839 TEST_P(QuicSpdyStreamTest, WritingTrailersSendsAFin) { | 823 TEST_P(QuicSpdyStreamTest, WritingTrailersSendsAFin) { |
840 // Test that writing trailers will send a FIN, as Trailers are the last thing | 824 // Test that writing trailers will send a FIN, as Trailers are the last thing |
841 // to be sent on a stream. | 825 // to be sent on a stream. |
842 Initialize(kShouldProcessData); | 826 Initialize(kShouldProcessData); |
843 EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) | 827 EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)) |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
959 | 943 |
960 // Writing Trailers should fail, as the FIN has already been sent. | 944 // Writing Trailers should fail, as the FIN has already been sent. |
961 // populated with the number of body bytes written. | 945 // populated with the number of body bytes written. |
962 EXPECT_QUIC_BUG(stream_->WriteTrailers(SpdyHeaderBlock(), nullptr), | 946 EXPECT_QUIC_BUG(stream_->WriteTrailers(SpdyHeaderBlock(), nullptr), |
963 "Trailers cannot be sent after a FIN"); | 947 "Trailers cannot be sent after a FIN"); |
964 } | 948 } |
965 | 949 |
966 } // namespace | 950 } // namespace |
967 } // namespace test | 951 } // namespace test |
968 } // namespace net | 952 } // namespace net |
OLD | NEW |