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

Unified Diff: net/quic/quic_connection_test.cc

Issue 23464033: Land Recent QUIC changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix valgrind error Created 7 years, 3 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_crypto_client_stream.cc » ('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 6e4631b749e9497aff66172d5497d7c56cc5d156..e57e7aea192ca469dd7c518e30e26b40565578b8 100644
--- a/net/quic/quic_connection_test.cc
+++ b/net/quic/quic_connection_test.cc
@@ -570,20 +570,27 @@ class QuicConnectionTest : public ::testing::Test {
return ProcessDataPacket(number, 1, entropy_flag);
}
- // Sends an FEC packet that covers the packets that would have been sent.
+ // Processes an FEC packet that covers the packets that would have been
+ // received.
size_t ProcessFecPacket(QuicPacketSequenceNumber number,
QuicPacketSequenceNumber min_protected_packet,
bool expect_revival,
- bool entropy_flag) {
+ bool entropy_flag,
+ QuicPacket* packet) {
if (expect_revival) {
EXPECT_CALL(visitor_, OnPacket(_, _, _, _)).WillOnce(DoAll(
SaveArg<2>(&revived_header_), Return(accept_packet_)));
}
// Construct the decrypted data packet so we can compute the correct
- // redundancy.
- scoped_ptr<QuicPacket> data_packet(ConstructDataPacket(number, 1,
- !kEntropyFlag));
+ // redundancy. If |packet| has been provided then use that, otherwise
+ // construct a default data packet.
+ scoped_ptr<QuicPacket> data_packet;
+ if (packet) {
+ data_packet.reset(packet);
+ } else {
+ data_packet.reset(ConstructDataPacket(number, 1, !kEntropyFlag));
+ }
header_.public_header.guid = guid_;
header_.public_header.reset_flag = false;
@@ -595,6 +602,7 @@ class QuicConnectionTest : public ::testing::Test {
header_.fec_group = min_protected_packet;
QuicFecData fec_data;
fec_data.fec_group = header_.fec_group;
+
// Since all data packets in this test have the same payload, the
// redundancy is either equal to that payload or the xor of that payload
// with itself, depending on the number of packets.
@@ -608,6 +616,7 @@ class QuicConnectionTest : public ::testing::Test {
}
}
fec_data.redundancy = data_packet->FecProtectedData();
+
scoped_ptr<QuicPacket> fec_packet(
framer_.BuildFecPacket(header_, fec_data).packet);
scoped_ptr<QuicEncryptedPacket> encrypted(
@@ -1598,14 +1607,14 @@ TEST_F(QuicConnectionTest, DontLatchUnackedPacket) {
TEST_F(QuicConnectionTest, ReviveMissingPacketAfterFecPacket) {
// Don't send missing packet 1.
- ProcessFecPacket(2, 1, true, !kEntropyFlag);
+ ProcessFecPacket(2, 1, true, !kEntropyFlag, NULL);
EXPECT_FALSE(revived_header_.entropy_flag);
}
TEST_F(QuicConnectionTest, ReviveMissingPacketAfterDataPacketThenFecPacket) {
ProcessFecProtectedPacket(1, false, kEntropyFlag);
// Don't send missing packet 2.
- ProcessFecPacket(3, 1, true, !kEntropyFlag);
+ ProcessFecPacket(3, 1, true, !kEntropyFlag, NULL);
EXPECT_TRUE(revived_header_.entropy_flag);
}
@@ -1613,13 +1622,13 @@ TEST_F(QuicConnectionTest, ReviveMissingPacketAfterDataPacketsThenFecPacket) {
ProcessFecProtectedPacket(1, false, !kEntropyFlag);
// Don't send missing packet 2.
ProcessFecProtectedPacket(3, false, !kEntropyFlag);
- ProcessFecPacket(4, 1, true, kEntropyFlag);
+ ProcessFecPacket(4, 1, true, kEntropyFlag, NULL);
EXPECT_TRUE(revived_header_.entropy_flag);
}
TEST_F(QuicConnectionTest, ReviveMissingPacketAfterDataPacket) {
// Don't send missing packet 1.
- ProcessFecPacket(3, 1, false, !kEntropyFlag);
+ ProcessFecPacket(3, 1, false, !kEntropyFlag, NULL);
// out of order
ProcessFecProtectedPacket(2, true, !kEntropyFlag);
EXPECT_FALSE(revived_header_.entropy_flag);
@@ -1628,7 +1637,7 @@ TEST_F(QuicConnectionTest, ReviveMissingPacketAfterDataPacket) {
TEST_F(QuicConnectionTest, ReviveMissingPacketAfterDataPackets) {
ProcessFecProtectedPacket(1, false, !kEntropyFlag);
// Don't send missing packet 2.
- ProcessFecPacket(6, 1, false, kEntropyFlag);
+ ProcessFecPacket(6, 1, false, kEntropyFlag, NULL);
ProcessFecProtectedPacket(3, false, kEntropyFlag);
ProcessFecProtectedPacket(4, false, kEntropyFlag);
ProcessFecProtectedPacket(5, true, !kEntropyFlag);
@@ -1899,7 +1908,7 @@ TEST_F(QuicConnectionTest, DontUpdateQuicCongestionFeedbackFrameForRevived) {
// Process an FEC packet, and revive the missing data packet
// but only contact the receive_algorithm once.
EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _, _));
- ProcessFecPacket(2, 1, true, !kEntropyFlag);
+ ProcessFecPacket(2, 1, true, !kEntropyFlag, NULL);
}
TEST_F(QuicConnectionTest, InitialTimeout) {
@@ -2477,7 +2486,7 @@ TEST_F(QuicConnectionTest, CheckReceiveStats) {
received_bytes += ProcessFecProtectedPacket(3, false, !kEntropyFlag);
// Should be counted against dropped packets.
received_bytes += ProcessDataPacket(3, 1, !kEntropyFlag);
- received_bytes += ProcessFecPacket(4, 1, true, !kEntropyFlag); // Fec packet
+ received_bytes += ProcessFecPacket(4, 1, true, !kEntropyFlag, NULL);
EXPECT_CALL(*send_algorithm_, SmoothedRtt()).WillOnce(
Return(QuicTime::Delta::Zero()));
@@ -2612,6 +2621,129 @@ TEST_F(QuicConnectionTest, ConnectionCloseWhenNothingPending) {
EXPECT_EQ(1u, helper_->packets_write_attempts());
}
+TEST_F(QuicConnectionTest, AckNotifierTriggerCallback) {
+ // Create a delegate which we expect to be called.
+ MockAckNotifierDelegate delegate;
+ EXPECT_CALL(delegate, OnAckNotification()).Times(1);;
+
+ // Send some data, which will register the delegate to be notified.
+ connection_.SendStreamDataAndNotifyWhenAcked(1, "foo", 0, !kFin, &delegate);
+
+ // Process an ACK from the server which should trigger the callback.
+ EXPECT_CALL(visitor_, OnAck(_)).Times(1);
+ EXPECT_CALL(*send_algorithm_, OnIncomingAck(_, _, _)).Times(1);
+ QuicAckFrame frame(1, QuicTime::Zero(), 0);
+ ProcessAckPacket(&frame, true);
+}
+
+TEST_F(QuicConnectionTest, AckNotifierFailToTriggerCallback) {
+ // Create a delegate which we don't expect to be called.
+ MockAckNotifierDelegate delegate;
+ EXPECT_CALL(delegate, OnAckNotification()).Times(0);;
+
+ EXPECT_CALL(visitor_, OnAck(_)).Times(1);
+ EXPECT_CALL(*send_algorithm_, OnIncomingAck(_, _, _)).Times(2);
+ EXPECT_CALL(*send_algorithm_, OnIncomingLoss(_)).Times(1);
+
+ // Send some data, which will register the delegate to be notified. This will
+ // not be ACKed and so the delegate should never be called.
+ connection_.SendStreamDataAndNotifyWhenAcked(1, "foo", 0, !kFin, &delegate);
+
+ // Send some other data which we will ACK.
+ connection_.SendStreamData(1, "foo", 0, !kFin);
+ connection_.SendStreamData(1, "bar", 0, !kFin);
+
+ // Now we receive ACK for packets 2 and 3, but importantly missing packet 1
+ // which we registered to be notified about.
+ QuicAckFrame frame(3, QuicTime::Zero(), 0);
+ frame.received_info.missing_packets.insert(1);
+ ProcessAckPacket(&frame, true);
+}
+
+TEST_F(QuicConnectionTest, AckNotifierCallbackAfterRetransmission) {
+ // Create a delegate which we expect to be called.
+ MockAckNotifierDelegate delegate;
+ EXPECT_CALL(delegate, OnAckNotification()).Times(1);;
+
+ // OnAck called twice: once with missing packet, once after retransmit.
+ EXPECT_CALL(visitor_, OnAck(_)).Times(2);
+
+ // In total expect ACKs for all 4 packets.
+ EXPECT_CALL(*send_algorithm_, OnIncomingAck(_, _, _)).Times(4);
+
+ // We will lose the second packet.
+ EXPECT_CALL(*send_algorithm_, OnIncomingLoss(_)).Times(1);
+
+ // Send four packets, and register to be notified on ACK of packet 2.
+ connection_.SendStreamData(1, "foo", 0, !kFin);
+ connection_.SendStreamDataAndNotifyWhenAcked(1, "bar", 0, !kFin, &delegate);
+ connection_.SendStreamData(1, "baz", 0, !kFin);
+ connection_.SendStreamData(1, "qux", 0, !kFin);
+
+ // Now we receive ACK for packets 1, 3, and 4.
+ QuicAckFrame frame(4, QuicTime::Zero(), 0);
+ frame.received_info.missing_packets.insert(2);
+ ProcessAckPacket(&frame, true);
+
+ // Advance time to trigger RTO, for packet 2 (which should be retransmitted as
+ // packet 5).
+ EXPECT_CALL(*send_algorithm_, AbandoningPacket(2, _)).Times(1);
+ EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(1);
+
+ clock_.AdvanceTime(DefaultRetransmissionTime());
+ connection_.OnRetransmissionTimeout();
+
+ // Now we get an ACK for packet 5 (retransmitted packet 2), which should
+ // trigger the callback.
+ QuicAckFrame second_ack_frame(5, QuicTime::Zero(), 0);
+ ProcessAckPacket(&second_ack_frame, true);
+}
+
+// TODO(rjshade): Add a similar test that FEC recovery on peer (and resulting
+// ACK) triggers notification on our end.
+TEST_F(QuicConnectionTest, AckNotifierCallbackAfterFECRecovery) {
+ EXPECT_CALL(visitor_, OnCanWrite()).Times(1).WillOnce(Return(true));
+
+ // Create a delegate which we expect to be called.
+ MockAckNotifierDelegate delegate;
+ EXPECT_CALL(delegate, OnAckNotification()).Times(1);;
+
+ // Expect ACKs for 1 packet.
+ EXPECT_CALL(visitor_, OnAck(_)).Times(1);
+ EXPECT_CALL(*send_algorithm_, OnIncomingAck(_, _, _)).Times(1);
+
+ // Send one packet, and register to be notified on ACK.
+ connection_.SendStreamDataAndNotifyWhenAcked(1, "foo", 0, !kFin, &delegate);
+
+ // Ack packet gets dropped, but we receive an FEC packet that covers it.
+ // Should recover the Ack packet and trigger the notification callback.
+ QuicFrames frames;
+
+ QuicAckFrame ack_frame(1, QuicTime::Zero(), 0);
+ frames.push_back(QuicFrame(&ack_frame));
+
+ // Dummy stream frame to satisfy expectations set elsewhere.
+ QuicFrame frame(&frame1_);
+ frames.push_back(frame);
+
+ QuicPacketHeader ack_header;
+ ack_header.public_header.guid = guid_;
+ ack_header.public_header.reset_flag = false;
+ ack_header.public_header.version_flag = false;
+ ack_header.entropy_flag = !kEntropyFlag;
+ ack_header.fec_flag = true;
+ ack_header.packet_sequence_number = 42;
+ ack_header.is_in_fec_group = IN_FEC_GROUP;
+ ack_header.fec_group = 1;
+
+ QuicPacket* packet =
+ framer_.BuildUnsizedDataPacket(ack_header, frames).packet;
+
+ // Take the packet which contains the ACK frame, and construct and deliver an
+ // FEC packet which allows the ACK packet to be recovered.
+ ProcessFecPacket(2, 1, true, !kEntropyFlag, packet);
+}
+
class MockQuicConnectionDebugVisitor
: public QuicConnectionDebugVisitorInterface {
public:
« no previous file with comments | « net/quic/quic_connection.cc ('k') | net/quic/quic_crypto_client_stream.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698