Index: net/quic/quic_packet_generator_test.cc |
diff --git a/net/quic/quic_packet_generator_test.cc b/net/quic/quic_packet_generator_test.cc |
index f7a7d72ab60a96a7a80fc5bbe64cdbd4daaea048..1ab7ca553e0d81246088895b89d86f510402a5fe 100644 |
--- a/net/quic/quic_packet_generator_test.cc |
+++ b/net/quic/quic_packet_generator_test.cc |
@@ -32,6 +32,8 @@ namespace net { |
namespace test { |
namespace { |
+const int64 kMinFecTimeoutMs = 5u; |
+ |
class MockDelegate : public QuicPacketGenerator::DelegateInterface { |
public: |
MockDelegate() {} |
@@ -42,7 +44,6 @@ class MockDelegate : public QuicPacketGenerator::DelegateInterface { |
HasRetransmittableData retransmittable, |
IsHandshake handshake)); |
MOCK_METHOD0(CreateAckFrame, QuicAckFrame*()); |
- MOCK_METHOD0(CreateFeedbackFrame, QuicCongestionFeedbackFrame*()); |
MOCK_METHOD0(CreateStopWaitingFrame, QuicStopWaitingFrame*()); |
MOCK_METHOD1(OnSerializedPacket, void(const SerializedPacket& packet)); |
MOCK_METHOD2(CloseConnection, void(QuicErrorCode, bool)); |
@@ -63,7 +64,7 @@ class MockDelegate : public QuicPacketGenerator::DelegateInterface { |
.WillRepeatedly(Return(false)); |
} |
- // Use this when only ack and feedback frames should be allowed to be written. |
+ // Use this when only ack frames should be allowed to be written. |
void SetCanWriteOnlyNonRetransmittable() { |
EXPECT_CALL(*this, ShouldGeneratePacket(NOT_RETRANSMISSION, _, _)) |
.WillRepeatedly(Return(false)); |
@@ -77,13 +78,12 @@ class MockDelegate : public QuicPacketGenerator::DelegateInterface { |
}; |
// Simple struct for describing the contents of a packet. |
-// Useful in conjunction with a SimpleQuicFrame for validating |
-// that a packet contains the expected frames. |
+// Useful in conjunction with a SimpleQuicFrame for validating that a packet |
+// contains the expected frames. |
struct PacketContents { |
PacketContents() |
: num_ack_frames(0), |
num_connection_close_frames(0), |
- num_feedback_frames(0), |
num_goaway_frames(0), |
num_rst_stream_frames(0), |
num_stop_waiting_frames(0), |
@@ -93,7 +93,6 @@ struct PacketContents { |
size_t num_ack_frames; |
size_t num_connection_close_frames; |
- size_t num_feedback_frames; |
size_t num_goaway_frames; |
size_t num_rst_stream_frames; |
size_t num_stop_waiting_frames; |
@@ -116,7 +115,8 @@ class QuicPacketGeneratorTest : public ::testing::Test { |
packet4_(0, PACKET_1BYTE_SEQUENCE_NUMBER, nullptr, 0, nullptr), |
packet5_(0, PACKET_1BYTE_SEQUENCE_NUMBER, nullptr, 0, nullptr), |
packet6_(0, PACKET_1BYTE_SEQUENCE_NUMBER, nullptr, 0, nullptr), |
- packet7_(0, PACKET_1BYTE_SEQUENCE_NUMBER, nullptr, 0, nullptr) {} |
+ packet7_(0, PACKET_1BYTE_SEQUENCE_NUMBER, nullptr, 0, nullptr), |
+ packet8_(0, PACKET_1BYTE_SEQUENCE_NUMBER, nullptr, 0, nullptr) {} |
~QuicPacketGeneratorTest() override { |
delete packet_.packet; |
@@ -133,6 +133,8 @@ class QuicPacketGeneratorTest : public ::testing::Test { |
delete packet6_.retransmittable_frames; |
delete packet7_.packet; |
delete packet7_.retransmittable_frames; |
+ delete packet8_.packet; |
+ delete packet8_.retransmittable_frames; |
} |
QuicAckFrame* CreateAckFrame() { |
@@ -140,13 +142,6 @@ class QuicPacketGeneratorTest : public ::testing::Test { |
return new QuicAckFrame(MakeAckFrame(0)); |
} |
- QuicCongestionFeedbackFrame* CreateFeedbackFrame() { |
- QuicCongestionFeedbackFrame* frame = new QuicCongestionFeedbackFrame; |
- frame->type = kTCP; |
- frame->tcp.receive_window = 0x4030; |
- return frame; |
- } |
- |
QuicStopWaitingFrame* CreateStopWaitingFrame() { |
QuicStopWaitingFrame* frame = new QuicStopWaitingFrame(); |
frame->entropy_hash = 0; |
@@ -167,8 +162,9 @@ class QuicPacketGeneratorTest : public ::testing::Test { |
size_t num_retransmittable_frames = contents.num_connection_close_frames + |
contents.num_goaway_frames + contents.num_rst_stream_frames + |
contents.num_stream_frames; |
- size_t num_frames = contents.num_feedback_frames + contents.num_ack_frames + |
- contents.num_stop_waiting_frames + num_retransmittable_frames; |
+ size_t num_frames = contents.num_ack_frames + |
+ contents.num_stop_waiting_frames + |
+ num_retransmittable_frames; |
if (num_retransmittable_frames == 0) { |
ASSERT_TRUE(packet.retransmittable_frames == nullptr); |
@@ -184,8 +180,6 @@ class QuicPacketGeneratorTest : public ::testing::Test { |
EXPECT_EQ(contents.num_ack_frames, simple_framer_.ack_frames().size()); |
EXPECT_EQ(contents.num_connection_close_frames, |
simple_framer_.connection_close_frames().size()); |
- EXPECT_EQ(contents.num_feedback_frames, |
- simple_framer_.feedback_frames().size()); |
EXPECT_EQ(contents.num_goaway_frames, |
simple_framer_.goaway_frames().size()); |
EXPECT_EQ(contents.num_rst_stream_frames, |
@@ -236,6 +230,7 @@ class QuicPacketGeneratorTest : public ::testing::Test { |
SerializedPacket packet5_; |
SerializedPacket packet6_; |
SerializedPacket packet7_; |
+ SerializedPacket packet8_; |
private: |
scoped_ptr<char[]> data_array_; |
@@ -250,7 +245,7 @@ class MockDebugDelegate : public QuicPacketGenerator::DebugDelegate { |
TEST_F(QuicPacketGeneratorTest, ShouldSendAck_NotWritable) { |
delegate_.SetCanNotWrite(); |
- generator_.SetShouldSendAck(false, false); |
+ generator_.SetShouldSendAck(false); |
EXPECT_TRUE(generator_.HasQueuedFrames()); |
} |
@@ -264,7 +259,7 @@ TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldNotFlush) { |
EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame())); |
EXPECT_CALL(debug_delegate, OnFrameAddedToPacket(_)).Times(1); |
- generator_.SetShouldSendAck(false, false); |
+ generator_.SetShouldSendAck(false); |
EXPECT_TRUE(generator_.HasQueuedFrames()); |
} |
@@ -274,53 +269,15 @@ TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldFlush) { |
EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame())); |
EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet_)); |
- generator_.SetShouldSendAck(false, false); |
- EXPECT_FALSE(generator_.HasQueuedFrames()); |
- |
- PacketContents contents; |
- contents.num_ack_frames = 1; |
- CheckPacketContains(contents, packet_); |
-} |
- |
-TEST_F(QuicPacketGeneratorTest, |
- ShouldSendAckWithFeedback_WritableAndShouldNotFlush) { |
- delegate_.SetCanWriteOnlyNonRetransmittable(); |
- generator_.StartBatchOperations(); |
- |
- EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame())); |
- EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce( |
- Return(CreateFeedbackFrame())); |
- |
- generator_.SetShouldSendAck(true, false); |
- EXPECT_TRUE(generator_.HasQueuedFrames()); |
-} |
- |
-TEST_F(QuicPacketGeneratorTest, |
- ShouldSendAckWithFeedback_WritableAndShouldFlush) { |
- delegate_.SetCanWriteOnlyNonRetransmittable(); |
- |
- EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame())); |
- EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce( |
- Return(CreateFeedbackFrame())); |
- EXPECT_CALL(delegate_, CreateStopWaitingFrame()).WillOnce( |
- Return(CreateStopWaitingFrame())); |
- |
- EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet_)); |
- |
- generator_.SetShouldSendAck(true, true); |
+ generator_.SetShouldSendAck(false); |
EXPECT_FALSE(generator_.HasQueuedFrames()); |
PacketContents contents; |
contents.num_ack_frames = 1; |
- contents.num_feedback_frames = 1; |
- contents.num_stop_waiting_frames = 1; |
CheckPacketContains(contents, packet_); |
} |
TEST_F(QuicPacketGeneratorTest, ShouldSendAck_MultipleCalls) { |
- ValueRestore<bool> old_flag(&FLAGS_quic_disallow_multiple_pending_ack_frames, |
- true); |
- |
// Make sure that calling SetShouldSendAck multiple times does not result in a |
// crash. Previously this would result in multiple QuicFrames queued in the |
// packet generator, with all but the last with internal pointers to freed |
@@ -336,8 +293,8 @@ TEST_F(QuicPacketGeneratorTest, ShouldSendAck_MultipleCalls) { |
.WillOnce(SaveArg<0>(&packet_)); |
generator_.StartBatchOperations(); |
- generator_.SetShouldSendAck(false, false); |
- generator_.SetShouldSendAck(false, false); |
+ generator_.SetShouldSendAck(false); |
+ generator_.SetShouldSendAck(false); |
generator_.FinishBatchOperations(); |
} |
@@ -431,7 +388,6 @@ TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldFlush) { |
} |
TEST_F(QuicPacketGeneratorTest, ConsumeData_EmptyData) { |
- ValueRestore<bool> old_flag(&FLAGS_quic_empty_data_no_fin_early_return, true); |
EXPECT_DFATAL(generator_.ConsumeData(kHeadersStreamId, MakeIOVector(""), 0, |
false, MAY_FEC_PROTECT, nullptr), |
"Attempt to consume empty data without FIN."); |
@@ -473,7 +429,7 @@ TEST_F(QuicPacketGeneratorTest, ConsumeData_BatchOperations) { |
CheckPacketContains(contents, packet_); |
} |
-TEST_F(QuicPacketGeneratorTest, ConsumeDataFEC) { |
+TEST_F(QuicPacketGeneratorTest, ConsumeDataSendsFecOnMaxGroupSize) { |
delegate_.SetCanWriteAnything(); |
// Send FEC every two packets. |
@@ -489,12 +445,10 @@ TEST_F(QuicPacketGeneratorTest, ConsumeDataFEC) { |
SaveArg<0>(&packet3_)); |
EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce( |
SaveArg<0>(&packet4_)); |
- EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce( |
- SaveArg<0>(&packet5_)); |
} |
- // Send enough data to create 3 packets: two full and one partial. Send |
- // with MUST_FEC_PROTECT flag. |
+ // Send enough data to create 3 packets: two full and one partial. Send with |
+ // MUST_FEC_PROTECT flag. |
size_t data_len = 2 * kDefaultMaxPacketSize + 100; |
QuicConsumedData consumed = generator_.ConsumeData( |
3, CreateData(data_len), 0, true, MUST_FEC_PROTECT, nullptr); |
@@ -505,38 +459,169 @@ TEST_F(QuicPacketGeneratorTest, ConsumeDataFEC) { |
CheckPacketHasSingleStreamFrame(packet_); |
CheckPacketHasSingleStreamFrame(packet2_); |
CheckPacketIsFec(packet3_, 1); |
- |
CheckPacketHasSingleStreamFrame(packet4_); |
- CheckPacketIsFec(packet5_, 4); |
+ EXPECT_TRUE(creator_->IsFecProtected()); |
+ |
+ // The FEC packet under construction will be sent when one more packet is sent |
+ // (since FEC group size is 2), or when OnFecTimeout is called. Send more data |
+ // with MAY_FEC_PROTECT. This packet should also be protected, and FEC packet |
+ // is sent since FEC group size is reached. |
+ { |
+ InSequence dummy; |
+ EXPECT_CALL(delegate_, OnSerializedPacket(_)) |
+ .WillOnce(SaveArg<0>(&packet5_)); |
+ EXPECT_CALL(delegate_, OnSerializedPacket(_)) |
+ .WillOnce(SaveArg<0>(&packet6_)); |
+ } |
+ consumed = generator_.ConsumeData(5, CreateData(1u), 0, true, MAY_FEC_PROTECT, |
+ nullptr); |
+ EXPECT_EQ(1u, consumed.bytes_consumed); |
+ CheckPacketHasSingleStreamFrame(packet5_); |
+ CheckPacketIsFec(packet6_, 4); |
+ EXPECT_FALSE(creator_->IsFecProtected()); |
} |
-TEST_F(QuicPacketGeneratorTest, ConsumeDataSendsFecAtEnd) { |
+TEST_F(QuicPacketGeneratorTest, ConsumeDataSendsFecOnTimeout) { |
delegate_.SetCanWriteAnything(); |
+ creator_->set_max_packets_per_fec_group(1000); |
- // Enable FEC. |
+ // Send data with MUST_FEC_PROTECT flag. No FEC packet is emitted, but the |
+ // creator FEC protects all data. |
+ EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet_)); |
+ QuicConsumedData consumed = generator_.ConsumeData(3, CreateData(1u), 0, true, |
+ MUST_FEC_PROTECT, nullptr); |
+ EXPECT_EQ(1u, consumed.bytes_consumed); |
+ EXPECT_TRUE(consumed.fin_consumed); |
+ CheckPacketHasSingleStreamFrame(packet_); |
+ EXPECT_TRUE(creator_->IsFecProtected()); |
+ |
+ // Send more data with MAY_FEC_PROTECT. This packet should also be protected, |
+ // and FEC packet is not yet sent. |
+ EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet2_)); |
+ consumed = generator_.ConsumeData(5, CreateData(1u), 0, true, MAY_FEC_PROTECT, |
+ nullptr); |
+ EXPECT_EQ(1u, consumed.bytes_consumed); |
+ CheckPacketHasSingleStreamFrame(packet2_); |
+ EXPECT_TRUE(creator_->IsFecProtected()); |
+ |
+ // Calling OnFecTimeout should cause the FEC packet to be emitted. |
+ EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet3_)); |
+ generator_.OnFecTimeout(); |
+ CheckPacketIsFec(packet3_, 1); |
+ EXPECT_FALSE(creator_->IsFecProtected()); |
+ |
+ // Subsequent data is protected under the next FEC group. Send enough data to |
+ // create 2 more packets: one full and one partial. |
+ { |
+ InSequence dummy; |
+ EXPECT_CALL(delegate_, OnSerializedPacket(_)) |
+ .WillOnce(SaveArg<0>(&packet4_)); |
+ EXPECT_CALL(delegate_, OnSerializedPacket(_)) |
+ .WillOnce(SaveArg<0>(&packet5_)); |
+ } |
+ size_t data_len = kDefaultMaxPacketSize + 1; |
+ consumed = generator_.ConsumeData(7, CreateData(data_len), 0, true, |
+ MUST_FEC_PROTECT, nullptr); |
+ EXPECT_EQ(data_len, consumed.bytes_consumed); |
+ EXPECT_TRUE(consumed.fin_consumed); |
+ CheckPacketHasSingleStreamFrame(packet4_); |
+ CheckPacketHasSingleStreamFrame(packet5_); |
+ EXPECT_TRUE(creator_->IsFecProtected()); |
+ |
+ // Calling OnFecTimeout should cause the FEC packet to be emitted. |
+ EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet6_)); |
+ generator_.OnFecTimeout(); |
+ CheckPacketIsFec(packet6_, 4); |
+ EXPECT_FALSE(creator_->IsFecProtected()); |
+} |
+ |
+TEST_F(QuicPacketGeneratorTest, GetFecTimeoutFiniteOnlyOnFirstPacketInGroup) { |
+ delegate_.SetCanWriteAnything(); |
creator_->set_max_packets_per_fec_group(6); |
+ |
+ // Send enough data to create 2 packets: one full and one partial. Send with |
+ // MUST_FEC_PROTECT flag. No FEC packet is emitted yet, but the creator FEC |
+ // protects all data. |
{ |
InSequence dummy; |
EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce( |
SaveArg<0>(&packet_)); |
EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce( |
SaveArg<0>(&packet2_)); |
- EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce( |
- SaveArg<0>(&packet3_)); |
} |
- |
- // Send enough data to create 2 packets: one full and one partial. Send |
- // with MUST_FEC_PROTECT flag. |
size_t data_len = 1 * kDefaultMaxPacketSize + 100; |
QuicConsumedData consumed = generator_.ConsumeData( |
3, CreateData(data_len), 0, true, MUST_FEC_PROTECT, nullptr); |
EXPECT_EQ(data_len, consumed.bytes_consumed); |
EXPECT_TRUE(consumed.fin_consumed); |
EXPECT_FALSE(generator_.HasQueuedFrames()); |
- |
CheckPacketHasSingleStreamFrame(packet_); |
CheckPacketHasSingleStreamFrame(packet2_); |
- CheckPacketIsFec(packet3_, 1); |
+ EXPECT_TRUE(creator_->IsFecProtected()); |
+ |
+ // GetFecTimeout returns finite timeout only for first packet in group. |
+ EXPECT_EQ(QuicTime::Delta::FromMilliseconds(kMinFecTimeoutMs), |
+ generator_.GetFecTimeout(/*sequence_number=*/1u)); |
+ EXPECT_EQ(QuicTime::Delta::Infinite(), |
+ generator_.GetFecTimeout(/*sequence_number=*/2u)); |
+ |
+ // Send more data with MAY_FEC_PROTECT. This packet should also be protected, |
+ // and FEC packet is not yet sent. |
+ EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet3_)); |
+ consumed = generator_.ConsumeData(5, CreateData(1u), 0, true, MAY_FEC_PROTECT, |
+ nullptr); |
+ CheckPacketHasSingleStreamFrame(packet3_); |
+ EXPECT_TRUE(creator_->IsFecProtected()); |
+ |
+ // GetFecTimeout returns finite timeout only for first packet in group. |
+ EXPECT_EQ(QuicTime::Delta::Infinite(), |
+ generator_.GetFecTimeout(/*sequence_number=*/3u)); |
+ |
+ // Calling OnFecTimeout should cause the FEC packet to be emitted. |
+ EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet4_)); |
+ generator_.OnFecTimeout(); |
+ CheckPacketIsFec(packet4_, /*fec_group=*/1u); |
+ EXPECT_FALSE(creator_->IsFecProtected()); |
+ |
+ // Subsequent data is protected under the next FEC group. Send enough data to |
+ // create 2 more packets: one full and one partial. |
+ { |
+ InSequence dummy; |
+ EXPECT_CALL(delegate_, OnSerializedPacket(_)) |
+ .WillOnce(SaveArg<0>(&packet5_)); |
+ EXPECT_CALL(delegate_, OnSerializedPacket(_)) |
+ .WillOnce(SaveArg<0>(&packet6_)); |
+ } |
+ data_len = kDefaultMaxPacketSize + 1u; |
+ consumed = generator_.ConsumeData(7, CreateData(data_len), 0, true, |
+ MUST_FEC_PROTECT, nullptr); |
+ EXPECT_EQ(data_len, consumed.bytes_consumed); |
+ EXPECT_TRUE(consumed.fin_consumed); |
+ CheckPacketHasSingleStreamFrame(packet5_); |
+ CheckPacketHasSingleStreamFrame(packet6_); |
+ EXPECT_TRUE(creator_->IsFecProtected()); |
+ |
+ // GetFecTimeout returns finite timeout for first packet in the new group. |
+ EXPECT_EQ(QuicTime::Delta::FromMilliseconds(kMinFecTimeoutMs), |
+ generator_.GetFecTimeout(/*sequence_number=*/5u)); |
+ EXPECT_EQ(QuicTime::Delta::Infinite(), |
+ generator_.GetFecTimeout(/*sequence_number=*/6u)); |
+ |
+ // Calling OnFecTimeout should cause the FEC packet to be emitted. |
+ EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet7_)); |
+ generator_.OnFecTimeout(); |
+ CheckPacketIsFec(packet7_, /*fec_group=*/5u); |
+ EXPECT_FALSE(creator_->IsFecProtected()); |
+ |
+ // Send more data with MAY_FEC_PROTECT. No FEC protection, so GetFecTimeout |
+ // returns infinite. |
+ EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet8_)); |
+ consumed = generator_.ConsumeData(9, CreateData(1u), 0, true, MAY_FEC_PROTECT, |
+ nullptr); |
+ CheckPacketHasSingleStreamFrame(packet8_); |
+ EXPECT_FALSE(creator_->IsFecProtected()); |
+ EXPECT_EQ(QuicTime::Delta::Infinite(), |
+ generator_.GetFecTimeout(/*sequence_number=*/8u)); |
} |
TEST_F(QuicPacketGeneratorTest, ConsumeData_FramesPreviouslyQueued) { |
@@ -544,8 +629,7 @@ TEST_F(QuicPacketGeneratorTest, ConsumeData_FramesPreviouslyQueued) { |
// but not enough for a stream frame of 0 offset and one with non-zero offset. |
size_t length = |
NullEncrypter().GetCiphertextSize(0) + |
- GetPacketHeaderSize(creator_->connection_id_length(), |
- true, |
+ GetPacketHeaderSize(creator_->connection_id_length(), true, |
creator_->next_sequence_number_length(), |
NOT_IN_FEC_GROUP) + |
// Add an extra 3 bytes for the payload and 1 byte so BytesFree is larger |
@@ -586,10 +670,42 @@ TEST_F(QuicPacketGeneratorTest, ConsumeData_FramesPreviouslyQueued) { |
CheckPacketContains(contents, packet2_); |
} |
+TEST_F(QuicPacketGeneratorTest, NoFecPacketSentWhenBatchEnds) { |
+ delegate_.SetCanWriteAnything(); |
+ creator_->set_max_packets_per_fec_group(6); |
+ |
+ generator_.StartBatchOperations(); |
+ |
+ generator_.ConsumeData(3, MakeIOVector("foo"), 2, true, MUST_FEC_PROTECT, |
+ nullptr); |
+ QuicConsumedData consumed = generator_.ConsumeData( |
+ 5, MakeIOVector("quux"), 7, false, MUST_FEC_PROTECT, nullptr); |
+ EXPECT_EQ(4u, consumed.bytes_consumed); |
+ EXPECT_FALSE(consumed.fin_consumed); |
+ EXPECT_TRUE(generator_.HasQueuedFrames()); |
+ |
+ // Now both frames will be flushed out, but FEC packet is not yet sent. |
+ EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet_)); |
+ generator_.FinishBatchOperations(); |
+ EXPECT_FALSE(generator_.HasQueuedFrames()); |
+ |
+ PacketContents contents; |
+ contents.num_stream_frames = 2u; |
+ contents.fec_group = 1u; |
+ CheckPacketContains(contents, packet_); |
+ |
+ // Forcing FEC timeout causes FEC packet to be emitted. |
+ EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet2_)); |
+ generator_.OnFecTimeout(); |
+ CheckPacketIsFec(packet2_, /*fec_group=*/1u); |
+} |
+ |
TEST_F(QuicPacketGeneratorTest, FecTimeoutOnRttChange) { |
- EXPECT_EQ(QuicTime::Delta::Zero(), generator_.fec_timeout()); |
+ EXPECT_EQ(QuicTime::Delta::Zero(), |
+ QuicPacketGeneratorPeer::GetFecTimeout(&generator_)); |
generator_.OnRttChange(QuicTime::Delta::FromMilliseconds(300)); |
- EXPECT_EQ(QuicTime::Delta::FromMilliseconds(150), generator_.fec_timeout()); |
+ EXPECT_EQ(QuicTime::Delta::FromMilliseconds(150), |
+ QuicPacketGeneratorPeer::GetFecTimeout(&generator_)); |
} |
TEST_F(QuicPacketGeneratorTest, FecGroupSizeOnCongestionWindowChange) { |
@@ -613,15 +729,13 @@ TEST_F(QuicPacketGeneratorTest, FecGroupSizeOnCongestionWindowChange) { |
TEST_F(QuicPacketGeneratorTest, FecGroupSizeChangeWithOpenGroup) { |
delegate_.SetCanWriteAnything(); |
- // TODO(jri): This starting of batch mode should not be required when |
- // FEC sending is separated from batching operations. |
generator_.StartBatchOperations(); |
creator_->set_max_packets_per_fec_group(50); |
EXPECT_EQ(50u, creator_->max_packets_per_fec_group()); |
EXPECT_FALSE(creator_->IsFecGroupOpen()); |
- // Send enough data to create 4 packets with MUST_FEC_PROTECT flag. |
- // 3 packets are sent, one is queued in the creator. |
+ // Send enough data to create 4 packets with MUST_FEC_PROTECT flag. 3 packets |
+ // are sent, one is queued in the creator. |
{ |
InSequence dummy; |
EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce( |
@@ -641,8 +755,8 @@ TEST_F(QuicPacketGeneratorTest, FecGroupSizeChangeWithOpenGroup) { |
generator_.OnCongestionWindowChange(2); |
EXPECT_EQ(2u, creator_->max_packets_per_fec_group()); |
- // Send enough data to trigger one unprotected data packet, |
- // causing the FEC packet to also be sent. |
+ // Send enough data to trigger one unprotected data packet, causing the FEC |
+ // packet to also be sent. |
{ |
InSequence dummy; |
EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce( |
@@ -687,8 +801,6 @@ TEST_F(QuicPacketGeneratorTest, SwitchFecOnOff) { |
SaveArg<0>(&packet4_)); |
EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce( |
SaveArg<0>(&packet5_)); |
- EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce( |
- SaveArg<0>(&packet6_)); |
} |
// Send enough data to create 3 packets with MUST_FEC_PROTECT flag. |
size_t data_len = 2 * kDefaultMaxPacketSize + 100; |
@@ -697,12 +809,16 @@ TEST_F(QuicPacketGeneratorTest, SwitchFecOnOff) { |
EXPECT_EQ(data_len, consumed.bytes_consumed); |
EXPECT_FALSE(generator_.HasQueuedFrames()); |
- // Verify that two FEC packets were sent. |
+ // Verify that packets sent were 3 data and 1 FEC. |
CheckPacketHasSingleStreamFrame(packet2_); |
CheckPacketHasSingleStreamFrame(packet3_); |
CheckPacketIsFec(packet4_, /*fec_group=*/2u); |
CheckPacketHasSingleStreamFrame(packet5_); |
- CheckPacketIsFec(packet6_, /*fec_group=*/5u); // Sent at the end of stream. |
+ |
+ // Calling OnFecTimeout should emit the pending FEC packet. |
+ EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet6_)); |
+ generator_.OnFecTimeout(); |
+ CheckPacketIsFec(packet6_, /*fec_group=*/5u); |
// Send one unprotected data packet. |
EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce( |
@@ -750,14 +866,12 @@ TEST_F(QuicPacketGeneratorTest, SwitchFecOnWithPendingFramesInGenerator) { |
// Queue control frames in generator. |
delegate_.SetCanNotWrite(); |
- generator_.SetShouldSendAck(true, true); |
+ generator_.SetShouldSendAck(true); |
delegate_.SetCanWriteAnything(); |
generator_.StartBatchOperations(); |
// Set up frames to write into the creator when control frames are written. |
EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame())); |
- EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce( |
- Return(CreateFeedbackFrame())); |
EXPECT_CALL(delegate_, CreateStopWaitingFrame()).WillOnce( |
Return(CreateStopWaitingFrame())); |
@@ -774,7 +888,6 @@ TEST_F(QuicPacketGeneratorTest, SwitchFecOnWithPendingFramesInGenerator) { |
EXPECT_EQ(1u, consumed.bytes_consumed); |
PacketContents contents; |
contents.num_ack_frames = 1; |
- contents.num_feedback_frames = 1; |
contents.num_stop_waiting_frames = 1; |
CheckPacketContains(contents, packet_); |
@@ -820,14 +933,11 @@ TEST_F(QuicPacketGeneratorTest, SwitchFecOnOffWithSubsequentPacketsProtected) { |
creator_->set_max_packets_per_fec_group(2); |
EXPECT_FALSE(creator_->IsFecProtected()); |
- generator_.StartBatchOperations(); |
// Send first packet, FEC protected. |
EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet_)); |
- // Write enough data to cause a packet to be emitted. |
- size_t data_len = kDefaultMaxPacketSize; |
- QuicConsumedData consumed = generator_.ConsumeData( |
- 5, CreateData(data_len), 0, true, MUST_FEC_PROTECT, nullptr); |
- EXPECT_EQ(data_len, consumed.bytes_consumed); |
+ QuicConsumedData consumed = generator_.ConsumeData(5, CreateData(1u), 0, true, |
+ MUST_FEC_PROTECT, nullptr); |
+ EXPECT_EQ(1u, consumed.bytes_consumed); |
PacketContents contents; |
contents.num_stream_frames = 1u; |
contents.fec_group = 1u; |
@@ -836,7 +946,7 @@ TEST_F(QuicPacketGeneratorTest, SwitchFecOnOffWithSubsequentPacketsProtected) { |
// FEC should still be on in creator. |
EXPECT_TRUE(creator_->IsFecProtected()); |
- // Send enough unprotected data to cause second packet to be sent, which gets |
+ // Send unprotected data to cause second packet to be sent, which gets |
// protected because it happens to fall within an open FEC group. Data packet |
// will be followed by FEC packet. |
{ |
@@ -846,10 +956,10 @@ TEST_F(QuicPacketGeneratorTest, SwitchFecOnOffWithSubsequentPacketsProtected) { |
EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce( |
SaveArg<0>(&packet3_)); |
} |
- consumed = generator_.ConsumeData(5, CreateData(data_len), 0, true, |
- MAY_FEC_PROTECT, nullptr); |
- EXPECT_EQ(data_len, consumed.bytes_consumed); |
- contents.num_stream_frames = 2u; |
+ consumed = generator_.ConsumeData(5, CreateData(1u), 0, true, MAY_FEC_PROTECT, |
+ nullptr); |
+ EXPECT_EQ(1u, consumed.bytes_consumed); |
+ contents.num_stream_frames = 1u; |
CheckPacketContains(contents, packet2_); |
CheckPacketIsFec(packet3_, /*fec_group=*/1u); |
@@ -907,7 +1017,7 @@ TEST_F(QuicPacketGeneratorTest, SwitchFecOnOffThenOnWithCreatorProtectionOn) { |
TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations) { |
delegate_.SetCanNotWrite(); |
- generator_.SetShouldSendAck(true, false); |
+ generator_.SetShouldSendAck(false); |
generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame())); |
EXPECT_TRUE(generator_.HasQueuedFrames()); |
@@ -915,11 +1025,8 @@ TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations) { |
generator_.StartBatchOperations(); |
- // When the first write operation is invoked, the ack and feedback |
- // frames will be returned. |
+ // When the first write operation is invoked, the ack frame will be returned. |
EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame())); |
- EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce( |
- Return(CreateFeedbackFrame())); |
// Send some data and a control frame |
generator_.ConsumeData(3, MakeIOVector("quux"), 7, false, MAY_FEC_PROTECT, |
@@ -934,7 +1041,6 @@ TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations) { |
PacketContents contents; |
contents.num_ack_frames = 1; |
contents.num_goaway_frames = 1; |
- contents.num_feedback_frames = 1; |
contents.num_rst_stream_frames = 1; |
contents.num_stream_frames = 1; |
CheckPacketContains(contents, packet_); |
@@ -943,7 +1049,7 @@ TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations) { |
TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations2) { |
delegate_.SetCanNotWrite(); |
- generator_.SetShouldSendAck(true, false); |
+ generator_.SetShouldSendAck(false); |
generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame())); |
EXPECT_TRUE(generator_.HasQueuedFrames()); |
@@ -951,11 +1057,8 @@ TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations2) { |
generator_.StartBatchOperations(); |
- // When the first write operation is invoked, the ack and feedback |
- // frames will be returned. |
+ // When the first write operation is invoked, the ack frame will be returned. |
EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame())); |
- EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce( |
- Return(CreateFeedbackFrame())); |
{ |
InSequence dummy; |
@@ -980,7 +1083,6 @@ TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations2) { |
// The first packet should have the queued data and part of the stream data. |
PacketContents contents; |
contents.num_ack_frames = 1; |
- contents.num_feedback_frames = 1; |
contents.num_rst_stream_frames = 1; |
contents.num_stream_frames = 1; |
CheckPacketContains(contents, packet_); |