| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_session.h" | 5 #include "net/quic/quic_session.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/containers/hash_tables.h" | 10 #include "base/containers/hash_tables.h" |
| 11 #include "base/rand_util.h" | 11 #include "base/rand_util.h" |
| 12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
| 13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 14 #include "net/quic/crypto/crypto_protocol.h" | 14 #include "net/quic/crypto/crypto_protocol.h" |
| 15 #include "net/quic/quic_crypto_stream.h" | 15 #include "net/quic/quic_crypto_stream.h" |
| 16 #include "net/quic/quic_flags.h" | 16 #include "net/quic/quic_flags.h" |
| 17 #include "net/quic/quic_protocol.h" | 17 #include "net/quic/quic_protocol.h" |
| 18 #include "net/quic/quic_utils.h" | 18 #include "net/quic/quic_utils.h" |
| 19 #include "net/quic/reliable_quic_stream.h" | 19 #include "net/quic/reliable_quic_stream.h" |
| 20 #include "net/quic/test_tools/quic_config_peer.h" | 20 #include "net/quic/test_tools/quic_config_peer.h" |
| 21 #include "net/quic/test_tools/quic_connection_peer.h" | 21 #include "net/quic/test_tools/quic_connection_peer.h" |
| 22 #include "net/quic/test_tools/quic_data_stream_peer.h" | 22 #include "net/quic/test_tools/quic_data_stream_peer.h" |
| 23 #include "net/quic/test_tools/quic_flow_controller_peer.h" | 23 #include "net/quic/test_tools/quic_flow_controller_peer.h" |
| 24 #include "net/quic/test_tools/quic_session_peer.h" | 24 #include "net/quic/test_tools/quic_session_peer.h" |
| 25 #include "net/quic/test_tools/quic_spdy_session_peer.h" |
| 25 #include "net/quic/test_tools/quic_test_utils.h" | 26 #include "net/quic/test_tools/quic_test_utils.h" |
| 26 #include "net/quic/test_tools/reliable_quic_stream_peer.h" | 27 #include "net/quic/test_tools/reliable_quic_stream_peer.h" |
| 27 #include "net/spdy/spdy_framer.h" | 28 #include "net/spdy/spdy_framer.h" |
| 28 #include "net/test/gtest_util.h" | 29 #include "net/test/gtest_util.h" |
| 29 #include "testing/gmock/include/gmock/gmock.h" | 30 #include "testing/gmock/include/gmock/gmock.h" |
| 30 #include "testing/gmock_mutant.h" | 31 #include "testing/gmock_mutant.h" |
| 31 #include "testing/gtest/include/gtest/gtest.h" | 32 #include "testing/gtest/include/gtest/gtest.h" |
| 32 | 33 |
| 33 using base::hash_map; | 34 using base::hash_map; |
| 34 using std::set; | 35 using std::set; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 EXPECT_EQ(QUIC_NO_ERROR, error); | 70 EXPECT_EQ(QUIC_NO_ERROR, error); |
| 70 session()->OnConfigNegotiated(); | 71 session()->OnConfigNegotiated(); |
| 71 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); | 72 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); |
| 72 } | 73 } |
| 73 | 74 |
| 74 MOCK_METHOD0(OnCanWrite, void()); | 75 MOCK_METHOD0(OnCanWrite, void()); |
| 75 }; | 76 }; |
| 76 | 77 |
| 77 class TestHeadersStream : public QuicHeadersStream { | 78 class TestHeadersStream : public QuicHeadersStream { |
| 78 public: | 79 public: |
| 79 explicit TestHeadersStream(QuicSession* session) | 80 explicit TestHeadersStream(QuicSpdySession* session) |
| 80 : QuicHeadersStream(session) { | 81 : QuicHeadersStream(session) {} |
| 81 } | |
| 82 | 82 |
| 83 MOCK_METHOD0(OnCanWrite, void()); | 83 MOCK_METHOD0(OnCanWrite, void()); |
| 84 }; | 84 }; |
| 85 | 85 |
| 86 class TestStream : public QuicDataStream { | 86 class TestStream : public QuicDataStream { |
| 87 public: | 87 public: |
| 88 TestStream(QuicStreamId id, QuicSession* session) | 88 TestStream(QuicStreamId id, QuicSpdySession* session) |
| 89 : QuicDataStream(id, session) { | 89 : QuicDataStream(id, session) {} |
| 90 } | |
| 91 | 90 |
| 92 using ReliableQuicStream::CloseWriteSide; | 91 using ReliableQuicStream::CloseWriteSide; |
| 93 | 92 |
| 94 uint32 ProcessData(const char* data, uint32 data_len) override { | 93 uint32 ProcessData(const char* data, uint32 data_len) override { |
| 95 return data_len; | 94 return data_len; |
| 96 } | 95 } |
| 97 | 96 |
| 98 void SendBody(const string& data, bool fin) { | 97 void SendBody(const string& data, bool fin) { |
| 99 WriteOrBufferData(data, fin, nullptr); | 98 WriteOrBufferData(data, fin, nullptr); |
| 100 } | 99 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 112 | 111 |
| 113 void MarkWriteBlocked() { | 112 void MarkWriteBlocked() { |
| 114 session_->MarkWriteBlocked(stream_id_, kSomeMiddlePriority); | 113 session_->MarkWriteBlocked(stream_id_, kSomeMiddlePriority); |
| 115 } | 114 } |
| 116 | 115 |
| 117 private: | 116 private: |
| 118 QuicSession* const session_; | 117 QuicSession* const session_; |
| 119 const QuicStreamId stream_id_; | 118 const QuicStreamId stream_id_; |
| 120 }; | 119 }; |
| 121 | 120 |
| 122 class TestSession : public QuicSession { | 121 class TestSession : public QuicSpdySession { |
| 123 public: | 122 public: |
| 124 explicit TestSession(QuicConnection* connection) | 123 explicit TestSession(QuicConnection* connection) |
| 125 : QuicSession(connection, DefaultQuicConfig()), | 124 : QuicSpdySession(connection, DefaultQuicConfig()), |
| 126 crypto_stream_(this), | 125 crypto_stream_(this), |
| 127 writev_consumes_all_data_(false) { | 126 writev_consumes_all_data_(false) { |
| 128 Initialize(); | 127 Initialize(); |
| 129 } | 128 } |
| 130 | 129 |
| 131 TestCryptoStream* GetCryptoStream() override { return &crypto_stream_; } | 130 TestCryptoStream* GetCryptoStream() override { return &crypto_stream_; } |
| 132 | 131 |
| 133 TestStream* CreateOutgoingDataStream() override { | 132 TestStream* CreateOutgoingDynamicStream() override { |
| 134 TestStream* stream = new TestStream(GetNextStreamId(), this); | 133 TestStream* stream = new TestStream(GetNextStreamId(), this); |
| 135 ActivateStream(stream); | 134 ActivateStream(stream); |
| 136 return stream; | 135 return stream; |
| 137 } | 136 } |
| 138 | 137 |
| 139 TestStream* CreateIncomingDataStream(QuicStreamId id) override { | 138 TestStream* CreateIncomingDynamicStream(QuicStreamId id) override { |
| 140 return new TestStream(id, this); | 139 return new TestStream(id, this); |
| 141 } | 140 } |
| 142 | 141 |
| 143 bool IsClosedStream(QuicStreamId id) { | 142 bool IsClosedStream(QuicStreamId id) { |
| 144 return QuicSession::IsClosedStream(id); | 143 return QuicSession::IsClosedStream(id); |
| 145 } | 144 } |
| 146 | 145 |
| 147 QuicDataStream* GetIncomingDataStream(QuicStreamId stream_id) { | 146 ReliableQuicStream* GetIncomingDynamicStream(QuicStreamId stream_id) { |
| 148 return QuicSession::GetIncomingDataStream(stream_id); | 147 return QuicSpdySession::GetIncomingDynamicStream(stream_id); |
| 149 } | 148 } |
| 150 | 149 |
| 151 QuicConsumedData WritevData( | 150 QuicConsumedData WritevData( |
| 152 QuicStreamId id, | 151 QuicStreamId id, |
| 153 const IOVector& data, | 152 const IOVector& data, |
| 154 QuicStreamOffset offset, | 153 QuicStreamOffset offset, |
| 155 bool fin, | 154 bool fin, |
| 156 FecProtection fec_protection, | 155 FecProtection fec_protection, |
| 157 QuicAckNotifier::DelegateInterface* ack_notifier_delegate) override { | 156 QuicAckNotifier::DelegateInterface* ack_notifier_delegate) override { |
| 158 // Always consumes everything. | 157 // Always consumes everything. |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 } | 266 } |
| 268 | 267 |
| 269 TEST_P(QuicSessionTestServer, IsClosedStreamDefault) { | 268 TEST_P(QuicSessionTestServer, IsClosedStreamDefault) { |
| 270 // Ensure that no streams are initially closed. | 269 // Ensure that no streams are initially closed. |
| 271 for (int i = kCryptoStreamId; i < 100; i++) { | 270 for (int i = kCryptoStreamId; i < 100; i++) { |
| 272 EXPECT_FALSE(session_.IsClosedStream(i)) << "stream id: " << i; | 271 EXPECT_FALSE(session_.IsClosedStream(i)) << "stream id: " << i; |
| 273 } | 272 } |
| 274 } | 273 } |
| 275 | 274 |
| 276 TEST_P(QuicSessionTestServer, ImplicitlyCreatedStreams) { | 275 TEST_P(QuicSessionTestServer, ImplicitlyCreatedStreams) { |
| 277 ASSERT_TRUE(session_.GetIncomingDataStream(9) != nullptr); | 276 ASSERT_TRUE(session_.GetIncomingDynamicStream(9) != nullptr); |
| 278 // Both 5 and 7 should be implicitly created. | 277 // Both 5 and 7 should be implicitly created. |
| 279 EXPECT_TRUE(QuicSessionPeer::IsStreamImplicitlyCreated(&session_, 5)); | 278 EXPECT_TRUE(QuicSessionPeer::IsStreamImplicitlyCreated(&session_, 5)); |
| 280 EXPECT_TRUE(QuicSessionPeer::IsStreamImplicitlyCreated(&session_, 7)); | 279 EXPECT_TRUE(QuicSessionPeer::IsStreamImplicitlyCreated(&session_, 7)); |
| 281 ASSERT_TRUE(session_.GetIncomingDataStream(7) != nullptr); | 280 ASSERT_TRUE(session_.GetIncomingDynamicStream(7) != nullptr); |
| 282 ASSERT_TRUE(session_.GetIncomingDataStream(5) != nullptr); | 281 ASSERT_TRUE(session_.GetIncomingDynamicStream(5) != nullptr); |
| 283 } | 282 } |
| 284 | 283 |
| 285 TEST_P(QuicSessionTestServer, IsClosedStreamLocallyCreated) { | 284 TEST_P(QuicSessionTestServer, IsClosedStreamLocallyCreated) { |
| 286 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 285 TestStream* stream2 = session_.CreateOutgoingDynamicStream(); |
| 287 EXPECT_EQ(2u, stream2->id()); | 286 EXPECT_EQ(2u, stream2->id()); |
| 288 TestStream* stream4 = session_.CreateOutgoingDataStream(); | 287 TestStream* stream4 = session_.CreateOutgoingDynamicStream(); |
| 289 EXPECT_EQ(4u, stream4->id()); | 288 EXPECT_EQ(4u, stream4->id()); |
| 290 | 289 |
| 291 CheckClosedStreams(); | 290 CheckClosedStreams(); |
| 292 CloseStream(4); | 291 CloseStream(4); |
| 293 CheckClosedStreams(); | 292 CheckClosedStreams(); |
| 294 CloseStream(2); | 293 CloseStream(2); |
| 295 CheckClosedStreams(); | 294 CheckClosedStreams(); |
| 296 } | 295 } |
| 297 | 296 |
| 298 TEST_P(QuicSessionTestServer, IsClosedStreamPeerCreated) { | 297 TEST_P(QuicSessionTestServer, IsClosedStreamPeerCreated) { |
| 299 QuicStreamId stream_id1 = kClientDataStreamId1; | 298 QuicStreamId stream_id1 = kClientDataStreamId1; |
| 300 QuicStreamId stream_id2 = kClientDataStreamId2; | 299 QuicStreamId stream_id2 = kClientDataStreamId2; |
| 301 QuicDataStream* stream1 = session_.GetIncomingDataStream(stream_id1); | 300 session_.GetIncomingDynamicStream(stream_id1); |
| 302 QuicDataStreamPeer::SetHeadersDecompressed(stream1, true); | 301 session_.GetIncomingDynamicStream(stream_id2); |
| 303 QuicDataStream* stream2 = session_.GetIncomingDataStream(stream_id2); | |
| 304 QuicDataStreamPeer::SetHeadersDecompressed(stream2, true); | |
| 305 | 302 |
| 306 CheckClosedStreams(); | 303 CheckClosedStreams(); |
| 307 CloseStream(stream_id1); | 304 CloseStream(stream_id1); |
| 308 CheckClosedStreams(); | 305 CheckClosedStreams(); |
| 309 CloseStream(stream_id2); | 306 CloseStream(stream_id2); |
| 310 // Create a stream explicitly, and another implicitly. | 307 // Create a stream explicitly, and another implicitly. |
| 311 QuicDataStream* stream3 = session_.GetIncomingDataStream(stream_id2 + 4); | 308 ReliableQuicStream* stream3 = |
| 312 QuicDataStreamPeer::SetHeadersDecompressed(stream3, true); | 309 session_.GetIncomingDynamicStream(stream_id2 + 4); |
| 313 CheckClosedStreams(); | 310 CheckClosedStreams(); |
| 314 // Close one, but make sure the other is still not closed | 311 // Close one, but make sure the other is still not closed |
| 315 CloseStream(stream3->id()); | 312 CloseStream(stream3->id()); |
| 316 CheckClosedStreams(); | 313 CheckClosedStreams(); |
| 317 } | 314 } |
| 318 | 315 |
| 319 TEST_P(QuicSessionTestServer, StreamIdTooLarge) { | 316 TEST_P(QuicSessionTestServer, StreamIdTooLarge) { |
| 320 QuicStreamId stream_id = kClientDataStreamId1; | 317 QuicStreamId stream_id = kClientDataStreamId1; |
| 321 session_.GetIncomingDataStream(stream_id); | 318 session_.GetIncomingDynamicStream(stream_id); |
| 322 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID)); | 319 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID)); |
| 323 session_.GetIncomingDataStream(stream_id + kMaxStreamIdDelta + 2); | 320 session_.GetIncomingDynamicStream(stream_id + kMaxStreamIdDelta + 2); |
| 324 } | 321 } |
| 325 | 322 |
| 326 TEST_P(QuicSessionTestServer, DebugDFatalIfMarkingClosedStreamWriteBlocked) { | 323 TEST_P(QuicSessionTestServer, DebugDFatalIfMarkingClosedStreamWriteBlocked) { |
| 327 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 324 TestStream* stream2 = session_.CreateOutgoingDynamicStream(); |
| 328 QuicStreamId kClosedStreamId = stream2->id(); | 325 QuicStreamId kClosedStreamId = stream2->id(); |
| 329 // Close the stream. | 326 // Close the stream. |
| 330 EXPECT_CALL(*connection_, SendRstStream(kClosedStreamId, _, _)); | 327 EXPECT_CALL(*connection_, SendRstStream(kClosedStreamId, _, _)); |
| 331 stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD); | 328 stream2->Reset(QUIC_BAD_APPLICATION_PAYLOAD); |
| 332 EXPECT_DEBUG_DFATAL( | 329 EXPECT_DEBUG_DFATAL( |
| 333 session_.MarkWriteBlocked(kClosedStreamId, kSomeMiddlePriority), | 330 session_.MarkWriteBlocked(kClosedStreamId, kSomeMiddlePriority), |
| 334 "Marking unknown stream 2 blocked."); | 331 "Marking unknown stream 2 blocked."); |
| 335 } | 332 } |
| 336 | 333 |
| 337 TEST_P(QuicSessionTestServer, | 334 TEST_P(QuicSessionTestServer, |
| 338 DebugDFatalIfMarkWriteBlockedCalledWithWrongPriority) { | 335 DebugDFatalIfMarkWriteBlockedCalledWithWrongPriority) { |
| 339 const QuicPriority kDifferentPriority = 0; | 336 const QuicPriority kDifferentPriority = 0; |
| 340 | 337 |
| 341 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 338 TestStream* stream2 = session_.CreateOutgoingDynamicStream(); |
| 342 EXPECT_NE(kDifferentPriority, stream2->EffectivePriority()); | 339 EXPECT_NE(kDifferentPriority, stream2->EffectivePriority()); |
| 343 EXPECT_DEBUG_DFATAL( | 340 EXPECT_DEBUG_DFATAL( |
| 344 session_.MarkWriteBlocked(stream2->id(), kDifferentPriority), | 341 session_.MarkWriteBlocked(stream2->id(), kDifferentPriority), |
| 345 "Priorities do not match. Got: 0 Expected: 3"); | 342 "Priorities do not match. Got: 0 Expected: 3"); |
| 346 } | 343 } |
| 347 | 344 |
| 348 TEST_P(QuicSessionTestServer, OnCanWrite) { | 345 TEST_P(QuicSessionTestServer, OnCanWrite) { |
| 349 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 346 TestStream* stream2 = session_.CreateOutgoingDynamicStream(); |
| 350 TestStream* stream4 = session_.CreateOutgoingDataStream(); | 347 TestStream* stream4 = session_.CreateOutgoingDynamicStream(); |
| 351 TestStream* stream6 = session_.CreateOutgoingDataStream(); | 348 TestStream* stream6 = session_.CreateOutgoingDynamicStream(); |
| 352 | 349 |
| 353 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); | 350 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); |
| 354 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); | 351 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); |
| 355 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); | 352 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); |
| 356 | 353 |
| 357 InSequence s; | 354 InSequence s; |
| 358 StreamBlocker stream2_blocker(&session_, stream2->id()); | 355 StreamBlocker stream2_blocker(&session_, stream2->id()); |
| 359 // Reregister, to test the loop limit. | 356 // Reregister, to test the loop limit. |
| 360 EXPECT_CALL(*stream2, OnCanWrite()) | 357 EXPECT_CALL(*stream2, OnCanWrite()) |
| 361 .WillOnce(Invoke(&stream2_blocker, &StreamBlocker::MarkWriteBlocked)); | 358 .WillOnce(Invoke(&stream2_blocker, &StreamBlocker::MarkWriteBlocked)); |
| 362 EXPECT_CALL(*stream6, OnCanWrite()); | 359 EXPECT_CALL(*stream6, OnCanWrite()); |
| 363 EXPECT_CALL(*stream4, OnCanWrite()); | 360 EXPECT_CALL(*stream4, OnCanWrite()); |
| 364 session_.OnCanWrite(); | 361 session_.OnCanWrite(); |
| 365 EXPECT_TRUE(session_.WillingAndAbleToWrite()); | 362 EXPECT_TRUE(session_.WillingAndAbleToWrite()); |
| 366 } | 363 } |
| 367 | 364 |
| 368 TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) { | 365 TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) { |
| 369 // Drive congestion control manually. | 366 // Drive congestion control manually. |
| 370 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; | 367 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; |
| 371 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm); | 368 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm); |
| 372 | 369 |
| 373 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 370 TestStream* stream2 = session_.CreateOutgoingDynamicStream(); |
| 374 TestStream* stream4 = session_.CreateOutgoingDataStream(); | 371 TestStream* stream4 = session_.CreateOutgoingDynamicStream(); |
| 375 TestStream* stream6 = session_.CreateOutgoingDataStream(); | 372 TestStream* stream6 = session_.CreateOutgoingDynamicStream(); |
| 376 | 373 |
| 377 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); | 374 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); |
| 378 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); | 375 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); |
| 379 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); | 376 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); |
| 380 | 377 |
| 381 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillRepeatedly( | 378 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillRepeatedly( |
| 382 Return(QuicTime::Delta::Zero())); | 379 Return(QuicTime::Delta::Zero())); |
| 383 EXPECT_CALL(*send_algorithm, GetCongestionWindow()) | 380 EXPECT_CALL(*send_algorithm, GetCongestionWindow()) |
| 384 .WillRepeatedly(Return(kMaxPacketSize * 10)); | 381 .WillRepeatedly(Return(kMaxPacketSize * 10)); |
| 385 EXPECT_CALL(*stream2, OnCanWrite()) | 382 EXPECT_CALL(*stream2, OnCanWrite()) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 404 EXPECT_FALSE(session_.WillingAndAbleToWrite()); | 401 EXPECT_FALSE(session_.WillingAndAbleToWrite()); |
| 405 } | 402 } |
| 406 | 403 |
| 407 TEST_P(QuicSessionTestServer, OnCanWriteCongestionControlBlocks) { | 404 TEST_P(QuicSessionTestServer, OnCanWriteCongestionControlBlocks) { |
| 408 InSequence s; | 405 InSequence s; |
| 409 | 406 |
| 410 // Drive congestion control manually. | 407 // Drive congestion control manually. |
| 411 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; | 408 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; |
| 412 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm); | 409 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm); |
| 413 | 410 |
| 414 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 411 TestStream* stream2 = session_.CreateOutgoingDynamicStream(); |
| 415 TestStream* stream4 = session_.CreateOutgoingDataStream(); | 412 TestStream* stream4 = session_.CreateOutgoingDynamicStream(); |
| 416 TestStream* stream6 = session_.CreateOutgoingDataStream(); | 413 TestStream* stream6 = session_.CreateOutgoingDynamicStream(); |
| 417 | 414 |
| 418 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); | 415 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); |
| 419 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); | 416 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); |
| 420 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); | 417 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); |
| 421 | 418 |
| 422 StreamBlocker stream2_blocker(&session_, stream2->id()); | 419 StreamBlocker stream2_blocker(&session_, stream2->id()); |
| 423 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( | 420 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( |
| 424 QuicTime::Delta::Zero())); | 421 QuicTime::Delta::Zero())); |
| 425 EXPECT_CALL(*stream2, OnCanWrite()); | 422 EXPECT_CALL(*stream2, OnCanWrite()); |
| 426 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( | 423 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( |
| (...skipping 18 matching lines...) Expand all Loading... |
| 445 QuicTime::Delta::Zero())); | 442 QuicTime::Delta::Zero())); |
| 446 EXPECT_CALL(*stream4, OnCanWrite()); | 443 EXPECT_CALL(*stream4, OnCanWrite()); |
| 447 session_.OnCanWrite(); | 444 session_.OnCanWrite(); |
| 448 EXPECT_FALSE(session_.WillingAndAbleToWrite()); | 445 EXPECT_FALSE(session_.WillingAndAbleToWrite()); |
| 449 } | 446 } |
| 450 | 447 |
| 451 TEST_P(QuicSessionTestServer, BufferedHandshake) { | 448 TEST_P(QuicSessionTestServer, BufferedHandshake) { |
| 452 EXPECT_FALSE(session_.HasPendingHandshake()); // Default value. | 449 EXPECT_FALSE(session_.HasPendingHandshake()); // Default value. |
| 453 | 450 |
| 454 // Test that blocking other streams does not change our status. | 451 // Test that blocking other streams does not change our status. |
| 455 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 452 TestStream* stream2 = session_.CreateOutgoingDynamicStream(); |
| 456 StreamBlocker stream2_blocker(&session_, stream2->id()); | 453 StreamBlocker stream2_blocker(&session_, stream2->id()); |
| 457 stream2_blocker.MarkWriteBlocked(); | 454 stream2_blocker.MarkWriteBlocked(); |
| 458 EXPECT_FALSE(session_.HasPendingHandshake()); | 455 EXPECT_FALSE(session_.HasPendingHandshake()); |
| 459 | 456 |
| 460 TestStream* stream3 = session_.CreateOutgoingDataStream(); | 457 TestStream* stream3 = session_.CreateOutgoingDynamicStream(); |
| 461 StreamBlocker stream3_blocker(&session_, stream3->id()); | 458 StreamBlocker stream3_blocker(&session_, stream3->id()); |
| 462 stream3_blocker.MarkWriteBlocked(); | 459 stream3_blocker.MarkWriteBlocked(); |
| 463 EXPECT_FALSE(session_.HasPendingHandshake()); | 460 EXPECT_FALSE(session_.HasPendingHandshake()); |
| 464 | 461 |
| 465 // Blocking (due to buffering of) the Crypto stream is detected. | 462 // Blocking (due to buffering of) the Crypto stream is detected. |
| 466 session_.MarkWriteBlocked(kCryptoStreamId, kHighestPriority); | 463 session_.MarkWriteBlocked(kCryptoStreamId, kHighestPriority); |
| 467 EXPECT_TRUE(session_.HasPendingHandshake()); | 464 EXPECT_TRUE(session_.HasPendingHandshake()); |
| 468 | 465 |
| 469 TestStream* stream4 = session_.CreateOutgoingDataStream(); | 466 TestStream* stream4 = session_.CreateOutgoingDynamicStream(); |
| 470 StreamBlocker stream4_blocker(&session_, stream4->id()); | 467 StreamBlocker stream4_blocker(&session_, stream4->id()); |
| 471 stream4_blocker.MarkWriteBlocked(); | 468 stream4_blocker.MarkWriteBlocked(); |
| 472 EXPECT_TRUE(session_.HasPendingHandshake()); | 469 EXPECT_TRUE(session_.HasPendingHandshake()); |
| 473 | 470 |
| 474 InSequence s; | 471 InSequence s; |
| 475 // Force most streams to re-register, which is common scenario when we block | 472 // Force most streams to re-register, which is common scenario when we block |
| 476 // the Crypto stream, and only the crypto stream can "really" write. | 473 // the Crypto stream, and only the crypto stream can "really" write. |
| 477 | 474 |
| 478 // Due to prioritization, we *should* be asked to write the crypto stream | 475 // Due to prioritization, we *should* be asked to write the crypto stream |
| 479 // first. | 476 // first. |
| 480 // Don't re-register the crypto stream (which signals complete writing). | 477 // Don't re-register the crypto stream (which signals complete writing). |
| 481 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); | 478 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); |
| 482 EXPECT_CALL(*crypto_stream, OnCanWrite()); | 479 EXPECT_CALL(*crypto_stream, OnCanWrite()); |
| 483 | 480 |
| 484 // Re-register all other streams, to show they weren't able to proceed. | 481 // Re-register all other streams, to show they weren't able to proceed. |
| 485 EXPECT_CALL(*stream2, OnCanWrite()) | 482 EXPECT_CALL(*stream2, OnCanWrite()) |
| 486 .WillOnce(Invoke(&stream2_blocker, &StreamBlocker::MarkWriteBlocked)); | 483 .WillOnce(Invoke(&stream2_blocker, &StreamBlocker::MarkWriteBlocked)); |
| 487 EXPECT_CALL(*stream3, OnCanWrite()) | 484 EXPECT_CALL(*stream3, OnCanWrite()) |
| 488 .WillOnce(Invoke(&stream3_blocker, &StreamBlocker::MarkWriteBlocked)); | 485 .WillOnce(Invoke(&stream3_blocker, &StreamBlocker::MarkWriteBlocked)); |
| 489 EXPECT_CALL(*stream4, OnCanWrite()) | 486 EXPECT_CALL(*stream4, OnCanWrite()) |
| 490 .WillOnce(Invoke(&stream4_blocker, &StreamBlocker::MarkWriteBlocked)); | 487 .WillOnce(Invoke(&stream4_blocker, &StreamBlocker::MarkWriteBlocked)); |
| 491 | 488 |
| 492 session_.OnCanWrite(); | 489 session_.OnCanWrite(); |
| 493 EXPECT_TRUE(session_.WillingAndAbleToWrite()); | 490 EXPECT_TRUE(session_.WillingAndAbleToWrite()); |
| 494 EXPECT_FALSE(session_.HasPendingHandshake()); // Crypto stream wrote. | 491 EXPECT_FALSE(session_.HasPendingHandshake()); // Crypto stream wrote. |
| 495 } | 492 } |
| 496 | 493 |
| 497 TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) { | 494 TEST_P(QuicSessionTestServer, OnCanWriteWithClosedStream) { |
| 498 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 495 TestStream* stream2 = session_.CreateOutgoingDynamicStream(); |
| 499 TestStream* stream4 = session_.CreateOutgoingDataStream(); | 496 TestStream* stream4 = session_.CreateOutgoingDynamicStream(); |
| 500 TestStream* stream6 = session_.CreateOutgoingDataStream(); | 497 TestStream* stream6 = session_.CreateOutgoingDynamicStream(); |
| 501 | 498 |
| 502 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); | 499 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); |
| 503 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); | 500 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); |
| 504 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); | 501 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); |
| 505 CloseStream(stream6->id()); | 502 CloseStream(stream6->id()); |
| 506 | 503 |
| 507 InSequence s; | 504 InSequence s; |
| 508 EXPECT_CALL(*stream2, OnCanWrite()); | 505 EXPECT_CALL(*stream2, OnCanWrite()); |
| 509 EXPECT_CALL(*stream4, OnCanWrite()); | 506 EXPECT_CALL(*stream4, OnCanWrite()); |
| 510 session_.OnCanWrite(); | 507 session_.OnCanWrite(); |
| 511 EXPECT_FALSE(session_.WillingAndAbleToWrite()); | 508 EXPECT_FALSE(session_.WillingAndAbleToWrite()); |
| 512 } | 509 } |
| 513 | 510 |
| 514 TEST_P(QuicSessionTestServer, OnCanWriteLimitsNumWritesIfFlowControlBlocked) { | 511 TEST_P(QuicSessionTestServer, OnCanWriteLimitsNumWritesIfFlowControlBlocked) { |
| 515 // Ensure connection level flow control blockage. | 512 // Ensure connection level flow control blockage. |
| 516 QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0); | 513 QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0); |
| 517 EXPECT_TRUE(session_.flow_controller()->IsBlocked()); | 514 EXPECT_TRUE(session_.flow_controller()->IsBlocked()); |
| 518 EXPECT_TRUE(session_.IsConnectionFlowControlBlocked()); | 515 EXPECT_TRUE(session_.IsConnectionFlowControlBlocked()); |
| 519 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 516 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
| 520 | 517 |
| 521 // Mark the crypto and headers streams as write blocked, we expect them to be | 518 // Mark the crypto and headers streams as write blocked, we expect them to be |
| 522 // allowed to write later. | 519 // allowed to write later. |
| 523 session_.MarkWriteBlocked(kCryptoStreamId, kHighestPriority); | 520 session_.MarkWriteBlocked(kCryptoStreamId, kHighestPriority); |
| 524 session_.MarkWriteBlocked(kHeadersStreamId, kHighestPriority); | 521 session_.MarkWriteBlocked(kHeadersStreamId, kHighestPriority); |
| 525 | 522 |
| 526 // Create a data stream, and although it is write blocked we never expect it | 523 // Create a data stream, and although it is write blocked we never expect it |
| 527 // to be allowed to write as we are connection level flow control blocked. | 524 // to be allowed to write as we are connection level flow control blocked. |
| 528 TestStream* stream = session_.CreateOutgoingDataStream(); | 525 TestStream* stream = session_.CreateOutgoingDynamicStream(); |
| 529 session_.MarkWriteBlocked(stream->id(), kSomeMiddlePriority); | 526 session_.MarkWriteBlocked(stream->id(), kSomeMiddlePriority); |
| 530 EXPECT_CALL(*stream, OnCanWrite()).Times(0); | 527 EXPECT_CALL(*stream, OnCanWrite()).Times(0); |
| 531 | 528 |
| 532 // The crypto and headers streams should be called even though we are | 529 // The crypto and headers streams should be called even though we are |
| 533 // connection flow control blocked. | 530 // connection flow control blocked. |
| 534 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); | 531 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); |
| 535 EXPECT_CALL(*crypto_stream, OnCanWrite()).Times(1); | 532 EXPECT_CALL(*crypto_stream, OnCanWrite()).Times(1); |
| 536 TestHeadersStream* headers_stream = new TestHeadersStream(&session_); | 533 TestHeadersStream* headers_stream = new TestHeadersStream(&session_); |
| 537 QuicSessionPeer::SetHeadersStream(&session_, headers_stream); | 534 QuicSpdySessionPeer::SetHeadersStream(&session_, headers_stream); |
| 538 EXPECT_CALL(*headers_stream, OnCanWrite()).Times(1); | 535 EXPECT_CALL(*headers_stream, OnCanWrite()).Times(1); |
| 539 | 536 |
| 540 session_.OnCanWrite(); | 537 session_.OnCanWrite(); |
| 541 EXPECT_FALSE(session_.WillingAndAbleToWrite()); | 538 EXPECT_FALSE(session_.WillingAndAbleToWrite()); |
| 542 } | 539 } |
| 543 | 540 |
| 544 TEST_P(QuicSessionTestServer, SendGoAway) { | 541 TEST_P(QuicSessionTestServer, SendGoAway) { |
| 545 EXPECT_CALL(*connection_, | 542 EXPECT_CALL(*connection_, |
| 546 SendGoAway(QUIC_PEER_GOING_AWAY, 0u, "Going Away.")); | 543 SendGoAway(QUIC_PEER_GOING_AWAY, 3u, "Going Away.")); |
| 547 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away."); | 544 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away."); |
| 548 EXPECT_TRUE(session_.goaway_sent()); | 545 EXPECT_TRUE(session_.goaway_sent()); |
| 549 | 546 |
| 550 EXPECT_CALL(*connection_, | 547 EXPECT_CALL(*connection_, |
| 551 SendRstStream(3u, QUIC_STREAM_PEER_GOING_AWAY, 0)).Times(0); | 548 SendRstStream(3u, QUIC_STREAM_PEER_GOING_AWAY, 0)).Times(0); |
| 552 EXPECT_TRUE(session_.GetIncomingDataStream(3u)); | 549 EXPECT_TRUE(session_.GetIncomingDynamicStream(3u)); |
| 553 } | 550 } |
| 554 | 551 |
| 555 TEST_P(QuicSessionTestServer, DoNotSendGoAwayTwice) { | 552 TEST_P(QuicSessionTestServer, DoNotSendGoAwayTwice) { |
| 556 EXPECT_CALL(*connection_, | 553 EXPECT_CALL(*connection_, SendGoAway(QUIC_PEER_GOING_AWAY, 3u, "Going Away.")) |
| 557 SendGoAway(QUIC_PEER_GOING_AWAY, 0u, "Going Away.")).Times(1); | 554 .Times(1); |
| 558 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away."); | 555 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away."); |
| 559 EXPECT_TRUE(session_.goaway_sent()); | 556 EXPECT_TRUE(session_.goaway_sent()); |
| 560 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away."); | 557 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away."); |
| 561 } | 558 } |
| 562 | 559 |
| 563 TEST_P(QuicSessionTestServer, IncreasedTimeoutAfterCryptoHandshake) { | 560 TEST_P(QuicSessionTestServer, IncreasedTimeoutAfterCryptoHandshake) { |
| 564 EXPECT_EQ(kInitialIdleTimeoutSecs + 3, | 561 EXPECT_EQ(kInitialIdleTimeoutSecs + 3, |
| 565 QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds()); | 562 QuicConnectionPeer::GetNetworkTimeout(connection_).ToSeconds()); |
| 566 CryptoHandshakeMessage msg; | 563 CryptoHandshakeMessage msg; |
| 567 session_.GetCryptoStream()->OnHandshakeMessage(msg); | 564 session_.GetCryptoStream()->OnHandshakeMessage(msg); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 | 611 |
| 615 TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedStream) { | 612 TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedStream) { |
| 616 // Test that if a stream is flow control blocked, then on receipt of the SHLO | 613 // Test that if a stream is flow control blocked, then on receipt of the SHLO |
| 617 // containing a suitable send window offset, the stream becomes unblocked. | 614 // containing a suitable send window offset, the stream becomes unblocked. |
| 618 | 615 |
| 619 // Ensure that Writev consumes all the data it is given (simulate no socket | 616 // Ensure that Writev consumes all the data it is given (simulate no socket |
| 620 // blocking). | 617 // blocking). |
| 621 session_.set_writev_consumes_all_data(true); | 618 session_.set_writev_consumes_all_data(true); |
| 622 | 619 |
| 623 // Create a stream, and send enough data to make it flow control blocked. | 620 // Create a stream, and send enough data to make it flow control blocked. |
| 624 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 621 TestStream* stream2 = session_.CreateOutgoingDynamicStream(); |
| 625 string body(kMinimumFlowControlSendWindow, '.'); | 622 string body(kMinimumFlowControlSendWindow, '.'); |
| 626 EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); | 623 EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); |
| 627 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 624 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 628 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 625 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
| 629 EXPECT_CALL(*connection_, SendBlocked(stream2->id())); | 626 EXPECT_CALL(*connection_, SendBlocked(stream2->id())); |
| 630 EXPECT_CALL(*connection_, SendBlocked(0)); | 627 EXPECT_CALL(*connection_, SendBlocked(0)); |
| 631 stream2->SendBody(body, false); | 628 stream2->SendBody(body, false); |
| 632 EXPECT_TRUE(stream2->flow_controller()->IsBlocked()); | 629 EXPECT_TRUE(stream2->flow_controller()->IsBlocked()); |
| 633 EXPECT_TRUE(session_.IsConnectionFlowControlBlocked()); | 630 EXPECT_TRUE(session_.IsConnectionFlowControlBlocked()); |
| 634 EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); | 631 EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 649 | 646 |
| 650 TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedCryptoStream) { | 647 TEST_P(QuicSessionTestServer, HandshakeUnblocksFlowControlBlockedCryptoStream) { |
| 651 // Test that if the crypto stream is flow control blocked, then if the SHLO | 648 // Test that if the crypto stream is flow control blocked, then if the SHLO |
| 652 // contains a larger send window offset, the stream becomes unblocked. | 649 // contains a larger send window offset, the stream becomes unblocked. |
| 653 session_.set_writev_consumes_all_data(true); | 650 session_.set_writev_consumes_all_data(true); |
| 654 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); | 651 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); |
| 655 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); | 652 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); |
| 656 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 653 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 657 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 654 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
| 658 QuicHeadersStream* headers_stream = | 655 QuicHeadersStream* headers_stream = |
| 659 QuicSessionPeer::GetHeadersStream(&session_); | 656 QuicSpdySessionPeer::GetHeadersStream(&session_); |
| 660 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); | 657 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); |
| 661 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 658 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 662 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 659 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
| 663 // Write until the crypto stream is flow control blocked. | 660 // Write until the crypto stream is flow control blocked. |
| 664 EXPECT_CALL(*connection_, SendBlocked(kCryptoStreamId)); | 661 EXPECT_CALL(*connection_, SendBlocked(kCryptoStreamId)); |
| 665 int i = 0; | 662 int i = 0; |
| 666 while (!crypto_stream->flow_controller()->IsBlocked() && i < 1000) { | 663 while (!crypto_stream->flow_controller()->IsBlocked() && i < 1000) { |
| 667 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 664 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 668 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 665 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
| 669 QuicConfig config; | 666 QuicConfig config; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 696 TEST_P(QuicSessionTestServer, | 693 TEST_P(QuicSessionTestServer, |
| 697 HandshakeUnblocksFlowControlBlockedHeadersStream) { | 694 HandshakeUnblocksFlowControlBlockedHeadersStream) { |
| 698 // Test that if the header stream is flow control blocked, then if the SHLO | 695 // Test that if the header stream is flow control blocked, then if the SHLO |
| 699 // contains a larger send window offset, the stream becomes unblocked. | 696 // contains a larger send window offset, the stream becomes unblocked. |
| 700 session_.set_writev_consumes_all_data(true); | 697 session_.set_writev_consumes_all_data(true); |
| 701 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); | 698 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); |
| 702 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); | 699 EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); |
| 703 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 700 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 704 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 701 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
| 705 QuicHeadersStream* headers_stream = | 702 QuicHeadersStream* headers_stream = |
| 706 QuicSessionPeer::GetHeadersStream(&session_); | 703 QuicSpdySessionPeer::GetHeadersStream(&session_); |
| 707 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); | 704 EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); |
| 708 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 705 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 709 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 706 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
| 710 QuicStreamId stream_id = 5; | 707 QuicStreamId stream_id = 5; |
| 711 // Write until the header stream is flow control blocked. | 708 // Write until the header stream is flow control blocked. |
| 712 EXPECT_CALL(*connection_, SendBlocked(kHeadersStreamId)); | 709 EXPECT_CALL(*connection_, SendBlocked(kHeadersStreamId)); |
| 713 SpdyHeaderBlock headers; | 710 SpdyHeaderBlock headers; |
| 714 while (!headers_stream->flow_controller()->IsBlocked() && stream_id < 2000) { | 711 while (!headers_stream->flow_controller()->IsBlocked() && stream_id < 2000) { |
| 715 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 712 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 716 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 713 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 741 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 738 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 742 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); | 739 EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); |
| 743 EXPECT_FALSE(headers_stream->HasBufferedData()); | 740 EXPECT_FALSE(headers_stream->HasBufferedData()); |
| 744 } | 741 } |
| 745 | 742 |
| 746 TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstOutOfOrder) { | 743 TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingRstOutOfOrder) { |
| 747 // Test that when we receive an out of order stream RST we correctly adjust | 744 // Test that when we receive an out of order stream RST we correctly adjust |
| 748 // our connection level flow control receive window. | 745 // our connection level flow control receive window. |
| 749 // On close, the stream should mark as consumed all bytes between the highest | 746 // On close, the stream should mark as consumed all bytes between the highest |
| 750 // byte consumed so far and the final byte offset from the RST frame. | 747 // byte consumed so far and the final byte offset from the RST frame. |
| 751 TestStream* stream = session_.CreateOutgoingDataStream(); | 748 TestStream* stream = session_.CreateOutgoingDynamicStream(); |
| 752 | 749 |
| 753 const QuicStreamOffset kByteOffset = | 750 const QuicStreamOffset kByteOffset = |
| 754 1 + kInitialSessionFlowControlWindowForTest / 2; | 751 1 + kInitialSessionFlowControlWindowForTest / 2; |
| 755 | 752 |
| 756 // Expect no stream WINDOW_UPDATE frames, as stream read side closed. | 753 // Expect no stream WINDOW_UPDATE frames, as stream read side closed. |
| 757 EXPECT_CALL(*connection_, SendWindowUpdate(stream->id(), _)).Times(0); | 754 EXPECT_CALL(*connection_, SendWindowUpdate(stream->id(), _)).Times(0); |
| 758 // We do expect a connection level WINDOW_UPDATE when the stream is reset. | 755 // We do expect a connection level WINDOW_UPDATE when the stream is reset. |
| 759 EXPECT_CALL(*connection_, | 756 EXPECT_CALL(*connection_, |
| 760 SendWindowUpdate(0, kInitialSessionFlowControlWindowForTest + | 757 SendWindowUpdate(0, kInitialSessionFlowControlWindowForTest + |
| 761 kByteOffset)).Times(1); | 758 kByteOffset)).Times(1); |
| 762 | 759 |
| 763 EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _)); | 760 EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _)); |
| 764 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, | 761 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, |
| 765 kByteOffset); | 762 kByteOffset); |
| 766 session_.OnRstStream(rst_frame); | 763 session_.OnRstStream(rst_frame); |
| 767 session_.PostProcessAfterData(); | 764 session_.PostProcessAfterData(); |
| 768 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); | 765 EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); |
| 769 } | 766 } |
| 770 | 767 |
| 771 TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAndLocalReset) { | 768 TEST_P(QuicSessionTestServer, ConnectionFlowControlAccountingFinAndLocalReset) { |
| 772 // Test the situation where we receive a FIN on a stream, and before we fully | 769 // Test the situation where we receive a FIN on a stream, and before we fully |
| 773 // consume all the data from the sequencer buffer we locally RST the stream. | 770 // consume all the data from the sequencer buffer we locally RST the stream. |
| 774 // The bytes between highest consumed byte, and the final byte offset that we | 771 // The bytes between highest consumed byte, and the final byte offset that we |
| 775 // determined when the FIN arrived, should be marked as consumed at the | 772 // determined when the FIN arrived, should be marked as consumed at the |
| 776 // connection level flow controller when the stream is reset. | 773 // connection level flow controller when the stream is reset. |
| 777 TestStream* stream = session_.CreateOutgoingDataStream(); | 774 TestStream* stream = session_.CreateOutgoingDynamicStream(); |
| 778 | 775 |
| 779 const QuicStreamOffset kByteOffset = | 776 const QuicStreamOffset kByteOffset = |
| 780 kInitialSessionFlowControlWindowForTest / 2; | 777 kInitialSessionFlowControlWindowForTest / 2; |
| 781 QuicStreamFrame frame(stream->id(), true, kByteOffset, StringPiece()); | 778 QuicStreamFrame frame(stream->id(), true, kByteOffset, StringPiece()); |
| 782 vector<QuicStreamFrame> frames; | 779 vector<QuicStreamFrame> frames; |
| 783 frames.push_back(frame); | 780 frames.push_back(frame); |
| 784 session_.OnStreamFrames(frames); | 781 session_.OnStreamFrames(frames); |
| 785 session_.PostProcessAfterData(); | 782 session_.PostProcessAfterData(); |
| 786 EXPECT_TRUE(connection_->connected()); | 783 EXPECT_TRUE(connection_->connected()); |
| 787 | 784 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 804 // due to other active streams. | 801 // due to other active streams. |
| 805 const uint64 kInitialConnectionBytesConsumed = 567; | 802 const uint64 kInitialConnectionBytesConsumed = 567; |
| 806 const uint64 kInitialConnectionHighestReceivedOffset = 1234; | 803 const uint64 kInitialConnectionHighestReceivedOffset = 1234; |
| 807 EXPECT_LT(kInitialConnectionBytesConsumed, | 804 EXPECT_LT(kInitialConnectionBytesConsumed, |
| 808 kInitialConnectionHighestReceivedOffset); | 805 kInitialConnectionHighestReceivedOffset); |
| 809 session_.flow_controller()->UpdateHighestReceivedOffset( | 806 session_.flow_controller()->UpdateHighestReceivedOffset( |
| 810 kInitialConnectionHighestReceivedOffset); | 807 kInitialConnectionHighestReceivedOffset); |
| 811 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); | 808 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); |
| 812 | 809 |
| 813 // Reset our stream: this results in the stream being closed locally. | 810 // Reset our stream: this results in the stream being closed locally. |
| 814 TestStream* stream = session_.CreateOutgoingDataStream(); | 811 TestStream* stream = session_.CreateOutgoingDynamicStream(); |
| 815 EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _)); | 812 EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _)); |
| 816 stream->Reset(QUIC_STREAM_CANCELLED); | 813 stream->Reset(QUIC_STREAM_CANCELLED); |
| 817 | 814 |
| 818 // Now receive a response from the peer with a FIN. We should handle this by | 815 // Now receive a response from the peer with a FIN. We should handle this by |
| 819 // adjusting the connection level flow control receive window to take into | 816 // adjusting the connection level flow control receive window to take into |
| 820 // account the total number of bytes sent by the peer. | 817 // account the total number of bytes sent by the peer. |
| 821 const QuicStreamOffset kByteOffset = 5678; | 818 const QuicStreamOffset kByteOffset = 5678; |
| 822 string body = "hello"; | 819 string body = "hello"; |
| 823 QuicStreamFrame frame(stream->id(), true, kByteOffset, StringPiece(body)); | 820 QuicStreamFrame frame(stream->id(), true, kByteOffset, StringPiece(body)); |
| 824 vector<QuicStreamFrame> frames; | 821 vector<QuicStreamFrame> frames; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 843 // due to other active streams. | 840 // due to other active streams. |
| 844 const uint64 kInitialConnectionBytesConsumed = 567; | 841 const uint64 kInitialConnectionBytesConsumed = 567; |
| 845 const uint64 kInitialConnectionHighestReceivedOffset = 1234; | 842 const uint64 kInitialConnectionHighestReceivedOffset = 1234; |
| 846 EXPECT_LT(kInitialConnectionBytesConsumed, | 843 EXPECT_LT(kInitialConnectionBytesConsumed, |
| 847 kInitialConnectionHighestReceivedOffset); | 844 kInitialConnectionHighestReceivedOffset); |
| 848 session_.flow_controller()->UpdateHighestReceivedOffset( | 845 session_.flow_controller()->UpdateHighestReceivedOffset( |
| 849 kInitialConnectionHighestReceivedOffset); | 846 kInitialConnectionHighestReceivedOffset); |
| 850 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); | 847 session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); |
| 851 | 848 |
| 852 // Reset our stream: this results in the stream being closed locally. | 849 // Reset our stream: this results in the stream being closed locally. |
| 853 TestStream* stream = session_.CreateOutgoingDataStream(); | 850 TestStream* stream = session_.CreateOutgoingDynamicStream(); |
| 854 EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _)); | 851 EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _)); |
| 855 stream->Reset(QUIC_STREAM_CANCELLED); | 852 stream->Reset(QUIC_STREAM_CANCELLED); |
| 856 | 853 |
| 857 // Now receive a RST from the peer. We should handle this by adjusting the | 854 // Now receive a RST from the peer. We should handle this by adjusting the |
| 858 // connection level flow control receive window to take into account the total | 855 // connection level flow control receive window to take into account the total |
| 859 // number of bytes sent by the peer. | 856 // number of bytes sent by the peer. |
| 860 const QuicStreamOffset kByteOffset = 5678; | 857 const QuicStreamOffset kByteOffset = 5678; |
| 861 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, | 858 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, |
| 862 kByteOffset); | 859 kByteOffset); |
| 863 session_.OnRstStream(rst_frame); | 860 session_.OnRstStream(rst_frame); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 894 | 891 |
| 895 TEST_P(QuicSessionTestServer, FlowControlWithInvalidFinalOffset) { | 892 TEST_P(QuicSessionTestServer, FlowControlWithInvalidFinalOffset) { |
| 896 // Test that if we receive a stream RST with a highest byte offset that | 893 // Test that if we receive a stream RST with a highest byte offset that |
| 897 // violates flow control, that we close the connection. | 894 // violates flow control, that we close the connection. |
| 898 const uint64 kLargeOffset = kInitialSessionFlowControlWindowForTest + 1; | 895 const uint64 kLargeOffset = kInitialSessionFlowControlWindowForTest + 1; |
| 899 EXPECT_CALL(*connection_, | 896 EXPECT_CALL(*connection_, |
| 900 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)) | 897 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)) |
| 901 .Times(2); | 898 .Times(2); |
| 902 | 899 |
| 903 // Check that stream frame + FIN results in connection close. | 900 // Check that stream frame + FIN results in connection close. |
| 904 TestStream* stream = session_.CreateOutgoingDataStream(); | 901 TestStream* stream = session_.CreateOutgoingDynamicStream(); |
| 905 EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _)); | 902 EXPECT_CALL(*connection_, SendRstStream(stream->id(), _, _)); |
| 906 stream->Reset(QUIC_STREAM_CANCELLED); | 903 stream->Reset(QUIC_STREAM_CANCELLED); |
| 907 QuicStreamFrame frame(stream->id(), true, kLargeOffset, StringPiece()); | 904 QuicStreamFrame frame(stream->id(), true, kLargeOffset, StringPiece()); |
| 908 vector<QuicStreamFrame> frames; | 905 vector<QuicStreamFrame> frames; |
| 909 frames.push_back(frame); | 906 frames.push_back(frame); |
| 910 session_.OnStreamFrames(frames); | 907 session_.OnStreamFrames(frames); |
| 911 | 908 |
| 912 // Check that RST results in connection close. | 909 // Check that RST results in connection close. |
| 913 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, | 910 QuicRstStreamFrame rst_frame(stream->id(), QUIC_STREAM_CANCELLED, |
| 914 kLargeOffset); | 911 kLargeOffset); |
| 915 session_.OnRstStream(rst_frame); | 912 session_.OnRstStream(rst_frame); |
| 916 } | 913 } |
| 917 | 914 |
| 918 TEST_P(QuicSessionTestServer, WindowUpdateUnblocksHeadersStream) { | 915 TEST_P(QuicSessionTestServer, WindowUpdateUnblocksHeadersStream) { |
| 919 // Test that a flow control blocked headers stream gets unblocked on recipt of | 916 // Test that a flow control blocked headers stream gets unblocked on recipt of |
| 920 // a WINDOW_UPDATE frame. | 917 // a WINDOW_UPDATE frame. |
| 921 | 918 |
| 922 // Set the headers stream to be flow control blocked. | 919 // Set the headers stream to be flow control blocked. |
| 923 QuicHeadersStream* headers_stream = | 920 QuicHeadersStream* headers_stream = |
| 924 QuicSessionPeer::GetHeadersStream(&session_); | 921 QuicSpdySessionPeer::GetHeadersStream(&session_); |
| 925 QuicFlowControllerPeer::SetSendWindowOffset(headers_stream->flow_controller(), | 922 QuicFlowControllerPeer::SetSendWindowOffset(headers_stream->flow_controller(), |
| 926 0); | 923 0); |
| 927 EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked()); | 924 EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked()); |
| 928 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); | 925 EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); |
| 929 EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); | 926 EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); |
| 930 | 927 |
| 931 // Unblock the headers stream by supplying a WINDOW_UPDATE. | 928 // Unblock the headers stream by supplying a WINDOW_UPDATE. |
| 932 QuicWindowUpdateFrame window_update_frame(headers_stream->id(), | 929 QuicWindowUpdateFrame window_update_frame(headers_stream->id(), |
| 933 2 * kMinimumFlowControlSendWindow); | 930 2 * kMinimumFlowControlSendWindow); |
| 934 vector<QuicWindowUpdateFrame> frames; | 931 vector<QuicWindowUpdateFrame> frames; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 970 class QuicSessionTestClient : public QuicSessionTestBase { | 967 class QuicSessionTestClient : public QuicSessionTestBase { |
| 971 protected: | 968 protected: |
| 972 QuicSessionTestClient() : QuicSessionTestBase(Perspective::IS_CLIENT) {} | 969 QuicSessionTestClient() : QuicSessionTestBase(Perspective::IS_CLIENT) {} |
| 973 }; | 970 }; |
| 974 | 971 |
| 975 INSTANTIATE_TEST_CASE_P(Tests, | 972 INSTANTIATE_TEST_CASE_P(Tests, |
| 976 QuicSessionTestClient, | 973 QuicSessionTestClient, |
| 977 ::testing::ValuesIn(QuicSupportedVersions())); | 974 ::testing::ValuesIn(QuicSupportedVersions())); |
| 978 | 975 |
| 979 TEST_P(QuicSessionTestClient, ImplicitlyCreatedStreamsClient) { | 976 TEST_P(QuicSessionTestClient, ImplicitlyCreatedStreamsClient) { |
| 980 ASSERT_TRUE(session_.GetIncomingDataStream(6) != nullptr); | 977 ASSERT_TRUE(session_.GetIncomingDynamicStream(6) != nullptr); |
| 981 // Both 2 and 4 should be implicitly created. | 978 // Both 2 and 4 should be implicitly created. |
| 982 EXPECT_TRUE(QuicSessionPeer::IsStreamImplicitlyCreated(&session_, 2)); | 979 EXPECT_TRUE(QuicSessionPeer::IsStreamImplicitlyCreated(&session_, 2)); |
| 983 EXPECT_TRUE(QuicSessionPeer::IsStreamImplicitlyCreated(&session_, 4)); | 980 EXPECT_TRUE(QuicSessionPeer::IsStreamImplicitlyCreated(&session_, 4)); |
| 984 ASSERT_TRUE(session_.GetIncomingDataStream(2) != nullptr); | 981 ASSERT_TRUE(session_.GetIncomingDynamicStream(2) != nullptr); |
| 985 ASSERT_TRUE(session_.GetIncomingDataStream(4) != nullptr); | 982 ASSERT_TRUE(session_.GetIncomingDynamicStream(4) != nullptr); |
| 986 // And 5 should be not implicitly created. | 983 // And 5 should be not implicitly created. |
| 987 EXPECT_FALSE(QuicSessionPeer::IsStreamImplicitlyCreated(&session_, 5)); | 984 EXPECT_FALSE(QuicSessionPeer::IsStreamImplicitlyCreated(&session_, 5)); |
| 988 } | 985 } |
| 989 | 986 |
| 990 } // namespace | 987 } // namespace |
| 991 } // namespace test | 988 } // namespace test |
| 992 } // namespace net | 989 } // namespace net |
| OLD | NEW |