Index: net/quic/quic_connection_test.cc |
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc |
index 597664d777e243f67b8cdbd2f915ff6b2a56054c..6d982ce66891e9f77cbfe3d277ed654f71b683cd 100644 |
--- a/net/quic/quic_connection_test.cc |
+++ b/net/quic/quic_connection_test.cc |
@@ -501,6 +501,7 @@ class QuicConnectionTest : public ::testing::Test { |
void ProcessClosePacket(QuicPacketSequenceNumber number, |
QuicFecGroupNumber fec_group) { |
+ EXPECT_CALL(visitor_, OnCanWrite()).Times(1).WillOnce(Return(true)); |
scoped_ptr<QuicPacket> packet(ConstructClosePacket(number, fec_group)); |
scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket( |
ENCRYPTION_NONE, number, *packet)); |
@@ -549,7 +550,8 @@ class QuicConnectionTest : public ::testing::Test { |
if (((number - min_protected_packet) % 2) == 0) { |
for (size_t i = GetStartOfFecProtectedData( |
header_.public_header.guid_length, |
- header_.public_header.version_flag); |
+ header_.public_header.version_flag, |
+ header_.public_header.sequence_number_length); |
i < data_packet->length(); ++i) { |
data_packet->mutable_data()[i] ^= data_packet->data()[i]; |
} |
@@ -585,7 +587,11 @@ class QuicConnectionTest : public ::testing::Test { |
EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(AnyNumber()); |
} |
- QuicPacketEntropyHash ProcessAckPacket(QuicAckFrame* frame) { |
+ QuicPacketEntropyHash ProcessAckPacket(QuicAckFrame* frame, |
+ bool expect_writes) { |
+ if (expect_writes) { |
+ EXPECT_CALL(visitor_, OnCanWrite()).Times(1).WillOnce(Return(true)); |
+ } |
return ProcessFramePacket(QuicFrame(frame)); |
} |
@@ -747,7 +753,7 @@ TEST_F(QuicConnectionTest, PacketsOutOfOrderWithAdditionsAndLeastAwaiting) { |
// retransmitted, and will remove it from the missing list. |
creator_.set_sequence_number(5); |
QuicAckFrame frame(0, QuicTime::Zero(), 4); |
- ProcessAckPacket(&frame); |
+ ProcessAckPacket(&frame, true); |
// Force an ack to be sent. |
SendAckPacketToPeer(); |
@@ -776,7 +782,7 @@ TEST_F(QuicConnectionTest, TruncatedAck) { |
QuicConnectionPeer::GetSentEntropyHash(&connection_, 192) ^ |
QuicConnectionPeer::GetSentEntropyHash(&connection_, 191); |
- ProcessAckPacket(&frame); |
+ ProcessAckPacket(&frame, true); |
EXPECT_TRUE(QuicConnectionPeer::GetReceivedTruncatedAck(&connection_)); |
@@ -785,7 +791,7 @@ TEST_F(QuicConnectionTest, TruncatedAck) { |
QuicConnectionPeer::GetSentEntropyHash(&connection_, 192) ^ |
QuicConnectionPeer::GetSentEntropyHash(&connection_, 190); |
- ProcessAckPacket(&frame); |
+ ProcessAckPacket(&frame, true); |
EXPECT_FALSE(QuicConnectionPeer::GetReceivedTruncatedAck(&connection_)); |
} |
@@ -797,21 +803,21 @@ TEST_F(QuicConnectionTest, LeastUnackedLower) { |
// Start out saying the least unacked is 2 |
creator_.set_sequence_number(5); |
QuicAckFrame frame(0, QuicTime::Zero(), 2); |
- ProcessAckPacket(&frame); |
+ ProcessAckPacket(&frame, true); |
// Change it to 1, but lower the sequence number to fake out-of-order packets. |
// This should be fine. |
creator_.set_sequence_number(1); |
QuicAckFrame frame2(0, QuicTime::Zero(), 1); |
// The scheduler will not process out of order acks. |
- ProcessAckPacket(&frame2); |
+ ProcessAckPacket(&frame2, false); |
// Now claim it's one, but set the ordering so it was sent "after" the first |
// one. This should cause a connection error. |
EXPECT_CALL(visitor_, ConnectionClose(QUIC_INVALID_ACK_DATA, false)); |
EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)); |
creator_.set_sequence_number(7); |
- ProcessAckPacket(&frame2); |
+ ProcessAckPacket(&frame2, false); |
} |
TEST_F(QuicConnectionTest, LargestObservedLower) { |
@@ -825,12 +831,12 @@ TEST_F(QuicConnectionTest, LargestObservedLower) { |
frame.received_info.entropy_hash = QuicConnectionPeer::GetSentEntropyHash( |
&connection_, 2); |
EXPECT_CALL(visitor_, OnAck(_)); |
- ProcessAckPacket(&frame); |
+ ProcessAckPacket(&frame, true); |
// Now change it to 1, and it should cause a connection error. |
QuicAckFrame frame2(1, QuicTime::Zero(), 0); |
EXPECT_CALL(visitor_, ConnectionClose(QUIC_INVALID_ACK_DATA, false)); |
- ProcessAckPacket(&frame2); |
+ ProcessAckPacket(&frame2, false); |
} |
TEST_F(QuicConnectionTest, LeastUnackedGreaterThanPacketSequenceNumber) { |
@@ -839,7 +845,7 @@ TEST_F(QuicConnectionTest, LeastUnackedGreaterThanPacketSequenceNumber) { |
// Create an ack with least_unacked is 2 in packet number 1. |
creator_.set_sequence_number(0); |
QuicAckFrame frame(0, QuicTime::Zero(), 2); |
- ProcessAckPacket(&frame); |
+ ProcessAckPacket(&frame, false); |
} |
TEST_F(QuicConnectionTest, |
@@ -852,7 +858,7 @@ TEST_F(QuicConnectionTest, |
EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)); |
QuicAckFrame frame(0, QuicTime::Zero(), 1); |
frame.received_info.missing_packets.insert(3); |
- ProcessAckPacket(&frame); |
+ ProcessAckPacket(&frame, false); |
} |
TEST_F(QuicConnectionTest, AckUnsentData) { |
@@ -860,7 +866,7 @@ TEST_F(QuicConnectionTest, AckUnsentData) { |
EXPECT_CALL(visitor_, ConnectionClose(QUIC_INVALID_ACK_DATA, false)); |
EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)); |
QuicAckFrame frame(1, QuicTime::Zero(), 0); |
- ProcessAckPacket(&frame); |
+ ProcessAckPacket(&frame, false); |
} |
TEST_F(QuicConnectionTest, AckAll) { |
@@ -868,7 +874,7 @@ TEST_F(QuicConnectionTest, AckAll) { |
creator_.set_sequence_number(1); |
QuicAckFrame frame1(0, QuicTime::Zero(), 1); |
- ProcessAckPacket(&frame1); |
+ ProcessAckPacket(&frame1, true); |
} |
TEST_F(QuicConnectionTest, DontWaitForPacketsBefore) { |
@@ -903,7 +909,7 @@ TEST_F(QuicConnectionTest, BasicSending) { |
QuicAckFrame frame(3, QuicTime::Zero(), 0); |
frame.received_info.entropy_hash = |
QuicConnectionPeer::GetSentEntropyHash(&connection_, 3); |
- ProcessAckPacket(&frame); |
+ ProcessAckPacket(&frame, true); |
SendAckPacketToPeer(); // Packet 6 |
// As soon as we've acked one, we skip ack packets 2 and 3 and note lack of |
@@ -918,7 +924,7 @@ TEST_F(QuicConnectionTest, BasicSending) { |
QuicAckFrame frame2(6, QuicTime::Zero(), 0); |
frame2.received_info.entropy_hash = |
QuicConnectionPeer::GetSentEntropyHash(&connection_, 6); |
- ProcessAckPacket(&frame2); // Even parity triggers ack packet 7 |
+ ProcessAckPacket(&frame2, true); // Even parity triggers ack packet 7 |
// The least packet awaiting ack should now be 7 |
EXPECT_EQ(7u, last_ack()->sent_info.least_unacked); |
@@ -965,6 +971,58 @@ TEST_F(QuicConnectionTest, FECQueueing) { |
EXPECT_EQ(2u, connection_.NumQueuedPackets()); |
} |
+TEST_F(QuicConnectionTest, AbandonFECFromCongestionWindow) { |
+ connection_.options()->max_packets_per_fec_group = 1; |
+ // 1 Data and 1 FEC packet. |
+ EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(2); |
+ connection_.SendStreamData(1, "foo", 0, !kFin); |
+ |
+ // Larger timeout for FEC bytes to expire. |
+ const QuicTime::Delta retransmission_time = |
+ QuicTime::Delta::FromMilliseconds(5000); |
+ clock_.AdvanceTime(retransmission_time); |
+ |
+ // Send only data packet. |
+ EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(1); |
+ // Abandon both FEC and data packet. |
+ EXPECT_CALL(*send_algorithm_, AbandoningPacket(_, _)).Times(2); |
+ |
+ connection_.OnRetransmissionTimeout(); |
+} |
+ |
+TEST_F(QuicConnectionTest, DontAbandonAckedFEC) { |
+ connection_.options()->max_packets_per_fec_group = 1; |
+ const QuicPacketSequenceNumber sequence_number = |
+ QuicConnectionPeer::GetPacketCreator(&connection_)->sequence_number() + 1; |
+ |
+ // 1 Data and 1 FEC packet. |
+ EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(2); |
+ connection_.SendStreamData(1, "foo", 0, !kFin); |
+ |
+ QuicAckFrame ack_fec(2, QuicTime::Zero(), 1); |
+ // Data packet missing. |
+ ack_fec.received_info.missing_packets.insert(1); |
+ ack_fec.received_info.entropy_hash = |
+ QuicConnectionPeer::GetSentEntropyHash(&connection_, 2) ^ |
+ QuicConnectionPeer::GetSentEntropyHash(&connection_, 1); |
+ |
+ EXPECT_CALL(visitor_, OnAck(_)).Times(1); |
+ EXPECT_CALL(*send_algorithm_, OnIncomingAck(_, _, _)).Times(1); |
+ EXPECT_CALL(*send_algorithm_, OnIncomingLoss(_)).Times(1); |
+ |
+ ProcessAckPacket(&ack_fec, true); |
+ |
+ const QuicTime::Delta kDefaultRetransmissionTime = |
+ QuicTime::Delta::FromMilliseconds(5000); |
+ clock_.AdvanceTime(kDefaultRetransmissionTime); |
+ |
+ // Abandon only data packet, FEC has been acked. |
+ EXPECT_CALL(*send_algorithm_, AbandoningPacket(sequence_number, _)).Times(1); |
+ // Send only data packet. |
+ EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(1); |
+ connection_.OnRetransmissionTimeout(); |
+} |
+ |
TEST_F(QuicConnectionTest, FramePacking) { |
// Block the connection. |
helper_->SetSendAlarm( |
@@ -1069,9 +1127,9 @@ TEST_F(QuicConnectionTest, RetransmitOnNack) { |
QuicAckFrame ack_one(1, QuicTime::Zero(), 0); |
ack_one.received_info.entropy_hash = |
QuicConnectionPeer::GetSentEntropyHash(&connection_, 1); |
- ProcessAckPacket(&ack_one); |
- ProcessAckPacket(&ack_one); |
- ProcessAckPacket(&ack_one); |
+ ProcessAckPacket(&ack_one, true); |
+ ProcessAckPacket(&ack_one, true); |
+ ProcessAckPacket(&ack_one, true); |
expected_acks.clear(); |
expected_acks.insert(3); |
@@ -1085,14 +1143,14 @@ TEST_F(QuicConnectionTest, RetransmitOnNack) { |
QuicConnectionPeer::GetSentEntropyHash(&connection_, 3) ^ |
QuicConnectionPeer::GetSentEntropyHash(&connection_, 2) ^ |
QuicConnectionPeer::GetSentEntropyHash(&connection_, 1); |
- ProcessAckPacket(&nack_two); |
- ProcessAckPacket(&nack_two); |
+ ProcessAckPacket(&nack_two, true); |
+ ProcessAckPacket(&nack_two, true); |
// The third nack should trigger a retransimission. |
EXPECT_CALL(*send_algorithm_, |
SentPacket(_, _, second_packet_size - kQuicVersionSize, |
IS_RETRANSMISSION)).Times(1); |
- ProcessAckPacket(&nack_two); |
+ ProcessAckPacket(&nack_two, true); |
} |
TEST_F(QuicConnectionTest, RetransmitNackedLargestObserved) { |
@@ -1107,15 +1165,15 @@ TEST_F(QuicConnectionTest, RetransmitNackedLargestObserved) { |
frame.received_info.missing_packets.insert(largest_observed); |
frame.received_info.entropy_hash = QuicConnectionPeer::GetSentEntropyHash( |
&connection_, largest_observed - 1); |
- ProcessAckPacket(&frame); |
+ ProcessAckPacket(&frame, true); |
// Second udp packet will force an ack frame. |
EXPECT_CALL(*send_algorithm_, |
SentPacket(_, _, _, NOT_RETRANSMISSION)); |
- ProcessAckPacket(&frame); |
+ ProcessAckPacket(&frame, true); |
// Third nack should retransmit the largest observed packet. |
EXPECT_CALL(*send_algorithm_, SentPacket(_, _, packet_size - kQuicVersionSize, |
IS_RETRANSMISSION)); |
- ProcessAckPacket(&frame); |
+ ProcessAckPacket(&frame, true); |
} |
TEST_F(QuicConnectionTest, RetransmitNackedPacketsOnTruncatedAck) { |
@@ -1136,7 +1194,7 @@ TEST_F(QuicConnectionTest, RetransmitNackedPacketsOnTruncatedAck) { |
EXPECT_CALL(*send_algorithm_, OnIncomingAck(_, _, _)).Times(1); |
EXPECT_CALL(*send_algorithm_, OnIncomingLoss(_)).Times(1); |
EXPECT_CALL(visitor_, OnAck(_)).Times(1); |
- ProcessAckPacket(&frame); |
+ ProcessAckPacket(&frame, true); |
EXPECT_TRUE(QuicConnectionPeer::GetReceivedTruncatedAck(&connection_)); |
QuicConnectionPeer::SetMaxPacketsPerRetransmissionAlarm(&connection_, 200); |
@@ -1182,17 +1240,17 @@ TEST_F(QuicConnectionTest, LimitPacketsPerNack) { |
EXPECT_CALL(visitor_, OnAck(ContainerEq(expected_acks))); |
// Nack three times. |
- ProcessAckPacket(&nack); |
+ ProcessAckPacket(&nack, true); |
// The second call will trigger an ack. |
EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(1); |
- ProcessAckPacket(&nack); |
+ ProcessAckPacket(&nack, true); |
// The third call should trigger retransmitting 10 packets. |
EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(10); |
- ProcessAckPacket(&nack); |
+ ProcessAckPacket(&nack, true); |
// The fourth call should trigger retransmitting the 11th packet and an ack. |
EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(2); |
- ProcessAckPacket(&nack); |
+ ProcessAckPacket(&nack, true); |
} |
// Test sending multiple acks from the connection to the session. |
@@ -1228,7 +1286,7 @@ TEST_F(QuicConnectionTest, MultipleAcks) { |
expected_acks.insert(5); |
EXPECT_CALL(visitor_, OnAck(ContainerEq(expected_acks))); |
- ProcessAckPacket(&frame1); |
+ ProcessAckPacket(&frame1, true); |
// Now the client implicitly acks 2, and explicitly acks 6 |
QuicAckFrame frame2(6, QuicTime::Zero(), 0); |
@@ -1240,7 +1298,7 @@ TEST_F(QuicConnectionTest, MultipleAcks) { |
expected_acks.insert(6); |
EXPECT_CALL(visitor_, OnAck(ContainerEq(expected_acks))); |
- ProcessAckPacket(&frame2); |
+ ProcessAckPacket(&frame2, true); |
} |
TEST_F(QuicConnectionTest, DontLatchUnackedPacket) { |
@@ -1257,7 +1315,7 @@ TEST_F(QuicConnectionTest, DontLatchUnackedPacket) { |
QuicAckFrame frame(1, QuicTime::Zero(), 0); |
frame.received_info.entropy_hash = QuicConnectionPeer::GetSentEntropyHash( |
&connection_, 1); |
- ProcessAckPacket(&frame); |
+ ProcessAckPacket(&frame, true); |
// Verify that our internal state has least-unacked as 3. |
EXPECT_EQ(3u, outgoing_ack()->sent_info.least_unacked); |
@@ -1477,7 +1535,7 @@ TEST_F(QuicConnectionTest, TestRetransmissionCountCalculation) { |
ack.received_info.entropy_hash = QuicConnectionPeer::GetSentEntropyHash( |
&connection_, rto_sequence_number - 1); |
for (int i = 0; i < 3; i++) { |
- ProcessAckPacket(&ack); |
+ ProcessAckPacket(&ack, true); |
} |
EXPECT_FALSE(QuicConnectionPeer::IsSavedForRetransmission( |
&connection_, rto_sequence_number)); |
@@ -1528,7 +1586,7 @@ TEST_F(QuicConnectionTest, CloseFecGroup) { |
// Now send non-fec protected ack packet and close the group |
QuicAckFrame frame(0, QuicTime::Zero(), 5); |
creator_.set_sequence_number(4); |
- ProcessAckPacket(&frame); |
+ ProcessAckPacket(&frame, true); |
ASSERT_EQ(0u, connection_.NumFecGroups()); |
} |
@@ -1750,8 +1808,7 @@ TEST_F(QuicConnectionTest, SendSchedulerDelayThenAckAndSend) { |
testing::Return(QuicTime::Delta::Zero())); |
EXPECT_CALL(*send_algorithm_, |
SentPacket(_, _, _, _)); |
- EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(Return(true)); |
- ProcessAckPacket(&frame); |
+ ProcessAckPacket(&frame, true); |
EXPECT_EQ(0u, connection_.NumQueuedPackets()); |
// Ensure alarm is not set |
@@ -1773,7 +1830,7 @@ TEST_F(QuicConnectionTest, SendSchedulerDelayThenAckAndHold) { |
EXPECT_CALL(*send_algorithm_, |
TimeUntilSend(_, NOT_RETRANSMISSION, _)).WillOnce( |
testing::Return(QuicTime::Delta::FromMicroseconds(1))); |
- ProcessAckPacket(&frame); |
+ ProcessAckPacket(&frame, false); |
EXPECT_EQ(1u, connection_.NumQueuedPackets()); |
} |
@@ -1864,7 +1921,7 @@ TEST_F(QuicConnectionTest, MissingPacketsBeforeLeastUnacked) { |
QuicAckFrame ack(0, QuicTime::Zero(), 4); |
// Set the sequence number of the ack packet to be least unacked (4) |
creator_.set_sequence_number(3); |
- ProcessAckPacket(&ack); |
+ ProcessAckPacket(&ack, true); |
EXPECT_TRUE(outgoing_ack()->received_info.missing_packets.empty()); |
} |
@@ -1889,7 +1946,7 @@ TEST_F(QuicConnectionTest, UpdateEntropyForReceivedPackets) { |
ack.sent_info.entropy_hash = kRandomEntropyHash; |
creator_.set_sequence_number(5); |
QuicPacketEntropyHash six_packet_entropy_hash = 0; |
- if (ProcessAckPacket(&ack)) { |
+ if (ProcessAckPacket(&ack, true)) { |
six_packet_entropy_hash = 1 << 6; |
}; |
@@ -1908,7 +1965,7 @@ TEST_F(QuicConnectionTest, UpdateEntropyHashUptoCurrentPacket) { |
// Current packet is the least unacked packet. |
QuicAckFrame ack(0, QuicTime::Zero(), 23); |
ack.sent_info.entropy_hash = kRandomEntropyHash; |
- QuicPacketEntropyHash ack_entropy_hash = ProcessAckPacket(&ack); |
+ QuicPacketEntropyHash ack_entropy_hash = ProcessAckPacket(&ack, true); |
EXPECT_EQ((kRandomEntropyHash + ack_entropy_hash), |
outgoing_ack()->received_info.entropy_hash); |
ProcessDataPacket(25, 1, kEntropyFlag); |
@@ -2033,6 +2090,7 @@ TEST_F(QuicConnectionTest, CheckSendStats) { |
EXPECT_CALL(visitor_, OnAck(_)); |
EXPECT_CALL(*send_algorithm_, OnIncomingAck(_, _, _)).Times(1); |
EXPECT_CALL(*send_algorithm_, OnIncomingLoss(_)).Times(1); |
+ EXPECT_CALL(visitor_, OnCanWrite()).Times(3).WillRepeatedly(Return(true)); |
ProcessFramePacket(frame); |
ProcessFramePacket(frame); |
@@ -2122,6 +2180,7 @@ TEST_F(QuicConnectionTest, DontProcessFramesIfPacketClosedConnection) { |
scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket( |
ENCRYPTION_NONE, 1, *packet)); |
+ EXPECT_CALL(visitor_, OnCanWrite()).Times(1).WillOnce(Return(true)); |
EXPECT_CALL(visitor_, ConnectionClose(QUIC_PEER_GOING_AWAY, true)); |
EXPECT_CALL(visitor_, OnPacket(_, _, _, _)).Times(0); |