Allow QuicSession::WritevData() to write data at a specified encryption level.

gfe-relnote: protected by gfe2_reloadable_flag_quic_writevdata_at_level
PiperOrigin-RevId: 297697074
Change-Id: Ib4e5d860f22f506f36db76f4f8ee1c1e406f6a20
diff --git a/quic/core/quic_stream_test.cc b/quic/core/quic_stream_test.cc
index c7e650b..4055b4c 100644
--- a/quic/core/quic_stream_test.cc
+++ b/quic/core/quic_stream_test.cc
@@ -31,6 +31,7 @@
 #include "net/third_party/quiche/src/quic/test_tools/quic_stream_sequencer_peer.h"
 #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
+#include "net/third_party/quiche/src/common/platform/api/quiche_optional.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
 
 using testing::_;
@@ -122,11 +123,13 @@
            write_blocked_list_->HasWriteBlockedDataStreams();
   }
 
-  QuicConsumedData CloseStreamOnWriteError(QuicStreamId id,
-                                           size_t /*write_length*/,
-                                           QuicStreamOffset /*offset*/,
-                                           StreamSendingState /*state*/,
-                                           QuicByteCount /*bytes_written*/) {
+  QuicConsumedData CloseStreamOnWriteError(
+      QuicStreamId id,
+      size_t /*write_length*/,
+      QuicStreamOffset /*offset*/,
+      StreamSendingState /*state*/,
+      QuicByteCount /*bytes_written*/,
+      quiche::QuicheOptional<EncryptionLevel> /*level*/) {
     session_->CloseStream(id);
     return QuicConsumedData(1, false);
   }
@@ -277,7 +280,7 @@
               VARIABLE_LENGTH_INTEGER_LENGTH_0, 0u);
   connection_->SetMaxPacketLength(length);
 
-  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
       .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   stream_->WriteOrBufferData(kData1, false, nullptr);
   EXPECT_FALSE(HasWriteBlockedStreams());
@@ -299,9 +302,10 @@
 
   // Write some data and no fin.  If we consume some but not all of the data,
   // we should be write blocked a not all the data was consumed.
-  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
       .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 1u, 0u, NO_FIN, false);
+        return session_->ConsumeData(stream_->id(), 1u, 0u, NO_FIN, false,
+                                     QuicheNullOpt);
       }));
   stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 2), false,
                              nullptr);
@@ -317,9 +321,10 @@
   // we should be write blocked because the fin was not consumed.
   // (This should never actually happen as the fin should be sent out with the
   // last data)
-  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
       .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 2u, 0u, NO_FIN, false);
+        return session_->ConsumeData(stream_->id(), 2u, 0u, NO_FIN, false,
+                                     QuicheNullOpt);
       }));
   stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 2), true,
                              nullptr);
@@ -332,7 +337,7 @@
 
   // Write no data and a fin.  If we consume nothing we should be write blocked,
   // as the fin was not consumed.
-  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
       .WillOnce(Return(QuicConsumedData(0, false)));
   stream_->WriteOrBufferData(quiche::QuicheStringPiece(), true, nullptr);
   ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
@@ -344,7 +349,7 @@
   // Write some data and no fin. However, while writing the data
   // close the stream and verify that MarkConnectionLevelWriteBlocked does not
   // crash with an unknown stream.
-  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
       .WillOnce(Invoke(this, &QuicStreamTest::CloseStreamOnWriteError));
   stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 2), false,
                              nullptr);
@@ -364,10 +369,10 @@
               VARIABLE_LENGTH_INTEGER_LENGTH_0, 0u);
   connection_->SetMaxPacketLength(length);
 
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(InvokeWithoutArgs([this]() {
         return session_->ConsumeData(stream_->id(), kDataLen - 1, 0u, NO_FIN,
-                                     false);
+                                     false, QuicheNullOpt);
       }));
   stream_->WriteOrBufferData(kData1, false, nullptr);
 
@@ -380,20 +385,20 @@
   EXPECT_EQ(10u, stream_->BufferedDataBytes());
   // Make sure we get the tail of the first write followed by the bytes_consumed
   InSequence s;
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(InvokeWithoutArgs([this]() {
         return session_->ConsumeData(stream_->id(), kDataLen - 1, kDataLen - 1,
-                                     NO_FIN, false);
+                                     NO_FIN, false, QuicheNullOpt);
       }));
   EXPECT_CALL(*stream_, OnCanWriteNewData());
   stream_->OnCanWrite();
   EXPECT_TRUE(session_->HasUnackedStreamData());
 
   // And finally the end of the bytes_consumed.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(InvokeWithoutArgs([this]() {
         return session_->ConsumeData(stream_->id(), 2u, 2 * kDataLen - 2,
-                                     NO_FIN, false);
+                                     NO_FIN, false, QuicheNullOpt);
       }));
   EXPECT_CALL(*stream_, OnCanWriteNewData());
   stream_->OnCanWrite();
@@ -405,7 +410,7 @@
   std::string data("aaaaa");
   QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - data.length(),
                                         stream_);
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   stream_->WriteOrBufferData(data, false, nullptr);
   EXPECT_TRUE(session_->HasUnackedStreamData());
@@ -437,9 +442,10 @@
   EXPECT_FALSE(rst_sent());
 
   // Write some data, with no FIN.
-  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
       .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 1u, 0u, NO_FIN, false);
+        return session_->ConsumeData(stream_->id(), 1u, 0u, NO_FIN, false,
+                                     QuicheNullOpt);
       }));
   stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 1), false,
                              nullptr);
@@ -465,9 +471,10 @@
   EXPECT_FALSE(rst_sent());
 
   // Write some data, with FIN.
-  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
       .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 1u, 0u, FIN, false);
+        return session_->ConsumeData(stream_->id(), 1u, 0u, FIN, false,
+                                     QuicheNullOpt);
       }));
   stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 1), true,
                              nullptr);
@@ -730,9 +737,10 @@
   EXPECT_EQ(1u, session_->GetNumOpenIncomingStreams());
 
   // Outgoing data with FIN.
-  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
       .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 2u, 0u, FIN, false);
+        return session_->ConsumeData(stream_->id(), 2u, 0u, FIN, false,
+                                     QuicheNullOpt);
       }));
   stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 2), true,
                              nullptr);
@@ -748,9 +756,10 @@
   Initialize();
 
   // Outgoing data with FIN.
-  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(kTestStreamId, _, _, _, _, _))
       .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 2u, 0u, FIN, false);
+        return session_->ConsumeData(stream_->id(), 2u, 0u, FIN, false,
+                                     QuicheNullOpt);
       }));
   stream_->WriteOrBufferData(quiche::QuicheStringPiece(kData1, 2), true,
                              nullptr);
@@ -777,7 +786,7 @@
 
   Initialize();
   EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
 
   // Receive data for the request.
@@ -799,7 +808,7 @@
 
 TEST_P(QuicStreamTest, StreamWaitsForAcks) {
   Initialize();
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   // Stream is not waiting for acks initially.
   EXPECT_FALSE(stream_->IsWaitingForAcks());
@@ -856,7 +865,7 @@
 
 TEST_P(QuicStreamTest, StreamDataGetAckedOutOfOrder) {
   Initialize();
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   // Send data.
   stream_->WriteOrBufferData(kData1, false, nullptr);
@@ -898,7 +907,7 @@
 
 TEST_P(QuicStreamTest, CancelStream) {
   Initialize();
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   EXPECT_FALSE(stream_->IsWaitingForAcks());
   EXPECT_FALSE(session_->HasUnackedStreamData());
@@ -940,7 +949,7 @@
   }
 
   Initialize();
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   EXPECT_FALSE(stream_->IsWaitingForAcks());
   EXPECT_FALSE(session_->HasUnackedStreamData());
@@ -966,7 +975,7 @@
 
 TEST_P(QuicStreamTest, RstFrameReceivedStreamFinishSending) {
   Initialize();
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   EXPECT_FALSE(stream_->IsWaitingForAcks());
   EXPECT_FALSE(session_->HasUnackedStreamData());
@@ -989,7 +998,7 @@
 
 TEST_P(QuicStreamTest, ConnectionClosed) {
   Initialize();
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   EXPECT_FALSE(stream_->IsWaitingForAcks());
   EXPECT_FALSE(session_->HasUnackedStreamData());
@@ -1024,9 +1033,10 @@
   EXPECT_TRUE(stream_->CanWriteNewData());
 
   // Testing WriteOrBufferData.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 100u, 0u, NO_FIN, false);
+        return session_->ConsumeData(stream_->id(), 100u, 0u, NO_FIN, false,
+                                     QuicheNullOpt);
       }));
   stream_->WriteOrBufferData(data, false, nullptr);
   stream_->WriteOrBufferData(data, false, nullptr);
@@ -1036,9 +1046,10 @@
   // Verify all data is saved.
   EXPECT_EQ(3 * data.length() - 100, stream_->BufferedDataBytes());
 
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 100, 100u, NO_FIN, false);
+        return session_->ConsumeData(stream_->id(), 100, 100u, NO_FIN, false,
+                                     QuicheNullOpt);
       }));
   // Buffered data size > threshold, do not ask upper layer for more data.
   EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(0);
@@ -1049,10 +1060,10 @@
   // Send buffered data to make buffered data size < threshold.
   size_t data_to_write = 3 * data.length() - 200 -
                          GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1;
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(InvokeWithoutArgs([this, data_to_write]() {
         return session_->ConsumeData(stream_->id(), data_to_write, 200u, NO_FIN,
-                                     false);
+                                     false, QuicheNullOpt);
       }));
   // Buffered data size < threshold, ask upper layer for more data.
   EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
@@ -1063,7 +1074,7 @@
   EXPECT_TRUE(stream_->CanWriteNewData());
 
   // Flush all buffered data.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
   stream_->OnCanWrite();
@@ -1072,7 +1083,7 @@
   EXPECT_TRUE(stream_->CanWriteNewData());
 
   // Testing Writev.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(Return(QuicConsumedData(0, false)));
   struct iovec iov = {const_cast<char*>(data.data()), data.length()};
   QuicMemSliceStorage storage(
@@ -1087,7 +1098,7 @@
   EXPECT_EQ(data.length(), stream_->BufferedDataBytes());
   EXPECT_FALSE(stream_->CanWriteNewData());
 
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
   QuicMemSliceStorage storage2(
       &iov, 1, session_->connection()->helper()->GetStreamSendBufferAllocator(),
       1024);
@@ -1099,10 +1110,10 @@
 
   data_to_write =
       data.length() - GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1;
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(InvokeWithoutArgs([this, data_to_write]() {
         return session_->ConsumeData(stream_->id(), data_to_write, 0u, NO_FIN,
-                                     false);
+                                     false, QuicheNullOpt);
       }));
 
   EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
@@ -1112,7 +1123,7 @@
             stream_->BufferedDataBytes());
   EXPECT_TRUE(stream_->CanWriteNewData());
 
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
   // All data can be consumed as buffered data is below upper limit.
   QuicMemSliceStorage storage3(
       &iov, 1, session_->connection()->helper()->GetStreamSendBufferAllocator(),
@@ -1130,7 +1141,7 @@
   std::string data("aaaaa");
   QuicStreamPeer::SetStreamBytesWritten(kMaxStreamLength - data.length(),
                                         stream_);
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   struct iovec iov = {const_cast<char*>(data.data()), 5u};
   QuicMemSliceStorage storage(
@@ -1161,9 +1172,10 @@
   QuicMemSliceSpan span1 = vector1.span();
   QuicMemSliceSpan span2 = vector2.span();
 
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 100u, 0u, NO_FIN, false);
+        return session_->ConsumeData(stream_->id(), 100u, 0u, NO_FIN, false,
+                                     QuicheNullOpt);
       }));
   // There is no buffered data before, all data should be consumed.
   QuicConsumedData consumed = stream_->WriteMemSlices(span1, false);
@@ -1172,7 +1184,7 @@
   EXPECT_EQ(2 * QUICHE_ARRAYSIZE(data) - 100, stream_->BufferedDataBytes());
   EXPECT_FALSE(stream_->fin_buffered());
 
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
   // No Data can be consumed as buffered data is beyond upper limit.
   consumed = stream_->WriteMemSlices(span2, true);
   EXPECT_EQ(0u, consumed.bytes_consumed);
@@ -1182,10 +1194,10 @@
 
   size_t data_to_write = 2 * QUICHE_ARRAYSIZE(data) - 100 -
                          GetQuicFlag(FLAGS_quic_buffered_data_threshold) + 1;
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(InvokeWithoutArgs([this, data_to_write]() {
         return session_->ConsumeData(stream_->id(), data_to_write, 100u, NO_FIN,
-                                     false);
+                                     false, QuicheNullOpt);
       }));
   EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
   stream_->OnCanWrite();
@@ -1193,7 +1205,7 @@
                 GetQuicFlag(FLAGS_quic_buffered_data_threshold) - 1),
             stream_->BufferedDataBytes());
   // Try to write slices2 again.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _)).Times(0);
   consumed = stream_->WriteMemSlices(span2, true);
   EXPECT_EQ(2048u, consumed.bytes_consumed);
   EXPECT_TRUE(consumed.fin_consumed);
@@ -1203,7 +1215,7 @@
   EXPECT_TRUE(stream_->fin_buffered());
 
   // Flush all buffered data.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   stream_->OnCanWrite();
   EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(0);
@@ -1219,9 +1231,10 @@
   buffers.push_back(std::make_pair(data, QUICHE_ARRAYSIZE(data)));
   QuicTestMemSliceVector vector1(buffers);
   QuicMemSliceSpan span1 = vector1.span();
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 5u, 0u, NO_FIN, false);
+        return session_->ConsumeData(stream_->id(), 5u, 0u, NO_FIN, false,
+                                     QuicheNullOpt);
       }));
   // There is no buffered data before, all data should be consumed.
   QuicConsumedData consumed = stream_->WriteMemSlices(span1, false);
@@ -1238,7 +1251,7 @@
 
 TEST_P(QuicStreamTest, StreamDataGetAckedMultipleTimes) {
   Initialize();
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   EXPECT_FALSE(stream_->IsWaitingForAcks());
   EXPECT_FALSE(session_->HasUnackedStreamData());
@@ -1305,14 +1318,14 @@
   Initialize();
 
   // Send [0, 9).
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   stream_->WriteOrBufferData(kData1, false, nullptr);
   EXPECT_FALSE(stream_->HasBufferedData());
   EXPECT_TRUE(stream_->IsStreamFrameOutstanding(0, 9, false));
 
   // Try to send [9, 27), but connection is blocked.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(Return(QuicConsumedData(0, false)));
   stream_->WriteOrBufferData(kData2, false, nullptr);
   stream_->WriteOrBufferData(kData2, false, nullptr);
@@ -1323,7 +1336,7 @@
   // transmitted.
   stream_->OnStreamFrameLost(0, 9, false);
   EXPECT_TRUE(stream_->HasPendingRetransmission());
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   EXPECT_CALL(*stream_, OnCanWriteNewData()).Times(1);
   stream_->OnCanWrite();
@@ -1331,13 +1344,13 @@
   EXPECT_TRUE(stream_->HasBufferedData());
 
   // This OnCanWrite causes [9, 27) to be sent.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   stream_->OnCanWrite();
   EXPECT_FALSE(stream_->HasBufferedData());
 
   // Send a fin only frame.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   stream_->WriteOrBufferData("", true, nullptr);
 
@@ -1356,9 +1369,10 @@
   EXPECT_TRUE(stream_->HasPendingRetransmission());
   // This OnCanWrite causes [18, 27) and fin to be retransmitted. Verify fin can
   // be bundled with data.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 9u, 18u, FIN, false);
+        return session_->ConsumeData(stream_->id(), 9u, 18u, FIN, false,
+                                     QuicheNullOpt);
       }));
   stream_->OnCanWrite();
   EXPECT_FALSE(stream_->HasPendingRetransmission());
@@ -1373,7 +1387,7 @@
   Initialize();
 
   // Send [0, 18) and fin.
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   stream_->WriteOrBufferData(kData1, false, nullptr);
   stream_->WriteOrBufferData(kData2, true, nullptr);
@@ -1385,11 +1399,12 @@
   // Retransmit lost data. Verify [0, 9) and fin are retransmitted in two
   // frames.
   InSequence s;
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 9u, 0u, NO_FIN, false);
+        return session_->ConsumeData(stream_->id(), 9u, 0u, NO_FIN, false,
+                                     QuicheNullOpt);
       }));
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillOnce(Return(QuicConsumedData(0, true)));
   stream_->OnCanWrite();
 }
@@ -1408,7 +1423,7 @@
                                session_.get(), BIDIRECTIONAL);
   session_->ActivateStream(QuicWrapUnique(stream));
 
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   EXPECT_CALL(*connection_, SendControlFrame(_))
       .WillOnce(Invoke(&ClearControlFrame));
@@ -1442,7 +1457,7 @@
   session_->ActivateStream(QuicWrapUnique(stream));
 
   std::string data(100, '.');
-  EXPECT_CALL(*session_, WritevData(_, _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(_, _, _, _, _, _))
       .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   EXPECT_CALL(*connection_, SendControlFrame(_))
       .WillOnce(Invoke(&ClearControlFrame));
@@ -1462,7 +1477,7 @@
   InSequence s;
 
   // Send [0, 18) with fin.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _))
+  EXPECT_CALL(*session_, WritevData(stream_->id(), _, _, _, _, _))
       .Times(2)
       .WillRepeatedly(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   stream_->WriteOrBufferData(kData1, false, nullptr);
@@ -1473,23 +1488,24 @@
                               QuicTime::Zero(), &newly_acked_length);
   EXPECT_EQ(3u, newly_acked_length);
   // Retransmit [0, 18) with fin, and only [0, 8) is consumed.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), 10, 0, NO_FIN, _))
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 10, 0, NO_FIN, _, _))
       .WillOnce(InvokeWithoutArgs([this]() {
-        return session_->ConsumeData(stream_->id(), 8, 0u, NO_FIN, false);
+        return session_->ConsumeData(stream_->id(), 8, 0u, NO_FIN, false,
+                                     QuicheNullOpt);
       }));
   EXPECT_FALSE(stream_->RetransmitStreamData(0, 18, true));
 
   // Retransmit [0, 18) with fin, and all is consumed.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), 10, 0, NO_FIN, _))
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 10, 0, NO_FIN, _, _))
       .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  EXPECT_CALL(*session_, WritevData(stream_->id(), 5, 13, FIN, _))
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 5, 13, FIN, _, _))
       .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   EXPECT_TRUE(stream_->RetransmitStreamData(0, 18, true));
 
   // Retransmit [0, 8) with fin, and all is consumed.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), 8, 0, NO_FIN, _))
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 8, 0, NO_FIN, _, _))
       .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
-  EXPECT_CALL(*session_, WritevData(stream_->id(), 0, 18, FIN, _))
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 0, 18, FIN, _, _))
       .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   EXPECT_TRUE(stream_->RetransmitStreamData(0, 8, true));
 }
@@ -1497,7 +1513,7 @@
 TEST_P(QuicStreamTest, ResetStreamOnTtlExpiresRetransmitLostData) {
   Initialize();
 
-  EXPECT_CALL(*session_, WritevData(stream_->id(), 200, 0, FIN, _))
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 200, 0, FIN, _, _))
       .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   std::string body(200, 'a');
   stream_->WriteOrBufferData(body, true, nullptr);
@@ -1506,7 +1522,7 @@
   QuicTime::Delta ttl = QuicTime::Delta::FromSeconds(1);
   ASSERT_TRUE(stream_->MaybeSetTtl(ttl));
   // Verify data gets retransmitted because TTL does not expire.
-  EXPECT_CALL(*session_, WritevData(stream_->id(), 100, 0, NO_FIN, _))
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 100, 0, NO_FIN, _, _))
       .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   EXPECT_TRUE(stream_->RetransmitStreamData(0, 100, false));
   stream_->OnStreamFrameLost(100, 100, true);
@@ -1521,7 +1537,7 @@
 TEST_P(QuicStreamTest, ResetStreamOnTtlExpiresEarlyRetransmitData) {
   Initialize();
 
-  EXPECT_CALL(*session_, WritevData(stream_->id(), 200, 0, FIN, _))
+  EXPECT_CALL(*session_, WritevData(stream_->id(), 200, 0, FIN, _, _))
       .WillOnce(Invoke(session_.get(), &MockQuicSession::ConsumeData));
   std::string body(200, 'a');
   stream_->WriteOrBufferData(body, true, nullptr);