Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(381)

Unified Diff: net/quic/quic_connection_test.cc

Issue 839163003: Adds an alarm for sending a QUIC FEC packet. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@Tell_QUIC_AckNotifierManager_83525991
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/quic/quic_connection.cc ('k') | net/quic/quic_packet_creator.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/quic/quic_connection_test.cc
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc
index dbb29212cf52d78d833b804387b1d27edc7fd21d..63cf071578ead3cadf7629bc6f8b999ba7bb6d8e 100644
--- a/net/quic/quic_connection_test.cc
+++ b/net/quic/quic_connection_test.cc
@@ -24,6 +24,7 @@
#include "net/quic/test_tools/quic_connection_peer.h"
#include "net/quic/test_tools/quic_framer_peer.h"
#include "net/quic/test_tools/quic_packet_creator_peer.h"
+#include "net/quic/test_tools/quic_packet_generator_peer.h"
#include "net/quic/test_tools/quic_sent_packet_manager_peer.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/quic/test_tools/simple_quic_framer.h"
@@ -564,6 +565,11 @@ class TestConnection : public QuicConnection {
QuicConnectionPeer::GetPingAlarm(this));
}
+ TestConnectionHelper::TestAlarm* GetFecAlarm() {
+ return reinterpret_cast<TestConnectionHelper::TestAlarm*>(
+ QuicConnectionPeer::GetFecAlarm(this));
+ }
+
TestConnectionHelper::TestAlarm* GetResumeWritesAlarm() {
return reinterpret_cast<TestConnectionHelper::TestAlarm*>(
QuicConnectionPeer::GetResumeWritesAlarm(this));
@@ -633,8 +639,15 @@ class QuicConnectionTest : public ::testing::TestWithParam<QuicVersion> {
helper_(new TestConnectionHelper(&clock_, &random_generator_)),
writer_(new TestPacketWriter(version(), &clock_)),
factory_(writer_.get()),
- connection_(connection_id_, IPEndPoint(), helper_.get(),
- factory_, false, version()),
+ connection_(connection_id_,
+ IPEndPoint(),
+ helper_.get(),
+ factory_,
+ false,
+ version()),
+ creator_(QuicConnectionPeer::GetPacketCreator(&connection_)),
+ generator_(QuicConnectionPeer::GetPacketGenerator(&connection_)),
+ manager_(QuicConnectionPeer::GetSentPacketManager(&connection_)),
frame1_(1, false, 0, MakeIOVector(data1)),
frame2_(1, false, 3, MakeIOVector(data2)),
sequence_number_length_(PACKET_6BYTE_SEQUENCE_NUMBER),
@@ -834,8 +847,7 @@ class QuicConnectionTest : public ::testing::TestWithParam<QuicVersion> {
.WillOnce(DoAll(SaveArg<3>(&packet_size), Return(true)));
connection_.SendStreamDataWithString(id, data, offset, fin, nullptr);
if (last_packet != nullptr) {
- *last_packet =
- QuicConnectionPeer::GetPacketCreator(&connection_)->sequence_number();
+ *last_packet = creator_->sequence_number();
}
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
.Times(AnyNumber());
@@ -1024,6 +1036,9 @@ class QuicConnectionTest : public ::testing::TestWithParam<QuicVersion> {
scoped_ptr<TestPacketWriter> writer_;
NiceMock<MockPacketWriterFactory> factory_;
TestConnection connection_;
+ QuicPacketCreator* creator_;
+ QuicPacketGenerator* generator_;
+ QuicSentPacketManager* manager_;
StrictMock<MockConnectionVisitor> visitor_;
QuicPacketHeader header_;
@@ -1174,10 +1189,8 @@ TEST_P(QuicConnectionTest, TruncatedAck) {
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
ProcessAckPacket(&frame);
- const QuicSentPacketManager& sent_packet_manager =
- connection_.sent_packet_manager();
// A truncated ack will not have the true largest observed.
- EXPECT_GT(num_packets, sent_packet_manager.largest_observed());
+ EXPECT_GT(num_packets, manager_->largest_observed());
AckPacket(192, &frame);
@@ -1187,7 +1200,7 @@ TEST_P(QuicConnectionTest, TruncatedAck) {
.WillOnce(Return(SequenceNumberSet()));
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
ProcessAckPacket(&frame);
- EXPECT_EQ(num_packets, sent_packet_manager.largest_observed());
+ EXPECT_EQ(num_packets, manager_->largest_observed());
}
TEST_P(QuicConnectionTest, AckReceiptCausesAckSendBadEntropy) {
@@ -1415,12 +1428,10 @@ TEST_P(QuicConnectionTest, AckAll) {
TEST_P(QuicConnectionTest, SendingDifferentSequenceNumberLengthsBandwidth) {
QuicPacketSequenceNumber last_packet;
- QuicPacketCreator* creator =
- QuicConnectionPeer::GetPacketCreator(&connection_);
SendStreamDataToPeer(1, "foo", 0, !kFin, &last_packet);
EXPECT_EQ(1u, last_packet);
EXPECT_EQ(PACKET_1BYTE_SEQUENCE_NUMBER,
- creator->next_sequence_number_length());
+ creator_->next_sequence_number_length());
EXPECT_EQ(PACKET_1BYTE_SEQUENCE_NUMBER,
writer_->header().public_header.sequence_number_length);
@@ -1430,7 +1441,7 @@ TEST_P(QuicConnectionTest, SendingDifferentSequenceNumberLengthsBandwidth) {
SendStreamDataToPeer(1, "bar", 3, !kFin, &last_packet);
EXPECT_EQ(2u, last_packet);
EXPECT_EQ(PACKET_2BYTE_SEQUENCE_NUMBER,
- creator->next_sequence_number_length());
+ creator_->next_sequence_number_length());
// The 1 packet lag is due to the sequence number length being recalculated in
// QuicConnection after a packet is sent.
EXPECT_EQ(PACKET_1BYTE_SEQUENCE_NUMBER,
@@ -1442,7 +1453,7 @@ TEST_P(QuicConnectionTest, SendingDifferentSequenceNumberLengthsBandwidth) {
SendStreamDataToPeer(1, "foo", 6, !kFin, &last_packet);
EXPECT_EQ(3u, last_packet);
EXPECT_EQ(PACKET_4BYTE_SEQUENCE_NUMBER,
- creator->next_sequence_number_length());
+ creator_->next_sequence_number_length());
EXPECT_EQ(PACKET_2BYTE_SEQUENCE_NUMBER,
writer_->header().public_header.sequence_number_length);
@@ -1452,7 +1463,7 @@ TEST_P(QuicConnectionTest, SendingDifferentSequenceNumberLengthsBandwidth) {
SendStreamDataToPeer(1, "bar", 9, !kFin, &last_packet);
EXPECT_EQ(4u, last_packet);
EXPECT_EQ(PACKET_4BYTE_SEQUENCE_NUMBER,
- creator->next_sequence_number_length());
+ creator_->next_sequence_number_length());
EXPECT_EQ(PACKET_4BYTE_SEQUENCE_NUMBER,
writer_->header().public_header.sequence_number_length);
@@ -1462,7 +1473,7 @@ TEST_P(QuicConnectionTest, SendingDifferentSequenceNumberLengthsBandwidth) {
SendStreamDataToPeer(1, "foo", 12, !kFin, &last_packet);
EXPECT_EQ(5u, last_packet);
EXPECT_EQ(PACKET_6BYTE_SEQUENCE_NUMBER,
- creator->next_sequence_number_length());
+ creator_->next_sequence_number_length());
EXPECT_EQ(PACKET_4BYTE_SEQUENCE_NUMBER,
writer_->header().public_header.sequence_number_length);
}
@@ -1472,44 +1483,42 @@ TEST_P(QuicConnectionTest, SendingDifferentSequenceNumberLengthsBandwidth) {
TEST_P(QuicConnectionTest,
DISABLED_SendingDifferentSequenceNumberLengthsUnackedDelta) {
QuicPacketSequenceNumber last_packet;
- QuicPacketCreator* creator =
- QuicConnectionPeer::GetPacketCreator(&connection_);
SendStreamDataToPeer(1, "foo", 0, !kFin, &last_packet);
EXPECT_EQ(1u, last_packet);
EXPECT_EQ(PACKET_1BYTE_SEQUENCE_NUMBER,
- creator->next_sequence_number_length());
+ creator_->next_sequence_number_length());
EXPECT_EQ(PACKET_1BYTE_SEQUENCE_NUMBER,
writer_->header().public_header.sequence_number_length);
- creator->set_sequence_number(100);
+ creator_->set_sequence_number(100);
SendStreamDataToPeer(1, "bar", 3, !kFin, &last_packet);
EXPECT_EQ(PACKET_2BYTE_SEQUENCE_NUMBER,
- creator->next_sequence_number_length());
+ creator_->next_sequence_number_length());
EXPECT_EQ(PACKET_1BYTE_SEQUENCE_NUMBER,
writer_->header().public_header.sequence_number_length);
- creator->set_sequence_number(100 * 256);
+ creator_->set_sequence_number(100 * 256);
SendStreamDataToPeer(1, "foo", 6, !kFin, &last_packet);
EXPECT_EQ(PACKET_4BYTE_SEQUENCE_NUMBER,
- creator->next_sequence_number_length());
+ creator_->next_sequence_number_length());
EXPECT_EQ(PACKET_2BYTE_SEQUENCE_NUMBER,
writer_->header().public_header.sequence_number_length);
- creator->set_sequence_number(100 * 256 * 256);
+ creator_->set_sequence_number(100 * 256 * 256);
SendStreamDataToPeer(1, "bar", 9, !kFin, &last_packet);
EXPECT_EQ(PACKET_4BYTE_SEQUENCE_NUMBER,
- creator->next_sequence_number_length());
+ creator_->next_sequence_number_length());
EXPECT_EQ(PACKET_4BYTE_SEQUENCE_NUMBER,
writer_->header().public_header.sequence_number_length);
- creator->set_sequence_number(100 * 256 * 256 * 256);
+ creator_->set_sequence_number(100 * 256 * 256 * 256);
SendStreamDataToPeer(1, "foo", 12, !kFin, &last_packet);
EXPECT_EQ(PACKET_6BYTE_SEQUENCE_NUMBER,
- creator->next_sequence_number_length());
+ creator_->next_sequence_number_length());
EXPECT_EQ(PACKET_4BYTE_SEQUENCE_NUMBER,
writer_->header().public_header.sequence_number_length);
}
@@ -1635,8 +1644,6 @@ TEST_P(QuicConnectionTest, RecordSentTimeBeforePacketSent) {
TEST_P(QuicConnectionTest, FECSending) {
// All packets carry version info till version is negotiated.
- QuicPacketCreator* creator =
- QuicConnectionPeer::GetPacketCreator(&connection_);
size_t payload_length;
// GetPacketLengthForOneStream() assumes a stream offset of 0 in determining
// packet length. The size of the offset field in a stream frame is 0 for
@@ -1647,7 +1654,7 @@ TEST_P(QuicConnectionTest, FECSending) {
connection_.version(), kIncludeVersion,
PACKET_8BYTE_CONNECTION_ID, PACKET_1BYTE_SEQUENCE_NUMBER,
IN_FEC_GROUP, &payload_length);
- creator->set_max_packet_length(length);
+ creator_->set_max_packet_length(length);
// Send 4 protected data packets, which should also trigger 1 FEC packet.
EXPECT_CALL(*send_algorithm_,
@@ -1656,58 +1663,107 @@ TEST_P(QuicConnectionTest, FECSending) {
const string payload(payload_length * 4 + 2, 'a');
connection_.SendStreamDataWithStringWithFec(1, payload, 0, !kFin, nullptr);
// Expect the FEC group to be closed after SendStreamDataWithString.
- EXPECT_FALSE(creator->IsFecGroupOpen());
- EXPECT_FALSE(creator->IsFecProtected());
+ EXPECT_FALSE(creator_->IsFecGroupOpen());
+ EXPECT_FALSE(creator_->IsFecProtected());
}
TEST_P(QuicConnectionTest, FECQueueing) {
// All packets carry version info till version is negotiated.
size_t payload_length;
- QuicPacketCreator* creator =
- QuicConnectionPeer::GetPacketCreator(&connection_);
size_t length = GetPacketLengthForOneStream(
connection_.version(), kIncludeVersion,
PACKET_8BYTE_CONNECTION_ID, PACKET_1BYTE_SEQUENCE_NUMBER,
IN_FEC_GROUP, &payload_length);
- creator->set_max_packet_length(length);
- EXPECT_TRUE(creator->IsFecEnabled());
+ creator_->set_max_packet_length(length);
+ EXPECT_TRUE(creator_->IsFecEnabled());
EXPECT_EQ(0u, connection_.NumQueuedPackets());
BlockOnNextWrite();
const string payload(payload_length, 'a');
connection_.SendStreamDataWithStringWithFec(1, payload, 0, !kFin, nullptr);
- EXPECT_FALSE(creator->IsFecGroupOpen());
- EXPECT_FALSE(creator->IsFecProtected());
+ EXPECT_FALSE(creator_->IsFecGroupOpen());
+ EXPECT_FALSE(creator_->IsFecProtected());
// Expect the first data packet and the fec packet to be queued.
EXPECT_EQ(2u, connection_.NumQueuedPackets());
}
+TEST_P(QuicConnectionTest, FECAlarmStoppedWhenFECPacketSent) {
+ EXPECT_TRUE(creator_->IsFecEnabled());
+ EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
+ EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
+
+ creator_->set_max_packets_per_fec_group(2);
+
+ // 1 Data packet. FEC alarm should be set.
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ connection_.SendStreamDataWithStringWithFec(3, "foo", 0, true, nullptr);
+ EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
+
+ // Second data packet triggers FEC packet out. FEC alarm should not be set.
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(2);
+ connection_.SendStreamDataWithStringWithFec(5, "foo", 0, true, nullptr);
+ EXPECT_TRUE(writer_->header().fec_flag);
+ EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, FECAlarmStoppedOnConnectionClose) {
+ EXPECT_TRUE(creator_->IsFecEnabled());
+ EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
+ creator_->set_max_packets_per_fec_group(100);
+
+ // 1 Data packet. FEC alarm should be set.
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ connection_.SendStreamDataWithStringWithFec(3, "foo", 0, kFin, nullptr);
+ EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
+
+ EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_NO_ERROR, false));
+ // Closing connection should stop the FEC alarm.
+ connection_.CloseConnection(QUIC_NO_ERROR, /*from_peer=*/false);
+ EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
+}
+
TEST_P(QuicConnectionTest, RemoveFECFromInflightOnRetransmissionTimeout) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_TRUE(QuicConnectionPeer::GetPacketCreator(
- &connection_)->IsFecEnabled());
- QuicSentPacketManager* manager =
- QuicConnectionPeer::GetSentPacketManager(&connection_);
- EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager));
+ EXPECT_TRUE(creator_->IsFecEnabled());
+ EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
+ EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
- // 1 Data and 1 FEC packet.
+ // 1 Data packet. FEC alarm should be set.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(2);
+ OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
connection_.SendStreamDataWithStringWithFec(3, "foo", 0, !kFin, nullptr);
- size_t data_and_fec = QuicSentPacketManagerPeer::GetBytesInFlight(manager);
- EXPECT_LT(0u, data_and_fec);
+ EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
+ size_t protected_packet =
+ QuicSentPacketManagerPeer::GetBytesInFlight(manager_);
+ // Force FEC timeout to send FEC packet out.
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, 2u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ connection_.GetFecAlarm()->Fire();
+ EXPECT_TRUE(writer_->header().fec_flag);
+
+ size_t fec_packet = protected_packet;
+ EXPECT_EQ(protected_packet + fec_packet,
+ QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
clock_.AdvanceTime(DefaultRetransmissionTime());
- // On RTO, both data and FEC packets are removed from inflight,
- // and retransmission of the data (but not FEC) gets added into the inflight.
+ // On RTO, both data and FEC packets are removed from inflight, only the data
+ // packet is retransmitted, and this retransmission (but not FEC) gets added
+ // back into the inflight.
EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
connection_.GetRetransmissionAlarm()->Fire();
- size_t data_only = QuicSentPacketManagerPeer::GetBytesInFlight(manager);
- EXPECT_LT(0u, data_only);
- EXPECT_GE(data_and_fec, 2 * data_only);
+ // The retransmission of packet 1 will be 3 bytes smaller than packet 1, since
+ // the first transmission will have 1 byte for FEC group number and 2 bytes of
+ // stream frame size, which are absent in the retransmission.
+ size_t retransmitted_packet = protected_packet - 3;
+ EXPECT_EQ(retransmitted_packet,
+ QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
+ EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
// Receive ack for the retransmission. No data should be outstanding.
QuicAckFrame ack = InitAckFrame(3);
@@ -1718,34 +1774,53 @@ TEST_P(QuicConnectionTest, RemoveFECFromInflightOnRetransmissionTimeout) {
.WillOnce(Return(lost_packets));
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
ProcessAckPacket(&ack);
- EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager));
+ EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
// Ensure the alarm is not set since all packets have been acked or abandoned.
EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
- EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager));
+ EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
}
TEST_P(QuicConnectionTest, RemoveFECFromInflightOnLossRetransmission) {
- EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_TRUE(QuicConnectionPeer::GetPacketCreator(
- &connection_)->IsFecEnabled());
- QuicSentPacketManager* manager =
- QuicConnectionPeer::GetSentPacketManager(&connection_);
+ EXPECT_TRUE(creator_->IsFecEnabled());
+ EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
- // 1 Data packet and 1 FEC packet, followed by more data to trigger NACKs.
+ // 1 FEC-protected data packet. FEC alarm should be set.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(6);
- connection_.SendStreamDataWithStringWithFec(3, "foo", 0, !kFin, nullptr);
- connection_.SendStreamDataWithString(3, "foo", 3, !kFin, nullptr);
- connection_.SendStreamDataWithString(3, "foo", 6, !kFin, nullptr);
- connection_.SendStreamDataWithString(3, "foo", 9, !kFin, nullptr);
- connection_.SendStreamDataWithString(3, "foo", 12, !kFin, nullptr);
- size_t multiple_data_and_fec =
- QuicSentPacketManagerPeer::GetBytesInFlight(manager);
- EXPECT_LT(0u, multiple_data_and_fec);
-
- // Ack data packets, and NACK 1 data packet and FEC packet. Triggers
- // NACK-based loss detection of data and FEC packet, but only data is
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ connection_.SendStreamDataWithStringWithFec(3, "foo", 0, kFin, nullptr);
+ EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
+ size_t protected_packet =
+ QuicSentPacketManagerPeer::GetBytesInFlight(manager_);
+
+ // Force FEC timeout to send FEC packet out.
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ connection_.GetFecAlarm()->Fire();
+ EXPECT_TRUE(writer_->header().fec_flag);
+ size_t fec_packet = protected_packet;
+ EXPECT_EQ(protected_packet + fec_packet,
+ QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
+
+ // Send more data to trigger NACKs. Note that all data starts at stream offset
+ // 0 to ensure the same packet size, for ease of testing.
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(4);
+ connection_.SendStreamDataWithString(5, "foo", 0, kFin, nullptr);
+ connection_.SendStreamDataWithString(7, "foo", 0, kFin, nullptr);
+ connection_.SendStreamDataWithString(9, "foo", 0, kFin, nullptr);
+ connection_.SendStreamDataWithString(11, "foo", 0, kFin, nullptr);
+
+ // An unprotected packet will be 3 bytes smaller than an FEC-protected packet,
+ // since the protected packet will have 1 byte for FEC group number and
+ // 2 bytes of stream frame size, which are absent in the unprotected packet.
+ size_t unprotected_packet = protected_packet - 3;
+ EXPECT_EQ(protected_packet + fec_packet + 4 * unprotected_packet,
+ QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
+ EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
+
+ // Ack data packets, and NACK FEC packet and one data packet. Triggers
+ // NACK-based loss detection of both packets, but only data packet is
// retransmitted and considered oustanding.
QuicAckFrame ack = InitAckFrame(6);
NackPacket(2, &ack);
@@ -1758,10 +1833,13 @@ TEST_P(QuicConnectionTest, RemoveFECFromInflightOnLossRetransmission) {
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
EXPECT_CALL(*send_algorithm_,
OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
ProcessAckPacket(&ack);
- size_t data_only = QuicSentPacketManagerPeer::GetBytesInFlight(manager);
- EXPECT_GT(multiple_data_and_fec, data_only);
- EXPECT_LT(0u, data_only);
+ // On receiving this ack from the server, the client will no longer send
+ // version number in subsequent packets, including in this retransmission.
+ size_t unprotected_packet_no_version = unprotected_packet - 4;
+ EXPECT_EQ(unprotected_packet_no_version,
+ QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
// Receive ack for the retransmission. No data should be outstanding.
QuicAckFrame ack2 = InitAckFrame(7);
@@ -1772,33 +1850,150 @@ TEST_P(QuicConnectionTest, RemoveFECFromInflightOnLossRetransmission) {
.WillOnce(Return(lost_packets2));
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
ProcessAckPacket(&ack2);
- EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager));
+ EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
}
-TEST_P(QuicConnectionTest, NoTLPForFECPacket) {
+TEST_P(QuicConnectionTest, FECRemainsInflightOnTLPOfEarlierData) {
+ // This test checks if TLP is sent correctly when a data and an FEC packet
+ // are outstanding. TLP should be sent for the data packet when the
+ // retransmission alarm fires.
// Turn on TLP for this test.
- QuicSentPacketManagerPeer::SetMaxTailLossProbes(
- QuicConnectionPeer::GetSentPacketManager(&connection_), 1);
+ QuicSentPacketManagerPeer::SetMaxTailLossProbes(manager_, 1);
+ EXPECT_TRUE(creator_->IsFecEnabled());
+ EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
+ EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
+
+ // 1 Data packet. FEC alarm should be set.
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ connection_.SendStreamDataWithStringWithFec(3, "foo", 0, kFin, nullptr);
+ EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
+ size_t protected_packet =
+ QuicSentPacketManagerPeer::GetBytesInFlight(manager_);
+ EXPECT_LT(0u, protected_packet);
+
+ // Force FEC timeout to send FEC packet out.
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, 2u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ connection_.GetFecAlarm()->Fire();
+ EXPECT_TRUE(writer_->header().fec_flag);
+ size_t fec_packet = protected_packet;
+ EXPECT_EQ(protected_packet + fec_packet,
+ QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
+
+ // TLP alarm should be set.
+ QuicTime retransmission_time =
+ connection_.GetRetransmissionAlarm()->deadline();
+ EXPECT_NE(QuicTime::Zero(), retransmission_time);
+ // Simulate the retransmission alarm firing and sending a TLP, so send
+ // algorithm's OnRetransmissionTimeout is not called.
+ clock_.AdvanceTime(retransmission_time.Subtract(clock_.Now()));
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, 3u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ connection_.GetRetransmissionAlarm()->Fire();
+ // The TLP retransmission of packet 1 will be 3 bytes smaller than packet 1,
+ // since packet 1 will have 1 byte for FEC group number and 2 bytes of stream
+ // frame size, which are absent in the the TLP retransmission.
+ size_t tlp_packet = protected_packet - 3;
+ EXPECT_EQ(protected_packet + fec_packet + tlp_packet,
+ QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
+}
+
+TEST_P(QuicConnectionTest, FECRemainsInflightOnTLPOfLaterData) {
+ // Tests if TLP is sent correctly when data packet 1 and an FEC packet are
+ // sent followed by data packet 2, and data packet 1 is acked. TLP should be
+ // sent for data packet 2 when the retransmission alarm fires. Turn on TLP for
+ // this test.
+ QuicSentPacketManagerPeer::SetMaxTailLossProbes(manager_, 1);
+ EXPECT_TRUE(creator_->IsFecEnabled());
+ EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
+ EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
+
+ // 1 Data packet. FEC alarm should be set.
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, 1u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ connection_.SendStreamDataWithStringWithFec(3, "foo", 0, kFin, nullptr);
+ EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
+ size_t protected_packet =
+ QuicSentPacketManagerPeer::GetBytesInFlight(manager_);
+ EXPECT_LT(0u, protected_packet);
+
+ // Force FEC timeout to send FEC packet out.
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, 2u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ connection_.GetFecAlarm()->Fire();
+ EXPECT_TRUE(writer_->header().fec_flag);
+ // Protected data packet and FEC packet oustanding.
+ size_t fec_packet = protected_packet;
+ EXPECT_EQ(protected_packet + fec_packet,
+ QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
+
+ // Send 1 unprotected data packet. No FEC alarm should be set.
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, 3u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ connection_.SendStreamDataWithString(5, "foo", 0, kFin, nullptr);
+ EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
+ // Protected data packet, FEC packet, and unprotected data packet oustanding.
+ // An unprotected packet will be 3 bytes smaller than an FEC-protected packet,
+ // since the protected packet will have 1 byte for FEC group number and
+ // 2 bytes of stream frame size, which are absent in the unprotected packet.
+ size_t unprotected_packet = protected_packet - 3;
+ EXPECT_EQ(protected_packet + fec_packet + unprotected_packet,
+ QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
+
+ // Receive ack for first data packet. FEC and second data packet are still
+ // outstanding.
+ QuicAckFrame ack = InitAckFrame(1);
+ EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
+ EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+ ProcessAckPacket(&ack);
+ // FEC packet and unprotected data packet oustanding.
+ EXPECT_EQ(fec_packet + unprotected_packet,
+ QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
+
+ // TLP alarm should be set.
+ QuicTime retransmission_time =
+ connection_.GetRetransmissionAlarm()->deadline();
+ EXPECT_NE(QuicTime::Zero(), retransmission_time);
+ // Simulate the retransmission alarm firing and sending a TLP, so send
+ // algorithm's OnRetransmissionTimeout is not called.
+ clock_.AdvanceTime(retransmission_time.Subtract(clock_.Now()));
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, 4u, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ connection_.GetRetransmissionAlarm()->Fire();
+ // Having received an ack from the server, the client will no longer send
+ // version number in subsequent packets, including in this retransmission.
+ size_t tlp_packet_no_version = unprotected_packet - 4;
+ EXPECT_EQ(fec_packet + unprotected_packet + tlp_packet_no_version,
+ QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
+}
+
+TEST_P(QuicConnectionTest, NoTLPForFECPacket) {
+ // Turn on TLP for this test.
+ QuicSentPacketManagerPeer::SetMaxTailLossProbes(manager_, 1);
+ EXPECT_TRUE(creator_->IsFecEnabled());
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
- EXPECT_TRUE(QuicConnectionPeer::GetPacketCreator(
- &connection_)->IsFecEnabled());
- QuicSentPacketManager* manager =
- QuicConnectionPeer::GetSentPacketManager(&connection_);
- // 1 Data packet and 1 FEC packet.
+ // Send 1 FEC-protected data packet. FEC alarm should be set.
EXPECT_CALL(*send_algorithm_,
- OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(2);
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
connection_.SendStreamDataWithStringWithFec(3, "foo", 0, !kFin, nullptr);
+ EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
+ // Force FEC timeout to send FEC packet out.
+ EXPECT_CALL(*send_algorithm_,
+ OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(1);
+ connection_.GetFecAlarm()->Fire();
+ EXPECT_TRUE(writer_->header().fec_flag);
// Ack data packet, but not FEC packet.
QuicAckFrame ack = InitAckFrame(1);
EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
ProcessAckPacket(&ack);
- // No TLP alarm for FEC, so when retransmission alarm fires, it is an RTO.
+ // No TLP alarm for FEC, but retransmission alarm should be set for an RTO.
+ EXPECT_LT(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
- EXPECT_LT(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager));
QuicTime rto_time = connection_.GetRetransmissionAlarm()->deadline();
EXPECT_NE(QuicTime::Zero(), rto_time);
@@ -1808,7 +2003,7 @@ TEST_P(QuicConnectionTest, NoTLPForFECPacket) {
clock_.AdvanceTime(rto_time.Subtract(clock_.Now()));
connection_.GetRetransmissionAlarm()->Fire();
EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
- EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager));
+ EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(manager_));
}
TEST_P(QuicConnectionTest, FramePacking) {
@@ -1887,13 +2082,12 @@ TEST_P(QuicConnectionTest, FramePackingCryptoThenNonCrypto) {
}
TEST_P(QuicConnectionTest, FramePackingFEC) {
- EXPECT_TRUE(QuicConnectionPeer::GetPacketCreator(
- &connection_)->IsFecEnabled());
+ EXPECT_TRUE(creator_->IsFecEnabled());
CongestionBlockWrites();
// Queue an ack and two stream frames. Ack gets flushed when FEC is turned on
- // for sending protected data; two stream frames are packing in 1 packet.
+ // for sending protected data; two stream frames are packed in 1 packet.
EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(DoAll(
IgnoreResult(InvokeWithoutArgs(
&connection_, &TestConnection::SendStreamData3WithFec)),
@@ -1901,7 +2095,7 @@ TEST_P(QuicConnectionTest, FramePackingFEC) {
&connection_, &TestConnection::SendStreamData5WithFec))));
connection_.SendAck();
- EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(3);
+ EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
CongestionUnblockWrites();
connection_.GetSendAlarm()->Fire();
EXPECT_EQ(0u, connection_.NumQueuedPackets());
@@ -1909,7 +2103,10 @@ TEST_P(QuicConnectionTest, FramePackingFEC) {
// Parse the last packet and ensure it's in an fec group.
EXPECT_EQ(2u, writer_->header().fec_group);
- EXPECT_EQ(0u, writer_->frame_count());
+ EXPECT_EQ(2u, writer_->frame_count());
+
+ // FEC alarm should be set.
+ EXPECT_TRUE(connection_.GetFecAlarm()->IsSet());
}
TEST_P(QuicConnectionTest, FramePackingAckResponse) {
@@ -2431,8 +2628,7 @@ TEST_P(QuicConnectionTest, ReviveMissingPacketAfterDataPackets) {
}
TEST_P(QuicConnectionTest, TLP) {
- QuicSentPacketManagerPeer::SetMaxTailLossProbes(
- QuicConnectionPeer::GetSentPacketManager(&connection_), 1);
+ QuicSentPacketManagerPeer::SetMaxTailLossProbes(manager_, 1);
SendStreamDataToPeer(3, "foo", 0, !kFin, nullptr);
EXPECT_EQ(1u, stop_waiting()->least_unacked);
@@ -2926,6 +3122,7 @@ TEST_P(QuicConnectionTest, InitialTimeout) {
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+ EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
EXPECT_FALSE(connection_.GetResumeWritesAlarm()->IsSet());
EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
@@ -2968,6 +3165,7 @@ TEST_P(QuicConnectionTest, OverallTimeout) {
EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+ EXPECT_FALSE(connection_.GetFecAlarm()->IsSet());
EXPECT_FALSE(connection_.GetResumeWritesAlarm()->IsSet());
EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
@@ -3139,8 +3337,7 @@ TEST_P(QuicConnectionTest, TestQueueLimitsOnSendStreamData) {
connection_.version(), kIncludeVersion,
PACKET_8BYTE_CONNECTION_ID, PACKET_1BYTE_SEQUENCE_NUMBER,
NOT_IN_FEC_GROUP, &payload_length);
- QuicConnectionPeer::GetPacketCreator(&connection_)->set_max_packet_length(
- length);
+ creator_->set_max_packet_length(length);
// Queue the first packet.
EXPECT_CALL(*send_algorithm_,
@@ -3164,8 +3361,7 @@ TEST_P(QuicConnectionTest, LoopThroughSendingPackets) {
connection_.version(), kIncludeVersion,
PACKET_8BYTE_CONNECTION_ID, PACKET_1BYTE_SEQUENCE_NUMBER,
NOT_IN_FEC_GROUP, &payload_length);
- QuicConnectionPeer::GetPacketCreator(&connection_)->set_max_packet_length(
- length);
+ creator_->set_max_packet_length(length);
// Queue the first packet.
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(7);
@@ -3738,8 +3934,7 @@ TEST_P(QuicConnectionTest, ClientHandlesVersionNegotiation) {
EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
connection_.ProcessUdpPacket(IPEndPoint(), IPEndPoint(), *encrypted);
- ASSERT_FALSE(QuicPacketCreatorPeer::SendVersionInPacket(
- QuicConnectionPeer::GetPacketCreator(&connection_)));
+ ASSERT_FALSE(QuicPacketCreatorPeer::SendVersionInPacket(creator_));
}
TEST_P(QuicConnectionTest, BadVersionNegotiation) {
@@ -4175,32 +4370,25 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackAfterFECRecovery) {
}
TEST_P(QuicConnectionTest, NetworkChangeVisitorCwndCallbackChangesFecState) {
- QuicPacketCreator* creator =
- QuicConnectionPeer::GetPacketCreator(&connection_);
- size_t max_packets_per_fec_group = creator->max_packets_per_fec_group();
+ size_t max_packets_per_fec_group = creator_->max_packets_per_fec_group();
QuicSentPacketManager::NetworkChangeVisitor* visitor =
- QuicSentPacketManagerPeer::GetNetworkChangeVisitor(
- QuicConnectionPeer::GetSentPacketManager(&connection_));
+ QuicSentPacketManagerPeer::GetNetworkChangeVisitor(manager_);
EXPECT_TRUE(visitor);
// Increase FEC group size by increasing congestion window to a large number.
EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
Return(1000 * kDefaultTCPMSS));
visitor->OnCongestionWindowChange();
- EXPECT_LT(max_packets_per_fec_group, creator->max_packets_per_fec_group());
+ EXPECT_LT(max_packets_per_fec_group, creator_->max_packets_per_fec_group());
}
TEST_P(QuicConnectionTest, NetworkChangeVisitorConfigCallbackChangesFecState) {
- QuicSentPacketManager* sent_packet_manager =
- QuicConnectionPeer::GetSentPacketManager(&connection_);
QuicSentPacketManager::NetworkChangeVisitor* visitor =
- QuicSentPacketManagerPeer::GetNetworkChangeVisitor(sent_packet_manager);
+ QuicSentPacketManagerPeer::GetNetworkChangeVisitor(manager_);
EXPECT_TRUE(visitor);
-
- QuicPacketGenerator* generator =
- QuicConnectionPeer::GetPacketGenerator(&connection_);
- EXPECT_EQ(QuicTime::Delta::Zero(), generator->fec_timeout());
+ EXPECT_EQ(QuicTime::Delta::Zero(),
+ QuicPacketGeneratorPeer::GetFecTimeout(generator_));
// Verify that sending a config with a new initial rtt changes fec timeout.
// Create and process a config with a non-zero initial RTT.
@@ -4208,28 +4396,25 @@ TEST_P(QuicConnectionTest, NetworkChangeVisitorConfigCallbackChangesFecState) {
QuicConfig config;
config.SetInitialRoundTripTimeUsToSend(300000);
connection_.SetFromConfig(config);
- EXPECT_LT(QuicTime::Delta::Zero(), generator->fec_timeout());
+ EXPECT_LT(QuicTime::Delta::Zero(),
+ QuicPacketGeneratorPeer::GetFecTimeout(generator_));
}
TEST_P(QuicConnectionTest, NetworkChangeVisitorRttCallbackChangesFecState) {
// Verify that sending a config with a new initial rtt changes fec timeout.
- QuicSentPacketManager* sent_packet_manager =
- QuicConnectionPeer::GetSentPacketManager(&connection_);
QuicSentPacketManager::NetworkChangeVisitor* visitor =
- QuicSentPacketManagerPeer::GetNetworkChangeVisitor(sent_packet_manager);
+ QuicSentPacketManagerPeer::GetNetworkChangeVisitor(manager_);
EXPECT_TRUE(visitor);
-
- QuicPacketGenerator* generator =
- QuicConnectionPeer::GetPacketGenerator(&connection_);
- EXPECT_EQ(QuicTime::Delta::Zero(), generator->fec_timeout());
+ EXPECT_EQ(QuicTime::Delta::Zero(),
+ QuicPacketGeneratorPeer::GetFecTimeout(generator_));
// Increase FEC timeout by increasing RTT.
- RttStats* rtt_stats =
- QuicSentPacketManagerPeer::GetRttStats(sent_packet_manager);
+ RttStats* rtt_stats = QuicSentPacketManagerPeer::GetRttStats(manager_);
rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(300),
QuicTime::Delta::Zero(), QuicTime::Zero());
visitor->OnRttChange();
- EXPECT_LT(QuicTime::Delta::Zero(), generator->fec_timeout());
+ EXPECT_LT(QuicTime::Delta::Zero(),
+ QuicPacketGeneratorPeer::GetFecTimeout(generator_));
}
class MockQuicConnectionDebugVisitor
« no previous file with comments | « net/quic/quic_connection.cc ('k') | net/quic/quic_packet_creator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698