Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(477)

Side by Side Diff: net/quic/quic_session_test.cc

Issue 285193006: Don't set QUIC's write alarm if we are connection flow control blocked. (Closed) Base URL: https://chromium.googlesource.com/chromium/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/quic/quic_session.cc ('k') | net/quic/quic_write_blocked_list.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/quic/quic_session.cc ('k') | net/quic/quic_write_blocked_list.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698