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