Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / net / quic / quic_connection_test.cc
index 38ead0c..22ad200 100644 (file)
@@ -38,6 +38,7 @@ using testing::Contains;
 using testing::DoAll;
 using testing::InSequence;
 using testing::InvokeWithoutArgs;
+using testing::NiceMock;
 using testing::Ref;
 using testing::Return;
 using testing::SaveArg;
@@ -57,7 +58,6 @@ const bool kEntropyFlag = true;
 const QuicPacketEntropyHash kTestEntropyHash = 76;
 
 const int kDefaultRetransmissionTimeMs = 500;
-const int kMinRetransmissionTimeMs = 200;
 
 class TestReceiveAlgorithm : public ReceiveAlgorithmInterface {
  public:
@@ -412,16 +412,20 @@ class TestConnection : public QuicConnection {
   TestConnection(QuicConnectionId connection_id,
                  IPEndPoint address,
                  TestConnectionHelper* helper,
-                 TestPacketWriter* writer,
+                 const PacketWriterFactory& factory,
                  bool is_server,
                  QuicVersion version)
-      : QuicConnection(connection_id, address, helper, writer, is_server,
-                       SupportedVersions(version)),
-        writer_(writer) {
+      : QuicConnection(connection_id,
+                       address,
+                       helper,
+                       factory,
+                       /* owns_writer= */ false,
+                       is_server,
+                       SupportedVersions(version)) {
     // Disable tail loss probes for most tests.
     QuicSentPacketManagerPeer::SetMaxTailLossProbes(
         QuicConnectionPeer::GetSentPacketManager(this), 0);
-    writer_->set_is_server(is_server);
+    writer()->set_is_server(is_server);
   }
 
   void SendAck() {
@@ -533,11 +537,11 @@ class TestConnection : public QuicConnection {
 
   void SetSupportedVersions(const QuicVersionVector& versions) {
     QuicConnectionPeer::GetFramer(this)->SetSupportedVersions(versions);
-    writer_->SetSupportedVersions(versions);
+    writer()->SetSupportedVersions(versions);
   }
 
   void set_is_server(bool is_server) {
-    writer_->set_is_server(is_server);
+    writer()->set_is_server(is_server);
     QuicConnectionPeer::SetIsServer(this, is_server);
   }
 
@@ -574,7 +578,9 @@ class TestConnection : public QuicConnection {
   using QuicConnection::SelectMutualVersion;
 
  private:
-  TestPacketWriter* writer_;
+  TestPacketWriter* writer() {
+    return static_cast<TestPacketWriter*>(QuicConnection::writer());
+  }
 
   DISALLOW_COPY_AND_ASSIGN(TestConnection);
 };
@@ -597,6 +603,16 @@ class FecQuicConnectionDebugVisitor
   QuicPacketHeader revived_header_;
 };
 
+class MockPacketWriterFactory : public QuicConnection::PacketWriterFactory {
+ public:
+  MockPacketWriterFactory(QuicPacketWriter* writer) {
+    ON_CALL(*this, Create(_)).WillByDefault(Return(writer));
+  }
+  virtual ~MockPacketWriterFactory() {}
+
+  MOCK_CONST_METHOD1(Create, QuicPacketWriter*(QuicConnection* connection));
+};
+
 class QuicConnectionTest : public ::testing::TestWithParam<QuicVersion> {
  protected:
   QuicConnectionTest()
@@ -607,8 +623,9 @@ class QuicConnectionTest : public ::testing::TestWithParam<QuicVersion> {
         loss_algorithm_(new MockLossAlgorithm()),
         helper_(new TestConnectionHelper(&clock_, &random_generator_)),
         writer_(new TestPacketWriter(version())),
+        factory_(writer_.get()),
         connection_(connection_id_, IPEndPoint(), helper_.get(),
-                    writer_.get(), false, version()),
+                    factory_, false, version()),
         frame1_(1, false, 0, MakeIOVector(data1)),
         frame2_(1, false, 3, MakeIOVector(data2)),
         sequence_number_length_(PACKET_6BYTE_SEQUENCE_NUMBER),
@@ -632,10 +649,18 @@ class QuicConnectionTest : public ::testing::TestWithParam<QuicVersion> {
         Return(kMaxPacketSize));
     ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
         .WillByDefault(Return(true));
+    EXPECT_CALL(*send_algorithm_, HasReliableBandwidthEstimate())
+        .Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(QuicBandwidth::Zero()));
+    EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber());
+    EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber());
     EXPECT_CALL(visitor_, WillingAndAbleToWrite()).Times(AnyNumber());
     EXPECT_CALL(visitor_, HasPendingHandshake()).Times(AnyNumber());
     EXPECT_CALL(visitor_, OnCanWrite()).Times(AnyNumber());
     EXPECT_CALL(visitor_, HasOpenDataStreams()).WillRepeatedly(Return(false));
+    EXPECT_CALL(visitor_, OnCongestionWindowChange(_)).Times(AnyNumber());
 
     EXPECT_CALL(*loss_algorithm_, GetLossTimeout())
         .WillRepeatedly(Return(QuicTime::Zero()));
@@ -652,13 +677,13 @@ class QuicConnectionTest : public ::testing::TestWithParam<QuicVersion> {
     return outgoing_ack_.get();
   }
 
+  QuicStopWaitingFrame* stop_waiting() {
+    stop_waiting_.reset(
+        QuicConnectionPeer::CreateStopWaitingFrame(&connection_));
+    return stop_waiting_.get();
+  }
+
   QuicPacketSequenceNumber least_unacked() {
-    if (version() <= QUIC_VERSION_15) {
-      if (writer_->ack_frames().empty()) {
-        return 0;
-      }
-      return writer_->ack_frames()[0].sent_info.least_unacked;
-    }
     if (writer_->stop_waiting_frames().empty()) {
       return 0;
     }
@@ -708,6 +733,13 @@ class QuicConnectionTest : public ::testing::TestWithParam<QuicVersion> {
     return encrypted->length();
   }
 
+  void ProcessPingPacket(QuicPacketSequenceNumber number) {
+    scoped_ptr<QuicPacket> packet(ConstructPingPacket(number));
+    scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket(
+        ENCRYPTION_NONE, number, *packet));
+    connection_.ProcessUdpPacket(IPEndPoint(), IPEndPoint(), *encrypted);
+  }
+
   void ProcessClosePacket(QuicPacketSequenceNumber number,
                           QuicFecGroupNumber fec_group) {
     scoped_ptr<QuicPacket> packet(ConstructClosePacket(number, fec_group));
@@ -821,7 +853,7 @@ class QuicConnectionTest : public ::testing::TestWithParam<QuicVersion> {
   }
 
   bool IsMissing(QuicPacketSequenceNumber number) {
-    return IsAwaitingPacket(outgoing_ack()->received_info, number);
+    return IsAwaitingPacket(*outgoing_ack(), number);
   }
 
   QuicPacket* ConstructDataPacket(QuicPacketSequenceNumber number,
@@ -847,6 +879,27 @@ class QuicConnectionTest : public ::testing::TestWithParam<QuicVersion> {
     return packet;
   }
 
+  QuicPacket* ConstructPingPacket(QuicPacketSequenceNumber number) {
+    header_.public_header.connection_id = connection_id_;
+    header_.packet_sequence_number = number;
+    header_.public_header.reset_flag = false;
+    header_.public_header.version_flag = false;
+    header_.entropy_flag = false;
+    header_.fec_flag = false;
+    header_.is_in_fec_group = NOT_IN_FEC_GROUP;
+    header_.fec_group = 0;
+
+    QuicPingFrame ping;
+
+    QuicFrames frames;
+    QuicFrame frame(&ping);
+    frames.push_back(frame);
+    QuicPacket* packet =
+        BuildUnsizedDataPacket(&framer_, header_, frames).packet;
+    EXPECT_TRUE(packet != NULL);
+    return packet;
+  }
+
   QuicPacket* ConstructClosePacket(QuicPacketSequenceNumber number,
                                    QuicFecGroupNumber fec_group) {
     header_.public_header.connection_id = connection_id_;
@@ -880,16 +933,16 @@ class QuicConnectionTest : public ::testing::TestWithParam<QuicVersion> {
   }
 
   QuicTime::Delta DefaultDelayedAckTime() {
-    return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs/2);
+    return QuicTime::Delta::FromMilliseconds(kMaxDelayedAckTimeMs);
   }
 
   // Initialize a frame acknowledging all packets up to largest_observed.
-  const QuicAckFrame InitAckFrame(QuicPacketSequenceNumber largest_observed,
-                                  QuicPacketSequenceNumber least_unacked) {
-    QuicAckFrame frame(MakeAckFrame(largest_observed, least_unacked));
+  const QuicAckFrame InitAckFrame(QuicPacketSequenceNumber largest_observed) {
+    QuicAckFrame frame(MakeAckFrame(largest_observed));
     if (largest_observed > 0) {
-      frame.received_info.entropy_hash =
-        QuicConnectionPeer::GetSentEntropyHash(&connection_, largest_observed);
+      frame.entropy_hash =
+          QuicConnectionPeer::GetSentEntropyHash(&connection_,
+                                                 largest_observed);
     }
     return frame;
   }
@@ -900,27 +953,20 @@ class QuicConnectionTest : public ::testing::TestWithParam<QuicVersion> {
     frame.least_unacked = least_unacked;
     return frame;
   }
+
   // Explicitly nack a packet.
   void NackPacket(QuicPacketSequenceNumber missing, QuicAckFrame* frame) {
-    frame->received_info.missing_packets.insert(missing);
-    frame->received_info.entropy_hash ^=
-      QuicConnectionPeer::GetSentEntropyHash(&connection_, missing);
-    if (missing > 1) {
-      frame->received_info.entropy_hash ^=
-        QuicConnectionPeer::GetSentEntropyHash(&connection_, missing - 1);
-    }
+    frame->missing_packets.insert(missing);
+    frame->entropy_hash ^=
+        QuicConnectionPeer::PacketEntropy(&connection_, missing);
   }
 
   // Undo nacking a packet within the frame.
   void AckPacket(QuicPacketSequenceNumber arrived, QuicAckFrame* frame) {
-    EXPECT_THAT(frame->received_info.missing_packets, Contains(arrived));
-    frame->received_info.missing_packets.erase(arrived);
-    frame->received_info.entropy_hash ^=
-      QuicConnectionPeer::GetSentEntropyHash(&connection_, arrived);
-    if (arrived > 1) {
-      frame->received_info.entropy_hash ^=
-        QuicConnectionPeer::GetSentEntropyHash(&connection_, arrived - 1);
-    }
+    EXPECT_THAT(frame->missing_packets, Contains(arrived));
+    frame->missing_packets.erase(arrived);
+    frame->entropy_hash ^=
+        QuicConnectionPeer::PacketEntropy(&connection_, arrived);
   }
 
   void TriggerConnectionClose() {
@@ -963,6 +1009,7 @@ class QuicConnectionTest : public ::testing::TestWithParam<QuicVersion> {
   MockRandom random_generator_;
   scoped_ptr<TestConnectionHelper> helper_;
   scoped_ptr<TestPacketWriter> writer_;
+  NiceMock<MockPacketWriterFactory> factory_;
   TestConnection connection_;
   StrictMock<MockConnectionVisitor> visitor_;
 
@@ -970,6 +1017,7 @@ class QuicConnectionTest : public ::testing::TestWithParam<QuicVersion> {
   QuicStreamFrame frame1_;
   QuicStreamFrame frame2_;
   scoped_ptr<QuicAckFrame> outgoing_ack_;
+  scoped_ptr<QuicStopWaitingFrame> stop_waiting_;
   QuicSequenceNumberLength sequence_number_length_;
   QuicConnectionIdLength connection_id_length_;
 
@@ -986,33 +1034,33 @@ TEST_P(QuicConnectionTest, PacketsInOrder) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
   ProcessPacket(1);
-  EXPECT_EQ(1u, outgoing_ack()->received_info.largest_observed);
-  EXPECT_EQ(0u, outgoing_ack()->received_info.missing_packets.size());
+  EXPECT_EQ(1u, outgoing_ack()->largest_observed);
+  EXPECT_EQ(0u, outgoing_ack()->missing_packets.size());
 
   ProcessPacket(2);
-  EXPECT_EQ(2u, outgoing_ack()->received_info.largest_observed);
-  EXPECT_EQ(0u, outgoing_ack()->received_info.missing_packets.size());
+  EXPECT_EQ(2u, outgoing_ack()->largest_observed);
+  EXPECT_EQ(0u, outgoing_ack()->missing_packets.size());
 
   ProcessPacket(3);
-  EXPECT_EQ(3u, outgoing_ack()->received_info.largest_observed);
-  EXPECT_EQ(0u, outgoing_ack()->received_info.missing_packets.size());
+  EXPECT_EQ(3u, outgoing_ack()->largest_observed);
+  EXPECT_EQ(0u, outgoing_ack()->missing_packets.size());
 }
 
 TEST_P(QuicConnectionTest, PacketsOutOfOrder) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
   ProcessPacket(3);
-  EXPECT_EQ(3u, outgoing_ack()->received_info.largest_observed);
+  EXPECT_EQ(3u, outgoing_ack()->largest_observed);
   EXPECT_TRUE(IsMissing(2));
   EXPECT_TRUE(IsMissing(1));
 
   ProcessPacket(2);
-  EXPECT_EQ(3u, outgoing_ack()->received_info.largest_observed);
+  EXPECT_EQ(3u, outgoing_ack()->largest_observed);
   EXPECT_FALSE(IsMissing(2));
   EXPECT_TRUE(IsMissing(1));
 
   ProcessPacket(1);
-  EXPECT_EQ(3u, outgoing_ack()->received_info.largest_observed);
+  EXPECT_EQ(3u, outgoing_ack()->largest_observed);
   EXPECT_FALSE(IsMissing(2));
   EXPECT_FALSE(IsMissing(1));
 }
@@ -1021,14 +1069,14 @@ TEST_P(QuicConnectionTest, DuplicatePacket) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
   ProcessPacket(3);
-  EXPECT_EQ(3u, outgoing_ack()->received_info.largest_observed);
+  EXPECT_EQ(3u, outgoing_ack()->largest_observed);
   EXPECT_TRUE(IsMissing(2));
   EXPECT_TRUE(IsMissing(1));
 
   // Send packet 3 again, but do not set the expectation that
   // the visitor OnStreamFrames() will be called.
   ProcessDataPacket(3, 0, !kEntropyFlag);
-  EXPECT_EQ(3u, outgoing_ack()->received_info.largest_observed);
+  EXPECT_EQ(3u, outgoing_ack()->largest_observed);
   EXPECT_TRUE(IsMissing(2));
   EXPECT_TRUE(IsMissing(1));
 }
@@ -1037,16 +1085,16 @@ TEST_P(QuicConnectionTest, PacketsOutOfOrderWithAdditionsAndLeastAwaiting) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
   ProcessPacket(3);
-  EXPECT_EQ(3u, outgoing_ack()->received_info.largest_observed);
+  EXPECT_EQ(3u, outgoing_ack()->largest_observed);
   EXPECT_TRUE(IsMissing(2));
   EXPECT_TRUE(IsMissing(1));
 
   ProcessPacket(2);
-  EXPECT_EQ(3u, outgoing_ack()->received_info.largest_observed);
+  EXPECT_EQ(3u, outgoing_ack()->largest_observed);
   EXPECT_TRUE(IsMissing(1));
 
   ProcessPacket(5);
-  EXPECT_EQ(5u, outgoing_ack()->received_info.largest_observed);
+  EXPECT_EQ(5u, outgoing_ack()->largest_observed);
   EXPECT_TRUE(IsMissing(1));
   EXPECT_TRUE(IsMissing(4));
 
@@ -1055,7 +1103,7 @@ TEST_P(QuicConnectionTest, PacketsOutOfOrderWithAdditionsAndLeastAwaiting) {
   // awaiting' is 4.  The connection should then realize 1 will not be
   // retransmitted, and will remove it from the missing list.
   peer_creator_.set_sequence_number(5);
-  QuicAckFrame frame = InitAckFrame(1, 4);
+  QuicAckFrame frame = InitAckFrame(1);
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(_, _, _, _));
   ProcessAckPacket(&frame);
 
@@ -1097,7 +1145,7 @@ TEST_P(QuicConnectionTest, TruncatedAck) {
     SendStreamDataToPeer(3, "foo", i * 3, !kFin, NULL);
   }
 
-  QuicAckFrame frame = InitAckFrame(num_packets, 1);
+  QuicAckFrame frame = InitAckFrame(num_packets);
   SequenceNumberSet lost_packets;
   // Create an ack with 256 nacks, none adjacent to one another.
   for (QuicPacketSequenceNumber i = 1; i <= 256; ++i) {
@@ -1113,11 +1161,10 @@ TEST_P(QuicConnectionTest, TruncatedAck) {
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   ProcessAckPacket(&frame);
 
-  QuicReceivedPacketManager* received_packet_manager =
-      QuicConnectionPeer::GetReceivedPacketManager(&connection_);
+  const QuicSentPacketManager& sent_packet_manager =
+      connection_.sent_packet_manager();
   // A truncated ack will not have the true largest observed.
-  EXPECT_GT(num_packets,
-            received_packet_manager->peer_largest_observed_packet());
+  EXPECT_GT(num_packets, sent_packet_manager.largest_observed());
 
   AckPacket(192, &frame);
 
@@ -1127,8 +1174,7 @@ TEST_P(QuicConnectionTest, TruncatedAck) {
       .WillOnce(Return(SequenceNumberSet()));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   ProcessAckPacket(&frame);
-  EXPECT_EQ(num_packets,
-            received_packet_manager->peer_largest_observed_packet());
+  EXPECT_EQ(num_packets, sent_packet_manager.largest_observed());
 }
 
 TEST_P(QuicConnectionTest, AckReceiptCausesAckSendBadEntropy) {
@@ -1148,7 +1194,7 @@ TEST_P(QuicConnectionTest, AckReceiptCausesAckSendBadEntropy) {
                   testing::Return(QuicTime::Delta::Zero()));
   // Skip a packet and then record an ack.
   peer_creator_.set_sequence_number(2);
-  QuicAckFrame frame = InitAckFrame(0, 3);
+  QuicAckFrame frame = InitAckFrame(0);
   ProcessAckPacket(&frame);
 }
 
@@ -1181,7 +1227,7 @@ TEST_P(QuicConnectionTest, AckReceiptCausesAckSend) {
       .WillOnce(DoAll(SaveArg<2>(&original), SaveArg<3>(&packet_size),
                       Return(true)));
   connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL);
-  QuicAckFrame frame = InitAckFrame(original, 1);
+  QuicAckFrame frame = InitAckFrame(original);
   NackPacket(original, &frame);
   // First nack triggers early retransmit.
   SequenceNumberSet lost_packets;
@@ -1196,7 +1242,7 @@ TEST_P(QuicConnectionTest, AckReceiptCausesAckSend) {
 
   ProcessAckPacket(&frame);
 
-  QuicAckFrame frame2 = InitAckFrame(retransmission, 1);
+  QuicAckFrame frame2 = InitAckFrame(retransmission);
   NackPacket(original, &frame2);
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
@@ -1221,11 +1267,7 @@ TEST_P(QuicConnectionTest, AckReceiptCausesAckSend) {
                                              HAS_RETRANSMITTABLE_DATA));
   connection_.SendStreamDataWithString(3, "foo", 3, !kFin, NULL);
   // Ack bundled.
-  if (version() > QUIC_VERSION_15) {
-    EXPECT_EQ(3u, writer_->frame_count());
-  } else {
-    EXPECT_EQ(2u, writer_->frame_count());
-  }
+  EXPECT_EQ(3u, writer_->frame_count());
   EXPECT_EQ(1u, writer_->stream_frames().size());
   EXPECT_FALSE(writer_->ack_frames().empty());
 
@@ -1235,6 +1277,24 @@ TEST_P(QuicConnectionTest, AckReceiptCausesAckSend) {
   ProcessAckPacket(&frame2);
 }
 
+TEST_P(QuicConnectionTest, 20AcksCausesAckSend) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+
+  SendStreamDataToPeer(1, "foo", 0, !kFin, NULL);
+
+  QuicAlarm* ack_alarm = QuicConnectionPeer::GetAckAlarm(&connection_);
+  // But an ack with no missing packets will not send an ack.
+  QuicAckFrame frame = InitAckFrame(1);
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
+  EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
+      .WillRepeatedly(Return(SequenceNumberSet()));
+  for (int i = 0; i < 20; ++i) {
+    EXPECT_FALSE(ack_alarm->IsSet());
+    ProcessAckPacket(&frame);
+  }
+  EXPECT_TRUE(ack_alarm->IsSet());
+}
+
 TEST_P(QuicConnectionTest, LeastUnackedLower) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
@@ -1244,13 +1304,8 @@ TEST_P(QuicConnectionTest, LeastUnackedLower) {
 
   // Start out saying the least unacked is 2.
   peer_creator_.set_sequence_number(5);
-  if (version() > QUIC_VERSION_15) {
-    QuicStopWaitingFrame frame = InitStopWaitingFrame(2);
-    ProcessStopWaitingPacket(&frame);
-  } else {
-    QuicAckFrame frame = InitAckFrame(0, 2);
-    ProcessAckPacket(&frame);
-  }
+  QuicStopWaitingFrame frame = InitStopWaitingFrame(2);
+  ProcessStopWaitingPacket(&frame);
 
   // Change it to 1, but lower the sequence number to fake out-of-order packets.
   // This should be fine.
@@ -1258,28 +1313,17 @@ TEST_P(QuicConnectionTest, LeastUnackedLower) {
   // The scheduler will not process out of order acks, but all packet processing
   // causes the connection to try to write.
   EXPECT_CALL(visitor_, OnCanWrite());
-  if (version() > QUIC_VERSION_15) {
-    QuicStopWaitingFrame frame2 = InitStopWaitingFrame(1);
-    ProcessStopWaitingPacket(&frame2);
-  } else {
-    QuicAckFrame frame2 = InitAckFrame(0, 1);
-    ProcessAckPacket(&frame2);
-  }
+  QuicStopWaitingFrame frame2 = InitStopWaitingFrame(1);
+  ProcessStopWaitingPacket(&frame2);
 
   // Now claim it's one, but set the ordering so it was sent "after" the first
   // one.  This should cause a connection error.
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
   peer_creator_.set_sequence_number(7);
-  if (version() > QUIC_VERSION_15) {
-    EXPECT_CALL(visitor_,
-                OnConnectionClosed(QUIC_INVALID_STOP_WAITING_DATA, false));
-    QuicStopWaitingFrame frame2 = InitStopWaitingFrame(1);
-    ProcessStopWaitingPacket(&frame2);
-  } else {
-    EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_INVALID_ACK_DATA, false));
-    QuicAckFrame frame2 = InitAckFrame(0, 1);
-    ProcessAckPacket(&frame2);
-  }
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(QUIC_INVALID_STOP_WAITING_DATA, false));
+  QuicStopWaitingFrame frame3 = InitStopWaitingFrame(1);
+  ProcessStopWaitingPacket(&frame3);
 }
 
 TEST_P(QuicConnectionTest, LargestObservedLower) {
@@ -1291,8 +1335,8 @@ TEST_P(QuicConnectionTest, LargestObservedLower) {
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
 
   // Start out saying the largest observed is 2.
-  QuicAckFrame frame1 = InitAckFrame(1, 0);
-  QuicAckFrame frame2 = InitAckFrame(2, 0);
+  QuicAckFrame frame1 = InitAckFrame(1);
+  QuicAckFrame frame2 = InitAckFrame(2);
   ProcessAckPacket(&frame2);
 
   // Now change it to 1, and it should cause a connection error.
@@ -1306,7 +1350,7 @@ TEST_P(QuicConnectionTest, AckUnsentData) {
   EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_INVALID_ACK_DATA, false));
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-  QuicAckFrame frame(MakeAckFrame(1, 0));
+  QuicAckFrame frame(MakeAckFrame(1));
   EXPECT_CALL(visitor_, OnCanWrite()).Times(0);
   ProcessAckPacket(&frame);
 }
@@ -1316,7 +1360,7 @@ TEST_P(QuicConnectionTest, AckAll) {
   ProcessPacket(1);
 
   peer_creator_.set_sequence_number(1);
-  QuicAckFrame frame1 = InitAckFrame(0, 1);
+  QuicAckFrame frame1 = InitAckFrame(0);
   ProcessAckPacket(&frame1);
 }
 
@@ -1374,7 +1418,10 @@ TEST_P(QuicConnectionTest, SendingDifferentSequenceNumberLengthsBandwidth) {
             writer_->header().public_header.sequence_number_length);
 }
 
-TEST_P(QuicConnectionTest, SendingDifferentSequenceNumberLengthsUnackedDelta) {
+// TODO(ianswett): Re-enable this test by finding a good way to test different
+// sequence number lengths without sending packets with giant gaps.
+TEST_P(QuicConnectionTest,
+       DISABLED_SendingDifferentSequenceNumberLengthsUnackedDelta) {
   QuicPacketSequenceNumber last_packet;
   QuicPacketCreator* creator =
       QuicConnectionPeer::GetPacketCreator(&connection_);
@@ -1438,7 +1485,7 @@ TEST_P(QuicConnectionTest, BasicSending) {
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
 
   // Peer acks up to packet 3.
-  QuicAckFrame frame = InitAckFrame(3, 0);
+  QuicAckFrame frame = InitAckFrame(3);
   ProcessAckPacket(&frame);
   SendAckPacketToPeer();  // Packet 6
 
@@ -1449,7 +1496,7 @@ TEST_P(QuicConnectionTest, BasicSending) {
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
 
   // Peer acks up to packet 4, the last packet.
-  QuicAckFrame frame2 = InitAckFrame(6, 0);
+  QuicAckFrame frame2 = InitAckFrame(6);
   ProcessAckPacket(&frame2);  // Acks don't instigate acks.
 
   // Verify that we did not send an ack.
@@ -1484,11 +1531,8 @@ TEST_P(QuicConnectionTest, FECSending) {
           IN_FEC_GROUP, &payload_length);
   creator->set_max_packet_length(length);
 
-  // Enable FEC.
-  creator->set_max_packets_per_fec_group(2);
-
-  // Send 4 protected data packets, which will also trigger 2 FEC packets.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(6);
+  // Send 4 protected data packets, which should also trigger 1 FEC packet.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(5);
   // The first stream frame will have 2 fewer overhead bytes than the other 3.
   const string payload(payload_length * 4 + 2, 'a');
   connection_.SendStreamDataWithStringWithFec(1, payload, 0, !kFin, NULL);
@@ -1506,8 +1550,7 @@ TEST_P(QuicConnectionTest, FECQueueing) {
       connection_.version(), kIncludeVersion, PACKET_1BYTE_SEQUENCE_NUMBER,
       IN_FEC_GROUP, &payload_length);
   creator->set_max_packet_length(length);
-  // Enable FEC.
-  creator->set_max_packets_per_fec_group(1);
+  EXPECT_TRUE(creator->IsFecEnabled());
 
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
   BlockOnNextWrite();
@@ -1520,9 +1563,8 @@ TEST_P(QuicConnectionTest, FECQueueing) {
 }
 
 TEST_P(QuicConnectionTest, AbandonFECFromCongestionWindow) {
-  // Enable FEC.
-  QuicConnectionPeer::GetPacketCreator(
-      &connection_)->set_max_packets_per_fec_group(1);
+  EXPECT_TRUE(QuicConnectionPeer::GetPacketCreator(
+      &connection_)->IsFecEnabled());
 
   // 1 Data and 1 FEC packet.
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
@@ -1541,9 +1583,8 @@ TEST_P(QuicConnectionTest, AbandonFECFromCongestionWindow) {
 
 TEST_P(QuicConnectionTest, DontAbandonAckedFEC) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  // Enable FEC.
-  QuicConnectionPeer::GetPacketCreator(
-      &connection_)->set_max_packets_per_fec_group(1);
+  EXPECT_TRUE(QuicConnectionPeer::GetPacketCreator(
+      &connection_)->IsFecEnabled());
 
   // 1 Data and 1 FEC packet.
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(6);
@@ -1552,7 +1593,7 @@ TEST_P(QuicConnectionTest, DontAbandonAckedFEC) {
   connection_.SendStreamDataWithStringWithFec(3, "foo", 3, !kFin, NULL);
   connection_.SendStreamDataWithStringWithFec(3, "foo", 6, !kFin, NULL);
 
-  QuicAckFrame ack_fec = InitAckFrame(2, 1);
+  QuicAckFrame ack_fec = InitAckFrame(2);
   // Data packet missing.
   // TODO(ianswett): Note that this is not a sensible ack, since if the FEC was
   // received, it would cause the covered packet to be acked as well.
@@ -1570,9 +1611,8 @@ TEST_P(QuicConnectionTest, DontAbandonAckedFEC) {
 
 TEST_P(QuicConnectionTest, AbandonAllFEC) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  // Enable FEC.
-  QuicConnectionPeer::GetPacketCreator(
-      &connection_)->set_max_packets_per_fec_group(1);
+  EXPECT_TRUE(QuicConnectionPeer::GetPacketCreator(
+      &connection_)->IsFecEnabled());
 
   // 1 Data and 1 FEC packet.
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(6);
@@ -1583,7 +1623,7 @@ TEST_P(QuicConnectionTest, AbandonAllFEC) {
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
   connection_.SendStreamDataWithStringWithFec(3, "foo", 6, !kFin, NULL);
 
-  QuicAckFrame ack_fec = InitAckFrame(5, 1);
+  QuicAckFrame ack_fec = InitAckFrame(5);
   // Ack all data packets, but no fec packets.
   NackPacket(2, &ack_fec);
   NackPacket(4, &ack_fec);
@@ -1626,12 +1666,8 @@ TEST_P(QuicConnectionTest, FramePacking) {
 
   // Parse the last packet and ensure it's an ack and two stream frames from
   // two different streams.
-  if (version() > QUIC_VERSION_15) {
-    EXPECT_EQ(4u, writer_->frame_count());
-    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
-  } else {
-    EXPECT_EQ(3u, writer_->frame_count());
-  }
+  EXPECT_EQ(4u, writer_->frame_count());
+  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
   EXPECT_FALSE(writer_->ack_frames().empty());
   ASSERT_EQ(2u, writer_->stream_frames().size());
   EXPECT_EQ(kClientDataStreamId1, writer_->stream_frames()[0].stream_id);
@@ -1687,9 +1723,8 @@ TEST_P(QuicConnectionTest, FramePackingCryptoThenNonCrypto) {
 }
 
 TEST_P(QuicConnectionTest, FramePackingFEC) {
-  // Enable FEC.
-  QuicConnectionPeer::GetPacketCreator(
-      &connection_)->set_max_packets_per_fec_group(6);
+  EXPECT_TRUE(QuicConnectionPeer::GetPacketCreator(
+      &connection_)->IsFecEnabled());
 
   CongestionBlockWrites();
 
@@ -1729,7 +1764,7 @@ TEST_P(QuicConnectionTest, FramePackingAckResponse) {
 
   // Process an ack to cause the visitor's OnCanWrite to be invoked.
   peer_creator_.set_sequence_number(2);
-  QuicAckFrame ack_one = InitAckFrame(0, 0);
+  QuicAckFrame ack_one = InitAckFrame(0);
   ProcessAckPacket(&ack_one);
 
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
@@ -1737,12 +1772,8 @@ TEST_P(QuicConnectionTest, FramePackingAckResponse) {
 
   // Parse the last packet and ensure it's an ack and two stream frames from
   // two different streams.
-  if (version() > QUIC_VERSION_15) {
-    EXPECT_EQ(4u, writer_->frame_count());
-    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
-  } else {
-    EXPECT_EQ(3u, writer_->frame_count());
-  }
+  EXPECT_EQ(4u, writer_->frame_count());
+  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
   EXPECT_FALSE(writer_->ack_frames().empty());
   ASSERT_EQ(2u, writer_->stream_frames().size());
   EXPECT_EQ(kClientDataStreamId1, writer_->stream_frames()[0].stream_id);
@@ -1849,11 +1880,11 @@ TEST_P(QuicConnectionTest, RetransmitOnNack) {
 
   // Don't lose a packet on an ack, and nothing is retransmitted.
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
-  QuicAckFrame ack_one = InitAckFrame(1, 0);
+  QuicAckFrame ack_one = InitAckFrame(1);
   ProcessAckPacket(&ack_one);
 
   // Lose a packet and ensure it triggers retransmission.
-  QuicAckFrame nack_two = InitAckFrame(3, 0);
+  QuicAckFrame nack_two = InitAckFrame(3);
   NackPacket(2, &nack_two);
   SequenceNumberSet lost_packets;
   lost_packets.insert(2);
@@ -1875,7 +1906,7 @@ TEST_P(QuicConnectionTest, DiscardRetransmit) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
   // Instigate a loss with an ack.
-  QuicAckFrame nack_two = InitAckFrame(3, 0);
+  QuicAckFrame nack_two = InitAckFrame(3);
   NackPacket(2, &nack_two);
   // The first nack should trigger a fast retransmission, but we'll be
   // write blocked, so the packet will be queued.
@@ -1891,7 +1922,7 @@ TEST_P(QuicConnectionTest, DiscardRetransmit) {
   // Now, ack the previous transmission.
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(SequenceNumberSet()));
-  QuicAckFrame ack_all = InitAckFrame(3, 0);
+  QuicAckFrame ack_all = InitAckFrame(3);
   ProcessAckPacket(&ack_all);
 
   // Unblock the socket and attempt to send the queued packets.  However,
@@ -1915,7 +1946,7 @@ TEST_P(QuicConnectionTest, RetransmitNackedLargestObserved) {
                       Return(true)));
   connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL);
 
-  QuicAckFrame frame = InitAckFrame(1, largest_observed);
+  QuicAckFrame frame = InitAckFrame(1);
   NackPacket(largest_observed, &frame);
   // The first nack should retransmit the largest observed packet.
   SequenceNumberSet lost_packets;
@@ -1956,29 +1987,13 @@ TEST_P(QuicConnectionTest, QueueAfterTwoRTOs) {
 TEST_P(QuicConnectionTest, WriteBlockedThenSent) {
   BlockOnNextWrite();
   writer_->set_is_write_blocked_data_buffered(true);
-  connection_.SendStreamDataWithString(1, "foo", 0, !kFin, NULL);
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
-  connection_.OnPacketSent(WriteResult(WRITE_STATUS_OK, 0));
-  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, WriteBlockedAckedThenSent) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  BlockOnNextWrite();
-  writer_->set_is_write_blocked_data_buffered(true);
   connection_.SendStreamDataWithString(1, "foo", 0, !kFin, NULL);
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-
-  // Ack the sent packet before the callback returns, which happens in
-  // rare circumstances with write blocked sockets.
-  QuicAckFrame ack = InitAckFrame(1, 0);
-  ProcessAckPacket(&ack);
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
 
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
-  connection_.OnPacketSent(WriteResult(WRITE_STATUS_OK, 0));
-  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  writer_->SetWritable();
+  connection_.OnCanWrite();
+  EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
 }
 
 TEST_P(QuicConnectionTest, RetransmitWriteBlockedAckedOriginalThenSent) {
@@ -1995,11 +2010,13 @@ TEST_P(QuicConnectionTest, RetransmitWriteBlockedAckedOriginalThenSent) {
 
   // Ack the sent packet before the callback returns, which happens in
   // rare circumstances with write blocked sockets.
-  QuicAckFrame ack = InitAckFrame(1, 0);
+  QuicAckFrame ack = InitAckFrame(1);
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
+  EXPECT_CALL(*send_algorithm_, RevertRetransmissionTimeout());
   ProcessAckPacket(&ack);
 
-  connection_.OnPacketSent(WriteResult(WRITE_STATUS_OK, 0));
+  writer_->SetWritable();
+  connection_.OnCanWrite();
   // There is now a pending packet, but with no retransmittable frames.
   EXPECT_TRUE(connection_.GetRetransmissionAlarm()->IsSet());
   EXPECT_FALSE(connection_.sent_packet_manager().HasRetransmittableFrames(2));
@@ -2033,7 +2050,7 @@ TEST_P(QuicConnectionTest, NoLimitPacketsPerNack) {
 
   // Ack 15, nack 1-14.
   SequenceNumberSet lost_packets;
-  QuicAckFrame nack = InitAckFrame(15, 0);
+  QuicAckFrame nack = InitAckFrame(15);
   for (int i = 1; i < 15; ++i) {
     NackPacket(i, &nack);
     lost_packets.insert(i);
@@ -2065,14 +2082,14 @@ TEST_P(QuicConnectionTest, MultipleAcks) {
 
   // Client will ack packets 1, 2, [!3], 4, 5.
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
-  QuicAckFrame frame1 = InitAckFrame(5, 0);
+  QuicAckFrame frame1 = InitAckFrame(5);
   NackPacket(3, &frame1);
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   ProcessAckPacket(&frame1);
 
   // Now the client implicitly acks 3, and explicitly acks 6.
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
-  QuicAckFrame frame2 = InitAckFrame(6, 0);
+  QuicAckFrame frame2 = InitAckFrame(6);
   ProcessAckPacket(&frame2);
 }
 
@@ -2085,36 +2102,37 @@ TEST_P(QuicConnectionTest, DontLatchUnackedPacket) {
 
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
-  QuicAckFrame frame = InitAckFrame(1, 0);
+  QuicAckFrame frame = InitAckFrame(1);
   ProcessAckPacket(&frame);
 
   // Verify that our internal state has least-unacked as 2, because we're still
   // waiting for a potential ack for 2.
-  EXPECT_EQ(2u, outgoing_ack()->sent_info.least_unacked);
+
+  EXPECT_EQ(2u, stop_waiting()->least_unacked);
 
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
-  frame = InitAckFrame(2, 0);
+  frame = InitAckFrame(2);
   ProcessAckPacket(&frame);
-  EXPECT_EQ(3u, outgoing_ack()->sent_info.least_unacked);
+  EXPECT_EQ(3u, stop_waiting()->least_unacked);
 
   // When we send an ack, we make sure our least-unacked makes sense.  In this
   // case since we're not waiting on an ack for 2 and all packets are acked, we
   // set it to 3.
   SendAckPacketToPeer();  // Packet 3
   // Least_unacked remains at 3 until another ack is received.
-  EXPECT_EQ(3u, outgoing_ack()->sent_info.least_unacked);
+  EXPECT_EQ(3u, stop_waiting()->least_unacked);
   // Check that the outgoing ack had its sequence number as least_unacked.
   EXPECT_EQ(3u, least_unacked());
 
   // Ack the ack, which updates the rtt and raises the least unacked.
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
-  frame = InitAckFrame(3, 0);
+  frame = InitAckFrame(3);
   ProcessAckPacket(&frame);
 
   ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
               .WillByDefault(Return(true));
   SendStreamDataToPeer(1, "bar", 3, false, NULL);  // Packet 4
-  EXPECT_EQ(4u, outgoing_ack()->sent_info.least_unacked);
+  EXPECT_EQ(4u, stop_waiting()->least_unacked);
   ON_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
               .WillByDefault(Return(false));
   SendAckPacketToPeer();  // Packet 5
@@ -2128,12 +2146,12 @@ TEST_P(QuicConnectionTest, DontLatchUnackedPacket) {
   SendStreamDataToPeer(1, "bar", 9, false, NULL);  // Packet 7
 
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
-  frame = InitAckFrame(7, 0);
+  frame = InitAckFrame(7);
   NackPacket(5, &frame);
   NackPacket(6, &frame);
   ProcessAckPacket(&frame);
 
-  EXPECT_EQ(6u, outgoing_ack()->sent_info.least_unacked);
+  EXPECT_EQ(6u, stop_waiting()->least_unacked);
 }
 
 TEST_P(QuicConnectionTest, ReviveMissingPacketAfterFecPacket) {
@@ -2149,9 +2167,9 @@ TEST_P(QuicConnectionTest, ReviveMissingPacketWithVaryingSeqNumLengths) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
   // Set up a debug visitor to the connection.
-  scoped_ptr<FecQuicConnectionDebugVisitor>
-      fec_visitor(new FecQuicConnectionDebugVisitor);
-  connection_.set_debug_visitor(fec_visitor.get());
+  FecQuicConnectionDebugVisitor* fec_visitor =
+      new FecQuicConnectionDebugVisitor();
+  connection_.set_debug_visitor(fec_visitor);
 
   QuicPacketSequenceNumber fec_packet = 0;
   QuicSequenceNumberLength lengths[] = {PACKET_6BYTE_SEQUENCE_NUMBER,
@@ -2177,9 +2195,9 @@ TEST_P(QuicConnectionTest, ReviveMissingPacketWithVaryingConnectionIdLengths) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
   // Set up a debug visitor to the connection.
-  scoped_ptr<FecQuicConnectionDebugVisitor>
-      fec_visitor(new FecQuicConnectionDebugVisitor);
-  connection_.set_debug_visitor(fec_visitor.get());
+  FecQuicConnectionDebugVisitor* fec_visitor =
+      new FecQuicConnectionDebugVisitor();
+  connection_.set_debug_visitor(fec_visitor);
 
   QuicPacketSequenceNumber fec_packet = 0;
   QuicConnectionIdLength lengths[] = {PACKET_8BYTE_CONNECTION_ID,
@@ -2253,7 +2271,7 @@ TEST_P(QuicConnectionTest, TLP) {
       QuicConnectionPeer::GetSentPacketManager(&connection_), 1);
 
   SendStreamDataToPeer(3, "foo", 0, !kFin, NULL);
-  EXPECT_EQ(1u, outgoing_ack()->sent_info.least_unacked);
+  EXPECT_EQ(1u, stop_waiting()->least_unacked);
   QuicTime retransmission_time =
       connection_.GetRetransmissionAlarm()->deadline();
   EXPECT_NE(QuicTime::Zero(), retransmission_time);
@@ -2266,14 +2284,14 @@ TEST_P(QuicConnectionTest, TLP) {
   connection_.GetRetransmissionAlarm()->Fire();
   EXPECT_EQ(2u, writer_->header().packet_sequence_number);
   // We do not raise the high water mark yet.
-  EXPECT_EQ(1u, outgoing_ack()->sent_info.least_unacked);
+  EXPECT_EQ(1u, stop_waiting()->least_unacked);
 }
 
 TEST_P(QuicConnectionTest, RTO) {
   QuicTime default_retransmission_time = clock_.ApproximateNow().Add(
       DefaultRetransmissionTime());
   SendStreamDataToPeer(3, "foo", 0, !kFin, NULL);
-  EXPECT_EQ(1u, outgoing_ack()->sent_info.least_unacked);
+  EXPECT_EQ(1u, stop_waiting()->least_unacked);
 
   EXPECT_EQ(1u, writer_->header().packet_sequence_number);
   EXPECT_EQ(default_retransmission_time,
@@ -2285,7 +2303,7 @@ TEST_P(QuicConnectionTest, RTO) {
   connection_.GetRetransmissionAlarm()->Fire();
   EXPECT_EQ(2u, writer_->header().packet_sequence_number);
   // We do not raise the high water mark yet.
-  EXPECT_EQ(1u, outgoing_ack()->sent_info.least_unacked);
+  EXPECT_EQ(1u, stop_waiting()->least_unacked);
 }
 
 TEST_P(QuicConnectionTest, RTOWithSameEncryptionLevel) {
@@ -2393,7 +2411,7 @@ TEST_P(QuicConnectionTest, RetransmitPacketsWithInitialEncryption) {
   SendStreamDataToPeer(2, "bar", 0, !kFin, NULL);
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
 
-  connection_.RetransmitUnackedPackets(INITIAL_ENCRYPTION_ONLY);
+  connection_.RetransmitUnackedPackets(ALL_INITIAL_RETRANSMISSION);
 }
 
 TEST_P(QuicConnectionTest, BufferNonDecryptablePackets) {
@@ -2496,7 +2514,7 @@ TEST_P(QuicConnectionTest, RetransmissionCountCalculation) {
       .Times(AnyNumber());
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
       .WillOnce(DoAll(SaveArg<2>(&nack_sequence_number), Return(true)));
-  QuicAckFrame ack = InitAckFrame(rto_sequence_number, 0);
+  QuicAckFrame ack = InitAckFrame(rto_sequence_number);
   // Nack the retransmitted packet.
   NackPacket(original_sequence_number, &ack);
   NackPacket(rto_sequence_number, &ack);
@@ -2538,7 +2556,7 @@ TEST_P(QuicConnectionTest, DelayRTOWithAckReceipt) {
   // packet to delay the RTO.
   clock_.AdvanceTime(DefaultRetransmissionTime());
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
-  QuicAckFrame ack = InitAckFrame(1, 0);
+  QuicAckFrame ack = InitAckFrame(1);
   ProcessAckPacket(&ack);
   EXPECT_TRUE(retransmission_alarm->IsSet());
   EXPECT_GT(retransmission_alarm->deadline(), clock_.Now());
@@ -2585,13 +2603,8 @@ TEST_P(QuicConnectionTest, CloseFecGroup) {
 
   // Now send non-fec protected ack packet and close the group.
   peer_creator_.set_sequence_number(4);
-  if (version() > QUIC_VERSION_15) {
-    QuicStopWaitingFrame frame = InitStopWaitingFrame(5);
-    ProcessStopWaitingPacket(&frame);
-  } else {
-    QuicAckFrame frame = InitAckFrame(0, 5);
-    ProcessAckPacket(&frame);
-  }
+  QuicStopWaitingFrame frame = InitStopWaitingFrame(5);
+  ProcessStopWaitingPacket(&frame);
   ASSERT_EQ(0u, connection_.NumFecGroups());
 }
 
@@ -2602,15 +2615,22 @@ TEST_P(QuicConnectionTest, NoQuicCongestionFeedbackFrame) {
 
 TEST_P(QuicConnectionTest, WithQuicCongestionFeedbackFrame) {
   QuicCongestionFeedbackFrame info;
-  info.type = kFixRate;
-  info.fix_rate.bitrate = QuicBandwidth::FromBytesPerSecond(123);
-  SetFeedback(&info);
+  info.type = kTCP;
+  info.tcp.receive_window = 0x4030;
 
-  SendAckPacketToPeer();
-  ASSERT_FALSE(writer_->feedback_frames().empty());
-  ASSERT_EQ(kFixRate, writer_->feedback_frames()[0].type);
-  ASSERT_EQ(info.fix_rate.bitrate,
-            writer_->feedback_frames()[0].fix_rate.bitrate);
+  // After QUIC_VERSION_22, do not send TCP Congestion Feedback Frames anymore.
+  if (version() > QUIC_VERSION_22) {
+    SendAckPacketToPeer();
+    ASSERT_TRUE(writer_->feedback_frames().empty());
+  } else {
+    // Only SetFeedback in this case because SetFeedback will create a receive
+    // algorithm which is how the received_packet_manager checks if it should be
+    // creating TCP Congestion Feedback Frames.
+    SetFeedback(&info);
+    SendAckPacketToPeer();
+    ASSERT_FALSE(writer_->feedback_frames().empty());
+    ASSERT_EQ(kTCP, writer_->feedback_frames()[0].type);
+  }
 }
 
 TEST_P(QuicConnectionTest, UpdateQuicCongestionFeedbackFrame) {
@@ -2632,16 +2652,27 @@ TEST_P(QuicConnectionTest, DontUpdateQuicCongestionFeedbackFrameForRevived) {
 TEST_P(QuicConnectionTest, InitialTimeout) {
   EXPECT_TRUE(connection_.connected());
   EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_CONNECTION_TIMED_OUT, false));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
 
   QuicTime default_timeout = clock_.ApproximateNow().Add(
       QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs));
   EXPECT_EQ(default_timeout, connection_.GetTimeoutAlarm()->deadline());
 
+  if (FLAGS_quic_timeouts_require_activity) {
+    // Simulate the timeout alarm firing.
+    clock_.AdvanceTime(
+        QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs));
+    connection_.GetTimeoutAlarm()->Fire();
+    // We should not actually timeout until a packet is sent.
+    EXPECT_TRUE(connection_.connected());
+    SendStreamDataToPeer(1, "GET /", 0, kFin, NULL);
+  }
+
   // Simulate the timeout alarm firing.
   clock_.AdvanceTime(
       QuicTime::Delta::FromSeconds(kDefaultInitialTimeoutSecs));
   connection_.GetTimeoutAlarm()->Fire();
+
   EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
   EXPECT_FALSE(connection_.connected());
 
@@ -2650,7 +2681,43 @@ TEST_P(QuicConnectionTest, InitialTimeout) {
   EXPECT_FALSE(connection_.GetResumeWritesAlarm()->IsSet());
   EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
   EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
+}
+
+TEST_P(QuicConnectionTest, OverallTimeout) {
+  connection_.SetOverallConnectionTimeout(
+      QuicTime::Delta::FromSeconds(kDefaultMaxTimeForCryptoHandshakeSecs));
+  EXPECT_TRUE(connection_.connected());
+  EXPECT_CALL(visitor_,
+              OnConnectionClosed(QUIC_CONNECTION_OVERALL_TIMED_OUT, false));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(AnyNumber());
+
+  QuicTime overall_timeout = clock_.ApproximateNow().Add(
+      QuicTime::Delta::FromSeconds(kDefaultMaxTimeForCryptoHandshakeSecs));
+  EXPECT_EQ(overall_timeout, connection_.GetTimeoutAlarm()->deadline());
+
+  EXPECT_TRUE(connection_.connected());
+  SendStreamDataToPeer(1, "GET /", 0, kFin, NULL);
+
+  clock_.AdvanceTime(
+      QuicTime::Delta::FromSeconds(2 * kDefaultInitialTimeoutSecs));
+
+  // Process an ack and see that the connection still times out.
+  QuicAckFrame frame = InitAckFrame(1);
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
+  ProcessAckPacket(&frame);
+
+  // Simulate the timeout alarm firing.
+  connection_.GetTimeoutAlarm()->Fire();
+
   EXPECT_FALSE(connection_.GetTimeoutAlarm()->IsSet());
+  EXPECT_FALSE(connection_.connected());
+
+  EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetPingAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetResumeWritesAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
 }
 
 TEST_P(QuicConnectionTest, PingAfterSend) {
@@ -2670,19 +2737,22 @@ TEST_P(QuicConnectionTest, PingAfterSend) {
   // Now recevie and ACK of the previous packet, which will move the
   // ping alarm forward.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  QuicAckFrame frame = InitAckFrame(1, 0);
+  QuicAckFrame frame = InitAckFrame(1);
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   ProcessAckPacket(&frame);
   EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
-  EXPECT_EQ(clock_.ApproximateNow().Add(QuicTime::Delta::FromSeconds(15)),
+  // The ping timer is set slightly less than 15 seconds in the future, because
+  // of the 1s ping timer alarm granularity.
+  EXPECT_EQ(clock_.ApproximateNow().Add(QuicTime::Delta::FromSeconds(15))
+                .Subtract(QuicTime::Delta::FromMilliseconds(5)),
             connection_.GetPingAlarm()->deadline());
 
   writer_->Reset();
   clock_.AdvanceTime(QuicTime::Delta::FromSeconds(15));
   connection_.GetPingAlarm()->Fire();
   EXPECT_EQ(1u, writer_->frame_count());
-  if (version() > QUIC_VERSION_17) {
+  if (version() >= QUIC_VERSION_18) {
     ASSERT_EQ(1u, writer_->ping_frames().size());
   } else {
     ASSERT_EQ(1u, writer_->stream_frames().size());
@@ -2737,162 +2807,21 @@ TEST_P(QuicConnectionTest, TimeoutAfterSend) {
 TEST_P(QuicConnectionTest, SendScheduler) {
   // Test that if we send a packet without delay, it is not queued.
   QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
-  EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _, _)).WillOnce(
-                  testing::Return(QuicTime::Delta::Zero()));
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
   connection_.SendPacket(
       ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA);
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
 }
 
-TEST_P(QuicConnectionTest, SendSchedulerDelay) {
-  // Test that if we send a packet with a delay, it ends up queued.
-  QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
-  EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _, _)).WillOnce(
-                  testing::Return(QuicTime::Delta::FromMicroseconds(1)));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
-  connection_.SendPacket(
-      ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA);
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-}
-
 TEST_P(QuicConnectionTest, SendSchedulerEAGAIN) {
   QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
   BlockOnNextWrite();
-  EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _, _)).WillOnce(
-                  testing::Return(QuicTime::Delta::Zero()));
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
   connection_.SendPacket(
       ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA);
   EXPECT_EQ(1u, connection_.NumQueuedPackets());
 }
 
-TEST_P(QuicConnectionTest, SendSchedulerDelayThenSend) {
-  // Test that if we send a packet with a delay, it ends up queued.
-  QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
-  EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _, _)).WillOnce(
-                  testing::Return(QuicTime::Delta::FromMicroseconds(1)));
-  connection_.SendPacket(
-       ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA);
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
-  // Advance the clock to fire the alarm, and configure the scheduler
-  // to permit the packet to be sent.
-  EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _, _)).WillRepeatedly(
-                  testing::Return(QuicTime::Delta::Zero()));
-  clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(1));
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-  connection_.GetSendAlarm()->Fire();
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-}
-
-TEST_P(QuicConnectionTest, SendSchedulerDelayThenRetransmit) {
-  CongestionUnblockWrites();
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _));
-  connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL);
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-  // Advance the time for retransmission of lost packet.
-  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(501));
-  // Test that if we send a retransmit with a delay, it ends up queued in the
-  // sent packet manager, but not yet serialized.
-  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
-  CongestionBlockWrites();
-  connection_.GetRetransmissionAlarm()->Fire();
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-
-  // Advance the clock to fire the alarm, and configure the scheduler
-  // to permit the packet to be sent.
-  CongestionUnblockWrites();
-
-  // Ensure the scheduler is notified this is a retransmit.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
-  clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(1));
-  connection_.GetSendAlarm()->Fire();
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-}
-
-TEST_P(QuicConnectionTest, SendSchedulerDelayAndQueue) {
-  QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
-  EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _, _)).WillOnce(
-                  testing::Return(QuicTime::Delta::FromMicroseconds(1)));
-  connection_.SendPacket(
-      ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA);
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
-  // Attempt to send another packet and make sure that it gets queued.
-  packet = ConstructDataPacket(2, 0, !kEntropyFlag);
-  connection_.SendPacket(
-      ENCRYPTION_NONE, 2, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA);
-  EXPECT_EQ(2u, connection_.NumQueuedPackets());
-}
-
-TEST_P(QuicConnectionTest, SendSchedulerDelayThenAckAndSend) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
-  EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _, _)).WillOnce(
-                  testing::Return(QuicTime::Delta::FromMicroseconds(10)));
-  connection_.SendPacket(
-      ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA);
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
-  // Now send non-retransmitting information, that we're not going to
-  // retransmit 3. The far end should stop waiting for it.
-  QuicAckFrame frame = InitAckFrame(0, 1);
-  EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _, _)).WillRepeatedly(
-                  testing::Return(QuicTime::Delta::Zero()));
-  EXPECT_CALL(*send_algorithm_,
-              OnPacketSent(_, _, _, _, _));
-  ProcessAckPacket(&frame);
-
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-  // Ensure alarm is not set
-  EXPECT_FALSE(connection_.GetSendAlarm()->IsSet());
-}
-
-TEST_P(QuicConnectionTest, SendSchedulerDelayThenAckAndHold) {
-  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
-  EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _, _)).WillOnce(
-                  testing::Return(QuicTime::Delta::FromMicroseconds(10)));
-  connection_.SendPacket(
-      ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA);
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
-  // Now send non-retransmitting information, that we're not going to
-  // retransmit 3.  The far end should stop waiting for it.
-  QuicAckFrame frame = InitAckFrame(0, 1);
-  EXPECT_CALL(*send_algorithm_,
-              TimeUntilSend(_, _, _)).WillOnce(
-                  testing::Return(QuicTime::Delta::FromMicroseconds(1)));
-  ProcessAckPacket(&frame);
-
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-}
-
-TEST_P(QuicConnectionTest, SendSchedulerDelayThenOnCanWrite) {
-  // TODO(ianswett): This test is unrealistic, because we would not serialize
-  // new data if the send algorithm said not to.
-  QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
-  CongestionBlockWrites();
-  connection_.SendPacket(
-      ENCRYPTION_NONE, 1, packet, kTestEntropyHash, HAS_RETRANSMITTABLE_DATA);
-  EXPECT_EQ(1u, connection_.NumQueuedPackets());
-
-  // OnCanWrite should send the packet, because it won't consult the send
-  // algorithm for queued packets.
-  connection_.OnCanWrite();
-  EXPECT_EQ(0u, connection_.NumQueuedPackets());
-}
-
 TEST_P(QuicConnectionTest, TestQueueLimitsOnSendStreamData) {
   // All packets carry version info till version is negotiated.
   size_t payload_length;
@@ -2958,12 +2887,8 @@ TEST_P(QuicConnectionTest, SendDelayedAck) {
   // Simulate delayed ack alarm firing.
   connection_.GetAckAlarm()->Fire();
   // Check that ack is sent and that delayed ack alarm is reset.
-  if (version() > QUIC_VERSION_15) {
-    EXPECT_EQ(2u, writer_->frame_count());
-    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
-  } else {
-    EXPECT_EQ(1u, writer_->frame_count());
-  }
+  EXPECT_EQ(2u, writer_->frame_count());
+  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
@@ -2980,12 +2905,8 @@ TEST_P(QuicConnectionTest, SendEarlyDelayedAckForCrypto) {
   // Simulate delayed ack alarm firing.
   connection_.GetAckAlarm()->Fire();
   // Check that ack is sent and that delayed ack alarm is reset.
-  if (version() > QUIC_VERSION_15) {
-    EXPECT_EQ(2u, writer_->frame_count());
-    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
-  } else {
-    EXPECT_EQ(1u, writer_->frame_count());
-  }
+  EXPECT_EQ(2u, writer_->frame_count());
+  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
@@ -2995,21 +2916,27 @@ TEST_P(QuicConnectionTest, SendDelayedAckOnSecondPacket) {
   ProcessPacket(1);
   ProcessPacket(2);
   // Check that ack is sent and that delayed ack alarm is reset.
-  if (version() > QUIC_VERSION_15) {
-    EXPECT_EQ(2u, writer_->frame_count());
-    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
-  } else {
-    EXPECT_EQ(1u, writer_->frame_count());
-  }
+  EXPECT_EQ(2u, writer_->frame_count());
+  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
 
+TEST_P(QuicConnectionTest, SendDelayedAckForPing) {
+  if (version() < QUIC_VERSION_18) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
+  ProcessPingPacket(1);
+  EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
+}
+
 TEST_P(QuicConnectionTest, NoAckOnOldNacks) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   // Drop one packet, triggering a sequence of acks.
   ProcessPacket(2);
-  size_t frames_per_ack = version() > QUIC_VERSION_15 ? 2 : 1;
+  size_t frames_per_ack = 2;
   EXPECT_EQ(frames_per_ack, writer_->frame_count());
   EXPECT_FALSE(writer_->ack_frames().empty());
   writer_->Reset();
@@ -3038,12 +2965,8 @@ TEST_P(QuicConnectionTest, SendDelayedAckOnOutgoingPacket) {
                                        !kFin, NULL);
   // Check that ack is bundled with outgoing data and that delayed ack
   // alarm is reset.
-  if (version() > QUIC_VERSION_15) {
-    EXPECT_EQ(3u, writer_->frame_count());
-    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
-  } else {
-    EXPECT_EQ(2u, writer_->frame_count());
-  }
+  EXPECT_EQ(3u, writer_->frame_count());
+  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
@@ -3053,11 +2976,24 @@ TEST_P(QuicConnectionTest, SendDelayedAckOnOutgoingCryptoPacket) {
   ProcessPacket(1);
   connection_.SendStreamDataWithString(kCryptoStreamId, "foo", 0, !kFin, NULL);
   // Check that ack is bundled with outgoing crypto data.
-  EXPECT_EQ(version() <= QUIC_VERSION_15 ? 2u : 3u, writer_->frame_count());
+  EXPECT_EQ(3u, writer_->frame_count());
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
 
+TEST_P(QuicConnectionTest, BlockAndBufferOnFirstCHLOPacketOfTwo) {
+  EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  ProcessPacket(1);
+  BlockOnNextWrite();
+  writer_->set_is_write_blocked_data_buffered(true);
+  connection_.SendStreamDataWithString(kCryptoStreamId, "foo", 0, !kFin, NULL);
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+  EXPECT_FALSE(connection_.HasQueuedData());
+  connection_.SendStreamDataWithString(kCryptoStreamId, "bar", 3, !kFin, NULL);
+  EXPECT_TRUE(writer_->IsWriteBlocked());
+  EXPECT_TRUE(connection_.HasQueuedData());
+}
+
 TEST_P(QuicConnectionTest, BundleAckForSecondCHLO) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
@@ -3069,12 +3005,8 @@ TEST_P(QuicConnectionTest, BundleAckForSecondCHLO) {
   // immediately send an ack, due to the packet gap.
   ProcessPacket(2);
   // Check that ack is sent and that delayed ack alarm is reset.
-  if (version() > QUIC_VERSION_15) {
-    EXPECT_EQ(3u, writer_->frame_count());
-    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
-  } else {
-    EXPECT_EQ(2u, writer_->frame_count());
-  }
+  EXPECT_EQ(3u, writer_->frame_count());
+  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
   EXPECT_EQ(1u, writer_->stream_frames().size());
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
@@ -3087,7 +3019,7 @@ TEST_P(QuicConnectionTest, BundleAckWithDataOnIncomingAck) {
   connection_.SendStreamDataWithString(kClientDataStreamId1, "foo", 3,
                                        !kFin, NULL);
   // Ack the second packet, which will retransmit the first packet.
-  QuicAckFrame ack = InitAckFrame(2, 0);
+  QuicAckFrame ack = InitAckFrame(2);
   NackPacket(1, &ack);
   SequenceNumberSet lost_packets;
   lost_packets.insert(1);
@@ -3101,7 +3033,7 @@ TEST_P(QuicConnectionTest, BundleAckWithDataOnIncomingAck) {
 
   // 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);
+  ack = InitAckFrame(3);
   NackPacket(1, &ack);
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(SequenceNumberSet()));
@@ -3114,7 +3046,7 @@ TEST_P(QuicConnectionTest, BundleAckWithDataOnIncomingAck) {
   writer_->Reset();
 
   // Send the same ack, but send both data and an ack together.
-  ack = InitAckFrame(3, 0);
+  ack = InitAckFrame(3);
   NackPacket(1, &ack);
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(SequenceNumberSet()));
@@ -3126,12 +3058,8 @@ TEST_P(QuicConnectionTest, BundleAckWithDataOnIncomingAck) {
 
   // Check that ack is bundled with outgoing data and the delayed ack
   // alarm is reset.
-  if (version() > QUIC_VERSION_15) {
-    EXPECT_EQ(3u, writer_->frame_count());
-    EXPECT_FALSE(writer_->stop_waiting_frames().empty());
-  } else {
-    EXPECT_EQ(2u, writer_->frame_count());
-  }
+  EXPECT_EQ(3u, writer_->frame_count());
+  EXPECT_FALSE(writer_->stop_waiting_frames().empty());
   EXPECT_FALSE(writer_->ack_frames().empty());
   EXPECT_EQ(1u, writer_->stream_frames().size());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
@@ -3150,6 +3078,7 @@ TEST_P(QuicConnectionTest, SendWhenDisconnected) {
   EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_PEER_GOING_AWAY, false));
   connection_.CloseConnection(QUIC_PEER_GOING_AWAY, false);
   EXPECT_FALSE(connection_.connected());
+  EXPECT_FALSE(connection_.CanWriteStreamData());
   QuicPacket* packet = ConstructDataPacket(1, 0, !kEntropyFlag);
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
   connection_.SendPacket(
@@ -3213,14 +3142,9 @@ TEST_P(QuicConnectionTest, MissingPacketsBeforeLeastUnacked) {
   // Set the sequence number of the ack packet to be least unacked (4).
   peer_creator_.set_sequence_number(3);
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  if (version() > QUIC_VERSION_15) {
-    QuicStopWaitingFrame frame = InitStopWaitingFrame(4);
-    ProcessStopWaitingPacket(&frame);
-  } else {
-    QuicAckFrame ack = InitAckFrame(0, 4);
-    ProcessAckPacket(&ack);
-  }
-  EXPECT_TRUE(outgoing_ack()->received_info.missing_packets.empty());
+  QuicStopWaitingFrame frame = InitStopWaitingFrame(4);
+  ProcessStopWaitingPacket(&frame);
+  EXPECT_TRUE(outgoing_ack()->missing_packets.empty());
 }
 
 TEST_P(QuicConnectionTest, ReceivedEntropyHashCalculation) {
@@ -3230,7 +3154,7 @@ TEST_P(QuicConnectionTest, ReceivedEntropyHashCalculation) {
   ProcessDataPacket(4, 1, kEntropyFlag);
   ProcessDataPacket(3, 1, !kEntropyFlag);
   ProcessDataPacket(7, 1, kEntropyFlag);
-  EXPECT_EQ(146u, outgoing_ack()->received_info.entropy_hash);
+  EXPECT_EQ(146u, outgoing_ack()->entropy_hash);
 }
 
 TEST_P(QuicConnectionTest, ReceivedEntropyHashCalculationHalfFEC) {
@@ -3241,7 +3165,7 @@ TEST_P(QuicConnectionTest, ReceivedEntropyHashCalculationHalfFEC) {
   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);
+  EXPECT_EQ(146u, outgoing_ack()->entropy_hash);
 }
 
 TEST_P(QuicConnectionTest, UpdateEntropyForReceivedPackets) {
@@ -3250,27 +3174,19 @@ TEST_P(QuicConnectionTest, UpdateEntropyForReceivedPackets) {
   ProcessDataPacket(1, 1, kEntropyFlag);
   ProcessDataPacket(5, 1, kEntropyFlag);
   ProcessDataPacket(4, 1, !kEntropyFlag);
-  EXPECT_EQ(34u, outgoing_ack()->received_info.entropy_hash);
+  EXPECT_EQ(34u, outgoing_ack()->entropy_hash);
   // Make 4th packet my least unacked, and update entropy for 2, 3 packets.
   peer_creator_.set_sequence_number(5);
   QuicPacketEntropyHash six_packet_entropy_hash = 0;
   QuicPacketEntropyHash kRandomEntropyHash = 129u;
-  if (version() > QUIC_VERSION_15) {
-    QuicStopWaitingFrame frame = InitStopWaitingFrame(4);
-    frame.entropy_hash = kRandomEntropyHash;
-    if (ProcessStopWaitingPacket(&frame)) {
-      six_packet_entropy_hash = 1 << 6;
-    }
-  } else {
-    QuicAckFrame ack = InitAckFrame(0, 4);
-    ack.sent_info.entropy_hash = kRandomEntropyHash;
-    if (ProcessAckPacket(&ack)) {
-      six_packet_entropy_hash = 1 << 6;
-    }
+  QuicStopWaitingFrame frame = InitStopWaitingFrame(4);
+  frame.entropy_hash = kRandomEntropyHash;
+  if (ProcessStopWaitingPacket(&frame)) {
+    six_packet_entropy_hash = 1 << 6;
   }
 
   EXPECT_EQ((kRandomEntropyHash + (1 << 5) + six_packet_entropy_hash),
-            outgoing_ack()->received_info.entropy_hash);
+            outgoing_ack()->entropy_hash);
 }
 
 TEST_P(QuicConnectionTest, UpdateEntropyHashUptoCurrentPacket) {
@@ -3279,25 +3195,19 @@ TEST_P(QuicConnectionTest, UpdateEntropyHashUptoCurrentPacket) {
   ProcessDataPacket(1, 1, kEntropyFlag);
   ProcessDataPacket(5, 1, !kEntropyFlag);
   ProcessDataPacket(22, 1, kEntropyFlag);
-  EXPECT_EQ(66u, outgoing_ack()->received_info.entropy_hash);
+  EXPECT_EQ(66u, outgoing_ack()->entropy_hash);
   peer_creator_.set_sequence_number(22);
   QuicPacketEntropyHash kRandomEntropyHash = 85u;
   // Current packet is the least unacked packet.
   QuicPacketEntropyHash ack_entropy_hash;
-  if (version() > QUIC_VERSION_15) {
-    QuicStopWaitingFrame frame = InitStopWaitingFrame(23);
-    frame.entropy_hash = kRandomEntropyHash;
-    ack_entropy_hash = ProcessStopWaitingPacket(&frame);
-  } else {
-    QuicAckFrame ack = InitAckFrame(0, 23);
-    ack.sent_info.entropy_hash = kRandomEntropyHash;
-    ack_entropy_hash = ProcessAckPacket(&ack);
-  }
+  QuicStopWaitingFrame frame = InitStopWaitingFrame(23);
+  frame.entropy_hash = kRandomEntropyHash;
+  ack_entropy_hash = ProcessStopWaitingPacket(&frame);
   EXPECT_EQ((kRandomEntropyHash + ack_entropy_hash),
-            outgoing_ack()->received_info.entropy_hash);
+            outgoing_ack()->entropy_hash);
   ProcessDataPacket(25, 1, kEntropyFlag);
   EXPECT_EQ((kRandomEntropyHash + ack_entropy_hash + (1 << (25 % 8))),
-            outgoing_ack()->received_info.entropy_hash);
+            outgoing_ack()->entropy_hash);
 }
 
 TEST_P(QuicConnectionTest, EntropyCalculationForTruncatedAck) {
@@ -3325,35 +3235,6 @@ TEST_P(QuicConnectionTest, EntropyCalculationForTruncatedAck) {
   }
 }
 
-TEST_P(QuicConnectionTest, CheckSentEntropyHash) {
-  peer_creator_.set_sequence_number(1);
-  SequenceNumberSet missing_packets;
-  QuicPacketEntropyHash entropy_hash = 0;
-  QuicPacketSequenceNumber max_sequence_number = 51;
-  for (QuicPacketSequenceNumber i = 1; i <= max_sequence_number; ++i) {
-    bool is_missing = i % 10 != 0;
-    bool entropy_flag = (i & (i - 1)) != 0;
-    QuicPacketEntropyHash packet_entropy_hash = 0;
-    if (entropy_flag) {
-      packet_entropy_hash = 1 << (i % 8);
-    }
-    QuicPacket* packet = ConstructDataPacket(i, 0, entropy_flag);
-    connection_.SendPacket(
-        ENCRYPTION_NONE, i, packet, packet_entropy_hash,
-        HAS_RETRANSMITTABLE_DATA);
-
-    if (is_missing)  {
-      missing_packets.insert(i);
-      continue;
-    }
-
-    entropy_hash ^= packet_entropy_hash;
-  }
-  EXPECT_TRUE(QuicConnectionPeer::IsValidEntropy(
-      &connection_, max_sequence_number, missing_packets, entropy_hash))
-      << "";
-}
-
 TEST_P(QuicConnectionTest, ServerSendsVersionNegotiationPacket) {
   connection_.SetSupportedVersions(QuicSupportedVersions());
   framer_.set_version_for_tests(QUIC_VERSION_UNSUPPORTED);
@@ -3553,7 +3434,7 @@ TEST_P(QuicConnectionTest, CheckSendStats) {
   connection_.GetRetransmissionAlarm()->Fire();
 
   // Retransmit due to explicit nacks.
-  QuicAckFrame nack_three = InitAckFrame(4, 0);
+  QuicAckFrame nack_three = InitAckFrame(4);
   NackPacket(3, &nack_three);
   NackPacket(1, &nack_three);
   SequenceNumberSet lost_packets;
@@ -3564,11 +3445,16 @@ TEST_P(QuicConnectionTest, CheckSendStats) {
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
   EXPECT_CALL(visitor_, OnCanWrite()).Times(2);
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
+  EXPECT_CALL(*send_algorithm_, RevertRetransmissionTimeout());
   ProcessAckPacket(&nack_three);
 
   EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillOnce(
       Return(QuicBandwidth::Zero()));
 
+  const uint32 kSlowStartThreshold = 23u;
+  EXPECT_CALL(*send_algorithm_, GetSlowStartThreshold()).WillOnce(
+      Return(kSlowStartThreshold));
+
   const QuicConnectionStats& stats = connection_.GetStats();
   EXPECT_EQ(3 * first_packet_size + 2 * second_packet_size - kQuicVersionSize,
             stats.bytes_sent);
@@ -3577,6 +3463,9 @@ TEST_P(QuicConnectionTest, CheckSendStats) {
             stats.bytes_retransmitted);
   EXPECT_EQ(3u, stats.packets_retransmitted);
   EXPECT_EQ(1u, stats.rto_count);
+  EXPECT_EQ(kMaxPacketSize, stats.congestion_window);
+  EXPECT_EQ(kSlowStartThreshold, stats.slow_start_threshold);
+  EXPECT_EQ(kDefaultMaxPacketSize, stats.max_packet_size);
 }
 
 TEST_P(QuicConnectionTest, CheckReceiveStats) {
@@ -3591,6 +3480,9 @@ TEST_P(QuicConnectionTest, CheckReceiveStats) {
 
   EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillOnce(
       Return(QuicBandwidth::Zero()));
+  const uint32 kSlowStartThreshold = 23u;
+  EXPECT_CALL(*send_algorithm_, GetSlowStartThreshold()).WillOnce(
+      Return(kSlowStartThreshold));
 
   const QuicConnectionStats& stats = connection_.GetStats();
   EXPECT_EQ(received_bytes, stats.bytes_received);
@@ -3598,6 +3490,8 @@ TEST_P(QuicConnectionTest, CheckReceiveStats) {
 
   EXPECT_EQ(1u, stats.packets_revived);
   EXPECT_EQ(1u, stats.packets_dropped);
+
+  EXPECT_EQ(kSlowStartThreshold, stats.slow_start_threshold);
 }
 
 TEST_P(QuicConnectionTest, TestFecGroupLimits) {
@@ -3717,14 +3611,14 @@ TEST_P(QuicConnectionTest, AckNotifierTriggerCallback) {
 
   // Create a delegate which we expect to be called.
   scoped_refptr<MockAckNotifierDelegate> delegate(new MockAckNotifierDelegate);
-  EXPECT_CALL(*delegate, OnAckNotification(_, _, _, _, _)).Times(1);
+  EXPECT_CALL(*delegate.get(), OnAckNotification(_, _, _, _, _)).Times(1);
 
   // Send some data, which will register the delegate to be notified.
   connection_.SendStreamDataWithString(1, "foo", 0, !kFin, delegate.get());
 
   // Process an ACK from the server which should trigger the callback.
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
-  QuicAckFrame frame = InitAckFrame(1, 0);
+  QuicAckFrame frame = InitAckFrame(1);
   ProcessAckPacket(&frame);
 }
 
@@ -3733,7 +3627,7 @@ TEST_P(QuicConnectionTest, AckNotifierFailToTriggerCallback) {
 
   // Create a delegate which we don't expect to be called.
   scoped_refptr<MockAckNotifierDelegate> delegate(new MockAckNotifierDelegate);
-  EXPECT_CALL(*delegate, OnAckNotification(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(*delegate.get(), OnAckNotification(_, _, _, _, _)).Times(0);
 
   // Send some data, which will register the delegate to be notified. This will
   // not be ACKed and so the delegate should never be called.
@@ -3745,7 +3639,7 @@ TEST_P(QuicConnectionTest, AckNotifierFailToTriggerCallback) {
 
   // Now we receive ACK for packets 2 and 3, but importantly missing packet 1
   // which we registered to be notified about.
-  QuicAckFrame frame = InitAckFrame(3, 0);
+  QuicAckFrame frame = InitAckFrame(3);
   NackPacket(1, &frame);
   SequenceNumberSet lost_packets;
   lost_packets.insert(1);
@@ -3760,7 +3654,7 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackAfterRetransmission) {
 
   // Create a delegate which we expect to be called.
   scoped_refptr<MockAckNotifierDelegate> delegate(new MockAckNotifierDelegate);
-  EXPECT_CALL(*delegate, OnAckNotification(_, _, _, _, _)).Times(1);
+  EXPECT_CALL(*delegate.get(), OnAckNotification(_, _, _, _, _)).Times(1);
 
   // Send four packets, and register to be notified on ACK of packet 2.
   connection_.SendStreamDataWithString(3, "foo", 0, !kFin, NULL);
@@ -3769,7 +3663,7 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackAfterRetransmission) {
   connection_.SendStreamDataWithString(3, "qux", 0, !kFin, NULL);
 
   // Now we receive ACK for packets 1, 3, and 4 and lose 2.
-  QuicAckFrame frame = InitAckFrame(4, 0);
+  QuicAckFrame frame = InitAckFrame(4);
   NackPacket(2, &frame);
   SequenceNumberSet lost_packets;
   lost_packets.insert(2);
@@ -3784,7 +3678,7 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackAfterRetransmission) {
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillRepeatedly(Return(SequenceNumberSet()));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
-  QuicAckFrame second_ack_frame = InitAckFrame(5, 0);
+  QuicAckFrame second_ack_frame = InitAckFrame(5);
   ProcessAckPacket(&second_ack_frame);
 }
 
@@ -3801,7 +3695,7 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackForAckAfterRTO) {
   QuicTime default_retransmission_time = clock_.ApproximateNow().Add(
       DefaultRetransmissionTime());
   connection_.SendStreamDataWithString(3, "foo", 0, !kFin, delegate.get());
-  EXPECT_EQ(1u, outgoing_ack()->sent_info.least_unacked);
+  EXPECT_EQ(1u, stop_waiting()->least_unacked);
 
   EXPECT_EQ(1u, writer_->header().packet_sequence_number);
   EXPECT_EQ(default_retransmission_time,
@@ -3813,18 +3707,19 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackForAckAfterRTO) {
   connection_.GetRetransmissionAlarm()->Fire();
   EXPECT_EQ(2u, writer_->header().packet_sequence_number);
   // We do not raise the high water mark yet.
-  EXPECT_EQ(1u, outgoing_ack()->sent_info.least_unacked);
+  EXPECT_EQ(1u, stop_waiting()->least_unacked);
 
-  // Ack the original packet.
+  // Ack the original packet, which will revert the RTO.
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
-  EXPECT_CALL(*delegate, OnAckNotification(1, _, 1, _, _));
+  EXPECT_CALL(*delegate.get(), OnAckNotification(1, _, 1, _, _));
+  EXPECT_CALL(*send_algorithm_, RevertRetransmissionTimeout());
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
-  QuicAckFrame ack_frame = InitAckFrame(1, 0);
+  QuicAckFrame ack_frame = InitAckFrame(1);
   ProcessAckPacket(&ack_frame);
 
   // Delegate is not notified again when the retransmit is acked.
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
-  QuicAckFrame second_ack_frame = InitAckFrame(2, 0);
+  QuicAckFrame second_ack_frame = InitAckFrame(2);
   ProcessAckPacket(&second_ack_frame);
 }
 
@@ -3845,7 +3740,7 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackForAckOfNackedPacket) {
   connection_.SendStreamDataWithString(3, "qux", 0, !kFin, NULL);
 
   // Now we receive ACK for packets 1, 3, and 4 and lose 2.
-  QuicAckFrame frame = InitAckFrame(4, 0);
+  QuicAckFrame frame = InitAckFrame(4);
   NackPacket(2, &frame);
   SequenceNumberSet lost_packets;
   lost_packets.insert(2);
@@ -3858,10 +3753,10 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackForAckOfNackedPacket) {
 
   // Now we get an ACK for packet 2, which was previously nacked.
   SequenceNumberSet no_lost_packets;
-  EXPECT_CALL(*delegate, OnAckNotification(1, _, 1, _, _));
+  EXPECT_CALL(*delegate.get(), OnAckNotification(1, _, 1, _, _));
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(no_lost_packets));
-  QuicAckFrame second_ack_frame = InitAckFrame(4, 0);
+  QuicAckFrame second_ack_frame = InitAckFrame(4);
   ProcessAckPacket(&second_ack_frame);
 
   // Verify that the delegate is not notified again when the
@@ -3869,7 +3764,7 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackForAckOfNackedPacket) {
   EXPECT_CALL(*loss_algorithm_, DetectLostPackets(_, _, _, _))
       .WillOnce(Return(no_lost_packets));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
-  QuicAckFrame third_ack_frame = InitAckFrame(5, 0);
+  QuicAckFrame third_ack_frame = InitAckFrame(5);
   ProcessAckPacket(&third_ack_frame);
 }
 
@@ -3879,7 +3774,7 @@ TEST_P(QuicConnectionTest, AckNotifierFECTriggerCallback) {
   // Create a delegate which we expect to be called.
   scoped_refptr<MockAckNotifierDelegate> delegate(
       new MockAckNotifierDelegate);
-  EXPECT_CALL(*delegate, OnAckNotification(_, _, _, _, _)).Times(1);
+  EXPECT_CALL(*delegate.get(), OnAckNotification(_, _, _, _, _)).Times(1);
 
   // Send some data, which will register the delegate to be notified.
   connection_.SendStreamDataWithString(1, "foo", 0, !kFin, delegate.get());
@@ -3888,9 +3783,9 @@ TEST_P(QuicConnectionTest, AckNotifierFECTriggerCallback) {
   // Process an ACK from the server with a revived packet, which should trigger
   // the callback.
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
-  QuicAckFrame frame = InitAckFrame(2, 0);
+  QuicAckFrame frame = InitAckFrame(2);
   NackPacket(1, &frame);
-  frame.received_info.revived_packets.insert(1);
+  frame.revived_packets.insert(1);
   ProcessAckPacket(&frame);
   // If the ack is processed again, the notifier should not be called again.
   ProcessAckPacket(&frame);
@@ -3902,7 +3797,7 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackAfterFECRecovery) {
 
   // Create a delegate which we expect to be called.
   scoped_refptr<MockAckNotifierDelegate> delegate(new MockAckNotifierDelegate);
-  EXPECT_CALL(*delegate, OnAckNotification(_, _, _, _, _)).Times(1);
+  EXPECT_CALL(*delegate.get(), OnAckNotification(_, _, _, _, _)).Times(1);
 
   // Expect ACKs for 1 packet.
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _));
@@ -3914,7 +3809,7 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackAfterFECRecovery) {
   // Should recover the Ack packet and trigger the notification callback.
   QuicFrames frames;
 
-  QuicAckFrame ack_frame = InitAckFrame(1, 0);
+  QuicAckFrame ack_frame = InitAckFrame(1);
   frames.push_back(QuicFrame(&ack_frame));
 
   // Dummy stream frame to satisfy expectations set elsewhere.
@@ -3938,6 +3833,21 @@ TEST_P(QuicConnectionTest, AckNotifierCallbackAfterFECRecovery) {
   ProcessFecPacket(2, 1, true, !kEntropyFlag, packet);
 }
 
+TEST_P(QuicConnectionTest, NetworkChangeVisitorCallbacksChangeFecState) {
+  QuicPacketCreator* creator =
+      QuicConnectionPeer::GetPacketCreator(&connection_);
+  size_t max_packets_per_fec_group = creator->max_packets_per_fec_group();
+
+  QuicSentPacketManager::NetworkChangeVisitor* visitor =
+      QuicSentPacketManagerPeer::GetNetworkChangeVisitor(
+          QuicConnectionPeer::GetSentPacketManager(&connection_));
+  EXPECT_TRUE(visitor);
+
+  // Increase FEC group size by increasing congestion window to a large number.
+  visitor->OnCongestionWindowChange(1000 * kDefaultTCPMSS);
+  EXPECT_LT(max_packets_per_fec_group, creator->max_packets_per_fec_group());
+}
+
 class MockQuicConnectionDebugVisitor
     : public QuicConnectionDebugVisitor {
  public:
@@ -3997,21 +3907,19 @@ class MockQuicConnectionDebugVisitor
 TEST_P(QuicConnectionTest, OnPacketHeaderDebugVisitor) {
   QuicPacketHeader header;
 
-  scoped_ptr<MockQuicConnectionDebugVisitor>
-      debug_visitor(new StrictMock<MockQuicConnectionDebugVisitor>);
-  connection_.set_debug_visitor(debug_visitor.get());
+  MockQuicConnectionDebugVisitor* debug_visitor =
+      new MockQuicConnectionDebugVisitor();
+  connection_.set_debug_visitor(debug_visitor);
   EXPECT_CALL(*debug_visitor, OnPacketHeader(Ref(header))).Times(1);
   connection_.OnPacketHeader(header);
 }
 
 TEST_P(QuicConnectionTest, Pacing) {
-  ValueRestore<bool> old_flag(&FLAGS_enable_quic_pacing, true);
-
   TestConnection server(connection_id_, IPEndPoint(), helper_.get(),
-                        writer_.get(), true, version());
+                        factory_, /* is_server= */ true, version());
   TestConnection client(connection_id_, IPEndPoint(), helper_.get(),
-                        writer_.get(), false, version());
-  EXPECT_TRUE(client.sent_packet_manager().using_pacing());
+                        factory_, /* is_server= */ false, version());
+  EXPECT_FALSE(client.sent_packet_manager().using_pacing());
   EXPECT_FALSE(server.sent_packet_manager().using_pacing());
 }