Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / net / quic / quic_connection_test.cc
index e2b0fef..a210fe2 100644 (file)
@@ -31,6 +31,7 @@ using std::map;
 using std::vector;
 using testing::_;
 using testing::AnyNumber;
+using testing::AtLeast;
 using testing::ContainerEq;
 using testing::Contains;
 using testing::DoAll;
@@ -76,8 +77,8 @@ class TestReceiveAlgorithm : public ReceiveAlgorithmInterface {
     return true;
   }
 
-  MOCK_METHOD4(RecordIncomingPacket,
-               void(QuicByteCount, QuicPacketSequenceNumber, QuicTime, bool));
+  MOCK_METHOD3(RecordIncomingPacket,
+               void(QuicByteCount, QuicPacketSequenceNumber, QuicTime));
 
  private:
   QuicCongestionFeedbackFrame* feedback_;
@@ -274,7 +275,7 @@ class TestPacketWriter : public QuicPacketWriter {
   TestPacketWriter()
       : last_packet_size_(0),
         write_blocked_(false),
-        block_next_write_(false),
+        block_on_next_write_(false),
         is_write_blocked_data_buffered_(false),
         is_server_(true),
         final_bytes_of_last_packet_(0),
@@ -287,8 +288,7 @@ class TestPacketWriter : public QuicPacketWriter {
   virtual WriteResult WritePacket(
       const char* buffer, size_t buf_len,
       const IPAddressNumber& self_address,
-      const IPEndPoint& peer_address,
-      QuicBlockedWriterInterface* blocked_writer) OVERRIDE {
+      const IPEndPoint& peer_address) OVERRIDE {
     QuicEncryptedPacket packet(buffer, buf_len);
     ++packets_write_attempts_;
 
@@ -305,9 +305,9 @@ class TestPacketWriter : public QuicPacketWriter {
     visitor_.Reset();
     framer.set_visitor(&visitor_);
     EXPECT_TRUE(framer.ProcessPacket(packet));
-    if (block_next_write_) {
+    if (block_on_next_write_) {
       write_blocked_ = true;
-      block_next_write_ = false;
+      block_on_next_write_ = false;
     }
     if (IsWriteBlocked()) {
       return WriteResult(WRITE_STATUS_BLOCKED, -1);
@@ -324,7 +324,7 @@ class TestPacketWriter : public QuicPacketWriter {
 
   virtual void SetWritable() OVERRIDE { write_blocked_ = false; }
 
-  void BlockNextWrite() { block_next_write_ = true; }
+  void BlockOnNextWrite() { block_on_next_write_ = true; }
 
   // Resets the visitor's state by clearing out the headers and frames.
   void Reset() {
@@ -380,7 +380,7 @@ class TestPacketWriter : public QuicPacketWriter {
   FramerVisitorCapturingFrames visitor_;
   size_t last_packet_size_;
   bool write_blocked_;
-  bool block_next_write_;
+  bool block_on_next_write_;
   bool is_write_blocked_data_buffered_;
   bool is_server_;
   uint32 final_bytes_of_last_packet_;
@@ -454,6 +454,12 @@ class TestConnection : public QuicConnection {
     return SendStreamDataWithString(kStreamId5, "food2", 0, !kFin, NULL);
   }
 
+  // Ensures the connection can write stream data before writing.
+  QuicConsumedData EnsureWritableAndSendStreamData5() {
+    EXPECT_TRUE(CanWriteStreamData());
+    return SendStreamData5();
+  }
+
   // The crypto stream has special semantics so that it is not blocked by a
   // congestion window limitation, and also so that it gets put into a separate
   // packet (so that it is easier to reason about a crypto frame not being
@@ -472,7 +478,7 @@ class TestConnection : public QuicConnection {
   }
 
   void set_version(QuicVersion version) {
-    framer_.set_version(version);
+    QuicConnectionPeer::GetFramer(this)->set_version(version);
   }
 
   void set_is_server(bool is_server) {
@@ -538,7 +544,7 @@ class QuicConnectionTest : public ::testing::TestWithParam<bool> {
         *send_algorithm_, TimeUntilSend(_, _, _, _)).WillRepeatedly(Return(
             QuicTime::Delta::Zero()));
     EXPECT_CALL(*receive_algorithm_,
-                RecordIncomingPacket(_, _, _, _)).Times(AnyNumber());
+                RecordIncomingPacket(_, _, _)).Times(AnyNumber());
     EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
         .Times(AnyNumber());
     EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
@@ -638,7 +644,7 @@ class QuicConnectionTest : public ::testing::TestWithParam<bool> {
   }
 
   size_t ProcessFecProtectedPacket(QuicPacketSequenceNumber number,
-                                 bool expect_revival, bool entropy_flag) {
+                                   bool expect_revival, bool entropy_flag) {
     if (expect_revival) {
       EXPECT_CALL(visitor_, OnStreamFrames(_)).WillOnce(Return(accept_packet_));
     }
@@ -841,6 +847,11 @@ class QuicConnectionTest : public ::testing::TestWithParam<bool> {
         QuicConnectionPeer::GetConnectionClosePacket(&connection_) == NULL);
   }
 
+  void BlockOnNextWrite() {
+    writer_->BlockOnNextWrite();
+    EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
+  }
+
   QuicGuid guid_;
   QuicFramer framer_;
   QuicPacketCreator creator_;
@@ -1104,8 +1115,9 @@ TEST_F(QuicConnectionTest, LeastUnackedLower) {
   // This should be fine.
   creator_.set_sequence_number(1);
   QuicAckFrame frame2 = InitAckFrame(0, 1);
-  // The scheduler will not process out of order acks.
-  EXPECT_CALL(visitor_, OnCanWrite()).Times(0);
+  // The scheduler will not process out of order acks, but all packet processing
+  // causes the connection to try to write.
+  EXPECT_CALL(visitor_, OnCanWrite()).Times(1);
   ProcessAckPacket(&frame2);
 
   // Now claim it's one, but set the ordering so it was sent "after" the first
@@ -1257,8 +1269,6 @@ TEST_F(QuicConnectionTest, SendingDifferentSequenceNumberLengthsUnackedDelta) {
 
 TEST_F(QuicConnectionTest, BasicSending) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-//  EXPECT_CALL(*send_algorithm_, UpdateRtt(_));
-//  EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _)).Times(6);
   QuicPacketSequenceNumber last_packet;
   SendStreamDataToPeer(1, "foo", 0, !kFin, &last_packet);  // Packet 1
   EXPECT_EQ(1u, last_packet);
@@ -1340,7 +1350,7 @@ TEST_F(QuicConnectionTest, FECQueueing) {
   connection_.options()->max_packets_per_fec_group = 2;
 
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
-  writer_->BlockNextWrite();
+  BlockOnNextWrite();
   const string payload(payload_length, 'a');
   connection_.SendStreamDataWithString(1, payload, 0, !kFin, NULL);
   EXPECT_FALSE(creator_.ShouldSendFec(true));
@@ -1610,7 +1620,7 @@ TEST_F(QuicConnectionTest, FramePackingSendvQueued) {
   // Try to send two stream frames in 1 packet by using writev.
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, NOT_RETRANSMISSION, _));
 
-  writer_->BlockNextWrite();
+  BlockOnNextWrite();
   char data[] = "ABCD";
   IOVector data_iov;
   data_iov.AppendNoCoalesce(data, 2);
@@ -1729,10 +1739,9 @@ TEST_F(QuicConnectionTest, DiscardRetransmit) {
   NackPacket(2, &nack_two);
   // The first nack should trigger a fast retransmission, but we'll be
   // write blocked, so the packet will be queued.
-  writer_->BlockNextWrite();
+  BlockOnNextWrite();
   EXPECT_CALL(*send_algorithm_, UpdateRtt(_));
   EXPECT_CALL(*send_algorithm_, OnPacketAcked(_, _));
-
   ProcessAckPacket(&nack_two);
   EXPECT_EQ(1u, connection_.NumQueuedPackets());
 
@@ -1779,7 +1788,7 @@ TEST_F(QuicConnectionTest, QueueAfterTwoRTOs) {
   }
 
   // Block the congestion window and ensure they're queued.
-  writer_->BlockNextWrite();
+  BlockOnNextWrite();
   clock_.AdvanceTime(DefaultRetransmissionTime());
   // Only one packet should be retransmitted.
   EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
@@ -1798,9 +1807,8 @@ TEST_F(QuicConnectionTest, QueueAfterTwoRTOs) {
 }
 
 TEST_F(QuicConnectionTest, WriteBlockedThenSent) {
-  writer_->BlockNextWrite();
+  BlockOnNextWrite();
   writer_->set_is_write_blocked_data_buffered(true);
-
   connection_.SendStreamDataWithString(1, "foo", 0, !kFin, NULL);
   EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
 
@@ -1811,8 +1819,7 @@ TEST_F(QuicConnectionTest, WriteBlockedThenSent) {
 
 TEST_F(QuicConnectionTest, WriteBlockedAckedThenSent) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  writer_->BlockNextWrite();
-
+  BlockOnNextWrite();
   writer_->set_is_write_blocked_data_buffered(true);
   connection_.SendStreamDataWithString(1, "foo", 0, !kFin, NULL);
   EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
@@ -1832,9 +1839,8 @@ TEST_F(QuicConnectionTest, RetransmitWriteBlockedAckedOriginalThenSent) {
   connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL);
   EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
 
-  writer_->BlockNextWrite();
+  BlockOnNextWrite();
   writer_->set_is_write_blocked_data_buffered(true);
-
   // Simulate the retransmission alarm firing.
   EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(_));
   clock_.AdvanceTime(DefaultRetransmissionTime());
@@ -1847,12 +1853,14 @@ TEST_F(QuicConnectionTest, RetransmitWriteBlockedAckedOriginalThenSent) {
   ProcessAckPacket(&ack);
 
   connection_.OnPacketSent(WriteResult(WRITE_STATUS_OK, 0));
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
+  // The retransmission alarm should not be set because there are
+  // no unacked packets.
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
 }
 
 TEST_F(QuicConnectionTest, ResumptionAlarmWhenWriteBlocked) {
   // Block the connection.
-  writer_->BlockNextWrite();
+  BlockOnNextWrite();
   connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL);
   EXPECT_EQ(1u, writer_->packets_write_attempts());
   EXPECT_TRUE(writer_->IsWriteBlocked());
@@ -1983,8 +1991,9 @@ TEST_F(QuicConnectionTest, ReviveMissingPacketAfterDataPacketsThenFecPacket) {
   // Don't send missing packet 2.
   ProcessFecProtectedPacket(3, false, !kEntropyFlag);
   ProcessFecPacket(4, 1, true, kEntropyFlag, NULL);
-  // Entropy flag should be true, so entropy should not be 0.
-  EXPECT_NE(0u, QuicConnectionPeer::ReceivedEntropyHash(&connection_, 2));
+  // Ensure QUIC no longer revives entropy for lost packets.
+  EXPECT_EQ(0u, QuicConnectionPeer::ReceivedEntropyHash(&connection_, 2));
+  EXPECT_NE(0u, QuicConnectionPeer::ReceivedEntropyHash(&connection_, 4));
 }
 
 TEST_F(QuicConnectionTest, ReviveMissingPacketAfterDataPacket) {
@@ -2007,8 +2016,9 @@ TEST_F(QuicConnectionTest, ReviveMissingPacketAfterDataPackets) {
   ProcessFecProtectedPacket(3, false, kEntropyFlag);
   ProcessFecProtectedPacket(4, false, kEntropyFlag);
   ProcessFecProtectedPacket(5, true, !kEntropyFlag);
-  // Entropy flag should be true, so entropy should be 0.
-  EXPECT_NE(0u, QuicConnectionPeer::ReceivedEntropyHash(&connection_, 2));
+  // Ensure entropy is not revived for the missing packet.
+  EXPECT_EQ(0u, QuicConnectionPeer::ReceivedEntropyHash(&connection_, 2));
+  EXPECT_NE(0u, QuicConnectionPeer::ReceivedEntropyHash(&connection_, 3));
 }
 
 TEST_F(QuicConnectionTest, RTO) {
@@ -2255,7 +2265,7 @@ TEST_F(QuicConnectionTest, RetransmissionCountCalculation) {
 }
 
 TEST_F(QuicConnectionTest, SetRTOAfterWritingToSocket) {
-  writer_->BlockNextWrite();
+  BlockOnNextWrite();
   connection_.SendStreamDataWithString(1, "foo", 0, !kFin, NULL);
   // Make sure that RTO is not started when the packet is queued.
   EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
@@ -2306,7 +2316,7 @@ TEST_F(QuicConnectionTest, DelayRTOWithAckReceipt) {
 
 TEST_F(QuicConnectionTest, TestQueued) {
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
-  writer_->BlockNextWrite();
+  BlockOnNextWrite();
   connection_.SendStreamDataWithString(1, "foo", 0, !kFin, NULL);
   EXPECT_EQ(1u, connection_.NumQueuedPackets());
 
@@ -2349,7 +2359,7 @@ TEST_F(QuicConnectionTest, WithQuicCongestionFeedbackFrame) {
 
 TEST_F(QuicConnectionTest, UpdateQuicCongestionFeedbackFrame) {
   SendAckPacketToPeer();
-  EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _, _));
+  EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _));
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   ProcessPacket(1);
 }
@@ -2359,7 +2369,7 @@ TEST_F(QuicConnectionTest, DontUpdateQuicCongestionFeedbackFrameForRevived) {
   SendAckPacketToPeer();
   // Process an FEC packet, and revive the missing data packet
   // but only contact the receive_algorithm once.
-  EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _, _));
+  EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _));
   ProcessFecPacket(2, 1, true, !kEntropyFlag, NULL);
 }
 
@@ -2461,7 +2471,7 @@ TEST_F(QuicConnectionTest, SendSchedulerForce) {
 
 TEST_F(QuicConnectionTest, SendSchedulerEAGAIN) {
   QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
-  writer_->BlockNextWrite();
+  BlockOnNextWrite();
   EXPECT_CALL(*send_algorithm_,
               TimeUntilSend(_, NOT_RETRANSMISSION, _, _)).WillOnce(
                   testing::Return(QuicTime::Delta::Zero()));
@@ -2709,6 +2719,56 @@ TEST_F(QuicConnectionTest, DontSendDelayedAckOnOutgoingCryptoPacket) {
   EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
 }
 
+TEST_F(QuicConnectionTest, BundleAckWithDataOnIncomingAck) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  connection_.SendStreamDataWithString(kStreamId3, "foo", 0, !kFin, NULL);
+  connection_.SendStreamDataWithString(kStreamId3, "foo", 3, !kFin, NULL);
+  // Ack the second packet, which will retransmit the first packet.
+  QuicAckFrame ack = InitAckFrame(2, 0);
+  NackPacket(1, &ack);
+  EXPECT_CALL(*send_algorithm_, UpdateRtt(_));
+  EXPECT_CALL(*send_algorithm_, OnPacketAcked(2, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnPacketLost(1, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnPacketAbandoned(1, _)).Times(1);
+  ProcessAckPacket(&ack);
+  EXPECT_EQ(1u, writer_->frame_count());
+  EXPECT_EQ(1u, writer_->stream_frames()->size());
+  writer_->Reset();
+
+  // Now ack the retransmission, which will both raise the high water mark
+  // and see if there is more data to send.
+  ack = InitAckFrame(3, 0);
+  NackPacket(1, &ack);
+  EXPECT_CALL(*send_algorithm_, UpdateRtt(_));
+  EXPECT_CALL(*send_algorithm_, OnPacketAcked(3, _)).Times(1);
+  ProcessAckPacket(&ack);
+  // TODO(ianswett): This extra ack should not be necessary, because the above
+  // ack raises the high water mark.
+  ProcessAckPacket(&ack);
+
+  // Check that ack alarm is set, but no packet is sent.
+  EXPECT_EQ(0u, writer_->frame_count());
+  EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+  writer_->Reset();
+
+  // Send the same ack, but send both data and an ack together.
+  ack = InitAckFrame(3, 0);
+  NackPacket(1, &ack);
+  EXPECT_CALL(visitor_, OnCanWrite()).WillOnce(DoAll(
+      IgnoreResult(InvokeWithoutArgs(
+          &connection_,
+          &TestConnection::EnsureWritableAndSendStreamData5)),
+      Return(true)));
+  ProcessAckPacket(&ack);
+
+  // Check that ack is bundled with outgoing data and the delayed ack
+  // alarm is reset.
+  EXPECT_EQ(2u, writer_->frame_count());
+  EXPECT_TRUE(writer_->ack());
+  EXPECT_EQ(1u, writer_->stream_frames()->size());
+  EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+}
+
 TEST_F(QuicConnectionTest, NoAckForClose) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   ProcessPacket(1);
@@ -2781,6 +2841,17 @@ TEST_F(QuicConnectionTest, ReceivedEntropyHashCalculation) {
   EXPECT_EQ(146u, outgoing_ack()->received_info.entropy_hash);
 }
 
+TEST_F(QuicConnectionTest, ReceivedEntropyHashCalculationHalfFEC) {
+  // FEC packets should not change the entropy hash calculation.
+  EXPECT_CALL(visitor_, OnStreamFrames(_)).WillRepeatedly(Return(true));
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  ProcessDataPacket(1, 1, kEntropyFlag);
+  ProcessFecPacket(4, 1, false, kEntropyFlag, NULL);
+  ProcessDataPacket(3, 3, !kEntropyFlag);
+  ProcessFecPacket(7, 3, false, kEntropyFlag, NULL);
+  EXPECT_EQ(146u, outgoing_ack()->received_info.entropy_hash);
+}
+
 TEST_F(QuicConnectionTest, UpdateEntropyForReceivedPackets) {
   EXPECT_CALL(visitor_, OnStreamFrames(_)).WillRepeatedly(Return(true));
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
@@ -2936,7 +3007,7 @@ TEST_F(QuicConnectionTest, ServerSendsVersionNegotiationPacketSocketBlocked) {
 
   framer_.set_version(QuicVersionMax());
   connection_.set_is_server(true);
-  writer_->BlockNextWrite();
+  BlockOnNextWrite();
   connection_.ProcessUdpPacket(IPEndPoint(), IPEndPoint(), *encrypted);
   EXPECT_EQ(0u, writer_->last_packet_size());
   EXPECT_TRUE(connection_.HasQueuedData());
@@ -2980,7 +3051,7 @@ TEST_F(QuicConnectionTest,
 
   framer_.set_version(QuicVersionMax());
   connection_.set_is_server(true);
-  writer_->BlockNextWrite();
+  BlockOnNextWrite();
   writer_->set_is_write_blocked_data_buffered(true);
   connection_.ProcessUdpPacket(IPEndPoint(), IPEndPoint(), *encrypted);
   EXPECT_EQ(0u, writer_->last_packet_size());
@@ -3258,14 +3329,14 @@ TEST_F(QuicConnectionTest, ConnectionCloseWhenWritable) {
 }
 
 TEST_F(QuicConnectionTest, ConnectionCloseGettingWriteBlocked) {
-  writer_->BlockNextWrite();
+  BlockOnNextWrite();
   TriggerConnectionClose();
   EXPECT_EQ(1u, writer_->packets_write_attempts());
   EXPECT_TRUE(writer_->IsWriteBlocked());
 }
 
 TEST_F(QuicConnectionTest, ConnectionCloseWhenWriteBlocked) {
-  writer_->BlockNextWrite();
+  BlockOnNextWrite();
   connection_.SendStreamDataWithString(1, "foo", 0, !kFin, NULL);
   EXPECT_EQ(1u, connection_.NumQueuedPackets());
   EXPECT_EQ(1u, writer_->packets_write_attempts());