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 |