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