Prevent QuicSession from directly accessing streams' flow controller. This change provides the following advantages: 1. QuicSession is no longer able to go cross QuicStream to modify its flow controller, and is limited on what it can do with stream's flow controller. 2. QuicStream::IsFlowControlBlocked() can be potentially transitioned to a stream state. This CL also removes some tests in quic_spdy_session_test that are redundant with quic_session_test. No behavior change. not protected. PiperOrigin-RevId: 325899044 Change-Id: I1b676da2736507aec0a4438afdbc596ca274ed13
diff --git a/quic/core/http/end_to_end_test.cc b/quic/core/http/end_to_end_test.cc index 32aed2b..55bd75b 100644 --- a/quic/core/http/end_to_end_test.cc +++ b/quic/core/http/end_to_end_test.cc
@@ -573,12 +573,10 @@ } static void ExpectFlowControlsSynced(QuicStream* client, QuicStream* server) { - EXPECT_EQ( - QuicFlowControllerPeer::SendWindowSize(client->flow_controller()), - QuicFlowControllerPeer::ReceiveWindowSize(server->flow_controller())); - EXPECT_EQ( - QuicFlowControllerPeer::ReceiveWindowSize(client->flow_controller()), - QuicFlowControllerPeer::SendWindowSize(server->flow_controller())); + EXPECT_EQ(QuicStreamPeer::SendWindowSize(client), + QuicStreamPeer::ReceiveWindowSize(server)); + EXPECT_EQ(QuicStreamPeer::ReceiveWindowSize(client), + QuicStreamPeer::SendWindowSize(server)); } // Must be called before Initialize to have effect. @@ -1748,9 +1746,9 @@ QuicSpdyClientStream* stream = client_->GetOrCreateStream(); QuicSession* session = GetClientSession(); ASSERT_TRUE(session); - QuicFlowControllerPeer::SetSendWindowOffset(stream->flow_controller(), 0); + QuicStreamPeer::SetSendWindowOffset(stream, 0); QuicFlowControllerPeer::SetSendWindowOffset(session->flow_controller(), 0); - EXPECT_TRUE(stream->flow_controller()->IsBlocked()); + EXPECT_TRUE(stream->IsFlowControlBlocked()); EXPECT_TRUE(session->flow_controller()->IsBlocked()); // Make sure that the stream has data pending so that it will be marked as @@ -2404,8 +2402,7 @@ ->config() ->ReceivedInitialSessionFlowControlWindowBytes()); } - EXPECT_EQ(kServerStreamIFCW, QuicFlowControllerPeer::SendWindowOffset( - stream->flow_controller())); + EXPECT_EQ(kServerStreamIFCW, QuicStreamPeer::SendWindowOffset(stream)); QuicSpdyClientSession* client_session = GetClientSession(); ASSERT_TRUE(client_session); EXPECT_EQ(kServerSessionIFCW, QuicFlowControllerPeer::SendWindowOffset( @@ -2480,8 +2477,7 @@ client_session->config() ->ReceivedInitialSessionFlowControlWindowBytes()); } - EXPECT_EQ(kExpectedStreamIFCW, QuicFlowControllerPeer::SendWindowOffset( - stream->flow_controller())); + EXPECT_EQ(kExpectedStreamIFCW, QuicStreamPeer::SendWindowOffset(stream)); EXPECT_EQ(kExpectedSessionIFCW, QuicFlowControllerPeer::SendWindowOffset( client_session->flow_controller())); } @@ -2512,9 +2508,7 @@ // In v47 and later, the crypto handshake (sent in CRYPTO frames) is not // subject to flow control. if (!version_.UsesCryptoFrames()) { - EXPECT_LT(QuicFlowControllerPeer::SendWindowSize( - crypto_stream->flow_controller()), - kStreamIFCW); + EXPECT_LT(QuicStreamPeer::SendWindowSize(crypto_stream), kStreamIFCW); } // When stream type is enabled, control streams will send settings and // contribute to flow control windows, so this expectation is no longer valid. @@ -2535,9 +2529,7 @@ QuicHeadersStream* headers_stream = QuicSpdySessionPeer::GetHeadersStream(client_session); ASSERT_TRUE(headers_stream); - EXPECT_LT( - QuicFlowControllerPeer::SendWindowSize(headers_stream->flow_controller()), - kStreamIFCW); + EXPECT_LT(QuicStreamPeer::SendWindowSize(headers_stream), kStreamIFCW); EXPECT_EQ(kSessionIFCW, QuicFlowControllerPeer::SendWindowSize( client_session->flow_controller())); @@ -2618,29 +2610,25 @@ kDefaultMaxUncompressedHeaderSize); SpdySerializedFrame frame(spdy_framer.SerializeFrame(settings_frame)); - QuicFlowController* client_header_stream_flow_controller = - QuicSpdySessionPeer::GetHeadersStream(client_session) - ->flow_controller(); - QuicFlowController* server_header_stream_flow_controller = - QuicSpdySessionPeer::GetHeadersStream(server_session) - ->flow_controller(); + QuicHeadersStream* client_header_stream = + QuicSpdySessionPeer::GetHeadersStream(client_session); + QuicHeadersStream* server_header_stream = + QuicSpdySessionPeer::GetHeadersStream(server_session); // Both client and server are sending this SETTINGS frame, and the send // window is consumed. But because of timing issue, the server may send or // not send the frame, and the client may send/ not send / receive / not // receive the frame. // TODO(fayang): Rewrite this part because it is hacky. - QuicByteCount win_difference1 = QuicFlowControllerPeer::ReceiveWindowSize( - server_header_stream_flow_controller) - - QuicFlowControllerPeer::SendWindowSize( - client_header_stream_flow_controller); + QuicByteCount win_difference1 = + QuicStreamPeer::ReceiveWindowSize(server_header_stream) - + QuicStreamPeer::SendWindowSize(client_header_stream); if (win_difference1 != 0) { EXPECT_EQ(frame.size(), win_difference1); } - QuicByteCount win_difference2 = QuicFlowControllerPeer::ReceiveWindowSize( - client_header_stream_flow_controller) - - QuicFlowControllerPeer::SendWindowSize( - server_header_stream_flow_controller); + QuicByteCount win_difference2 = + QuicStreamPeer::ReceiveWindowSize(client_header_stream) - + QuicStreamPeer::SendWindowSize(server_header_stream); if (win_difference2 != 0) { EXPECT_EQ(frame.size(), win_difference2); } @@ -2649,14 +2637,12 @@ // TODO(fayang): Rewrite this part because it is hacky. float ratio1 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize( client_session->flow_controller())) / - QuicFlowControllerPeer::ReceiveWindowSize( - QuicSpdySessionPeer::GetHeadersStream(client_session) - ->flow_controller()); + QuicStreamPeer::ReceiveWindowSize( + QuicSpdySessionPeer::GetHeadersStream(client_session)); float ratio2 = static_cast<float>(QuicFlowControllerPeer::ReceiveWindowSize( client_session->flow_controller())) / - (QuicFlowControllerPeer::ReceiveWindowSize( - QuicSpdySessionPeer::GetHeadersStream(client_session) - ->flow_controller()) + + (QuicStreamPeer::ReceiveWindowSize( + QuicSpdySessionPeer::GetHeadersStream(client_session)) + frame.size()); EXPECT_TRUE(ratio1 == kSessionToStreamRatio || ratio2 == kSessionToStreamRatio);
diff --git a/quic/core/http/quic_spdy_client_session_test.cc b/quic/core/http/quic_spdy_client_session_test.cc index a6be1e6..70b7b36 100644 --- a/quic/core/http/quic_spdy_client_session_test.cc +++ b/quic/core/http/quic_spdy_client_session_test.cc
@@ -33,6 +33,7 @@ #include "net/third_party/quiche/src/quic/test_tools/quic_packet_creator_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h" +#include "net/third_party/quiche/src/quic/test_tools/quic_stream_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/simple_session_cache.h" #include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h" @@ -1031,7 +1032,7 @@ auto* control_stream = QuicSpdySessionPeer::GetSendControlStream(session_.get()); EXPECT_EQ(kInitialStreamFlowControlWindowForTest, - control_stream->flow_controller()->send_window_offset()); + QuicStreamPeer::SendWindowOffset(control_stream)); EXPECT_EQ(5u, session_->max_outbound_header_list_size()); } else { auto* id_manager = QuicSessionPeer::GetStreamIdManager(session_.get()); @@ -1064,7 +1065,7 @@ kHttp3StaticUnidirectionalStreamCount + 1, id_manager->max_outgoing_unidirectional_streams()); EXPECT_EQ(kInitialStreamFlowControlWindowForTest + 1, - control_stream->flow_controller()->send_window_offset()); + QuicStreamPeer::SendWindowOffset(control_stream)); } else { auto* id_manager = QuicSessionPeer::GetStreamIdManager(session_.get()); EXPECT_EQ(kDefaultMaxStreamsPerConnection + 1,
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc index ede4d2c..18d3d75 100644 --- a/quic/core/http/quic_spdy_session_test.cc +++ b/quic/core/http/quic_spdy_session_test.cc
@@ -1305,12 +1305,12 @@ // Create a stream, and send enough data to make it flow control blocked. TestStream* stream2 = session_.CreateOutgoingBidirectionalStream(); std::string body(kMinimumFlowControlSendWindow, '.'); - EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); + EXPECT_FALSE(stream2->IsFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AtLeast(1)); stream2->WriteOrBufferBody(body, false); - EXPECT_TRUE(stream2->flow_controller()->IsBlocked()); + EXPECT_TRUE(stream2->IsFlowControlBlocked()); EXPECT_TRUE(session_.IsConnectionFlowControlBlocked()); EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); @@ -1319,7 +1319,7 @@ CompleteHandshake(); EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id())); // Stream is now unblocked. - EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); + EXPECT_FALSE(stream2->IsFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); } @@ -1335,18 +1335,18 @@ // contains a larger send window offset, the stream becomes unblocked. session_.set_writev_consumes_all_data(true); TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream(); - EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); + EXPECT_FALSE(crypto_stream->IsFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); QuicHeadersStream* headers_stream = QuicSpdySessionPeer::GetHeadersStream(&session_); - EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); + EXPECT_FALSE(headers_stream->IsFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); EXPECT_CALL(*connection_, SendControlFrame(_)) .WillOnce(Invoke(&ClearControlFrame)); - for (QuicStreamId i = 0; - !crypto_stream->flow_controller()->IsBlocked() && i < 1000u; i++) { + for (QuicStreamId i = 0; !crypto_stream->IsFlowControlBlocked() && i < 1000u; + i++) { EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); QuicStreamOffset offset = crypto_stream->stream_bytes_written(); @@ -1358,8 +1358,8 @@ QuicDataWriter writer(1000, buf, quiche::NETWORK_BYTE_ORDER); crypto_stream->WriteStreamData(offset, crypto_message.size(), &writer); } - EXPECT_TRUE(crypto_stream->flow_controller()->IsBlocked()); - EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); + EXPECT_TRUE(crypto_stream->IsFlowControlBlocked()); + EXPECT_FALSE(headers_stream->IsFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); EXPECT_FALSE(session_.HasDataToWrite()); @@ -1371,7 +1371,7 @@ EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked( &session_, QuicUtils::GetCryptoStreamId(transport_version()))); // Stream is now unblocked and will no longer have buffered data. - EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); + EXPECT_FALSE(crypto_stream->IsFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); } @@ -1400,12 +1400,12 @@ // contains a larger send window offset, the stream becomes unblocked. session_.set_writev_consumes_all_data(true); TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream(); - EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); + EXPECT_FALSE(crypto_stream->IsFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); QuicHeadersStream* headers_stream = QuicSpdySessionPeer::GetHeadersStream(&session_); - EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); + EXPECT_FALSE(headers_stream->IsFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); QuicStreamId stream_id = 5; @@ -1414,7 +1414,7 @@ .WillOnce(Invoke(&ClearControlFrame)); SpdyHeaderBlock headers; SimpleRandom random; - while (!headers_stream->flow_controller()->IsBlocked() && stream_id < 2000) { + while (!headers_stream->IsFlowControlBlocked() && stream_id < 2000) { EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); headers["header"] = quiche::QuicheStrCat( @@ -1430,8 +1430,8 @@ spdy::SpdyStreamPrecedence(0), nullptr); EXPECT_TRUE(headers_stream->HasBufferedData()); - EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked()); - EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); + EXPECT_TRUE(headers_stream->IsFlowControlBlocked()); + EXPECT_FALSE(crypto_stream->IsFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); EXPECT_FALSE(session_.HasDataToWrite()); @@ -1441,7 +1441,7 @@ CompleteHandshake(); // Stream is now unblocked and will no longer have buffered data. - EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); + EXPECT_FALSE(headers_stream->IsFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); EXPECT_TRUE(headers_stream->HasBufferedData()); @@ -1495,119 +1495,6 @@ EXPECT_EQ(kByteOffset, session_.flow_controller()->bytes_consumed()); } -TEST_P(QuicSpdySessionTestServer, - ConnectionFlowControlAccountingFinAndLocalReset) { - // Test the situation where we receive a FIN on a stream, and before we fully - // consume all the data from the sequencer buffer we locally RST the stream. - // The bytes between highest consumed byte, and the final byte offset that we - // determined when the FIN arrived, should be marked as consumed at the - // connection level flow controller when the stream is reset. - TestStream* stream = session_.CreateOutgoingBidirectionalStream(); - - const QuicStreamOffset kByteOffset = - kInitialSessionFlowControlWindowForTest / 2 - 1; - QuicStreamFrame frame(stream->id(), true, kByteOffset, "."); - session_.OnStreamFrame(frame); - EXPECT_TRUE(connection_->connected()); - - EXPECT_EQ(0u, stream->flow_controller()->bytes_consumed()); - EXPECT_EQ(kByteOffset + frame.data_length, - stream->flow_controller()->highest_received_byte_offset()); - - // Reset stream locally. - EXPECT_CALL(*connection_, SendControlFrame(_)); - EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _)); - stream->Reset(QUIC_STREAM_CANCELLED); - EXPECT_EQ(kByteOffset + frame.data_length, - session_.flow_controller()->bytes_consumed()); -} - -TEST_P(QuicSpdySessionTestServer, ConnectionFlowControlAccountingFinAfterRst) { - CompleteHandshake(); - EXPECT_CALL(*connection_, SendControlFrame(_)) - .WillRepeatedly(Invoke(&ClearControlFrame)); - // Test that when we RST the stream (and tear down stream state), and then - // receive a FIN from the peer, we correctly adjust our connection level flow - // control receive window. - - // Connection starts with some non-zero highest received byte offset, - // due to other active streams. - const uint64_t kInitialConnectionBytesConsumed = 567; - const uint64_t kInitialConnectionHighestReceivedOffset = 1234; - EXPECT_LT(kInitialConnectionBytesConsumed, - kInitialConnectionHighestReceivedOffset); - session_.flow_controller()->UpdateHighestReceivedOffset( - kInitialConnectionHighestReceivedOffset); - session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); - - // Reset our stream: this results in the stream being closed locally. - TestStream* stream = session_.CreateOutgoingBidirectionalStream(); - if (VersionUsesHttp3(transport_version())) { - EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _)) - .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0))); - } - EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _)); - stream->Reset(QUIC_STREAM_CANCELLED); - - // Now receive a response from the peer with a FIN. We should handle this by - // adjusting the connection level flow control receive window to take into - // account the total number of bytes sent by the peer. - const QuicStreamOffset kByteOffset = 5678; - std::string body = "hello"; - QuicStreamFrame frame(stream->id(), true, kByteOffset, - quiche::QuicheStringPiece(body)); - session_.OnStreamFrame(frame); - - QuicStreamOffset total_stream_bytes_sent_by_peer = - kByteOffset + body.length(); - EXPECT_EQ(kInitialConnectionBytesConsumed + total_stream_bytes_sent_by_peer, - session_.flow_controller()->bytes_consumed()); - EXPECT_EQ( - kInitialConnectionHighestReceivedOffset + total_stream_bytes_sent_by_peer, - session_.flow_controller()->highest_received_byte_offset()); -} - -TEST_P(QuicSpdySessionTestServer, ConnectionFlowControlAccountingRstAfterRst) { - CompleteHandshake(); - // Test that when we RST the stream (and tear down stream state), and then - // receive a RST from the peer, we correctly adjust our connection level flow - // control receive window. - - // Connection starts with some non-zero highest received byte offset, - // due to other active streams. - const uint64_t kInitialConnectionBytesConsumed = 567; - const uint64_t kInitialConnectionHighestReceivedOffset = 1234; - EXPECT_LT(kInitialConnectionBytesConsumed, - kInitialConnectionHighestReceivedOffset); - session_.flow_controller()->UpdateHighestReceivedOffset( - kInitialConnectionHighestReceivedOffset); - session_.flow_controller()->AddBytesConsumed(kInitialConnectionBytesConsumed); - - // Reset our stream: this results in the stream being closed locally. - TestStream* stream = session_.CreateOutgoingBidirectionalStream(); - if (VersionUsesHttp3(transport_version())) { - EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _)) - .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0))); - } - EXPECT_CALL(*connection_, SendControlFrame(_)); - EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _)); - stream->Reset(QUIC_STREAM_CANCELLED); - EXPECT_TRUE(QuicStreamPeer::read_side_closed(stream)); - - // Now receive a RST from the peer. We should handle this by adjusting the - // connection level flow control receive window to take into account the total - // number of bytes sent by the peer. - const QuicStreamOffset kByteOffset = 5678; - QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(), - QUIC_STREAM_CANCELLED, kByteOffset); - session_.OnRstStream(rst_frame); - - EXPECT_EQ(kInitialConnectionBytesConsumed + kByteOffset, - session_.flow_controller()->bytes_consumed()); - EXPECT_EQ(kInitialConnectionHighestReceivedOffset + kByteOffset, - session_.flow_controller()->highest_received_byte_offset()); -} - TEST_P(QuicSpdySessionTestServer, InvalidStreamFlowControlWindowInHandshake) { if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) { // IETF Quic doesn't require a minimum flow control window. @@ -1624,22 +1511,6 @@ session_.OnConfigNegotiated(); } -TEST_P(QuicSpdySessionTestServer, InvalidSessionFlowControlWindowInHandshake) { - if (GetParam().handshake_protocol == PROTOCOL_TLS1_3) { - // IETF Quic doesn't require a minimum flow control window. - return; - } - // Test that receipt of an invalid (< default) session flow control window - // from the peer results in the connection being torn down. - const uint32_t kInvalidWindow = kMinimumFlowControlSendWindow - 1; - QuicConfigPeer::SetReceivedInitialSessionFlowControlWindow(session_.config(), - kInvalidWindow); - - EXPECT_CALL(*connection_, - CloseConnection(QUIC_FLOW_CONTROL_INVALID_WINDOW, _, _)); - session_.OnConfigNegotiated(); -} - TEST_P(QuicSpdySessionTestServer, TooLowUnidirectionalStreamLimitHttp3) { if (!VersionUsesHttp3(transport_version())) { return; @@ -1666,34 +1537,6 @@ session_.flow_controller())); } -TEST_P(QuicSpdySessionTestServer, FlowControlWithInvalidFinalOffset) { - CompleteHandshake(); - // Test that if we receive a stream RST with a highest byte offset that - // violates flow control, that we close the connection. - const uint64_t kLargeOffset = kInitialSessionFlowControlWindowForTest + 1; - EXPECT_CALL(*connection_, - CloseConnection(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA, _, _)) - .Times(2); - - // Check that stream frame + FIN results in connection close. - TestStream* stream = session_.CreateOutgoingBidirectionalStream(); - if (VersionUsesHttp3(transport_version())) { - EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _)) - .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0))); - } - EXPECT_CALL(*connection_, SendControlFrame(_)); - EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _)); - stream->Reset(QUIC_STREAM_CANCELLED); - QuicStreamFrame frame(stream->id(), true, kLargeOffset, - quiche::QuicheStringPiece()); - session_.OnStreamFrame(frame); - - // Check that RST results in connection close. - QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(), - QUIC_STREAM_CANCELLED, kLargeOffset); - session_.OnRstStream(rst_frame); -} - TEST_P(QuicSpdySessionTestServer, WindowUpdateUnblocksHeadersStream) { if (VersionUsesHttp3(transport_version())) { // The test relies on headers stream, which no longer exists in IETF QUIC. @@ -1706,9 +1549,8 @@ // Set the headers stream to be flow control blocked. QuicHeadersStream* headers_stream = QuicSpdySessionPeer::GetHeadersStream(&session_); - QuicFlowControllerPeer::SetSendWindowOffset(headers_stream->flow_controller(), - 0); - EXPECT_TRUE(headers_stream->flow_controller()->IsBlocked()); + QuicStreamPeer::SetSendWindowOffset(headers_stream, 0); + EXPECT_TRUE(headers_stream->IsFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); @@ -1717,7 +1559,7 @@ headers_stream->id(), 2 * kMinimumFlowControlSendWindow); session_.OnWindowUpdateFrame(window_update_frame); - EXPECT_FALSE(headers_stream->flow_controller()->IsBlocked()); + EXPECT_FALSE(headers_stream->IsFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); } @@ -2048,7 +1890,7 @@ EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_)); QuicStream* stream = session_.GetOrCreateStream(stream_id1); - EXPECT_EQ(1u, stream->flow_controller()->bytes_consumed()); + EXPECT_EQ(1u, QuicStreamPeer::bytes_consumed(stream)); EXPECT_EQ(1u, session_.flow_controller()->bytes_consumed()); // The same stream type can be encoded differently. @@ -2060,7 +1902,7 @@ EXPECT_EQ(2u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_)); stream = session_.GetOrCreateStream(stream_id2); - EXPECT_EQ(4u, stream->flow_controller()->bytes_consumed()); + EXPECT_EQ(4u, QuicStreamPeer::bytes_consumed(stream)); EXPECT_EQ(5u, session_.flow_controller()->bytes_consumed()); } @@ -2092,7 +1934,7 @@ session_.OnStreamFrame(data1); EXPECT_EQ(1u, QuicSessionPeer::GetNumOpenDynamicStreams(&session_)); QuicStream* stream = session_.GetOrCreateStream(stream_id); - EXPECT_EQ(3u, stream->flow_controller()->highest_received_byte_offset()); + EXPECT_EQ(3u, stream->highest_received_byte_offset()); } TEST_P(QuicSpdySessionTestServer, OnStreamFrameLost) {
diff --git a/quic/core/http/quic_spdy_stream.cc b/quic/core/http/quic_spdy_stream.cc index 7dfe1fe..259493f 100644 --- a/quic/core/http/quic_spdy_stream.cc +++ b/quic/core/http/quic_spdy_stream.cc
@@ -639,10 +639,9 @@ if (VersionUsesHttp3(transport_version())) { if (fin) { - OnStreamFrame( - QuicStreamFrame(id(), /* fin = */ true, - flow_controller()->highest_received_byte_offset(), - quiche::QuicheStringPiece())); + OnStreamFrame(QuicStreamFrame(id(), /* fin = */ true, + highest_received_byte_offset(), + quiche::QuicheStringPiece())); } return; } @@ -701,10 +700,9 @@ } trailers_decompressed_ = true; if (fin) { - const QuicStreamOffset offset = - VersionUsesHttp3(transport_version()) - ? flow_controller()->highest_received_byte_offset() - : final_byte_offset; + const QuicStreamOffset offset = VersionUsesHttp3(transport_version()) + ? highest_received_byte_offset() + : final_byte_offset; OnStreamFrame( QuicStreamFrame(id(), fin, offset, quiche::QuicheStringPiece())); }
diff --git a/quic/core/http/quic_spdy_stream_test.cc b/quic/core/http/quic_spdy_stream_test.cc index b556367..7746ff2 100644 --- a/quic/core/http/quic_spdy_stream_test.cc +++ b/quic/core/http/quic_spdy_stream_test.cc
@@ -827,7 +827,7 @@ EXPECT_EQ(body, std::string(static_cast<char*>(vec.iov_base), vec.iov_len)); stream_->MarkConsumed(body.length()); - EXPECT_EQ(data.length(), stream_->flow_controller()->bytes_consumed()); + EXPECT_EQ(data.length(), QuicStreamPeer::bytes_consumed(stream_)); } TEST_P(QuicSpdyStreamTest, ProcessHeadersAndConsumeMultipleBody) { @@ -848,7 +848,7 @@ stream_->MarkConsumed(body1.length() + body2.length()); EXPECT_EQ(data1.length() + data2.length(), - stream_->flow_controller()->bytes_consumed()); + QuicStreamPeer::bytes_consumed(stream_)); } TEST_P(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) { @@ -911,10 +911,8 @@ // Set a small flow control limit. const uint64_t kWindow = 36; - QuicFlowControllerPeer::SetSendWindowOffset(stream_->flow_controller(), - kWindow); - EXPECT_EQ(kWindow, QuicFlowControllerPeer::SendWindowOffset( - stream_->flow_controller())); + QuicStreamPeer::SetSendWindowOffset(stream_, kWindow); + EXPECT_EQ(kWindow, QuicStreamPeer::SendWindowOffset(stream_)); // Try to send more data than the flow control limit allows. const uint64_t kOverflow = 15; @@ -931,8 +929,7 @@ stream_->WriteOrBufferBody(body, false); // Should have sent as much as possible, resulting in no send window left. - EXPECT_EQ(0u, - QuicFlowControllerPeer::SendWindowSize(stream_->flow_controller())); + EXPECT_EQ(0u, QuicStreamPeer::SendWindowSize(stream_)); // And we should have queued the overflowed data. EXPECT_EQ(kOverflow + kHeaderLength, stream_->BufferedDataBytes()); @@ -950,12 +947,8 @@ // Set a small flow control receive window. const uint64_t kWindow = 36; - QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), - kWindow); - QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), - kWindow); - EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset( - stream_->flow_controller())); + QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow); + QuicStreamPeer::SetMaxReceiveWindow(stream_, kWindow); // Stream receives enough data to fill a fraction of the receive window. std::string body(kWindow / 3, 'a'); @@ -977,9 +970,8 @@ QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0, quiche::QuicheStringPiece(data)); stream_->OnStreamFrame(frame1); - EXPECT_EQ( - kWindow - (kWindow / 3) - header_length, - QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller())); + EXPECT_EQ(kWindow - (kWindow / 3) - header_length, + QuicStreamPeer::ReceiveWindowSize(stream_)); // Now receive another frame which results in the receive window being over // half full. This should all be buffered, decreasing the receive window but @@ -988,9 +980,8 @@ kWindow / 3 + header_length, quiche::QuicheStringPiece(data)); stream_->OnStreamFrame(frame2); - EXPECT_EQ( - kWindow - (2 * kWindow / 3) - 2 * header_length, - QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller())); + EXPECT_EQ(kWindow - (2 * kWindow / 3) - 2 * header_length, + QuicStreamPeer::ReceiveWindowSize(stream_)); } // Tests that on receipt of data, the stream updates its receive window offset @@ -1001,12 +992,8 @@ // Set a small flow control limit. const uint64_t kWindow = 36; - QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), - kWindow); - QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), - kWindow); - EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset( - stream_->flow_controller())); + QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow); + QuicStreamPeer::SetMaxReceiveWindow(stream_, kWindow); // Stream receives enough data to fill a fraction of the receive window. std::string body(kWindow / 3, 'a'); @@ -1029,9 +1016,8 @@ QuicStreamFrame frame1(GetNthClientInitiatedBidirectionalId(0), false, 0, quiche::QuicheStringPiece(data)); stream_->OnStreamFrame(frame1); - EXPECT_EQ( - kWindow - (kWindow / 3) - header_length, - QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller())); + EXPECT_EQ(kWindow - (kWindow / 3) - header_length, + QuicStreamPeer::ReceiveWindowSize(stream_)); // Now receive another frame which results in the receive window being over // half full. This will trigger the stream to increase its receive window @@ -1043,8 +1029,7 @@ EXPECT_CALL(*session_, SendWindowUpdate(_, _)); EXPECT_CALL(*connection_, SendControlFrame(_)); stream_->OnStreamFrame(frame2); - EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowSize( - stream_->flow_controller())); + EXPECT_EQ(kWindow, QuicStreamPeer::ReceiveWindowSize(stream_)); } // Tests that on receipt of data, the connection updates its receive window @@ -1055,14 +1040,10 @@ // Set a small flow control limit for streams and connection. const uint64_t kWindow = 36; - QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), - kWindow); - QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), - kWindow); - QuicFlowControllerPeer::SetReceiveWindowOffset(stream2_->flow_controller(), - kWindow); - QuicFlowControllerPeer::SetMaxReceiveWindow(stream2_->flow_controller(), - kWindow); + QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow); + QuicStreamPeer::SetMaxReceiveWindow(stream_, kWindow); + QuicStreamPeer::SetReceiveWindowOffset(stream2_, kWindow); + QuicStreamPeer::SetMaxReceiveWindow(stream2_, kWindow); QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(), kWindow); QuicFlowControllerPeer::SetMaxReceiveWindow(session_->flow_controller(), @@ -1130,8 +1111,7 @@ // Set a small flow control limit. const uint64_t kWindow = 50; - QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), - kWindow); + QuicStreamPeer::SetReceiveWindowOffset(stream_, kWindow); ProcessHeaders(false, headers_); @@ -1166,8 +1146,7 @@ // Set a small flow control window on streams, and connection. const uint64_t kStreamWindow = 50; const uint64_t kConnectionWindow = 10; - QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), - kStreamWindow); + QuicStreamPeer::SetReceiveWindowOffset(stream_, kStreamWindow); QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(), kConnectionWindow); @@ -1192,9 +1171,7 @@ Initialize(kShouldProcessData); // Set a flow control limit of zero. - QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), 0); - EXPECT_EQ(0u, QuicFlowControllerPeer::ReceiveWindowOffset( - stream_->flow_controller())); + QuicStreamPeer::SetReceiveWindowOffset(stream_, 0); // Send a frame with a FIN but no data. This should not be blocked. std::string body = "";
diff --git a/quic/core/quic_flow_controller.h b/quic/core/quic_flow_controller.h index daad3d9..1a45821 100644 --- a/quic/core/quic_flow_controller.h +++ b/quic/core/quic_flow_controller.h
@@ -194,7 +194,7 @@ // Used to dynamically enable receive window auto-tuning. bool auto_tune_receive_window_; - // The session's flow controller. null if this is stream id 0. + // The session's flow controller. Null if this is the session flow controller. // Not owned. QuicFlowControllerInterface* session_flow_controller_;
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc index 39d969c..59bf083 100644 --- a/quic/core/quic_session.cc +++ b/quic/core/quic_session.cc
@@ -566,7 +566,7 @@ bool QuicSession::CheckStreamWriteBlocked(QuicStream* stream) const { if (!stream->write_side_closed() && stream->HasBufferedData() && - !stream->flow_controller()->IsBlocked() && + !stream->IsFlowControlBlocked() && !write_blocked_streams_.IsStreamBlocked(stream->id())) { QUIC_DLOG(ERROR) << ENDPOINT << "stream " << stream->id() << " has buffered " << stream->BufferedDataBytes() @@ -654,7 +654,7 @@ QUIC_DVLOG(1) << ENDPOINT << "Removing stream " << currently_writing_stream_id_ << " from write-blocked list"; QuicStream* stream = GetOrCreateStream(currently_writing_stream_id_); - if (stream != nullptr && !stream->flow_controller()->IsBlocked()) { + if (stream != nullptr && !stream->IsFlowControlBlocked()) { // If the stream can't write all bytes it'll re-add itself to the blocked // list. uint64_t previous_bytes_written = stream->stream_bytes_written(); @@ -961,7 +961,7 @@ // perspective. Do not inform stream Id manager yet. DCHECK(!stream->was_draining()); InsertLocallyClosedStreamsHighestOffset( - stream_id, stream->flow_controller()->highest_received_byte_offset()); + stream_id, stream->highest_received_byte_offset()); if (!remove_zombie_streams_) { stream_map_.erase(it); } @@ -1310,11 +1310,10 @@ flow_controller_.UpdateReceiveWindowSize(session_window); // Inform all existing streams about the new window. for (auto const& kv : stream_map_) { - kv.second->flow_controller()->UpdateReceiveWindowSize(stream_window); + kv.second->UpdateReceiveWindowSize(stream_window); } if (!QuicVersionUsesCryptoFrames(transport_version())) { - GetMutableCryptoStream()->flow_controller()->UpdateReceiveWindowSize( - stream_window); + GetMutableCryptoStream()->UpdateReceiveWindowSize(stream_window); } } @@ -2048,12 +2047,12 @@ bool QuicSession::IsStreamFlowControlBlocked() { for (auto const& kv : stream_map_) { - if (kv.second->flow_controller()->IsBlocked()) { + if (kv.second->IsFlowControlBlocked()) { return true; } } if (!QuicVersionUsesCryptoFrames(transport_version()) && - GetMutableCryptoStream()->flow_controller()->IsBlocked()) { + GetMutableCryptoStream()->IsFlowControlBlocked()) { return true; } return false;
diff --git a/quic/core/quic_session_test.cc b/quic/core/quic_session_test.cc index 3973bd5..e8dbce5 100644 --- a/quic/core/quic_session_test.cc +++ b/quic/core/quic_session_test.cc
@@ -1598,12 +1598,12 @@ // Create a stream, and send enough data to make it flow control blocked. TestStream* stream2 = session_.CreateOutgoingBidirectionalStream(); std::string body(kMinimumFlowControlSendWindow, '.'); - EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); + EXPECT_FALSE(stream2->IsFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); EXPECT_CALL(*connection_, SendControlFrame(_)).Times(AtLeast(1)); stream2->WriteOrBufferData(body, false, nullptr); - EXPECT_TRUE(stream2->flow_controller()->IsBlocked()); + EXPECT_TRUE(stream2->IsFlowControlBlocked()); EXPECT_TRUE(session_.IsConnectionFlowControlBlocked()); EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); @@ -1613,7 +1613,7 @@ session_.GetMutableCryptoStream()->OnHandshakeMessage(msg); EXPECT_TRUE(QuicSessionPeer::IsStreamWriteBlocked(&session_, stream2->id())); // Stream is now unblocked. - EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); + EXPECT_FALSE(stream2->IsFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); } @@ -1629,15 +1629,15 @@ // contains a larger send window offset, the stream becomes unblocked. session_.set_writev_consumes_all_data(true); TestCryptoStream* crypto_stream = session_.GetMutableCryptoStream(); - EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); + EXPECT_FALSE(crypto_stream->IsFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); EXPECT_CALL(*connection_, SendControlFrame(_)) .WillOnce(Invoke(&ClearControlFrame)); - for (QuicStreamId i = 0; - !crypto_stream->flow_controller()->IsBlocked() && i < 1000u; i++) { + for (QuicStreamId i = 0; !crypto_stream->IsFlowControlBlocked() && i < 1000u; + i++) { EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); QuicStreamOffset offset = crypto_stream->stream_bytes_written(); @@ -1649,7 +1649,7 @@ QuicDataWriter writer(1000, buf, quiche::NETWORK_BYTE_ORDER); crypto_stream->WriteStreamData(offset, crypto_message.size(), &writer); } - EXPECT_TRUE(crypto_stream->flow_controller()->IsBlocked()); + EXPECT_TRUE(crypto_stream->IsFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); EXPECT_FALSE(session_.HasDataToWrite()); @@ -1663,7 +1663,7 @@ &session_, QuicUtils::GetCryptoStreamId(connection_->transport_version()))); // Stream is now unblocked and will no longer have buffered data. - EXPECT_FALSE(crypto_stream->flow_controller()->IsBlocked()); + EXPECT_FALSE(crypto_stream->IsFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); } @@ -1711,9 +1711,9 @@ session_.OnStreamFrame(frame); EXPECT_TRUE(connection_->connected()); - EXPECT_EQ(0u, stream->flow_controller()->bytes_consumed()); + EXPECT_EQ(0u, session_.flow_controller()->bytes_consumed()); EXPECT_EQ(kByteOffset + frame.data_length, - stream->flow_controller()->highest_received_byte_offset()); + stream->highest_received_byte_offset()); // Reset stream locally. EXPECT_CALL(*connection_, SendControlFrame(_)); @@ -3057,7 +3057,7 @@ // blocked. QuicSessionPeer::SetMaxOpenOutgoingBidirectionalStreams(&session_, 10); TestStream* stream2 = session_.CreateOutgoingBidirectionalStream(); - EXPECT_TRUE(stream2->flow_controller()->IsBlocked()); + EXPECT_TRUE(stream2->IsFlowControlBlocked()); EXPECT_TRUE(session_.IsConnectionFlowControlBlocked()); EXPECT_TRUE(session_.IsStreamFlowControlBlocked()); @@ -3069,7 +3069,7 @@ session_.OnConfigNegotiated(); // Stream is now unblocked. - EXPECT_FALSE(stream2->flow_controller()->IsBlocked()); + EXPECT_FALSE(stream2->IsFlowControlBlocked()); EXPECT_FALSE(session_.IsConnectionFlowControlBlocked()); EXPECT_FALSE(session_.IsStreamFlowControlBlocked()); }
diff --git a/quic/core/quic_stream.cc b/quic/core/quic_stream.cc index cafad49..c13c05c 100644 --- a/quic/core/quic_stream.cc +++ b/quic/core/quic_stream.cc
@@ -1313,20 +1313,28 @@ session_->SendStopSending(code, id_); } -QuicFlowController* QuicStream::flow_controller() { - if (flow_controller_.has_value()) { - return &flow_controller_.value(); +bool QuicStream::IsFlowControlBlocked() const { + if (!flow_controller_.has_value()) { + QUIC_BUG << "Trying to access non-existent flow controller."; + return false; } - QUIC_BUG << "Trying to access non-existent flow controller."; - return nullptr; + return flow_controller_->IsBlocked(); } -const QuicFlowController* QuicStream::flow_controller() const { - if (flow_controller_.has_value()) { - return &flow_controller_.value(); +QuicStreamOffset QuicStream::highest_received_byte_offset() const { + if (!flow_controller_.has_value()) { + QUIC_BUG << "Trying to access non-existent flow controller."; + return 0; } - QUIC_BUG << "Trying to access non-existent flow controller."; - return nullptr; + return flow_controller_->highest_received_byte_offset(); +} + +void QuicStream::UpdateReceiveWindowSize(QuicStreamOffset size) { + if (!flow_controller_.has_value()) { + QUIC_BUG << "Trying to access non-existent flow controller."; + return; + } + flow_controller_->UpdateReceiveWindowSize(size); } // static
diff --git a/quic/core/quic_stream.h b/quic/core/quic_stream.h index a01d163..3590190 100644 --- a/quic/core/quic_stream.h +++ b/quic/core/quic_stream.h
@@ -228,9 +228,10 @@ int num_frames_received() const; int num_duplicate_frames_received() const; - QuicFlowController* flow_controller(); - - const QuicFlowController* flow_controller() const; + // Flow controller related methods. + bool IsFlowControlBlocked() const; + QuicStreamOffset highest_received_byte_offset() const; + void UpdateReceiveWindowSize(QuicStreamOffset size); // Called when endpoint receives a frame which could increase the highest // offset.
diff --git a/quic/core/quic_stream_test.cc b/quic/core/quic_stream_test.cc index 1c76eb9..206fb71 100644 --- a/quic/core/quic_stream_test.cc +++ b/quic/core/quic_stream_test.cc
@@ -238,8 +238,7 @@ EXPECT_EQ(3u, stream.stream_bytes_read()); EXPECT_EQ(1, stream.num_duplicate_frames_received()); EXPECT_EQ(true, stream.fin_received()); - EXPECT_EQ(frame2.offset + 1, - stream.flow_controller()->highest_received_byte_offset()); + EXPECT_EQ(frame2.offset + 1, stream.highest_received_byte_offset()); EXPECT_EQ(frame2.offset + 1, session_->flow_controller()->highest_received_byte_offset()); } @@ -262,8 +261,7 @@ EXPECT_EQ(2, stream->num_frames_received()); EXPECT_EQ(2u, stream->stream_bytes_read()); EXPECT_EQ(true, stream->fin_received()); - EXPECT_EQ(frame2.offset + 1, - stream->flow_controller()->highest_received_byte_offset()); + EXPECT_EQ(frame2.offset + 1, stream->highest_received_byte_offset()); EXPECT_EQ(frame2.offset + 1, session_->flow_controller()->highest_received_byte_offset()); } @@ -523,16 +521,15 @@ // want to make sure we latch the largest offset we see. // Initially should be default. - EXPECT_EQ( - kMinimumFlowControlSendWindow, - QuicFlowControllerPeer::SendWindowOffset(stream_->flow_controller())); + EXPECT_EQ(kMinimumFlowControlSendWindow, + QuicStreamPeer::SendWindowOffset(stream_)); // Check a single WINDOW_UPDATE results in correct offset. QuicWindowUpdateFrame window_update_1(kInvalidControlFrameId, stream_->id(), kMinimumFlowControlSendWindow + 5); stream_->OnWindowUpdateFrame(window_update_1); - EXPECT_EQ(window_update_1.max_data, QuicFlowControllerPeer::SendWindowOffset( - stream_->flow_controller())); + EXPECT_EQ(window_update_1.max_data, + QuicStreamPeer::SendWindowOffset(stream_)); // Now send a few more WINDOW_UPDATES and make sure that only the largest is // remembered. @@ -545,8 +542,8 @@ stream_->OnWindowUpdateFrame(window_update_2); stream_->OnWindowUpdateFrame(window_update_3); stream_->OnWindowUpdateFrame(window_update_4); - EXPECT_EQ(window_update_3.max_data, QuicFlowControllerPeer::SendWindowOffset( - stream_->flow_controller())); + EXPECT_EQ(window_update_3.max_data, + QuicStreamPeer::SendWindowOffset(stream_)); } TEST_P(QuicStreamTest, FrameStats) { @@ -576,8 +573,7 @@ // higher than the receive window offset. QuicStreamFrame frame(stream_->id(), false, kInitialSessionFlowControlWindowForTest + 1, "."); - EXPECT_GT(frame.offset, QuicFlowControllerPeer::ReceiveWindowOffset( - stream_->flow_controller())); + EXPECT_GT(frame.offset, QuicStreamPeer::ReceiveWindowOffset(stream_)); // Stream should not accept the frame, and the connection should be closed. EXPECT_CALL(*connection_, @@ -607,9 +603,8 @@ QuicStreamFrame frame(stream_->id(), false, offset, data); stream_->OnStreamFrame(frame); } - EXPECT_LT( - kInitialStreamFlowControlWindowForTest, - QuicFlowControllerPeer::ReceiveWindowOffset(stream_->flow_controller())); + EXPECT_LT(kInitialStreamFlowControlWindowForTest, + QuicStreamPeer::ReceiveWindowOffset(stream_)); } TEST_P(QuicStreamTest, FinalByteOffsetFromFin) { @@ -664,7 +659,7 @@ const QuicStreamOffset kByteOffsetExceedingFlowControlWindow = kInitialSessionFlowControlWindowForTest + 1; const QuicStreamOffset current_stream_flow_control_offset = - QuicFlowControllerPeer::ReceiveWindowOffset(stream_->flow_controller()); + QuicStreamPeer::ReceiveWindowOffset(stream_); const QuicStreamOffset current_connection_flow_control_offset = QuicFlowControllerPeer::ReceiveWindowOffset(session_->flow_controller()); ASSERT_GT(kByteOffsetExceedingFlowControlWindow, @@ -681,9 +676,8 @@ EXPECT_TRUE(stream_->HasReceivedFinalOffset()); // The flow control receive offset values should not have changed. - EXPECT_EQ( - current_stream_flow_control_offset, - QuicFlowControllerPeer::ReceiveWindowOffset(stream_->flow_controller())); + EXPECT_EQ(current_stream_flow_control_offset, + QuicStreamPeer::ReceiveWindowOffset(stream_)); EXPECT_EQ( current_connection_flow_control_offset, QuicFlowControllerPeer::ReceiveWindowOffset(session_->flow_controller())); @@ -702,8 +696,7 @@ // Modify receive window offset and sequencer buffer total_bytes_read_ to // avoid flow control violation. - QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), - kMaxStreamLength + 5u); + QuicStreamPeer::SetReceiveWindowOffset(stream_, kMaxStreamLength + 5u); QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(), kMaxStreamLength + 5u); QuicStreamSequencerPeer::SetFrameBufferTotalBytesRead(
diff --git a/quic/test_tools/quic_stream_peer.cc b/quic/test_tools/quic_stream_peer.cc index 50eec57..aaf4bc3 100644 --- a/quic/test_tools/quic_stream_peer.cc +++ b/quic/test_tools/quic_stream_peer.cc
@@ -7,6 +7,8 @@ #include <list> #include "net/third_party/quiche/src/quic/core/quic_stream.h" +#include "net/third_party/quiche/src/quic/core/quic_types.h" +#include "net/third_party/quiche/src/quic/test_tools/quic_flow_controller_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_stream_send_buffer_peer.h" namespace quic { @@ -28,6 +30,52 @@ } // static +void QuicStreamPeer::SetSendWindowOffset(QuicStream* stream, + QuicStreamOffset offset) { + QuicFlowControllerPeer::SetSendWindowOffset(&*stream->flow_controller_, + offset); +} + +// static +QuicByteCount QuicStreamPeer::bytes_consumed(QuicStream* stream) { + return stream->flow_controller_->bytes_consumed(); +} + +// static +void QuicStreamPeer::SetReceiveWindowOffset(QuicStream* stream, + QuicStreamOffset offset) { + QuicFlowControllerPeer::SetReceiveWindowOffset(&*stream->flow_controller_, + offset); +} + +// static +void QuicStreamPeer::SetMaxReceiveWindow(QuicStream* stream, + QuicStreamOffset size) { + QuicFlowControllerPeer::SetMaxReceiveWindow(&*stream->flow_controller_, size); +} + +// static +QuicByteCount QuicStreamPeer::SendWindowSize(QuicStream* stream) { + return stream->flow_controller_->SendWindowSize(); +} + +// static +QuicStreamOffset QuicStreamPeer::ReceiveWindowOffset(QuicStream* stream) { + return QuicFlowControllerPeer::ReceiveWindowOffset( + &*stream->flow_controller_); +} + +// static +QuicByteCount QuicStreamPeer::ReceiveWindowSize(QuicStream* stream) { + return QuicFlowControllerPeer::ReceiveWindowSize(&*stream->flow_controller_); +} + +// static +QuicStreamOffset QuicStreamPeer::SendWindowOffset(QuicStream* stream) { + return stream->flow_controller_->send_window_offset(); +} + +// static bool QuicStreamPeer::read_side_closed(QuicStream* stream) { return stream->read_side_closed_; }
diff --git a/quic/test_tools/quic_stream_peer.h b/quic/test_tools/quic_stream_peer.h index e57825f..8d9a136 100644 --- a/quic/test_tools/quic_stream_peer.h +++ b/quic/test_tools/quic_stream_peer.h
@@ -10,6 +10,7 @@ #include "net/third_party/quiche/src/quic/core/quic_packets.h" #include "net/third_party/quiche/src/quic/core/quic_stream_send_buffer.h" #include "net/third_party/quiche/src/quic/core/quic_stream_sequencer.h" +#include "net/third_party/quiche/src/quic/core/quic_types.h" namespace quic { @@ -25,8 +26,17 @@ static void SetWriteSideClosed(bool value, QuicStream* stream); static void SetStreamBytesWritten(QuicStreamOffset stream_bytes_written, QuicStream* stream); + static void SetSendWindowOffset(QuicStream* stream, QuicStreamOffset offset); + static void SetReceiveWindowOffset(QuicStream* stream, + QuicStreamOffset offset); + static void SetMaxReceiveWindow(QuicStream* stream, QuicStreamOffset size); static bool read_side_closed(QuicStream* stream); static void CloseReadSide(QuicStream* stream); + static QuicByteCount bytes_consumed(QuicStream* stream); + static QuicByteCount ReceiveWindowSize(QuicStream* stream); + static QuicByteCount SendWindowSize(QuicStream* stream); + static QuicStreamOffset SendWindowOffset(QuicStream* stream); + static QuicStreamOffset ReceiveWindowOffset(QuicStream* stream); static bool StreamContributesToConnectionFlowControl(QuicStream* stream);