Index: net/quic/quic_sent_packet_manager_test.cc |
diff --git a/net/quic/quic_sent_packet_manager_test.cc b/net/quic/quic_sent_packet_manager_test.cc |
index ffc11e5739377f2d5aedcc51b040be10230f5ce3..b44334090a9fc9a9587c5a26f7d4f0e189f35461 100644 |
--- a/net/quic/quic_sent_packet_manager_test.cc |
+++ b/net/quic/quic_sent_packet_manager_test.cc |
@@ -22,6 +22,7 @@ using testing::Not; |
using testing::Pair; |
using testing::Pointwise; |
using testing::Return; |
+using testing::SetArgPointee; |
using testing::StrictMock; |
using testing::_; |
@@ -1548,6 +1549,73 @@ TEST_P(QuicSentPacketManagerTest, NegotiateNewRTOFromOptionsAtClient) { |
EXPECT_TRUE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_)); |
} |
+TEST_P(QuicSentPacketManagerTest, NegotiateUndoFromOptionsAtServer) { |
+ FLAGS_quic_loss_recovery_use_largest_acked = true; |
+ EXPECT_FALSE(QuicSentPacketManagerPeer::GetUndoRetransmits(&manager_)); |
+ QuicConfig config; |
+ QuicTagVector options; |
+ |
+ options.push_back(kUNDO); |
+ QuicConfigPeer::SetReceivedConnectionOptions(&config, options); |
+ EXPECT_CALL(*network_change_visitor_, OnCongestionChange()); |
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); |
+ manager_.SetFromConfig(config); |
+ EXPECT_TRUE(QuicSentPacketManagerPeer::GetUndoRetransmits(&manager_)); |
+ |
+ // Ensure undo works as intended. |
+ // Send 5 packets, mark the first 4 for retransmission, and then cancel |
+ // them when 1 is acked. |
+ EXPECT_CALL(*send_algorithm_, PacingRate()) |
+ .WillRepeatedly(Return(QuicBandwidth::Zero())); |
+ EXPECT_CALL(*send_algorithm_, GetCongestionWindow()) |
+ .WillOnce(Return(10 * kDefaultTCPMSS)); |
+ const size_t kNumSentPackets = 5; |
+ for (size_t i = 1; i <= kNumSentPackets; ++i) { |
+ SendDataPacket(i); |
+ } |
+ MockLossAlgorithm* loss_algorithm = new MockLossAlgorithm(); |
+ QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm); |
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _)); |
+ EXPECT_CALL(*network_change_visitor_, OnCongestionChange()); |
+ SendAlgorithmInterface::CongestionVector lost_packets; |
+ for (size_t i = 1; i < kNumSentPackets; ++i) { |
+ lost_packets.push_back(std::make_pair(i, kMaxPacketSize)); |
+ } |
+ EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _)) |
+ .WillOnce(SetArgPointee<4>(lost_packets)); |
+ QuicAckFrame ack_frame = InitAckFrame(kNumSentPackets); |
+ NackPackets(1, kNumSentPackets, &ack_frame); |
+ // Congestion block the sending right before losing the packets. |
+ EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _)) |
+ .WillRepeatedly(Return(QuicTime::Delta::Infinite())); |
+ manager_.OnIncomingAck(ack_frame, clock_.Now()); |
+ EXPECT_TRUE(manager_.HasPendingRetransmissions()); |
+ EXPECT_EQ(0u, BytesInFlight()); |
+ |
+ // Ack 1 and ensure the retransmissions are cancelled and put back in flight. |
+ EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _)); |
+ ack_frame = InitAckFrame(5); |
+ NackPackets(2, kNumSentPackets, &ack_frame); |
+ manager_.OnIncomingAck(ack_frame, clock_.Now()); |
+ EXPECT_FALSE(manager_.HasPendingRetransmissions()); |
+ EXPECT_EQ(3u * kDefaultLength, BytesInFlight()); |
+} |
+ |
+TEST_P(QuicSentPacketManagerTest, NegotiateUndoFromOptionsAtClient) { |
+ FLAGS_quic_loss_recovery_use_largest_acked = true; |
+ EXPECT_FALSE(QuicSentPacketManagerPeer::GetUndoRetransmits(&manager_)); |
+ QuicConfig client_config; |
+ QuicTagVector options; |
+ |
+ options.push_back(kUNDO); |
+ QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT); |
+ client_config.SetConnectionOptionsToSend(options); |
+ EXPECT_CALL(*network_change_visitor_, OnCongestionChange()); |
+ EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)); |
+ manager_.SetFromConfig(client_config); |
+ EXPECT_TRUE(QuicSentPacketManagerPeer::GetUndoRetransmits(&manager_)); |
+} |
+ |
TEST_P(QuicSentPacketManagerTest, |
NegotiateConservativeReceiveWindowFromOptions) { |
EXPECT_EQ(kDefaultSocketReceiveBuffer, |