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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 | 160 |
151 void set_writev_consumes_all_data(bool val) { | 161 void set_writev_consumes_all_data(bool val) { |
152 writev_consumes_all_data_ = val; | 162 writev_consumes_all_data_ = val; |
153 } | 163 } |
154 | 164 |
155 QuicConsumedData SendStreamData() { | 165 QuicConsumedData SendStreamData() { |
156 return WritevData(5, IOVector(), 0, true, NULL); | 166 return WritevData(5, IOVector(), 0, true, NULL); |
157 } | 167 } |
158 | 168 |
159 private: | 169 private: |
160 TestCryptoStream crypto_stream_; | 170 StrictMock<TestCryptoStream> crypto_stream_; |
161 | 171 |
162 bool writev_consumes_all_data_; | 172 bool writev_consumes_all_data_; |
163 }; | 173 }; |
164 | 174 |
165 class QuicSessionTest : public ::testing::TestWithParam<QuicVersion> { | 175 class QuicSessionTest : public ::testing::TestWithParam<QuicVersion> { |
166 protected: | 176 protected: |
167 QuicSessionTest() | 177 QuicSessionTest() |
168 : connection_(new MockConnection(true, SupportedVersions(GetParam()))), | 178 : connection_(new MockConnection(true, SupportedVersions(GetParam()))), |
169 session_(connection_, kInitialFlowControlWindowForTest) { | 179 session_(connection_, kInitialFlowControlWindowForTest) { |
170 headers_[":host"] = "www.google.com"; | 180 headers_[":host"] = "www.google.com"; |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); | 353 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); |
344 | 354 |
345 InSequence s; | 355 InSequence s; |
346 StreamBlocker stream2_blocker(&session_, stream2->id()); | 356 StreamBlocker stream2_blocker(&session_, stream2->id()); |
347 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce( | 357 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce( |
348 // Reregister, to test the loop limit. | 358 // Reregister, to test the loop limit. |
349 InvokeWithoutArgs(&stream2_blocker, &StreamBlocker::MarkWriteBlocked)); | 359 InvokeWithoutArgs(&stream2_blocker, &StreamBlocker::MarkWriteBlocked)); |
350 EXPECT_CALL(*stream6, OnCanWrite()); | 360 EXPECT_CALL(*stream6, OnCanWrite()); |
351 EXPECT_CALL(*stream4, OnCanWrite()); | 361 EXPECT_CALL(*stream4, OnCanWrite()); |
352 session_.OnCanWrite(); | 362 session_.OnCanWrite(); |
353 EXPECT_TRUE(session_.HasPendingWrites()); | 363 EXPECT_TRUE(session_.WillingAndAbleToWrite()); |
354 } | 364 } |
355 | 365 |
356 TEST_P(QuicSessionTest, OnCanWriteBundlesStreams) { | 366 TEST_P(QuicSessionTest, OnCanWriteBundlesStreams) { |
357 // Drive congestion control manually. | 367 // Drive congestion control manually. |
358 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; | 368 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; |
359 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm); | 369 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm); |
360 | 370 |
361 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 371 TestStream* stream2 = session_.CreateOutgoingDataStream(); |
362 TestStream* stream4 = session_.CreateOutgoingDataStream(); | 372 TestStream* stream4 = session_.CreateOutgoingDataStream(); |
363 TestStream* stream6 = session_.CreateOutgoingDataStream(); | 373 TestStream* stream6 = session_.CreateOutgoingDataStream(); |
(...skipping 13 matching lines...) Expand all Loading... |
377 InvokeWithoutArgs(&session_, &TestSession::SendStreamData))); | 387 InvokeWithoutArgs(&session_, &TestSession::SendStreamData))); |
378 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(IgnoreResult( | 388 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce(IgnoreResult( |
379 InvokeWithoutArgs(&session_, &TestSession::SendStreamData))); | 389 InvokeWithoutArgs(&session_, &TestSession::SendStreamData))); |
380 MockPacketWriter* writer = | 390 MockPacketWriter* writer = |
381 static_cast<MockPacketWriter*>( | 391 static_cast<MockPacketWriter*>( |
382 QuicConnectionPeer::GetWriter(session_.connection())); | 392 QuicConnectionPeer::GetWriter(session_.connection())); |
383 EXPECT_CALL(*writer, WritePacket(_, _, _, _)).WillOnce( | 393 EXPECT_CALL(*writer, WritePacket(_, _, _, _)).WillOnce( |
384 Return(WriteResult(WRITE_STATUS_OK, 0))); | 394 Return(WriteResult(WRITE_STATUS_OK, 0))); |
385 EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _)); | 395 EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _)); |
386 session_.OnCanWrite(); | 396 session_.OnCanWrite(); |
387 EXPECT_FALSE(session_.HasPendingWrites()); | 397 EXPECT_FALSE(session_.WillingAndAbleToWrite()); |
388 } | 398 } |
389 | 399 |
390 TEST_P(QuicSessionTest, OnCanWriteCongestionControlBlocks) { | 400 TEST_P(QuicSessionTest, OnCanWriteCongestionControlBlocks) { |
391 InSequence s; | 401 InSequence s; |
392 | 402 |
393 // Drive congestion control manually. | 403 // Drive congestion control manually. |
394 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; | 404 MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; |
395 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm); | 405 QuicConnectionPeer::SetSendAlgorithm(session_.connection(), send_algorithm); |
396 | 406 |
397 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 407 TestStream* stream2 = session_.CreateOutgoingDataStream(); |
398 TestStream* stream4 = session_.CreateOutgoingDataStream(); | 408 TestStream* stream4 = session_.CreateOutgoingDataStream(); |
399 TestStream* stream6 = session_.CreateOutgoingDataStream(); | 409 TestStream* stream6 = session_.CreateOutgoingDataStream(); |
400 | 410 |
401 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); | 411 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); |
402 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); | 412 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); |
403 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); | 413 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); |
404 | 414 |
405 StreamBlocker stream2_blocker(&session_, stream2->id()); | 415 StreamBlocker stream2_blocker(&session_, stream2->id()); |
406 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( | 416 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( |
407 QuicTime::Delta::Zero())); | 417 QuicTime::Delta::Zero())); |
408 EXPECT_CALL(*stream2, OnCanWrite()); | 418 EXPECT_CALL(*stream2, OnCanWrite()); |
409 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( | 419 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( |
410 QuicTime::Delta::Zero())); | 420 QuicTime::Delta::Zero())); |
411 EXPECT_CALL(*stream6, OnCanWrite()); | 421 EXPECT_CALL(*stream6, OnCanWrite()); |
412 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( | 422 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( |
413 QuicTime::Delta::Infinite())); | 423 QuicTime::Delta::Infinite())); |
414 // stream4->OnCanWrite is not called. | 424 // stream4->OnCanWrite is not called. |
415 | 425 |
416 session_.OnCanWrite(); | 426 session_.OnCanWrite(); |
417 EXPECT_TRUE(session_.HasPendingWrites()); | 427 EXPECT_TRUE(session_.WillingAndAbleToWrite()); |
418 | 428 |
419 // Still congestion-control blocked. | 429 // Still congestion-control blocked. |
420 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( | 430 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( |
421 QuicTime::Delta::Infinite())); | 431 QuicTime::Delta::Infinite())); |
422 session_.OnCanWrite(); | 432 session_.OnCanWrite(); |
423 EXPECT_TRUE(session_.HasPendingWrites()); | 433 EXPECT_TRUE(session_.WillingAndAbleToWrite()); |
424 | 434 |
425 // stream4->OnCanWrite is called once the connection stops being | 435 // stream4->OnCanWrite is called once the connection stops being |
426 // congestion-control blocked. | 436 // congestion-control blocked. |
427 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( | 437 EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _, _)).WillOnce(Return( |
428 QuicTime::Delta::Zero())); | 438 QuicTime::Delta::Zero())); |
429 EXPECT_CALL(*stream4, OnCanWrite()); | 439 EXPECT_CALL(*stream4, OnCanWrite()); |
430 session_.OnCanWrite(); | 440 session_.OnCanWrite(); |
431 EXPECT_FALSE(session_.HasPendingWrites()); | 441 EXPECT_FALSE(session_.WillingAndAbleToWrite()); |
432 } | 442 } |
433 | 443 |
434 TEST_P(QuicSessionTest, BufferedHandshake) { | 444 TEST_P(QuicSessionTest, BufferedHandshake) { |
435 EXPECT_FALSE(session_.HasPendingHandshake()); // Default value. | 445 EXPECT_FALSE(session_.HasPendingHandshake()); // Default value. |
436 | 446 |
437 // Test that blocking other streams does not change our status. | 447 // Test that blocking other streams does not change our status. |
438 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 448 TestStream* stream2 = session_.CreateOutgoingDataStream(); |
439 StreamBlocker stream2_blocker(&session_, stream2->id()); | 449 StreamBlocker stream2_blocker(&session_, stream2->id()); |
440 stream2_blocker.MarkWriteBlocked(); | 450 stream2_blocker.MarkWriteBlocked(); |
441 EXPECT_FALSE(session_.HasPendingHandshake()); | 451 EXPECT_FALSE(session_.HasPendingHandshake()); |
(...skipping 26 matching lines...) Expand all Loading... |
468 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce( | 478 EXPECT_CALL(*stream2, OnCanWrite()).WillOnce( |
469 InvokeWithoutArgs(&stream2_blocker, &StreamBlocker::MarkWriteBlocked)); | 479 InvokeWithoutArgs(&stream2_blocker, &StreamBlocker::MarkWriteBlocked)); |
470 | 480 |
471 EXPECT_CALL(*stream3, OnCanWrite()).WillOnce( | 481 EXPECT_CALL(*stream3, OnCanWrite()).WillOnce( |
472 InvokeWithoutArgs(&stream3_blocker, &StreamBlocker::MarkWriteBlocked)); | 482 InvokeWithoutArgs(&stream3_blocker, &StreamBlocker::MarkWriteBlocked)); |
473 | 483 |
474 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce( | 484 EXPECT_CALL(*stream4, OnCanWrite()).WillOnce( |
475 InvokeWithoutArgs(&stream4_blocker, &StreamBlocker::MarkWriteBlocked)); | 485 InvokeWithoutArgs(&stream4_blocker, &StreamBlocker::MarkWriteBlocked)); |
476 | 486 |
477 session_.OnCanWrite(); | 487 session_.OnCanWrite(); |
478 EXPECT_TRUE(session_.HasPendingWrites()); | 488 EXPECT_TRUE(session_.WillingAndAbleToWrite()); |
479 EXPECT_FALSE(session_.HasPendingHandshake()); // Crypto stream wrote. | 489 EXPECT_FALSE(session_.HasPendingHandshake()); // Crypto stream wrote. |
480 } | 490 } |
481 | 491 |
482 TEST_P(QuicSessionTest, OnCanWriteWithClosedStream) { | 492 TEST_P(QuicSessionTest, OnCanWriteWithClosedStream) { |
483 TestStream* stream2 = session_.CreateOutgoingDataStream(); | 493 TestStream* stream2 = session_.CreateOutgoingDataStream(); |
484 TestStream* stream4 = session_.CreateOutgoingDataStream(); | 494 TestStream* stream4 = session_.CreateOutgoingDataStream(); |
485 TestStream* stream6 = session_.CreateOutgoingDataStream(); | 495 TestStream* stream6 = session_.CreateOutgoingDataStream(); |
486 | 496 |
487 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); | 497 session_.MarkWriteBlocked(stream2->id(), kSomeMiddlePriority); |
488 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); | 498 session_.MarkWriteBlocked(stream6->id(), kSomeMiddlePriority); |
489 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); | 499 session_.MarkWriteBlocked(stream4->id(), kSomeMiddlePriority); |
490 CloseStream(stream6->id()); | 500 CloseStream(stream6->id()); |
491 | 501 |
492 InSequence s; | 502 InSequence s; |
493 EXPECT_CALL(*stream2, OnCanWrite()); | 503 EXPECT_CALL(*stream2, OnCanWrite()); |
494 EXPECT_CALL(*stream4, OnCanWrite()); | 504 EXPECT_CALL(*stream4, OnCanWrite()); |
495 session_.OnCanWrite(); | 505 session_.OnCanWrite(); |
496 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()); |
497 } | 540 } |
498 | 541 |
499 TEST_P(QuicSessionTest, SendGoAway) { | 542 TEST_P(QuicSessionTest, SendGoAway) { |
500 EXPECT_CALL(*connection_, | 543 EXPECT_CALL(*connection_, |
501 SendGoAway(QUIC_PEER_GOING_AWAY, 0u, "Going Away.")); | 544 SendGoAway(QUIC_PEER_GOING_AWAY, 0u, "Going Away.")); |
502 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away."); | 545 session_.SendGoAway(QUIC_PEER_GOING_AWAY, "Going Away."); |
503 EXPECT_TRUE(session_.goaway_sent()); | 546 EXPECT_TRUE(session_.goaway_sent()); |
504 | 547 |
505 EXPECT_CALL(*connection_, | 548 EXPECT_CALL(*connection_, |
506 SendRstStream(3u, QUIC_STREAM_PEER_GOING_AWAY, 0)).Times(0); | 549 SendRstStream(3u, QUIC_STREAM_PEER_GOING_AWAY, 0)).Times(0); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 const uint32 kSmallerFlowControlWindow = kDefaultFlowControlSendWindow - 1; | 668 const uint32 kSmallerFlowControlWindow = kDefaultFlowControlSendWindow - 1; |
626 TestSession session(connection, kSmallerFlowControlWindow); | 669 TestSession session(connection, kSmallerFlowControlWindow); |
627 | 670 |
628 EXPECT_EQ(kDefaultFlowControlSendWindow, | 671 EXPECT_EQ(kDefaultFlowControlSendWindow, |
629 session.max_flow_control_receive_window_bytes()); | 672 session.max_flow_control_receive_window_bytes()); |
630 } | 673 } |
631 | 674 |
632 } // namespace | 675 } // namespace |
633 } // namespace test | 676 } // namespace test |
634 } // namespace net | 677 } // namespace net |
OLD | NEW |