Index: net/quic/quic_connection_test.cc |
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc |
index f8bfc189c47270766d159d6d9d1c02a787c76c23..8984aa62d6a9c67ccf948b3cddaed0f958fddd65 100644 |
--- a/net/quic/quic_connection_test.cc |
+++ b/net/quic/quic_connection_test.cc |
@@ -311,6 +311,10 @@ class TestPacketWriter : public QuicPacketWriter { |
return framer_.connection_close_frames(); |
} |
+ const vector<QuicRstStreamFrame>& rst_stream_frames() const { |
+ return framer_.rst_stream_frames(); |
+ } |
+ |
const vector<QuicStreamFrame>& stream_frames() const { |
return framer_.stream_frames(); |
} |
@@ -2202,6 +2206,108 @@ TEST_P(QuicConnectionTest, RetransmitOnNack) { |
ProcessAckPacket(&nack_two); |
} |
+TEST_P(QuicConnectionTest, DoNotSendQueuedPacketForResetStream) { |
+ ValueRestore<bool> old_flag(&FLAGS_quic_do_not_retransmit_for_reset_streams, |
+ true); |
+ |
+ // Block the connection to queue the packet. |
+ BlockOnNextWrite(); |
+ |
+ QuicStreamId stream_id = 2; |
+ connection_.SendStreamDataWithString(stream_id, "foo", 0, !kFin, nullptr); |
+ |
+ // Now that there is a queued packet, reset the stream. |
+ connection_.SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 14); |
+ |
+ // Unblock the connection and verify that only the RST_STREAM is sent. |
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1); |
+ writer_->SetWritable(); |
+ connection_.OnCanWrite(); |
+ EXPECT_EQ(1u, writer_->frame_count()); |
+ EXPECT_EQ(1u, writer_->rst_stream_frames().size()); |
+} |
+ |
+TEST_P(QuicConnectionTest, DoNotRetransmitForResetStreamOnNack) { |
+ ValueRestore<bool> old_flag(&FLAGS_quic_do_not_retransmit_for_reset_streams, |
+ true); |
+ |
+ QuicStreamId stream_id = 2; |
+ QuicPacketSequenceNumber last_packet; |
+ SendStreamDataToPeer(stream_id, "foo", 0, !kFin, &last_packet); |
+ SendStreamDataToPeer(stream_id, "foos", 3, !kFin, &last_packet); |
+ SendStreamDataToPeer(stream_id, "fooos", 7, !kFin, &last_packet); |
+ |
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1); |
+ connection_.SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 14); |
+ |
+ // Lose a packet and ensure it does not trigger retransmission. |
+ QuicAckFrame nack_two = InitAckFrame(last_packet); |
+ NackPacket(last_packet - 1, &nack_two); |
+ SequenceNumberSet lost_packets; |
+ lost_packets.insert(last_packet - 1); |
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); |
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _)) |
+ .WillOnce(Return(lost_packets)); |
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _)); |
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0); |
+ ProcessAckPacket(&nack_two); |
+} |
+ |
+TEST_P(QuicConnectionTest, DoNotRetransmitForResetStreamOnRTO) { |
+ ValueRestore<bool> old_flag(&FLAGS_quic_do_not_retransmit_for_reset_streams, |
+ true); |
+ |
+ QuicStreamId stream_id = 2; |
+ QuicPacketSequenceNumber last_packet; |
+ SendStreamDataToPeer(stream_id, "foo", 0, !kFin, &last_packet); |
+ |
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1); |
+ connection_.SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 14); |
+ |
+ // Fire the RTO and verify that the RST_STREAM is resent, not stream data. |
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1); |
+ clock_.AdvanceTime(DefaultRetransmissionTime()); |
+ connection_.GetRetransmissionAlarm()->Fire(); |
+ EXPECT_EQ(1u, writer_->frame_count()); |
+ EXPECT_EQ(1u, writer_->rst_stream_frames().size()); |
+ EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id); |
+} |
+ |
+TEST_P(QuicConnectionTest, DoNotSendPendingRetransmissionForResetStream) { |
+ ValueRestore<bool> old_flag(&FLAGS_quic_do_not_retransmit_for_reset_streams, |
+ true); |
+ |
+ QuicStreamId stream_id = 2; |
+ QuicPacketSequenceNumber last_packet; |
+ SendStreamDataToPeer(stream_id, "foo", 0, !kFin, &last_packet); |
+ SendStreamDataToPeer(stream_id, "foos", 3, !kFin, &last_packet); |
+ BlockOnNextWrite(); |
+ connection_.SendStreamDataWithString(stream_id, "fooos", 7, !kFin, nullptr); |
+ |
+ // Lose a packet which will trigger a pending retransmission. |
+ QuicAckFrame ack = InitAckFrame(last_packet); |
+ NackPacket(last_packet - 1, &ack); |
+ SequenceNumberSet lost_packets; |
+ lost_packets.insert(last_packet - 1); |
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_)); |
+ EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _)) |
+ .WillOnce(Return(lost_packets)); |
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _)); |
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0); |
+ ProcessAckPacket(&ack); |
+ |
+ connection_.SendRstStream(stream_id, QUIC_STREAM_NO_ERROR, 14); |
+ |
+ // Unblock the connection and verify that the RST_STREAM is sent but not the |
+ // second data packet nor a retransmit. |
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1); |
+ writer_->SetWritable(); |
+ connection_.OnCanWrite(); |
+ EXPECT_EQ(1u, writer_->frame_count()); |
+ EXPECT_EQ(1u, writer_->rst_stream_frames().size()); |
+ EXPECT_EQ(stream_id, writer_->rst_stream_frames().front().stream_id); |
+} |
+ |
TEST_P(QuicConnectionTest, DiscardRetransmit) { |
QuicPacketSequenceNumber last_packet; |
SendStreamDataToPeer(1, "foo", 0, !kFin, &last_packet); // Packet 1 |