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);