gfe-relnote: Do not include QPACK encoder stream data size in WriteHeaders() return value. Protected by gfe2_reloadable_flag_quic_writeheaders_excludes_encoder_stream_data.
This is necessary in order to enable QPACK dynamic table in QuicTestClient and QuicTestServer, see cl/306230335.
PiperOrigin-RevId: 308657464
Change-Id: I18098d3600fb9bcdcb5a65f269a96e09e4927d8a
diff --git a/quic/core/http/quic_spdy_stream_test.cc b/quic/core/http/quic_spdy_stream_test.cc
index 6d708d4..b0e2c66 100644
--- a/quic/core/http/quic_spdy_stream_test.cc
+++ b/quic/core/http/quic_spdy_stream_test.cc
@@ -39,6 +39,7 @@
using spdy::SpdyHeaderBlock;
using spdy::SpdyPriority;
using testing::_;
+using testing::AnyNumber;
using testing::AtLeast;
using testing::ElementsAre;
using testing::Invoke;
@@ -46,6 +47,7 @@
using testing::MatchesRegex;
using testing::Pair;
using testing::Return;
+using testing::SaveArg;
using testing::StrictMock;
namespace quic {
@@ -175,7 +177,8 @@
if (VersionUsesHttp3(transport_version())) {
// In this case, call QuicSpdyStream::WriteHeadersImpl() that does the
// actual work of closing the stream.
- QuicSpdyStream::WriteHeadersImpl(saved_headers_.Clone(), fin, nullptr);
+ return QuicSpdyStream::WriteHeadersImpl(saved_headers_.Clone(), fin,
+ nullptr);
}
return 0;
}
@@ -351,8 +354,7 @@
.Times(num_control_stream_writes);
}
TestCryptoStream* crypto_stream = session_->GetMutableCryptoStream();
- EXPECT_CALL(*crypto_stream, HasPendingRetransmission())
- .Times(testing::AnyNumber());
+ EXPECT_CALL(*crypto_stream, HasPendingRetransmission()).Times(AnyNumber());
if (connection_->version().HasHandshakeDone() &&
session_->perspective() == Perspective::IS_SERVER) {
@@ -2895,6 +2897,50 @@
kInvalidControlFrameId, stream_->id(), QUIC_STREAM_CANCELLED, 0));
}
+TEST_P(QuicSpdyStreamTest, WriteHeadersReturnValue) {
+ if (!UsesHttp3()) {
+ return;
+ }
+
+ Initialize(kShouldProcessData);
+ testing::InSequence s;
+
+ // Enable QPACK dynamic table.
+ session_->OnSetting(SETTINGS_QPACK_MAX_TABLE_CAPACITY, 1024);
+ session_->OnSetting(SETTINGS_QPACK_BLOCKED_STREAMS, 1);
+
+ EXPECT_CALL(*stream_, WriteHeadersMock(true));
+
+ QpackSendStream* encoder_stream =
+ QuicSpdySessionPeer::GetQpackEncoderSendStream(session_.get());
+ EXPECT_CALL(*session_, WritevData(encoder_stream->id(), _, _, _, _, _))
+ .Times(AnyNumber());
+
+ // HEADERS frame header.
+ EXPECT_CALL(*session_,
+ WritevData(stream_->id(), _, /* offset = */ 0, _, _, _));
+ // HEADERS frame payload.
+ size_t headers_frame_payload_length = 0;
+ EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
+ .WillOnce(
+ DoAll(SaveArg<1>(&headers_frame_payload_length),
+ Invoke(session_.get(), &MockQuicSpdySession::ConsumeData)));
+
+ SpdyHeaderBlock request_headers;
+ request_headers["foo"] = "bar";
+ size_t write_headers_return_value =
+ stream_->WriteHeaders(std::move(request_headers), /*fin=*/true, nullptr);
+ EXPECT_TRUE(stream_->fin_sent());
+
+ if (GetQuicReloadableFlag(quic_writeheaders_excludes_encoder_stream_data)) {
+ EXPECT_EQ(headers_frame_payload_length, write_headers_return_value);
+ } else {
+ // Return value of WriteHeaders includes length of dynamic table insertions
+ // written on encoder stream.
+ EXPECT_LT(headers_frame_payload_length, write_headers_return_value);
+ }
+}
+
} // namespace
} // namespace test
} // namespace quic