Project import generated by Copybara.

PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/core/quic_sent_packet_manager_test.cc b/quic/core/quic_sent_packet_manager_test.cc
new file mode 100644
index 0000000..eb3c6a8
--- /dev/null
+++ b/quic/core/quic_sent_packet_manager_test.cc
@@ -0,0 +1,2438 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/quic_sent_packet_manager.h"
+
+#include <memory>
+
+#include "net/third_party/quiche/src/quic/core/quic_pending_retransmission.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_sent_packet_manager_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+
+using testing::_;
+using testing::AnyNumber;
+using testing::Invoke;
+using testing::InvokeWithoutArgs;
+using testing::IsEmpty;
+using testing::Not;
+using testing::Pointwise;
+using testing::Return;
+using testing::StrictMock;
+using testing::WithArgs;
+
+namespace quic {
+namespace test {
+namespace {
+// Default packet length.
+const uint32_t kDefaultLength = 1000;
+
+// Stream ID for data sent in CreatePacket().
+const QuicStreamId kStreamId = 7;
+
+// Matcher to check that the packet number matches the second argument.
+MATCHER(PacketNumberEq, "") {
+  return ::testing::get<0>(arg).packet_number ==
+         QuicPacketNumber(::testing::get<1>(arg));
+}
+
+class MockDebugDelegate : public QuicSentPacketManager::DebugDelegate {
+ public:
+  MOCK_METHOD2(OnSpuriousPacketRetransmission,
+               void(TransmissionType transmission_type,
+                    QuicByteCount byte_size));
+  MOCK_METHOD3(OnPacketLoss,
+               void(QuicPacketNumber lost_packet_number,
+                    TransmissionType transmission_type,
+                    QuicTime detection_time));
+};
+
+class QuicSentPacketManagerTest : public QuicTestWithParam<bool> {
+ public:
+  void RetransmitCryptoPacket(uint64_t packet_number) {
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
+                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
+    SerializedPacket packet(CreatePacket(packet_number, false));
+    packet.retransmittable_frames.push_back(
+        QuicFrame(QuicStreamFrame(1, false, 0, QuicStringPiece())));
+    packet.has_crypto_handshake = IS_HANDSHAKE;
+    manager_.OnPacketSent(&packet, QuicPacketNumber(), clock_.Now(),
+                          HANDSHAKE_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
+  }
+
+  void RetransmitDataPacket(uint64_t packet_number, TransmissionType type) {
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
+                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
+    SerializedPacket packet(CreatePacket(packet_number, true));
+    manager_.OnPacketSent(&packet, QuicPacketNumber(), clock_.Now(), type,
+                          HAS_RETRANSMITTABLE_DATA);
+  }
+
+ protected:
+  QuicSentPacketManagerTest()
+      : manager_(Perspective::IS_SERVER, &clock_, &stats_, kCubicBytes, kNack),
+        send_algorithm_(new StrictMock<MockSendAlgorithm>),
+        network_change_visitor_(new StrictMock<MockNetworkChangeVisitor>) {
+    QuicSentPacketManagerPeer::SetSendAlgorithm(&manager_, send_algorithm_);
+    // Disable tail loss probes for most tests.
+    QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 0);
+    // Advance the time 1s so the send times are never QuicTime::Zero.
+    clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
+    manager_.SetNetworkChangeVisitor(network_change_visitor_.get());
+    manager_.SetSessionNotifier(&notifier_);
+    manager_.SetSessionDecideWhatToWrite(GetParam());
+
+    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(*network_change_visitor_, OnPathMtuIncreased(1000))
+        .Times(AnyNumber());
+    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
+    EXPECT_CALL(notifier_, HasUnackedCryptoData())
+        .WillRepeatedly(Return(false));
+    EXPECT_CALL(notifier_, OnStreamFrameRetransmitted(_)).Times(AnyNumber());
+    EXPECT_CALL(notifier_, OnFrameAcked(_, _)).WillRepeatedly(Return(true));
+  }
+
+  ~QuicSentPacketManagerTest() override {}
+
+  QuicByteCount BytesInFlight() {
+    return QuicSentPacketManagerPeer::GetBytesInFlight(&manager_);
+  }
+  void VerifyUnackedPackets(uint64_t* packets, size_t num_packets) {
+    if (num_packets == 0) {
+      EXPECT_TRUE(manager_.unacked_packets().empty());
+      EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetNumRetransmittablePackets(
+                        &manager_));
+      return;
+    }
+
+    EXPECT_FALSE(manager_.unacked_packets().empty());
+    EXPECT_EQ(QuicPacketNumber(packets[0]), manager_.GetLeastUnacked());
+    for (size_t i = 0; i < num_packets; ++i) {
+      EXPECT_TRUE(QuicSentPacketManagerPeer::IsUnacked(&manager_, packets[i]))
+          << packets[i];
+    }
+  }
+
+  void VerifyRetransmittablePackets(uint64_t* packets, size_t num_packets) {
+    EXPECT_EQ(
+        num_packets,
+        QuicSentPacketManagerPeer::GetNumRetransmittablePackets(&manager_));
+    for (size_t i = 0; i < num_packets; ++i) {
+      EXPECT_TRUE(QuicSentPacketManagerPeer::HasRetransmittableFrames(
+          &manager_, packets[i]))
+          << " packets[" << i << "]:" << packets[i];
+    }
+  }
+
+  void ExpectAck(uint64_t largest_observed) {
+    EXPECT_CALL(
+        *send_algorithm_,
+        // Ensure the AckedPacketVector argument contains largest_observed.
+        OnCongestionEvent(true, _, _,
+                          Pointwise(PacketNumberEq(), {largest_observed}),
+                          IsEmpty()));
+    EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  }
+
+  void ExpectUpdatedRtt(uint64_t largest_observed) {
+    EXPECT_CALL(*send_algorithm_,
+                OnCongestionEvent(true, _, _, IsEmpty(), IsEmpty()));
+    EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  }
+
+  void ExpectAckAndLoss(bool rtt_updated,
+                        uint64_t largest_observed,
+                        uint64_t lost_packet) {
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnCongestionEvent(rtt_updated, _, _,
+                          Pointwise(PacketNumberEq(), {largest_observed}),
+                          Pointwise(PacketNumberEq(), {lost_packet})));
+    EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  }
+
+  // |packets_acked| and |packets_lost| should be in packet number order.
+  void ExpectAcksAndLosses(bool rtt_updated,
+                           uint64_t* packets_acked,
+                           size_t num_packets_acked,
+                           uint64_t* packets_lost,
+                           size_t num_packets_lost) {
+    std::vector<QuicPacketNumber> ack_vector;
+    for (size_t i = 0; i < num_packets_acked; ++i) {
+      ack_vector.push_back(QuicPacketNumber(packets_acked[i]));
+    }
+    std::vector<QuicPacketNumber> lost_vector;
+    for (size_t i = 0; i < num_packets_lost; ++i) {
+      lost_vector.push_back(QuicPacketNumber(packets_lost[i]));
+    }
+    EXPECT_CALL(*send_algorithm_,
+                OnCongestionEvent(rtt_updated, _, _,
+                                  Pointwise(PacketNumberEq(), ack_vector),
+                                  Pointwise(PacketNumberEq(), lost_vector)));
+    EXPECT_CALL(*network_change_visitor_, OnCongestionChange())
+        .Times(AnyNumber());
+  }
+
+  void RetransmitAndSendPacket(uint64_t old_packet_number,
+                               uint64_t new_packet_number) {
+    RetransmitAndSendPacket(old_packet_number, new_packet_number,
+                            TLP_RETRANSMISSION);
+  }
+
+  void RetransmitAndSendPacket(uint64_t old_packet_number,
+                               uint64_t new_packet_number,
+                               TransmissionType transmission_type) {
+    bool is_lost = false;
+    if (manager_.session_decides_what_to_write()) {
+      if (transmission_type == HANDSHAKE_RETRANSMISSION ||
+          transmission_type == TLP_RETRANSMISSION ||
+          transmission_type == RTO_RETRANSMISSION ||
+          transmission_type == PROBING_RETRANSMISSION) {
+        EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+            .WillOnce(WithArgs<1>(
+                Invoke([this, new_packet_number](TransmissionType type) {
+                  RetransmitDataPacket(new_packet_number, type);
+                })));
+      } else {
+        EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
+        is_lost = true;
+      }
+    }
+    QuicSentPacketManagerPeer::MarkForRetransmission(
+        &manager_, old_packet_number, transmission_type);
+    if (manager_.session_decides_what_to_write()) {
+      if (!is_lost) {
+        return;
+      }
+      EXPECT_CALL(
+          *send_algorithm_,
+          OnPacketSent(_, BytesInFlight(), QuicPacketNumber(new_packet_number),
+                       kDefaultLength, HAS_RETRANSMITTABLE_DATA));
+      SerializedPacket packet(CreatePacket(new_packet_number, true));
+      manager_.OnPacketSent(&packet, QuicPacketNumber(), clock_.Now(),
+                            transmission_type, HAS_RETRANSMITTABLE_DATA);
+      return;
+    }
+    EXPECT_TRUE(manager_.HasPendingRetransmissions());
+    QuicPendingRetransmission next_retransmission =
+        manager_.NextPendingRetransmission();
+    EXPECT_EQ(QuicPacketNumber(old_packet_number),
+              next_retransmission.packet_number);
+    EXPECT_EQ(transmission_type, next_retransmission.transmission_type);
+
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(new_packet_number),
+                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
+    SerializedPacket packet(CreatePacket(new_packet_number, false));
+    manager_.OnPacketSent(&packet, QuicPacketNumber(old_packet_number),
+                          clock_.Now(), transmission_type,
+                          HAS_RETRANSMITTABLE_DATA);
+    EXPECT_TRUE(QuicSentPacketManagerPeer::IsRetransmission(&manager_,
+                                                            new_packet_number));
+  }
+
+  SerializedPacket CreateDataPacket(uint64_t packet_number) {
+    return CreatePacket(packet_number, true);
+  }
+
+  SerializedPacket CreatePacket(uint64_t packet_number, bool retransmittable) {
+    SerializedPacket packet(QuicPacketNumber(packet_number),
+                            PACKET_4BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                            false, false);
+    if (retransmittable) {
+      packet.retransmittable_frames.push_back(
+          QuicFrame(QuicStreamFrame(kStreamId, false, 0, QuicStringPiece())));
+    }
+    return packet;
+  }
+
+  void SendDataPacket(uint64_t packet_number) {
+    EXPECT_CALL(*send_algorithm_,
+                OnPacketSent(_, BytesInFlight(),
+                             QuicPacketNumber(packet_number), _, _));
+    SerializedPacket packet(CreateDataPacket(packet_number));
+    manager_.OnPacketSent(&packet, QuicPacketNumber(), clock_.Now(),
+                          NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
+  }
+
+  void SendCryptoPacket(uint64_t packet_number) {
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
+                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
+    SerializedPacket packet(CreatePacket(packet_number, false));
+    packet.retransmittable_frames.push_back(
+        QuicFrame(QuicStreamFrame(1, false, 0, QuicStringPiece())));
+    packet.has_crypto_handshake = IS_HANDSHAKE;
+    manager_.OnPacketSent(&packet, QuicPacketNumber(), clock_.Now(),
+                          NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
+    if (manager_.session_decides_what_to_write()) {
+      EXPECT_CALL(notifier_, HasUnackedCryptoData())
+          .WillRepeatedly(Return(true));
+    }
+  }
+
+  void SendAckPacket(uint64_t packet_number, uint64_t largest_acked) {
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
+                     kDefaultLength, NO_RETRANSMITTABLE_DATA));
+    SerializedPacket packet(CreatePacket(packet_number, false));
+    packet.largest_acked = QuicPacketNumber(largest_acked);
+    manager_.OnPacketSent(&packet, QuicPacketNumber(), clock_.Now(),
+                          NOT_RETRANSMISSION, NO_RETRANSMITTABLE_DATA);
+  }
+
+  // Based on QuicConnection's WritePendingRetransmissions.
+  void RetransmitNextPacket(uint64_t retransmission_packet_number) {
+    EXPECT_TRUE(manager_.HasPendingRetransmissions());
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, _, QuicPacketNumber(retransmission_packet_number),
+                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
+    const QuicPendingRetransmission pending =
+        manager_.NextPendingRetransmission();
+    SerializedPacket packet(CreatePacket(retransmission_packet_number, false));
+    manager_.OnPacketSent(&packet, pending.packet_number, clock_.Now(),
+                          pending.transmission_type, HAS_RETRANSMITTABLE_DATA);
+  }
+
+  QuicSentPacketManager manager_;
+  MockClock clock_;
+  QuicConnectionStats stats_;
+  MockSendAlgorithm* send_algorithm_;
+  std::unique_ptr<MockNetworkChangeVisitor> network_change_visitor_;
+  StrictMock<MockSessionNotifier> notifier_;
+};
+
+INSTANTIATE_TEST_SUITE_P(Tests, QuicSentPacketManagerTest, testing::Bool());
+
+TEST_P(QuicSentPacketManagerTest, IsUnacked) {
+  VerifyUnackedPackets(nullptr, 0);
+  SendDataPacket(1);
+
+  uint64_t unacked[] = {1};
+  VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+  uint64_t retransmittable[] = {1};
+  VerifyRetransmittablePackets(retransmittable,
+                               QUIC_ARRAYSIZE(retransmittable));
+}
+
+TEST_P(QuicSentPacketManagerTest, IsUnAckedRetransmit) {
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+
+  EXPECT_TRUE(QuicSentPacketManagerPeer::IsRetransmission(&manager_, 2));
+  uint64_t unacked[] = {1, 2};
+  VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+  std::vector<uint64_t> retransmittable;
+  if (manager_.session_decides_what_to_write()) {
+    retransmittable = {1, 2};
+  } else {
+    retransmittable = {2};
+  }
+  VerifyRetransmittablePackets(&retransmittable[0], retransmittable.size());
+}
+
+TEST_P(QuicSentPacketManagerTest, RetransmitThenAck) {
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+
+  // Ack 2 but not 1.
+  ExpectAck(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  }
+  // Packet 1 is unacked, pending, but not retransmittable.
+  uint64_t unacked[] = {1};
+  VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
+  VerifyRetransmittablePackets(nullptr, 0);
+}
+
+TEST_P(QuicSentPacketManagerTest, RetransmitThenAckBeforeSend) {
+  SendDataPacket(1);
+  if (manager_.session_decides_what_to_write()) {
+    if (manager_.session_decides_what_to_write()) {
+      EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+          .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+            RetransmitDataPacket(2, type);
+          })));
+    }
+  }
+  QuicSentPacketManagerPeer::MarkForRetransmission(&manager_, 1,
+                                                   TLP_RETRANSMISSION);
+  if (!manager_.session_decides_what_to_write()) {
+    EXPECT_TRUE(manager_.HasPendingRetransmissions());
+  }
+  // Ack 1.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+
+  // There should no longer be a pending retransmission.
+  EXPECT_FALSE(manager_.HasPendingRetransmissions());
+
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+    uint64_t unacked[] = {2};
+    VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+    // We do not know packet 2 is a spurious retransmission until it gets acked.
+  } else {
+    // No unacked packets remain.
+    VerifyUnackedPackets(nullptr, 0);
+  }
+  VerifyRetransmittablePackets(nullptr, 0);
+  EXPECT_EQ(0u, stats_.packets_spuriously_retransmitted);
+}
+
+TEST_P(QuicSentPacketManagerTest, RetransmitThenStopRetransmittingBeforeSend) {
+  SendDataPacket(1);
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _));
+  }
+  QuicSentPacketManagerPeer::MarkForRetransmission(&manager_, 1,
+                                                   TLP_RETRANSMISSION);
+  if (!manager_.session_decides_what_to_write()) {
+    EXPECT_TRUE(manager_.HasPendingRetransmissions());
+  }
+
+  manager_.CancelRetransmissionsForStream(kStreamId);
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  }
+
+  // There should no longer be a pending retransmission.
+  EXPECT_FALSE(manager_.HasPendingRetransmissions());
+
+  uint64_t unacked[] = {1};
+  VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(nullptr, 0);
+  EXPECT_EQ(0u, stats_.packets_spuriously_retransmitted);
+}
+
+TEST_P(QuicSentPacketManagerTest, RetransmitThenAckPrevious) {
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+  QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(15);
+  clock_.AdvanceTime(rtt);
+
+  // Ack 1 but not 2.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  }
+  // 2 remains unacked, but no packets have retransmittable data.
+  uint64_t unacked[] = {2};
+  VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
+  VerifyRetransmittablePackets(nullptr, 0);
+  if (manager_.session_decides_what_to_write()) {
+    // Ack 2 causes 2 be considered as spurious retransmission.
+    EXPECT_CALL(notifier_, OnFrameAcked(_, _)).WillOnce(Return(false));
+    ExpectAck(2);
+    manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                             clock_.Now());
+    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+    EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+  }
+
+  EXPECT_EQ(1u, stats_.packets_spuriously_retransmitted);
+}
+
+TEST_P(QuicSentPacketManagerTest, RetransmitThenAckPreviousThenNackRetransmit) {
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+  QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(15);
+  clock_.AdvanceTime(rtt);
+
+  // First, ACK packet 1 which makes packet 2 non-retransmittable.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+
+  SendDataPacket(3);
+  SendDataPacket(4);
+  SendDataPacket(5);
+  clock_.AdvanceTime(rtt);
+
+  // Next, NACK packet 2 three times.
+  ExpectAck(3);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+
+  ExpectAck(4);
+  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+
+  ExpectAckAndLoss(true, 5, 2);
+  if (manager_.session_decides_what_to_write()) {
+    // Frames in all packets are acked.
+    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+    // Notify session that stream frame in packet 2 gets lost although it is
+    // not outstanding.
+    EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
+  }
+  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+
+  if (manager_.session_decides_what_to_write()) {
+    uint64_t unacked[] = {2};
+    VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+  } else {
+    // No packets remain unacked.
+    VerifyUnackedPackets(nullptr, 0);
+  }
+  EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  // Verify that the retransmission alarm would not fire,
+  // since there is no retransmittable data outstanding.
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+}
+
+TEST_P(QuicSentPacketManagerTest,
+       DISABLED_RetransmitTwiceThenAckPreviousBeforeSend) {
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+
+  // Fire the RTO, which will mark 2 for retransmission (but will not send it).
+  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.OnRetransmissionTimeout();
+  EXPECT_TRUE(manager_.HasPendingRetransmissions());
+
+  // Ack 1 but not 2, before 2 is able to be sent.
+  // Since 1 has been retransmitted, it has already been lost, and so the
+  // send algorithm is not informed that it has been ACK'd.
+  ExpectUpdatedRtt(1);
+  EXPECT_CALL(*send_algorithm_, RevertRetransmissionTimeout());
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+
+  // Since 2 was marked for retransmit, when 1 is acked, 2 is kept for RTT.
+  uint64_t unacked[] = {2};
+  VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+  EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  // Verify that the retransmission alarm would not fire,
+  // since there is no retransmittable data outstanding.
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+}
+
+TEST_P(QuicSentPacketManagerTest, RetransmitTwiceThenAckFirst) {
+  StrictMock<MockDebugDelegate> debug_delegate;
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(debug_delegate, OnSpuriousPacketRetransmission(
+                                    TLP_RETRANSMISSION, kDefaultLength))
+        .Times(1);
+  } else {
+    EXPECT_CALL(debug_delegate, OnSpuriousPacketRetransmission(
+                                    TLP_RETRANSMISSION, kDefaultLength))
+        .Times(2);
+  }
+  manager_.SetDebugDelegate(&debug_delegate);
+
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+  RetransmitAndSendPacket(2, 3);
+  QuicTime::Delta rtt = QuicTime::Delta::FromMilliseconds(15);
+  clock_.AdvanceTime(rtt);
+
+  // Ack 1 but not 2 or 3.
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+  if (manager_.session_decides_what_to_write()) {
+    // Frames in packets 2 and 3 are acked.
+    EXPECT_CALL(notifier_, IsFrameOutstanding(_))
+        .Times(2)
+        .WillRepeatedly(Return(false));
+  }
+
+  // 2 and 3 remain unacked, but no packets have retransmittable data.
+  uint64_t unacked[] = {2, 3};
+  VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
+  VerifyRetransmittablePackets(nullptr, 0);
+
+  // Ensure packet 2 is lost when 4 is sent and 3 and 4 are acked.
+  SendDataPacket(4);
+  if (manager_.session_decides_what_to_write()) {
+    // No new data gets acked in packet 3.
+    EXPECT_CALL(notifier_, OnFrameAcked(_, _))
+        .WillOnce(Return(false))
+        .WillRepeatedly(Return(true));
+  }
+  uint64_t acked[] = {3, 4};
+  ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+
+  uint64_t unacked2[] = {2};
+  VerifyUnackedPackets(unacked2, QUIC_ARRAYSIZE(unacked2));
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
+
+  SendDataPacket(5);
+  ExpectAckAndLoss(true, 5, 2);
+  EXPECT_CALL(debug_delegate,
+              OnPacketLoss(QuicPacketNumber(2), LOSS_RETRANSMISSION, _));
+  if (manager_.session_decides_what_to_write()) {
+    // Frames in all packets are acked.
+    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+    // Notify session that stream frame in packet 2 gets lost although it is
+    // not outstanding.
+    EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
+  }
+  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+
+  if (manager_.session_decides_what_to_write()) {
+    uint64_t unacked[] = {2};
+    VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+  } else {
+    VerifyUnackedPackets(nullptr, 0);
+  }
+  EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
+  if (manager_.session_decides_what_to_write()) {
+    // Spurious retransmission is detected when packet 3 gets acked. We cannot
+    // know packet 2 is a spurious until it gets acked.
+    EXPECT_EQ(1u, stats_.packets_spuriously_retransmitted);
+  } else {
+    EXPECT_EQ(2u, stats_.packets_spuriously_retransmitted);
+  }
+}
+
+TEST_P(QuicSentPacketManagerTest, AckOriginalTransmission) {
+  auto loss_algorithm = QuicMakeUnique<MockLossAlgorithm>();
+  QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm.get());
+
+  SendDataPacket(1);
+  RetransmitAndSendPacket(1, 2);
+
+  // Ack original transmission, but that wasn't lost via fast retransmit,
+  // so no call on OnSpuriousRetransmission is expected.
+  {
+    ExpectAck(1);
+    EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+    manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                             clock_.Now());
+    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+    EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+  }
+
+  SendDataPacket(3);
+  SendDataPacket(4);
+  // Ack 4, which causes 3 to be retransmitted.
+  {
+    ExpectAck(4);
+    EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+    manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                             clock_.Now());
+    manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
+    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+    EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+    RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION);
+  }
+
+  // Ack 3, which causes SpuriousRetransmitDetected to be called.
+  {
+    uint64_t acked[] = {3};
+    ExpectAcksAndLosses(false, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
+    EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+    EXPECT_CALL(*loss_algorithm,
+                SpuriousRetransmitDetected(_, _, _, QuicPacketNumber(5)));
+    manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                             clock_.Now());
+    manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
+    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+    EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+    if (manager_.session_decides_what_to_write()) {
+      // Ack 3 will not cause 5 be considered as a spurious retransmission. Ack
+      // 5 will cause 5 be considered as a spurious retransmission as no new
+      // data gets acked.
+      ExpectAck(5);
+      EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+      EXPECT_CALL(notifier_, OnFrameAcked(_, _)).WillOnce(Return(false));
+      manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                               clock_.Now());
+      manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
+      manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+      EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+    }
+  }
+}
+
+TEST_P(QuicSentPacketManagerTest, GetLeastUnacked) {
+  EXPECT_EQ(QuicPacketNumber(1u), manager_.GetLeastUnacked());
+}
+
+TEST_P(QuicSentPacketManagerTest, GetLeastUnackedUnacked) {
+  SendDataPacket(1);
+  EXPECT_EQ(QuicPacketNumber(1u), manager_.GetLeastUnacked());
+}
+
+TEST_P(QuicSentPacketManagerTest, AckAckAndUpdateRtt) {
+  EXPECT_FALSE(manager_.largest_packet_peer_knows_is_acked().IsInitialized());
+  SendDataPacket(1);
+  SendAckPacket(2, 1);
+
+  // Now ack the ack and expect an RTT update.
+  uint64_t acked[] = {1, 2};
+  ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(2),
+                           QuicTime::Delta::FromMilliseconds(5), clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+  EXPECT_EQ(QuicPacketNumber(1), manager_.largest_packet_peer_knows_is_acked());
+
+  SendAckPacket(3, 3);
+
+  // Now ack the ack and expect only an RTT update.
+  uint64_t acked2[] = {3};
+  ExpectAcksAndLosses(true, acked2, QUIC_ARRAYSIZE(acked2), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+  EXPECT_EQ(QuicPacketNumber(3u),
+            manager_.largest_packet_peer_knows_is_acked());
+}
+
+TEST_P(QuicSentPacketManagerTest, Rtt) {
+  QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(20);
+  SendDataPacket(1);
+  clock_.AdvanceTime(expected_rtt);
+
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+  EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
+}
+
+TEST_P(QuicSentPacketManagerTest, RttWithInvalidDelta) {
+  // Expect that the RTT is equal to the local time elapsed, since the
+  // ack_delay_time is larger than the local time elapsed
+  // and is hence invalid.
+  QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
+  SendDataPacket(1);
+  clock_.AdvanceTime(expected_rtt);
+
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1),
+                           QuicTime::Delta::FromMilliseconds(11), clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+  EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
+}
+
+TEST_P(QuicSentPacketManagerTest, RttWithInfiniteDelta) {
+  // Expect that the RTT is equal to the local time elapsed, since the
+  // ack_delay_time is infinite, and is hence invalid.
+  QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
+  SendDataPacket(1);
+  clock_.AdvanceTime(expected_rtt);
+
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+  EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
+}
+
+TEST_P(QuicSentPacketManagerTest, RttZeroDelta) {
+  // Expect that the RTT is the time between send and receive since the
+  // ack_delay_time is zero.
+  QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
+  SendDataPacket(1);
+  clock_.AdvanceTime(expected_rtt);
+
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+  EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
+}
+
+TEST_P(QuicSentPacketManagerTest, TailLossProbeTimeout) {
+  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
+
+  // Send 1 packet.
+  SendDataPacket(1);
+
+  // The first tail loss probe retransmits 1 packet.
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(WithArgs<1>(Invoke(
+            [this](TransmissionType type) { RetransmitDataPacket(2, type); })));
+  }
+  manager_.MaybeRetransmitTailLossProbe();
+  if (!manager_.session_decides_what_to_write()) {
+    EXPECT_TRUE(manager_.HasPendingRetransmissions());
+    RetransmitNextPacket(2);
+    EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  }
+
+  // The second tail loss probe retransmits 1 packet.
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(WithArgs<1>(Invoke(
+            [this](TransmissionType type) { RetransmitDataPacket(3, type); })));
+  }
+  manager_.MaybeRetransmitTailLossProbe();
+  if (!manager_.session_decides_what_to_write()) {
+    EXPECT_TRUE(manager_.HasPendingRetransmissions());
+    RetransmitNextPacket(3);
+  }
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
+  EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_FALSE(manager_.HasPendingRetransmissions());
+
+  // Ack the third and ensure the first two are still pending.
+  ExpectAck(3);
+
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
+
+  // Acking two more packets will lose both of them due to nacks.
+  SendDataPacket(4);
+  SendDataPacket(5);
+  uint64_t acked[] = {4, 5};
+  uint64_t lost[] = {1, 2};
+  ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), lost,
+                      QUIC_ARRAYSIZE(lost));
+  if (manager_.session_decides_what_to_write()) {
+    // Frames in all packets are acked.
+    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+    // Notify session that stream frame in packets 1 and 2 get lost although
+    // they are not outstanding.
+    EXPECT_CALL(notifier_, OnFrameLost(_)).Times(2);
+  }
+  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+
+  EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
+  EXPECT_EQ(2u, stats_.tlp_count);
+  EXPECT_EQ(0u, stats_.rto_count);
+}
+
+TEST_P(QuicSentPacketManagerTest, TailLossProbeThenRTO) {
+  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
+
+  // Send 100 packets.
+  const size_t kNumSentPackets = 100;
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+  QuicTime rto_packet_time = clock_.Now();
+  // Advance the time.
+  clock_.AdvanceTime(manager_.GetRetransmissionTime() - clock_.Now());
+
+  // The first tail loss probe retransmits 1 packet.
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+          RetransmitDataPacket(101, type);
+        })));
+  }
+  manager_.MaybeRetransmitTailLossProbe();
+  if (!manager_.session_decides_what_to_write()) {
+    EXPECT_TRUE(manager_.HasPendingRetransmissions());
+    RetransmitNextPacket(101);
+  }
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
+  EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  clock_.AdvanceTime(manager_.GetRetransmissionTime() - clock_.Now());
+
+  // The second tail loss probe retransmits 1 packet.
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+          RetransmitDataPacket(102, type);
+        })));
+  }
+  EXPECT_TRUE(manager_.MaybeRetransmitTailLossProbe());
+  if (!manager_.session_decides_what_to_write()) {
+    EXPECT_TRUE(manager_.HasPendingRetransmissions());
+    RetransmitNextPacket(102);
+  }
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
+  EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
+
+  // Ensure the RTO is set based on the correct packet.
+  rto_packet_time = clock_.Now();
+  EXPECT_EQ(rto_packet_time + QuicTime::Delta::FromMilliseconds(500),
+            manager_.GetRetransmissionTime());
+
+  // Advance the time enough to ensure all packets are RTO'd.
+  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1000));
+
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .Times(2)
+        .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+          RetransmitDataPacket(103, type);
+        })))
+        .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+          RetransmitDataPacket(104, type);
+        })));
+  }
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(2u, stats_.tlp_count);
+  EXPECT_EQ(1u, stats_.rto_count);
+  if (manager_.session_decides_what_to_write()) {
+    // There are 2 RTO retransmissions.
+    EXPECT_EQ(104 * kDefaultLength,
+              QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+  }
+  if (!manager_.session_decides_what_to_write()) {
+    // Send and Ack the RTO and ensure OnRetransmissionTimeout is called.
+    EXPECT_EQ(102 * kDefaultLength,
+              QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+    EXPECT_TRUE(manager_.HasPendingRetransmissions());
+    RetransmitNextPacket(103);
+  }
+  QuicPacketNumber largest_acked = QuicPacketNumber(103);
+  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(
+                  true, _, _, Pointwise(PacketNumberEq(), {largest_acked}), _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  if (manager_.session_decides_what_to_write()) {
+    // Although frames in packet 3 gets acked, it would be kept for another
+    // RTT.
+    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
+    // Packets [1, 102] are lost, although stream frame in packet 3 is not
+    // outstanding.
+    EXPECT_CALL(notifier_, OnFrameLost(_)).Times(102);
+  }
+  manager_.OnAckFrameStart(QuicPacketNumber(103), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(103), QuicPacketNumber(104));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+  // All packets before 103 should be lost.
+  if (manager_.session_decides_what_to_write()) {
+    // Packet 104 is still in flight.
+    EXPECT_EQ(1000u, QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+  } else {
+    EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+  }
+}
+
+TEST_P(QuicSentPacketManagerTest, CryptoHandshakeTimeout) {
+  // Send 2 crypto packets and 3 data packets.
+  const size_t kNumSentCryptoPackets = 2;
+  for (size_t i = 1; i <= kNumSentCryptoPackets; ++i) {
+    SendCryptoPacket(i);
+  }
+  const size_t kNumSentDataPackets = 3;
+  for (size_t i = 1; i <= kNumSentDataPackets; ++i) {
+    SendDataPacket(kNumSentCryptoPackets + i);
+  }
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+
+  // The first retransmits 2 packets.
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .Times(2)
+        .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(6); }))
+        .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(7); }));
+  }
+  manager_.OnRetransmissionTimeout();
+  if (!manager_.session_decides_what_to_write()) {
+    EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+    RetransmitNextPacket(6);
+    RetransmitNextPacket(7);
+    EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  }
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+
+  // The second retransmits 2 packets.
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .Times(2)
+        .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(8); }))
+        .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(9); }));
+  }
+  manager_.OnRetransmissionTimeout();
+  if (!manager_.session_decides_what_to_write()) {
+    EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+    RetransmitNextPacket(8);
+    RetransmitNextPacket(9);
+    EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  }
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+
+  // Now ack the two crypto packets and the speculatively encrypted request,
+  // and ensure the first four crypto packets get abandoned, but not lost.
+  uint64_t acked[] = {3, 4, 5, 8, 9};
+  ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, HasUnackedCryptoData())
+        .WillRepeatedly(Return(false));
+  }
+  manager_.OnAckFrameStart(QuicPacketNumber(9), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(8), QuicPacketNumber(10));
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+
+  EXPECT_FALSE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+}
+
+TEST_P(QuicSentPacketManagerTest, CryptoHandshakeTimeoutVersionNegotiation) {
+  // Send 2 crypto packets and 3 data packets.
+  const size_t kNumSentCryptoPackets = 2;
+  for (size_t i = 1; i <= kNumSentCryptoPackets; ++i) {
+    SendCryptoPacket(i);
+  }
+  const size_t kNumSentDataPackets = 3;
+  for (size_t i = 1; i <= kNumSentDataPackets; ++i) {
+    SendDataPacket(kNumSentCryptoPackets + i);
+  }
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .Times(2)
+        .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(6); }))
+        .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(7); }));
+  }
+  manager_.OnRetransmissionTimeout();
+  if (!manager_.session_decides_what_to_write()) {
+    RetransmitNextPacket(6);
+    RetransmitNextPacket(7);
+    EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  }
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+
+  // Now act like a version negotiation packet arrived, which would cause all
+  // unacked packets to be retransmitted.
+  if (manager_.session_decides_what_to_write()) {
+    // Mark packets [1, 7] lost. And the frames in 6 and 7 are same as packets 1
+    // and 2, respectively.
+    EXPECT_CALL(notifier_, OnFrameLost(_)).Times(7);
+  }
+  manager_.RetransmitUnackedPackets(ALL_UNACKED_RETRANSMISSION);
+
+  // Ensure the first two pending packets are the crypto retransmits.
+  if (manager_.session_decides_what_to_write()) {
+    RetransmitCryptoPacket(8);
+    RetransmitCryptoPacket(9);
+    RetransmitDataPacket(10, ALL_UNACKED_RETRANSMISSION);
+    RetransmitDataPacket(11, ALL_UNACKED_RETRANSMISSION);
+    RetransmitDataPacket(12, ALL_UNACKED_RETRANSMISSION);
+  } else {
+    ASSERT_TRUE(manager_.HasPendingRetransmissions());
+    EXPECT_EQ(QuicPacketNumber(6u),
+              manager_.NextPendingRetransmission().packet_number);
+    RetransmitNextPacket(8);
+    EXPECT_EQ(QuicPacketNumber(7u),
+              manager_.NextPendingRetransmission().packet_number);
+    RetransmitNextPacket(9);
+    EXPECT_TRUE(manager_.HasPendingRetransmissions());
+    // Send 3 more data packets and ensure the least unacked is raised.
+    RetransmitNextPacket(10);
+    RetransmitNextPacket(11);
+    RetransmitNextPacket(12);
+    EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  }
+
+  EXPECT_EQ(QuicPacketNumber(1u), manager_.GetLeastUnacked());
+  // Least unacked isn't raised until an ack is received, so ack the
+  // crypto packets.
+  uint64_t acked[] = {8, 9};
+  ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(9), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(8), QuicPacketNumber(10));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, HasUnackedCryptoData())
+        .WillRepeatedly(Return(false));
+  }
+  EXPECT_EQ(QuicPacketNumber(10u), manager_.GetLeastUnacked());
+}
+
+TEST_P(QuicSentPacketManagerTest, CryptoHandshakeSpuriousRetransmission) {
+  // Send 1 crypto packet.
+  SendCryptoPacket(1);
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+
+  // Retransmit the crypto packet as 2.
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(2); }));
+  }
+  manager_.OnRetransmissionTimeout();
+  if (!manager_.session_decides_what_to_write()) {
+    RetransmitNextPacket(2);
+  }
+
+  // Retransmit the crypto packet as 3.
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(3); }));
+  }
+  manager_.OnRetransmissionTimeout();
+  if (!manager_.session_decides_what_to_write()) {
+    RetransmitNextPacket(3);
+  }
+
+  // Now ack the second crypto packet, and ensure the first gets removed, but
+  // the third does not.
+  uint64_t acked[] = {2};
+  ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, HasUnackedCryptoData())
+        .WillRepeatedly(Return(false));
+    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  }
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+
+  EXPECT_FALSE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+  uint64_t unacked[] = {3};
+  VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+}
+
+TEST_P(QuicSentPacketManagerTest, CryptoHandshakeTimeoutUnsentDataPacket) {
+  // Send 2 crypto packets and 1 data packet.
+  const size_t kNumSentCryptoPackets = 2;
+  for (size_t i = 1; i <= kNumSentCryptoPackets; ++i) {
+    SendCryptoPacket(i);
+  }
+  SendDataPacket(3);
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+
+  // Retransmit 2 crypto packets, but not the serialized packet.
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .Times(2)
+        .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(4); }))
+        .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(5); }));
+  }
+  manager_.OnRetransmissionTimeout();
+  if (!manager_.session_decides_what_to_write()) {
+    RetransmitNextPacket(4);
+    RetransmitNextPacket(5);
+    EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  }
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+}
+
+TEST_P(QuicSentPacketManagerTest,
+       CryptoHandshakeRetransmissionThenRetransmitAll) {
+  // Send 1 crypto packet.
+  SendCryptoPacket(1);
+
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+
+  // Retransmit the crypto packet as 2.
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(2); }));
+  }
+  manager_.OnRetransmissionTimeout();
+  if (!manager_.session_decides_what_to_write()) {
+    RetransmitNextPacket(2);
+  }
+  // Now retransmit all the unacked packets, which occurs when there is a
+  // version negotiation.
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, OnFrameLost(_)).Times(2);
+  }
+  manager_.RetransmitUnackedPackets(ALL_UNACKED_RETRANSMISSION);
+  if (manager_.session_decides_what_to_write()) {
+    // Both packets 1 and 2 are unackable.
+    EXPECT_FALSE(QuicSentPacketManagerPeer::IsUnacked(&manager_, 1));
+    EXPECT_FALSE(QuicSentPacketManagerPeer::IsUnacked(&manager_, 2));
+  } else {
+    // Packet 2 is useful because it does not get retransmitted and still has
+    // retransmittable frames.
+    uint64_t unacked[] = {1, 2};
+    VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+    EXPECT_TRUE(manager_.HasPendingRetransmissions());
+  }
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+  EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
+}
+
+TEST_P(QuicSentPacketManagerTest,
+       CryptoHandshakeRetransmissionThenNeuterAndAck) {
+  // Send 1 crypto packet.
+  SendCryptoPacket(1);
+
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+
+  // Retransmit the crypto packet as 2.
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(2); }));
+  }
+  manager_.OnRetransmissionTimeout();
+  if (!manager_.session_decides_what_to_write()) {
+    RetransmitNextPacket(2);
+  }
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+
+  // Retransmit the crypto packet as 3.
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(3); }));
+  }
+  manager_.OnRetransmissionTimeout();
+  if (!manager_.session_decides_what_to_write()) {
+    RetransmitNextPacket(3);
+  }
+  EXPECT_TRUE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+
+  // Now neuter all unacked unencrypted packets, which occurs when the
+  // connection goes forward secure.
+  manager_.NeuterUnencryptedPackets();
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, HasUnackedCryptoData())
+        .WillRepeatedly(Return(false));
+    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
+  }
+  EXPECT_FALSE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+  uint64_t unacked[] = {1, 2, 3};
+  VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
+  VerifyRetransmittablePackets(nullptr, 0);
+  EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  EXPECT_FALSE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
+  EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
+
+  // Ensure both packets get discarded when packet 2 is acked.
+  uint64_t acked[] = {3};
+  ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+  VerifyUnackedPackets(nullptr, 0);
+  VerifyRetransmittablePackets(nullptr, 0);
+}
+
+TEST_P(QuicSentPacketManagerTest, RetransmissionTimeout) {
+  StrictMock<MockDebugDelegate> debug_delegate;
+  manager_.SetDebugDelegate(&debug_delegate);
+
+  // Send 100 packets.
+  const size_t kNumSentPackets = 100;
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+
+  EXPECT_FALSE(manager_.MaybeRetransmitTailLossProbe());
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .Times(2)
+        .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+          RetransmitDataPacket(101, type);
+        })))
+        .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+          RetransmitDataPacket(102, type);
+        })));
+  }
+  manager_.OnRetransmissionTimeout();
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_EQ(102 * kDefaultLength,
+              QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+  } else {
+    ASSERT_TRUE(manager_.HasPendingRetransmissions());
+    EXPECT_EQ(100 * kDefaultLength,
+              QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+    RetransmitNextPacket(101);
+    ASSERT_TRUE(manager_.HasPendingRetransmissions());
+    RetransmitNextPacket(102);
+    EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  }
+
+  // Ack a retransmission.
+  // Ensure no packets are lost.
+  QuicPacketNumber largest_acked = QuicPacketNumber(102);
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(true, _, _,
+                                Pointwise(PacketNumberEq(), {largest_acked}),
+                                /*lost_packets=*/IsEmpty()));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+  // RTO's use loss detection instead of immediately declaring retransmitted
+  // packets lost.
+  for (int i = 1; i <= 99; ++i) {
+    EXPECT_CALL(debug_delegate,
+                OnPacketLoss(QuicPacketNumber(i), LOSS_RETRANSMISSION, _));
+  }
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
+    // Packets [1, 99] are considered as lost, although stream frame in packet
+    // 2 is not outstanding.
+    EXPECT_CALL(notifier_, OnFrameLost(_)).Times(99);
+  }
+  manager_.OnAckFrameStart(QuicPacketNumber(102), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(102), QuicPacketNumber(103));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+}
+
+TEST_P(QuicSentPacketManagerTest, RetransmissionTimeoutOnePacket) {
+  // Set the 1RTO connection option.
+  QuicConfig client_config;
+  QuicTagVector options;
+  options.push_back(k1RTO);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  manager_.SetFromConfig(client_config);
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+
+  StrictMock<MockDebugDelegate> debug_delegate;
+  manager_.SetDebugDelegate(&debug_delegate);
+
+  // Send 100 packets.
+  const size_t kNumSentPackets = 100;
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+
+  EXPECT_FALSE(manager_.MaybeRetransmitTailLossProbe());
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .Times(1)
+        .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+          RetransmitDataPacket(101, type);
+        })));
+  }
+  manager_.OnRetransmissionTimeout();
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_EQ(101 * kDefaultLength,
+              QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+  } else {
+    ASSERT_TRUE(manager_.HasPendingRetransmissions());
+    EXPECT_EQ(100 * kDefaultLength,
+              QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+    RetransmitNextPacket(101);
+    EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  }
+}
+
+TEST_P(QuicSentPacketManagerTest, NewRetransmissionTimeout) {
+  QuicConfig client_config;
+  QuicTagVector options;
+  options.push_back(kNRTO);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+  manager_.SetFromConfig(client_config);
+  EXPECT_TRUE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillRepeatedly(Return(true));
+
+  // Send 100 packets.
+  const size_t kNumSentPackets = 100;
+  for (size_t i = 1; i <= kNumSentPackets; ++i) {
+    SendDataPacket(i);
+  }
+
+  EXPECT_FALSE(manager_.MaybeRetransmitTailLossProbe());
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .Times(2)
+        .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+          RetransmitDataPacket(101, type);
+        })))
+        .WillOnce(WithArgs<1>(Invoke([this](TransmissionType type) {
+          RetransmitDataPacket(102, type);
+        })));
+  }
+  manager_.OnRetransmissionTimeout();
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_EQ(102 * kDefaultLength,
+              QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+  } else {
+    EXPECT_TRUE(manager_.HasPendingRetransmissions());
+    EXPECT_EQ(100 * kDefaultLength,
+              QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+    RetransmitNextPacket(101);
+    RetransmitNextPacket(102);
+    EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  }
+
+  // Ack a retransmission and expect no call to OnRetransmissionTimeout.
+  // This will include packets in the lost packet map.
+  QuicPacketNumber largest_acked = QuicPacketNumber(102);
+  EXPECT_CALL(*send_algorithm_,
+              OnCongestionEvent(true, _, _,
+                                Pointwise(PacketNumberEq(), {largest_acked}),
+                                /*lost_packets=*/Not(IsEmpty())));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(true));
+    // Packets [1, 99] are considered as lost, although stream frame in packet
+    // 2 is not outstanding.
+    EXPECT_CALL(notifier_, OnFrameLost(_)).Times(99);
+  }
+  manager_.OnAckFrameStart(QuicPacketNumber(102), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(102), QuicPacketNumber(103));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+}
+
+TEST_P(QuicSentPacketManagerTest, TwoRetransmissionTimeoutsAckSecond) {
+  // Send 1 packet.
+  SendDataPacket(1);
+
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(WithArgs<1>(Invoke(
+            [this](TransmissionType type) { RetransmitDataPacket(2, type); })));
+  }
+  manager_.OnRetransmissionTimeout();
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_EQ(2 * kDefaultLength,
+              QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+  } else {
+    EXPECT_TRUE(manager_.HasPendingRetransmissions());
+    EXPECT_EQ(kDefaultLength,
+              QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+    RetransmitNextPacket(2);
+    EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  }
+
+  // Rto a second time.
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(WithArgs<1>(Invoke(
+            [this](TransmissionType type) { RetransmitDataPacket(3, type); })));
+  }
+  manager_.OnRetransmissionTimeout();
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_EQ(3 * kDefaultLength,
+              QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+  } else {
+    EXPECT_TRUE(manager_.HasPendingRetransmissions());
+    EXPECT_EQ(2 * kDefaultLength,
+              QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+    RetransmitNextPacket(3);
+    EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  }
+
+  // Ack a retransmission and ensure OnRetransmissionTimeout is called.
+  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+  ExpectAck(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+
+  // The original packet and newest should be outstanding.
+  EXPECT_EQ(2 * kDefaultLength,
+            QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+}
+
+TEST_P(QuicSentPacketManagerTest, TwoRetransmissionTimeoutsAckFirst) {
+  // Send 1 packet.
+  SendDataPacket(1);
+
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(WithArgs<1>(Invoke(
+            [this](TransmissionType type) { RetransmitDataPacket(2, type); })));
+  }
+  manager_.OnRetransmissionTimeout();
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_EQ(2 * kDefaultLength,
+              QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+  } else {
+    EXPECT_TRUE(manager_.HasPendingRetransmissions());
+    EXPECT_EQ(kDefaultLength,
+              QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+    RetransmitNextPacket(2);
+    EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  }
+
+  // Rto a second time.
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(WithArgs<1>(Invoke(
+            [this](TransmissionType type) { RetransmitDataPacket(3, type); })));
+  }
+  manager_.OnRetransmissionTimeout();
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_EQ(3 * kDefaultLength,
+              QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+  } else {
+    EXPECT_TRUE(manager_.HasPendingRetransmissions());
+    EXPECT_EQ(2 * kDefaultLength,
+              QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+    RetransmitNextPacket(3);
+    EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  }
+
+  // Ack a retransmission and ensure OnRetransmissionTimeout is called.
+  EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
+  ExpectAck(3);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+
+  // The first two packets should still be outstanding.
+  EXPECT_EQ(2 * kDefaultLength,
+            QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+}
+
+TEST_P(QuicSentPacketManagerTest, GetTransmissionTime) {
+  EXPECT_EQ(QuicTime::Zero(), manager_.GetRetransmissionTime());
+}
+
+TEST_P(QuicSentPacketManagerTest, GetTransmissionTimeCryptoHandshake) {
+  QuicTime crypto_packet_send_time = clock_.Now();
+  SendCryptoPacket(1);
+
+  // Check the min.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromMilliseconds(10),
+            manager_.GetRetransmissionTime());
+
+  // Test with a standard smoothed RTT.
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(100));
+
+  QuicTime::Delta srtt = rtt_stats->initial_rtt();
+  QuicTime expected_time = clock_.Now() + 1.5 * srtt;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+
+  // Retransmit the packet by invoking the retransmission timeout.
+  clock_.AdvanceTime(1.5 * srtt);
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(2); }));
+    // When session decides what to write, crypto_packet_send_time gets updated.
+    crypto_packet_send_time = clock_.Now();
+  }
+  manager_.OnRetransmissionTimeout();
+  if (!manager_.session_decides_what_to_write()) {
+    RetransmitNextPacket(2);
+  }
+
+  // The retransmission time should now be twice as far in the future.
+  expected_time = crypto_packet_send_time + srtt * 2 * 1.5;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+
+  // Retransmit the packet for the 2nd time.
+  clock_.AdvanceTime(2 * 1.5 * srtt);
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(3); }));
+    // When session decides what to write, crypto_packet_send_time gets updated.
+    crypto_packet_send_time = clock_.Now();
+  }
+  manager_.OnRetransmissionTimeout();
+  if (!manager_.session_decides_what_to_write()) {
+    RetransmitNextPacket(3);
+  }
+
+  // Verify exponential backoff of the retransmission timeout.
+  expected_time = crypto_packet_send_time + srtt * 4 * 1.5;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+}
+
+TEST_P(QuicSentPacketManagerTest,
+       GetConservativeTransmissionTimeCryptoHandshake) {
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kCONH);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  // Calling SetFromConfig requires mocking out some send algorithm methods.
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillRepeatedly(Return(10 * kDefaultTCPMSS));
+
+  QuicTime crypto_packet_send_time = clock_.Now();
+  SendCryptoPacket(1);
+
+  // Check the min.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromMilliseconds(25),
+            manager_.GetRetransmissionTime());
+
+  // Test with a standard smoothed RTT.
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(100));
+
+  QuicTime::Delta srtt = rtt_stats->initial_rtt();
+  QuicTime expected_time = clock_.Now() + 2 * srtt;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+
+  // Retransmit the packet by invoking the retransmission timeout.
+  clock_.AdvanceTime(2 * srtt);
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(InvokeWithoutArgs([this]() { RetransmitCryptoPacket(2); }));
+    crypto_packet_send_time = clock_.Now();
+  }
+  manager_.OnRetransmissionTimeout();
+  if (!manager_.session_decides_what_to_write()) {
+    RetransmitNextPacket(2);
+  }
+
+  // The retransmission time should now be twice as far in the future.
+  expected_time = crypto_packet_send_time + srtt * 2 * 2;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+}
+
+TEST_P(QuicSentPacketManagerTest, GetTransmissionTimeTailLossProbe) {
+  QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
+  SendDataPacket(1);
+  SendDataPacket(2);
+
+  // Check the min.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(1));
+  EXPECT_EQ(clock_.Now() + QuicTime::Delta::FromMilliseconds(10),
+            manager_.GetRetransmissionTime());
+
+  // Test with a standard smoothed RTT.
+  rtt_stats->set_initial_rtt(QuicTime::Delta::FromMilliseconds(100));
+  QuicTime::Delta srtt = rtt_stats->initial_rtt();
+  QuicTime::Delta expected_tlp_delay = 2 * srtt;
+  QuicTime expected_time = clock_.Now() + expected_tlp_delay;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+
+  // Retransmit the packet by invoking the retransmission timeout.
+  clock_.AdvanceTime(expected_tlp_delay);
+  manager_.OnRetransmissionTimeout();
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .WillOnce(WithArgs<1>(Invoke(
+            [this](TransmissionType type) { RetransmitDataPacket(3, type); })));
+  }
+  EXPECT_TRUE(manager_.MaybeRetransmitTailLossProbe());
+  if (!manager_.session_decides_what_to_write()) {
+    EXPECT_TRUE(manager_.HasPendingRetransmissions());
+    RetransmitNextPacket(3);
+  }
+  EXPECT_CALL(*send_algorithm_, CanSend(_)).WillOnce(Return(false));
+  EXPECT_EQ(QuicTime::Delta::Infinite(), manager_.TimeUntilSend(clock_.Now()));
+  EXPECT_FALSE(manager_.HasPendingRetransmissions());
+
+  expected_time = clock_.Now() + expected_tlp_delay;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+}
+
+TEST_P(QuicSentPacketManagerTest, GetTransmissionTimeSpuriousRTO) {
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+
+  SendDataPacket(1);
+  SendDataPacket(2);
+  SendDataPacket(3);
+  SendDataPacket(4);
+
+  QuicTime::Delta expected_rto_delay =
+      rtt_stats->smoothed_rtt() + 4 * rtt_stats->mean_deviation();
+  QuicTime expected_time = clock_.Now() + expected_rto_delay;
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+
+  // Retransmit the packet by invoking the retransmission timeout.
+  clock_.AdvanceTime(expected_rto_delay);
+  if (manager_.session_decides_what_to_write()) {
+    EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+        .Times(2)
+        .WillOnce(WithArgs<1>(Invoke(
+            [this](TransmissionType type) { RetransmitDataPacket(5, type); })))
+        .WillOnce(WithArgs<1>(Invoke(
+            [this](TransmissionType type) { RetransmitDataPacket(6, type); })));
+  }
+  manager_.OnRetransmissionTimeout();
+  if (!manager_.session_decides_what_to_write()) {
+    // All packets are still considered inflight.
+    EXPECT_EQ(4 * kDefaultLength,
+              QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+    RetransmitNextPacket(5);
+    RetransmitNextPacket(6);
+  }
+  // All previous packets are inflight, plus two rto retransmissions.
+  EXPECT_EQ(6 * kDefaultLength,
+            QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+  EXPECT_FALSE(manager_.HasPendingRetransmissions());
+
+  // The delay should double the second time.
+  expected_time = clock_.Now() + expected_rto_delay + expected_rto_delay;
+  // Once we always base the timer on the right edge, leaving the older packets
+  // in flight doesn't change the timeout.
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+
+  // Ack a packet before the first RTO and ensure the RTO timeout returns to the
+  // original value and OnRetransmissionTimeout is not called or reverted.
+  ExpectAck(2);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+  EXPECT_FALSE(manager_.HasPendingRetransmissions());
+  EXPECT_EQ(5 * kDefaultLength,
+            QuicSentPacketManagerPeer::GetBytesInFlight(&manager_));
+
+  // Wait 2RTTs from now for the RTO, since it's the max of the RTO time
+  // and the TLP time.  In production, there would always be two TLP's first.
+  // Since retransmission was spurious, smoothed_rtt_ is expired, and replaced
+  // by the latest RTT sample of 500ms.
+  expected_time = clock_.Now() + QuicTime::Delta::FromMilliseconds(1000);
+  // Once we always base the timer on the right edge, leaving the older packets
+  // in flight doesn't change the timeout.
+  EXPECT_EQ(expected_time, manager_.GetRetransmissionTime());
+}
+
+TEST_P(QuicSentPacketManagerTest, GetTransmissionDelayMin) {
+  SendDataPacket(1);
+  // Provide a 1ms RTT sample.
+  const_cast<RttStats*>(manager_.GetRttStats())
+      ->UpdateRtt(QuicTime::Delta::FromMilliseconds(1), QuicTime::Delta::Zero(),
+                  QuicTime::Zero());
+  QuicTime::Delta delay = QuicTime::Delta::FromMilliseconds(200);
+
+  // If the delay is smaller than the min, ensure it exponentially backs off
+  // from the min.
+  for (int i = 0; i < 5; ++i) {
+    EXPECT_EQ(delay,
+              QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+    EXPECT_EQ(delay,
+              QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, i));
+    delay = delay + delay;
+    if (manager_.session_decides_what_to_write()) {
+      EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+          .WillOnce(WithArgs<1>(Invoke([this, i](TransmissionType type) {
+            RetransmitDataPacket(i + 2, type);
+          })));
+    }
+    manager_.OnRetransmissionTimeout();
+    if (!manager_.session_decides_what_to_write()) {
+      RetransmitNextPacket(i + 2);
+    }
+  }
+}
+
+TEST_P(QuicSentPacketManagerTest, GetTransmissionDelayMax) {
+  SendDataPacket(1);
+  // Provide a 60s RTT sample.
+  const_cast<RttStats*>(manager_.GetRttStats())
+      ->UpdateRtt(QuicTime::Delta::FromSeconds(60), QuicTime::Delta::Zero(),
+                  QuicTime::Zero());
+
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(60),
+            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(60),
+            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, 0));
+}
+
+TEST_P(QuicSentPacketManagerTest, GetTransmissionDelayExponentialBackoff) {
+  SendDataPacket(1);
+  QuicTime::Delta delay = QuicTime::Delta::FromMilliseconds(500);
+
+  // Delay should back off exponentially.
+  for (int i = 0; i < 5; ++i) {
+    EXPECT_EQ(delay,
+              QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+    EXPECT_EQ(delay,
+              QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, i));
+    delay = delay + delay;
+    if (manager_.session_decides_what_to_write()) {
+      EXPECT_CALL(notifier_, RetransmitFrames(_, _))
+          .WillOnce(WithArgs<1>(Invoke([this, i](TransmissionType type) {
+            RetransmitDataPacket(i + 2, type);
+          })));
+    }
+    manager_.OnRetransmissionTimeout();
+    if (!manager_.session_decides_what_to_write()) {
+      RetransmitNextPacket(i + 2);
+    }
+  }
+}
+
+TEST_P(QuicSentPacketManagerTest, RetransmissionDelay) {
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  const int64_t kRttMs = 250;
+  const int64_t kDeviationMs = 5;
+
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(kRttMs),
+                       QuicTime::Delta::Zero(), clock_.Now());
+
+  // Initial value is to set the median deviation to half of the initial rtt,
+  // the median in then multiplied by a factor of 4 and finally the smoothed rtt
+  // is added which is the initial rtt.
+  QuicTime::Delta expected_delay =
+      QuicTime::Delta::FromMilliseconds(kRttMs + kRttMs / 2 * 4);
+  EXPECT_EQ(expected_delay,
+            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+  EXPECT_EQ(expected_delay,
+            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, 0));
+
+  for (int i = 0; i < 100; ++i) {
+    // Run to make sure that we converge.
+    rtt_stats->UpdateRtt(
+        QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs),
+        QuicTime::Delta::Zero(), clock_.Now());
+    rtt_stats->UpdateRtt(
+        QuicTime::Delta::FromMilliseconds(kRttMs - kDeviationMs),
+        QuicTime::Delta::Zero(), clock_.Now());
+  }
+  expected_delay = QuicTime::Delta::FromMilliseconds(kRttMs + kDeviationMs * 4);
+
+  EXPECT_NEAR(kRttMs, rtt_stats->smoothed_rtt().ToMilliseconds(), 1);
+  EXPECT_NEAR(expected_delay.ToMilliseconds(),
+              QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_)
+                  .ToMilliseconds(),
+              1);
+  EXPECT_EQ(QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, 0),
+            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+}
+
+TEST_P(QuicSentPacketManagerTest, GetLossDelay) {
+  auto loss_algorithm = QuicMakeUnique<MockLossAlgorithm>();
+  QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm.get());
+
+  EXPECT_CALL(*loss_algorithm, GetLossTimeout())
+      .WillRepeatedly(Return(QuicTime::Zero()));
+  SendDataPacket(1);
+  SendDataPacket(2);
+
+  // Handle an ack which causes the loss algorithm to be evaluated and
+  // set the loss timeout.
+  ExpectAck(2);
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+
+  QuicTime timeout(clock_.Now() + QuicTime::Delta::FromMilliseconds(10));
+  EXPECT_CALL(*loss_algorithm, GetLossTimeout())
+      .WillRepeatedly(Return(timeout));
+  EXPECT_EQ(timeout, manager_.GetRetransmissionTime());
+
+  // Fire the retransmission timeout and ensure the loss detection algorithm
+  // is invoked.
+  EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
+  manager_.OnRetransmissionTimeout();
+}
+
+TEST_P(QuicSentPacketManagerTest, NegotiateTimeLossDetectionFromOptions) {
+  EXPECT_EQ(kNack, QuicSentPacketManagerPeer::GetLossAlgorithm(&manager_)
+                       ->GetLossDetectionType());
+
+  QuicConfig config;
+  QuicTagVector options;
+  options.push_back(kTIME);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_EQ(kTime, QuicSentPacketManagerPeer::GetLossAlgorithm(&manager_)
+                       ->GetLossDetectionType());
+}
+
+TEST_P(QuicSentPacketManagerTest, NegotiateCongestionControlFromOptions) {
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(kRENO);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                            ->GetCongestionControlType());
+
+  options.clear();
+  options.push_back(kTBBR);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kBBR, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                      ->GetCongestionControlType());
+
+  options.clear();
+  options.push_back(kBYTE);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kCubicBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                             ->GetCongestionControlType());
+  options.clear();
+  options.push_back(kRENO);
+  options.push_back(kBYTE);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                            ->GetCongestionControlType());
+}
+
+TEST_P(QuicSentPacketManagerTest, NegotiateClientCongestionControlFromOptions) {
+  QuicConfig config;
+  QuicTagVector options;
+
+  // No change if the server receives client options.
+  const SendAlgorithmInterface* mock_sender =
+      QuicSentPacketManagerPeer::GetSendAlgorithm(manager_);
+  options.push_back(kRENO);
+  config.SetClientConnectionOptions(options);
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(mock_sender, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_));
+
+  // Change the congestion control on the client with client options.
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                            ->GetCongestionControlType());
+
+  options.clear();
+  options.push_back(kTBBR);
+  config.SetClientConnectionOptions(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kBBR, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                      ->GetCongestionControlType());
+
+  options.clear();
+  options.push_back(kBYTE);
+  config.SetClientConnectionOptions(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kCubicBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                             ->GetCongestionControlType());
+
+  options.clear();
+  options.push_back(kRENO);
+  options.push_back(kBYTE);
+  config.SetClientConnectionOptions(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+                            ->GetCongestionControlType());
+}
+
+TEST_P(QuicSentPacketManagerTest, NegotiateNumConnectionsFromOptions) {
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(k1CON);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetNumEmulatedConnections(1));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(config);
+
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  QuicConfig client_config;
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetNumEmulatedConnections(1));
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(client_config);
+}
+
+TEST_P(QuicSentPacketManagerTest, NegotiateNoMinTLPFromOptionsAtServer) {
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(kMAD2);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillOnce(Return(10 * kDefaultTCPMSS));
+  manager_.SetFromConfig(config);
+  // Set the initial RTT to 1us.
+  QuicSentPacketManagerPeer::GetRttStats(&manager_)->set_initial_rtt(
+      QuicTime::Delta::FromMicroseconds(1));
+  // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(200ms).
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
+
+  // Send two packets, and the TLP should be 2 us.
+  SendDataPacket(1);
+  SendDataPacket(2);
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
+}
+
+TEST_P(QuicSentPacketManagerTest, NegotiateNoMinTLPFromOptionsAtClient) {
+  QuicConfig client_config;
+  QuicTagVector options;
+
+  options.push_back(kMAD2);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, PacingRate(_))
+      .WillRepeatedly(Return(QuicBandwidth::Zero()));
+  EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
+      .WillOnce(Return(10 * kDefaultTCPMSS));
+  manager_.SetFromConfig(client_config);
+  // Set the initial RTT to 1us.
+  QuicSentPacketManagerPeer::GetRttStats(&manager_)->set_initial_rtt(
+      QuicTime::Delta::FromMicroseconds(1));
+  // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(200ms).
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(100002),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
+  // Send two packets, and the TLP should be 2 us.
+  SendDataPacket(1);
+  SendDataPacket(2);
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
+}
+
+TEST_P(QuicSentPacketManagerTest, NegotiateIETFTLPFromOptionsAtServer) {
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(kMAD4);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(config);
+  // Provide an RTT measurement of 100ms.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  // Expect 1.5x * SRTT + 0ms MAD
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(150),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(150),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
+  // Expect 1.5x * SRTT + 50ms MAD
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(150),
+                       QuicTime::Delta::FromMilliseconds(50), QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), rtt_stats->smoothed_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
+}
+
+TEST_P(QuicSentPacketManagerTest, NegotiateIETFTLPFromOptionsAtClient) {
+  QuicConfig client_config;
+  QuicTagVector options;
+
+  options.push_back(kMAD4);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(client_config);
+  // Provide an RTT measurement of 100ms.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(100),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  // Expect 1.5x * SRTT + 0ms MAD
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(150),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(150),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
+  // Expect 1.5x * SRTT + 50ms MAD
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMilliseconds(150),
+                       QuicTime::Delta::FromMilliseconds(50), QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(100), rtt_stats->smoothed_rtt());
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(200),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
+}
+
+TEST_P(QuicSentPacketManagerTest, NegotiateNoMinRTOFromOptionsAtServer) {
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(kMAD3);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(config);
+  // Provide one RTT measurement, because otherwise we use the default of 500ms.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMicroseconds(1),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1),
+            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1),
+            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, 0));
+  // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(0ms).
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
+}
+
+TEST_P(QuicSentPacketManagerTest, NegotiateNoMinRTOFromOptionsAtClient) {
+  QuicConfig client_config;
+  QuicTagVector options;
+
+  options.push_back(kMAD3);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(client_config);
+  // Provide one RTT measurement, because otherwise we use the default of 500ms.
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  rtt_stats->UpdateRtt(QuicTime::Delta::FromMicroseconds(1),
+                       QuicTime::Delta::Zero(), QuicTime::Zero());
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1),
+            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_));
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(1),
+            QuicSentPacketManagerPeer::GetRetransmissionDelay(&manager_, 0));
+  // The TLP with fewer than 2 packets outstanding includes 1/2 min RTO(0ms).
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_));
+  EXPECT_EQ(QuicTime::Delta::FromMicroseconds(2),
+            QuicSentPacketManagerPeer::GetTailLossProbeDelay(&manager_, 0));
+}
+
+TEST_P(QuicSentPacketManagerTest, NegotiateNoTLPFromOptionsAtServer) {
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(kNTLP);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
+}
+
+TEST_P(QuicSentPacketManagerTest, NegotiateNoTLPFromOptionsAtClient) {
+  QuicConfig client_config;
+  QuicTagVector options;
+
+  options.push_back(kNTLP);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(client_config);
+  EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
+}
+
+TEST_P(QuicSentPacketManagerTest, Negotiate1TLPFromOptionsAtServer) {
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(k1TLP);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(config);
+  EXPECT_EQ(1u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
+}
+
+TEST_P(QuicSentPacketManagerTest, Negotiate1TLPFromOptionsAtClient) {
+  QuicConfig client_config;
+  QuicTagVector options;
+
+  options.push_back(k1TLP);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(client_config);
+  EXPECT_EQ(1u, QuicSentPacketManagerPeer::GetMaxTailLossProbes(&manager_));
+}
+
+TEST_P(QuicSentPacketManagerTest, NegotiateTLPRttFromOptionsAtServer) {
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(kTLPR);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(config);
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::GetEnableHalfRttTailLossProbe(&manager_));
+}
+
+TEST_P(QuicSentPacketManagerTest, NegotiateTLPRttFromOptionsAtClient) {
+  QuicConfig client_config;
+  QuicTagVector options;
+
+  options.push_back(kTLPR);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(client_config);
+  EXPECT_TRUE(
+      QuicSentPacketManagerPeer::GetEnableHalfRttTailLossProbe(&manager_));
+}
+
+TEST_P(QuicSentPacketManagerTest, NegotiateNewRTOFromOptionsAtServer) {
+  EXPECT_FALSE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
+  QuicConfig config;
+  QuicTagVector options;
+
+  options.push_back(kNRTO);
+  QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(config);
+  EXPECT_TRUE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
+}
+
+TEST_P(QuicSentPacketManagerTest, NegotiateNewRTOFromOptionsAtClient) {
+  EXPECT_FALSE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
+  QuicConfig client_config;
+  QuicTagVector options;
+
+  options.push_back(kNRTO);
+  QuicSentPacketManagerPeer::SetPerspective(&manager_, Perspective::IS_CLIENT);
+  client_config.SetConnectionOptionsToSend(options);
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  manager_.SetFromConfig(client_config);
+  EXPECT_TRUE(QuicSentPacketManagerPeer::GetUseNewRto(&manager_));
+}
+
+TEST_P(QuicSentPacketManagerTest, UseInitialRoundTripTimeToSend) {
+  QuicTime::Delta initial_rtt = QuicTime::Delta::FromMilliseconds(325);
+  EXPECT_NE(initial_rtt, manager_.GetRttStats()->smoothed_rtt());
+
+  QuicConfig config;
+  config.SetInitialRoundTripTimeUsToSend(initial_rtt.ToMicroseconds());
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+  manager_.SetFromConfig(config);
+
+  EXPECT_EQ(QuicTime::Delta::Zero(), manager_.GetRttStats()->smoothed_rtt());
+  EXPECT_EQ(initial_rtt, manager_.GetRttStats()->initial_rtt());
+}
+
+TEST_P(QuicSentPacketManagerTest, ResumeConnectionState) {
+  // The sent packet manager should use the RTT from CachedNetworkParameters if
+  // it is provided.
+  const QuicTime::Delta kRtt = QuicTime::Delta::FromMilliseconds(1234);
+  CachedNetworkParameters cached_network_params;
+  cached_network_params.set_min_rtt_ms(kRtt.ToMilliseconds());
+
+  EXPECT_CALL(*send_algorithm_,
+              AdjustNetworkParameters(QuicBandwidth::Zero(), kRtt));
+  manager_.ResumeConnectionState(cached_network_params, false);
+  EXPECT_EQ(kRtt, manager_.GetRttStats()->initial_rtt());
+}
+
+TEST_P(QuicSentPacketManagerTest, ConnectionMigrationUnspecifiedChange) {
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
+  rtt_stats->set_initial_rtt(default_init_rtt * 2);
+  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
+
+  QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 1);
+  EXPECT_EQ(1u, manager_.GetConsecutiveRtoCount());
+  QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, 2);
+  EXPECT_EQ(2u, manager_.GetConsecutiveTlpCount());
+
+  EXPECT_CALL(*send_algorithm_, OnConnectionMigration());
+  manager_.OnConnectionMigration(IPV4_TO_IPV4_CHANGE);
+
+  EXPECT_EQ(default_init_rtt, rtt_stats->initial_rtt());
+  EXPECT_EQ(0u, manager_.GetConsecutiveRtoCount());
+  EXPECT_EQ(0u, manager_.GetConsecutiveTlpCount());
+}
+
+TEST_P(QuicSentPacketManagerTest, ConnectionMigrationIPSubnetChange) {
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
+  rtt_stats->set_initial_rtt(default_init_rtt * 2);
+  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
+
+  QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 1);
+  EXPECT_EQ(1u, manager_.GetConsecutiveRtoCount());
+  QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, 2);
+  EXPECT_EQ(2u, manager_.GetConsecutiveTlpCount());
+
+  manager_.OnConnectionMigration(IPV4_SUBNET_CHANGE);
+
+  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
+  EXPECT_EQ(1u, manager_.GetConsecutiveRtoCount());
+  EXPECT_EQ(2u, manager_.GetConsecutiveTlpCount());
+}
+
+TEST_P(QuicSentPacketManagerTest, ConnectionMigrationPortChange) {
+  RttStats* rtt_stats = const_cast<RttStats*>(manager_.GetRttStats());
+  QuicTime::Delta default_init_rtt = rtt_stats->initial_rtt();
+  rtt_stats->set_initial_rtt(default_init_rtt * 2);
+  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
+
+  QuicSentPacketManagerPeer::SetConsecutiveRtoCount(&manager_, 1);
+  EXPECT_EQ(1u, manager_.GetConsecutiveRtoCount());
+  QuicSentPacketManagerPeer::SetConsecutiveTlpCount(&manager_, 2);
+  EXPECT_EQ(2u, manager_.GetConsecutiveTlpCount());
+
+  manager_.OnConnectionMigration(PORT_CHANGE);
+
+  EXPECT_EQ(2 * default_init_rtt, rtt_stats->initial_rtt());
+  EXPECT_EQ(1u, manager_.GetConsecutiveRtoCount());
+  EXPECT_EQ(2u, manager_.GetConsecutiveTlpCount());
+}
+
+TEST_P(QuicSentPacketManagerTest, PathMtuIncreased) {
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, BytesInFlight(), QuicPacketNumber(1), _, _));
+  SerializedPacket packet(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
+                          nullptr, kDefaultLength + 100, false, false);
+  manager_.OnPacketSent(&packet, QuicPacketNumber(), clock_.Now(),
+                        NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
+
+  // Ack the large packet and expect the path MTU to increase.
+  ExpectAck(1);
+  EXPECT_CALL(*network_change_visitor_,
+              OnPathMtuIncreased(kDefaultLength + 100));
+  QuicAckFrame ack_frame = InitAckFrame(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+}
+
+TEST_P(QuicSentPacketManagerTest, OnAckRangeSlowPath) {
+  // Send packets 1 - 20.
+  for (size_t i = 1; i <= 20; ++i) {
+    SendDataPacket(i);
+  }
+  // Ack [5, 7), [10, 12), [15, 17).
+  uint64_t acked1[] = {5, 6, 10, 11, 15, 16};
+  uint64_t lost1[] = {1, 2, 3, 4, 7, 8, 9, 12, 13};
+  ExpectAcksAndLosses(true, acked1, QUIC_ARRAYSIZE(acked1), lost1,
+                      QUIC_ARRAYSIZE(lost1));
+  EXPECT_CALL(notifier_, OnFrameLost(_)).Times(AnyNumber());
+  manager_.OnAckFrameStart(QuicPacketNumber(16), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(15), QuicPacketNumber(17));
+  manager_.OnAckRange(QuicPacketNumber(10), QuicPacketNumber(12));
+  manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(7));
+  // Make sure empty range does not harm.
+  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(4));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+
+  // Ack [4, 8), [9, 13), [14, 21).
+  uint64_t acked2[] = {4, 7, 9, 12, 14, 17, 18, 19, 20};
+  ExpectAcksAndLosses(true, acked2, QUIC_ARRAYSIZE(acked2), nullptr, 0);
+  manager_.OnAckFrameStart(QuicPacketNumber(20), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(14), QuicPacketNumber(21));
+  manager_.OnAckRange(QuicPacketNumber(9), QuicPacketNumber(13));
+  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(8));
+  EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic