Chromium Code Reviews| 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 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| 11 #include "base/containers/hash_tables.h" | 11 #include "base/containers/hash_tables.h" |
| 12 #include "net/quic/crypto/crypto_protocol.h" | 12 #include "net/quic/crypto/crypto_protocol.h" |
| 13 #include "net/quic/quic_crypto_stream.h" | 13 #include "net/quic/quic_crypto_stream.h" |
| 14 #include "net/quic/quic_flags.h" | 14 #include "net/quic/quic_flags.h" |
| 15 #include "net/quic/quic_protocol.h" | 15 #include "net/quic/quic_protocol.h" |
| 16 #include "net/quic/quic_utils.h" | 16 #include "net/quic/quic_utils.h" |
| 17 #include "net/quic/reliable_quic_stream.h" | 17 #include "net/quic/reliable_quic_stream.h" |
| 18 #include "net/quic/test_tools/quic_connection_peer.h" | 18 #include "net/quic/test_tools/quic_connection_peer.h" |
| 19 #include "net/quic/test_tools/quic_data_stream_peer.h" | 19 #include "net/quic/test_tools/quic_data_stream_peer.h" |
| 20 #include "net/quic/test_tools/quic_flow_controller_peer.h" | |
| 20 #include "net/quic/test_tools/quic_session_peer.h" | 21 #include "net/quic/test_tools/quic_session_peer.h" |
| 21 #include "net/quic/test_tools/quic_test_utils.h" | 22 #include "net/quic/test_tools/quic_test_utils.h" |
| 22 #include "net/quic/test_tools/reliable_quic_stream_peer.h" | 23 #include "net/quic/test_tools/reliable_quic_stream_peer.h" |
| 23 #include "net/spdy/spdy_framer.h" | 24 #include "net/spdy/spdy_framer.h" |
| 24 #include "net/test/gtest_util.h" | 25 #include "net/test/gtest_util.h" |
| 25 #include "testing/gmock/include/gmock/gmock.h" | 26 #include "testing/gmock/include/gmock/gmock.h" |
| 26 #include "testing/gtest/include/gtest/gtest.h" | 27 #include "testing/gtest/include/gtest/gtest.h" |
| 27 | 28 |
| 28 using base::hash_map; | 29 using base::hash_map; |
| 29 using std::set; | 30 using std::set; |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 59 const QuicErrorCode error = session()->config()->ProcessPeerHello( | 60 const QuicErrorCode error = session()->config()->ProcessPeerHello( |
| 60 msg, CLIENT, &error_details); | 61 msg, CLIENT, &error_details); |
| 61 EXPECT_EQ(QUIC_NO_ERROR, error); | 62 EXPECT_EQ(QUIC_NO_ERROR, error); |
| 62 session()->OnConfigNegotiated(); | 63 session()->OnConfigNegotiated(); |
| 63 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); | 64 session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED); |
| 64 } | 65 } |
| 65 | 66 |
| 66 MOCK_METHOD0(OnCanWrite, void()); | 67 MOCK_METHOD0(OnCanWrite, void()); |
| 67 }; | 68 }; |
| 68 | 69 |
| 70 class TestHeadersStream : public QuicHeadersStream { | |
| 71 public: | |
| 72 explicit TestHeadersStream(QuicSession* session) | |
| 73 : QuicHeadersStream(session) { | |
| 74 } | |
| 75 | |
| 76 MOCK_METHOD0(OnCanWrite, void()); | |
| 77 }; | |
| 78 | |
| 69 class TestStream : public QuicDataStream { | 79 class TestStream : public QuicDataStream { |
| 70 public: | 80 public: |
| 71 TestStream(QuicStreamId id, QuicSession* session) | 81 TestStream(QuicStreamId id, QuicSession* session) |
| 72 : QuicDataStream(id, session) { | 82 : QuicDataStream(id, session) { |
| 73 } | 83 } |
| 74 | 84 |
| 75 using ReliableQuicStream::CloseWriteSide; | 85 using ReliableQuicStream::CloseWriteSide; |
| 76 | 86 |
| 77 virtual uint32 ProcessData(const char* data, uint32 data_len) { | 87 virtual uint32 ProcessData(const char* data, uint32 data_len) { |
| 78 return data_len; | 88 return data_len; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 97 session_->MarkWriteBlocked(stream_id_, kSomeMiddlePriority); | 107 session_->MarkWriteBlocked(stream_id_, kSomeMiddlePriority); |
| 98 } | 108 } |
| 99 | 109 |
| 100 private: | 110 private: |
| 101 QuicSession* const session_; | 111 QuicSession* const session_; |
| 102 const QuicStreamId stream_id_; | 112 const QuicStreamId stream_id_; |
| 103 }; | 113 }; |
| 104 | 114 |
| 105 class TestSession : public QuicSession { | 115 class TestSession : public QuicSession { |
| 106 public: | 116 public: |
| 107 explicit TestSession(QuicConnection* connection) | 117 explicit TestSession(QuicConnection* connection, |
|
wtc
2014/05/19 18:58:40
Nit: this "explicit" keyword can be removed now.
ramant (doing other things)
2014/05/20 03:22:32
Done.
| |
| 108 : QuicSession(connection, DefaultQuicConfig()), | 118 uint32 max_initial_flow_control_window) |
| 119 : QuicSession(connection, max_initial_flow_control_window, | |
| 120 DefaultQuicConfig()), | |
| 109 crypto_stream_(this), | 121 crypto_stream_(this), |
| 110 writev_consumes_all_data_(false) { | 122 writev_consumes_all_data_(false) {} |
| 111 } | |
| 112 | 123 |
| 113 virtual TestCryptoStream* GetCryptoStream() OVERRIDE { | 124 virtual TestCryptoStream* GetCryptoStream() OVERRIDE { |
| 114 return &crypto_stream_; | 125 return &crypto_stream_; |
| 115 } | 126 } |
| 116 | 127 |
| 117 virtual TestStream* CreateOutgoingDataStream() OVERRIDE { | 128 virtual TestStream* CreateOutgoingDataStream() OVERRIDE { |
| 118 TestStream* stream = new TestStream(GetNextStreamId(), this); | 129 TestStream* stream = new TestStream(GetNextStreamId(), this); |
| 119 ActivateStream(stream); | 130 ActivateStream(stream); |
| 120 return stream; | 131 return stream; |
| 121 } | 132 } |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 149 | 160 |
| 150 void set_writev_consumes_all_data(bool val) { | 161 void set_writev_consumes_all_data(bool val) { |
| 151 writev_consumes_all_data_ = val; | 162 writev_consumes_all_data_ = val; |
| 152 } | 163 } |
| 153 | 164 |
| 154 QuicConsumedData SendStreamData() { | 165 QuicConsumedData SendStreamData() { |
| 155 return WritevData(5, IOVector(), 0, true, NULL); | 166 return WritevData(5, IOVector(), 0, true, NULL); |
| 156 } | 167 } |
| 157 | 168 |
| 158 private: | 169 private: |
| 159 TestCryptoStream crypto_stream_; | 170 StrictMock<TestCryptoStream> crypto_stream_; |
| 160 | 171 |
| 161 bool writev_consumes_all_data_; | 172 bool writev_consumes_all_data_; |
| 162 }; | 173 }; |
| 163 | 174 |
| 164 class QuicSessionTest : public ::testing::TestWithParam<QuicVersion> { | 175 class QuicSessionTest : public ::testing::TestWithParam<QuicVersion> { |
| 165 protected: | 176 protected: |
| 166 QuicSessionTest() | 177 QuicSessionTest() |
| 167 : connection_(new MockConnection(true, SupportedVersions(GetParam()))), | 178 : connection_(new MockConnection(true, SupportedVersions(GetParam()))), |
| 168 session_(connection_) { | 179 session_(connection_, kInitialFlowControlWindowForTest) { |
| 169 headers_[":host"] = "www.google.com"; | 180 headers_[":host"] = "www.google.com"; |
| 170 headers_[":path"] = "/index.hml"; | 181 headers_[":path"] = "/index.hml"; |
| 171 headers_[":scheme"] = "http"; | 182 headers_[":scheme"] = "http"; |
| 172 headers_["cookie"] = | 183 headers_["cookie"] = |
| 173 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; " | 184 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; " |
| 174 "__utmc=160408618; " | 185 "__utmc=160408618; " |
| 175 "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX" | 186 "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX" |
| 176 "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX" | 187 "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX" |
| 177 "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT" | 188 "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT" |
| 178 "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0" | 189 "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0" |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 342 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); | 353 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); |
| 343 | 354 |
| 344 InSequence s; | 355 InSequence s; |
| 345 StreamBlocker stream2_blocker(&session_, stream2->id()); | 356 StreamBlocker stream2_blocker(&session_, stream2->id()); |
| 346 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce( | 357 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce( |
| 347 // Reregister, to test the loop limit. | 358 // Reregister, to test the loop limit. |
| 348 InvokeWithoutArgs(&stream2_blocker, &StreamBlocker::MarkWriteBlocked)); | 359 InvokeWithoutArgs(&stream2_blocker, &StreamBlocker::MarkWriteBlocked)); |
| 349 EXPECT_CALL(*stream6, OnCanWrite()); | 360 EXPECT_CALL(*stream6, OnCanWrite()); |
| 350 EXPECT_CALL(*stream4, OnCanWrite()); | 361 EXPECT_CALL(*stream4, OnCanWrite()); |
| 351 session_.OnCanWrite(); | 362 session_.OnCanWrite(); |
| 352 EXPECT_TRUE(session_.HasPendingWrites()); | 363 EXPECT_TRUE(session_.WillingAndAbleToWrite()); |
| 353 } | 364 } |
| 354 | 365 |
| 355 TEST_P(QuicSessionTest, OnCanWriteBundlesStreams) { | 366 TEST_P(QuicSessionTest, OnCanWriteBundlesStreams) { |
| 356 // Drive congestion control manually. | 367 // Drive congestion control manually. |
| 357 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; | 368 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; |
| 358 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm); | 369 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm); |
| 359 | 370 |
| 360 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 371 TestStream* stream2 = session_.CreateOutgoingDataStream(); |
| 361 TestStream* stream4 = session_.CreateOutgoingDataStream(); | 372 TestStream* stream4 = session_.CreateOutgoingDataStream(); |
| 362 TestStream* stream6 = session_.CreateOutgoingDataStream(); | 373 TestStream* stream6 = session_.CreateOutgoingDataStream(); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 376 InvokeWithoutArgs(&session_, &TestSession::SendStreamData))); | 387 InvokeWithoutArgs(&session_, &TestSession::SendStreamData))); |
| 377 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(IgnoreResult( | 388 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(IgnoreResult( |
| 378 InvokeWithoutArgs(&session_, &TestSession::SendStreamData))); | 389 InvokeWithoutArgs(&session_, &TestSession::SendStreamData))); |
| 379 MockPacketWriter* writer = | 390 MockPacketWriter* writer = |
| 380 static_cast<MockPacketWriter*>( | 391 static_cast<MockPacketWriter*>( |
| 381 QuicConnectionPeer::GetWriter(session_.connection())); | 392 QuicConnectionPeer::GetWriter(session_.connection())); |
| 382 EXPECT_CALL(*writer, WritePacket(_, _, _, _)).WillOnce( | 393 EXPECT_CALL(*writer, WritePacket(_, _, _, _)).WillOnce( |
| 383 Return(WriteResult(WRITE_STATUS_OK, 0))); | 394 Return(WriteResult(WRITE_STATUS_OK, 0))); |
| 384 EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _)); | 395 EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _)); |
| 385 session_.OnCanWrite(); | 396 session_.OnCanWrite(); |
| 386 EXPECT_FALSE(session_.HasPendingWrites()); | 397 EXPECT_FALSE(session_.WillingAndAbleToWrite()); |
| 387 } | 398 } |
| 388 | 399 |
| 389 TEST_P(QuicSessionTest, OnCanWriteCongestionControlBlocks) { | 400 TEST_P(QuicSessionTest, OnCanWriteCongestionControlBlocks) { |
| 390 InSequence s; | 401 InSequence s; |
| 391 | 402 |
| 392 // Drive congestion control manually. | 403 // Drive congestion control manually. |
| 393 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; | 404 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; |
| 394 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm); | 405 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm); |
| 395 | 406 |
| 396 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 407 TestStream* stream2 = session_.CreateOutgoingDataStream(); |
| 397 TestStream* stream4 = session_.CreateOutgoingDataStream(); | 408 TestStream* stream4 = session_.CreateOutgoingDataStream(); |
| 398 TestStream* stream6 = session_.CreateOutgoingDataStream(); | 409 TestStream* stream6 = session_.CreateOutgoingDataStream(); |
| 399 | 410 |
| 400 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); | 411 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); |
| 401 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); | 412 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); |
| 402 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); | 413 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); |
| 403 | 414 |
| 404 StreamBlocker stream2_blocker(&session_, stream2->id()); | 415 StreamBlocker stream2_blocker(&session_, stream2->id()); |
| 405 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( | 416 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( |
| 406 QuicTime::Delta::Zero())); | 417 QuicTime::Delta::Zero())); |
| 407 EXPECT_CALL(*stream2, OnCanWrite()); | 418 EXPECT_CALL(*stream2, OnCanWrite()); |
| 408 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( | 419 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( |
| 409 QuicTime::Delta::Zero())); | 420 QuicTime::Delta::Zero())); |
| 410 EXPECT_CALL(*stream6, OnCanWrite()); | 421 EXPECT_CALL(*stream6, OnCanWrite()); |
| 411 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( | 422 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( |
| 412 QuicTime::Delta::Infinite())); | 423 QuicTime::Delta::Infinite())); |
| 413 // stream4->OnCanWrite is not called. | 424 // stream4->OnCanWrite is not called. |
| 414 | 425 |
| 415 session_.OnCanWrite(); | 426 session_.OnCanWrite(); |
| 416 EXPECT_TRUE(session_.HasPendingWrites()); | 427 EXPECT_TRUE(session_.WillingAndAbleToWrite()); |
| 417 | 428 |
| 418 // Still congestion-control blocked. | 429 // Still congestion-control blocked. |
| 419 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( | 430 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( |
| 420 QuicTime::Delta::Infinite())); | 431 QuicTime::Delta::Infinite())); |
| 421 session_.OnCanWrite(); | 432 session_.OnCanWrite(); |
| 422 EXPECT_TRUE(session_.HasPendingWrites()); | 433 EXPECT_TRUE(session_.WillingAndAbleToWrite()); |
| 423 | 434 |
| 424 // stream4->OnCanWrite is called once the connection stops being | 435 // stream4->OnCanWrite is called once the connection stops being |
| 425 // congestion-control blocked. | 436 // congestion-control blocked. |
| 426 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( | 437 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( |
| 427 QuicTime::Delta::Zero())); | 438 QuicTime::Delta::Zero())); |
| 428 EXPECT_CALL(*stream4, OnCanWrite()); | 439 EXPECT_CALL(*stream4, OnCanWrite()); |
| 429 session_.OnCanWrite(); | 440 session_.OnCanWrite(); |
| 430 EXPECT_FALSE(session_.HasPendingWrites()); | 441 EXPECT_FALSE(session_.WillingAndAbleToWrite()); |
| 431 } | 442 } |
| 432 | 443 |
| 433 TEST_P(QuicSessionTest, BufferedHandshake) { | 444 TEST_P(QuicSessionTest, BufferedHandshake) { |
| 434 EXPECT_FALSE(session_.HasPendingHandshake()); // Default value. | 445 EXPECT_FALSE(session_.HasPendingHandshake()); // Default value. |
| 435 | 446 |
| 436 // Test that blocking other streams does not change our status. | 447 // Test that blocking other streams does not change our status. |
| 437 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 448 TestStream* stream2 = session_.CreateOutgoingDataStream(); |
| 438 StreamBlocker stream2_blocker(&session_, stream2->id()); | 449 StreamBlocker stream2_blocker(&session_, stream2->id()); |
| 439 stream2_blocker.MarkWriteBlocked(); | 450 stream2_blocker.MarkWriteBlocked(); |
| 440 EXPECT_FALSE(session_.HasPendingHandshake()); | 451 EXPECT_FALSE(session_.HasPendingHandshake()); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 467 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce( | 478 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce( |
| 468 InvokeWithoutArgs(&stream2_blocker, &StreamBlocker::MarkWriteBlocked)); | 479 InvokeWithoutArgs(&stream2_blocker, &StreamBlocker::MarkWriteBlocked)); |
| 469 | 480 |
| 470 EXPECT_CALL(*stream3, OnCanWrite()).WillOnce( | 481 EXPECT_CALL(*stream3, OnCanWrite()).WillOnce( |
| 471 InvokeWithoutArgs(&stream3_blocker, &StreamBlocker::MarkWriteBlocked)); | 482 InvokeWithoutArgs(&stream3_blocker, &StreamBlocker::MarkWriteBlocked)); |
| 472 | 483 |
| 473 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce( | 484 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce( |
| 474 InvokeWithoutArgs(&stream4_blocker, &StreamBlocker::MarkWriteBlocked)); | 485 InvokeWithoutArgs(&stream4_blocker, &StreamBlocker::MarkWriteBlocked)); |
| 475 | 486 |
| 476 session_.OnCanWrite(); | 487 session_.OnCanWrite(); |
| 477 EXPECT_TRUE(session_.HasPendingWrites()); | 488 EXPECT_TRUE(session_.WillingAndAbleToWrite()); |
| 478 EXPECT_FALSE(session_.HasPendingHandshake()); // Crypto stream wrote. | 489 EXPECT_FALSE(session_.HasPendingHandshake()); // Crypto stream wrote. |
| 479 } | 490 } |
| 480 | 491 |
| 481 TEST_P(QuicSessionTest, OnCanWriteWithClosedStream) { | 492 TEST_P(QuicSessionTest, OnCanWriteWithClosedStream) { |
| 482 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 493 TestStream* stream2 = session_.CreateOutgoingDataStream(); |
| 483 TestStream* stream4 = session_.CreateOutgoingDataStream(); | 494 TestStream* stream4 = session_.CreateOutgoingDataStream(); |
| 484 TestStream* stream6 = session_.CreateOutgoingDataStream(); | 495 TestStream* stream6 = session_.CreateOutgoingDataStream(); |
| 485 | 496 |
| 486 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); | 497 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); |
| 487 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); | 498 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); |
| 488 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); | 499 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); |
| 489 CloseStream(stream6->id()); | 500 CloseStream(stream6->id()); |
| 490 | 501 |
| 491 InSequence s; | 502 InSequence s; |
| 492 EXPECT_CALL(*stream2, OnCanWrite()); | 503 EXPECT_CALL(*stream2, OnCanWrite()); |
| 493 EXPECT_CALL(*stream4, OnCanWrite()); | 504 EXPECT_CALL(*stream4, OnCanWrite()); |
| 494 session_.OnCanWrite(); | 505 session_.OnCanWrite(); |
| 495 EXPECT_FALSE(session_.HasPendingWrites()); | 506 EXPECT_FALSE(session_.WillingAndAbleToWrite()); |
| 507 } | |
| 508 | |
| 509 TEST_P(QuicSessionTest, OnCanWriteLimitsNumWritesIfFlowControlBlocked) { | |
| 510 ValueRestore<bool> old_flag(&FLAGS_enable_quic_connection_flow_control, true); | |
| 511 if (version() < QUIC_VERSION_19) { | |
| 512 return; | |
| 513 } | |
| 514 | |
| 515 // Ensure connection level flow control blockage. | |
| 516 QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0); | |
| 517 EXPECT_TRUE(session_.flow_controller()->IsBlocked()); | |
| 518 | |
| 519 // Mark the crypto and headers streams as write blocked, we expect them to be | |
| 520 // allowed to write later. | |
| 521 session_.MarkWriteBlocked(kCryptoStreamId, kHighestPriority); | |
| 522 session_.MarkWriteBlocked(kHeadersStreamId, kHighestPriority); | |
| 523 | |
| 524 // Create a data stream, and although it is write blocked we never expect it | |
| 525 // to be allowed to write as we are connection level flow control blocked. | |
| 526 TestStream* stream = session_.CreateOutgoingDataStream(); | |
| 527 session_.MarkWriteBlocked(stream->id(), kSomeMiddlePriority); | |
| 528 EXPECT_CALL(*stream, OnCanWrite()).Times(0); | |
| 529 | |
| 530 // The crypto and headers streams should be called even though we are | |
| 531 // connection flow control blocked. | |
| 532 TestCryptoStream* crypto_stream = session_.GetCryptoStream(); | |
| 533 EXPECT_CALL(*crypto_stream, OnCanWrite()).Times(1); | |
| 534 TestHeadersStream* headers_stream = new TestHeadersStream(&session_); | |
| 535 QuicSessionPeer::SetHeadersStream(&session_, headers_stream); | |
| 536 EXPECT_CALL(*headers_stream, OnCanWrite()).Times(1); | |
| 537 | |
| 538 session_.OnCanWrite(); | |
| 539 EXPECT_FALSE(session_.WillingAndAbleToWrite()); | |
| 496 } | 540 } |
| 497 | 541 |
| 498 TEST_P(QuicSessionTest, SendGoAway) { | 542 TEST_P(QuicSessionTest, SendGoAway) { |
| 499 EXPECT_CALL(*connection_, | 543 EXPECT_CALL(*connection_, |
| 500 SendGoAway(QUIC_PEER_GOING_AWAY, 0u, "Going Away.")); | 544 SendGoAway(QUIC_PEER_GOING_AWAY, 0u, "Going Away.")); |
| 501 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away."); | 545 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away."); |
| 502 EXPECT_TRUE(session_.goaway_sent()); | 546 EXPECT_TRUE(session_.goaway_sent()); |
| 503 | 547 |
| 504 EXPECT_CALL(*connection_, | 548 EXPECT_CALL(*connection_, |
| 505 SendRstStream(3u, QUIC_STREAM_PEER_GOING_AWAY, 0)).Times(0); | 549 SendRstStream(3u, QUIC_STREAM_PEER_GOING_AWAY, 0)).Times(0); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 610 session_.config()->SetInitialFlowControlWindowToSend(kInvalidWindow); | 654 session_.config()->SetInitialFlowControlWindowToSend(kInvalidWindow); |
| 611 session_.config()->ToHandshakeMessage(&msg); | 655 session_.config()->ToHandshakeMessage(&msg); |
| 612 const QuicErrorCode error = | 656 const QuicErrorCode error = |
| 613 session_.config()->ProcessPeerHello(msg, CLIENT, &error_details); | 657 session_.config()->ProcessPeerHello(msg, CLIENT, &error_details); |
| 614 EXPECT_EQ(QUIC_NO_ERROR, error); | 658 EXPECT_EQ(QUIC_NO_ERROR, error); |
| 615 | 659 |
| 616 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_FLOW_CONTROL_ERROR)); | 660 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_FLOW_CONTROL_ERROR)); |
| 617 session_.OnConfigNegotiated(); | 661 session_.OnConfigNegotiated(); |
| 618 } | 662 } |
| 619 | 663 |
| 664 TEST_P(QuicSessionTest, InvalidFlowControlWindow) { | |
| 665 QuicConnection* connection = | |
| 666 new MockConnection(true, SupportedVersions(GetParam())); | |
| 667 | |
| 668 const uint32 kSmallerFlowControlWindow = kDefaultFlowControlSendWindow - 1; | |
| 669 TestSession session(connection, kSmallerFlowControlWindow); | |
| 670 | |
| 671 EXPECT_EQ(kDefaultFlowControlSendWindow, | |
| 672 session.max_flow_control_receive_window_bytes()); | |
| 673 } | |
| 674 | |
| 620 } // namespace | 675 } // namespace |
| 621 } // namespace test | 676 } // namespace test |
| 622 } // namespace net | 677 } // namespace net |
| OLD | NEW |