// Copyright (c) 2014 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/quic/congestion_control/prr_sender.h"

#include <algorithm>

#include "base/logging.h"
#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/quic_bandwidth.h"
#include "net/quic/quic_protocol.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {
namespace test {

namespace {
// Constant based on TCP defaults.
const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS;
}  // namespace

class PrrSenderTest : public ::testing::Test {};

TEST_F(PrrSenderTest, SingleLossResultsInSendOnEveryOtherAck) {
  PrrSender prr;
  QuicPacketCount num_packets_in_flight = 50;
  QuicByteCount bytes_in_flight = num_packets_in_flight * kMaxSegmentSize;
  const QuicPacketCount ssthresh_after_loss = num_packets_in_flight / 2;
  const QuicByteCount congestion_window = ssthresh_after_loss * kMaxSegmentSize;

  prr.OnPacketLost(bytes_in_flight);
  // Ack a packet. PRR allows one packet to leave immediately.
  prr.OnPacketAcked(kMaxSegmentSize);
  bytes_in_flight -= kMaxSegmentSize;
  EXPECT_EQ(QuicTime::Delta::Zero(),
            prr.TimeUntilSend(congestion_window, bytes_in_flight,
                              ssthresh_after_loss));
  // Send retransmission.
  prr.OnPacketSent(kMaxSegmentSize);
  // PRR shouldn't allow sending any more packets.
  EXPECT_EQ(QuicTime::Delta::Infinite(),
            prr.TimeUntilSend(congestion_window, bytes_in_flight,
                              ssthresh_after_loss));

  // One packet is lost, and one ack was consumed above. PRR now paces
  // transmissions through the remaining 48 acks. PRR will alternatively
  // disallow and allow a packet to be sent in response to an ack.
  for (uint64 i = 0; i < ssthresh_after_loss - 1; ++i) {
    // Ack a packet. PRR shouldn't allow sending a packet in response.
    prr.OnPacketAcked(kMaxSegmentSize);
    bytes_in_flight -= kMaxSegmentSize;
    EXPECT_EQ(QuicTime::Delta::Infinite(),
              prr.TimeUntilSend(congestion_window, bytes_in_flight,
                                ssthresh_after_loss));
    // Ack another packet. PRR should now allow sending a packet in response.
    prr.OnPacketAcked(kMaxSegmentSize);
    bytes_in_flight -= kMaxSegmentSize;
    EXPECT_EQ(QuicTime::Delta::Zero(),
              prr.TimeUntilSend(congestion_window, bytes_in_flight,
                                ssthresh_after_loss));
    // Send a packet in response.
    prr.OnPacketSent(kMaxSegmentSize);
    bytes_in_flight += kMaxSegmentSize;
  }

  // Since bytes_in_flight is now equal to congestion_window, PRR now maintains
  // packet conservation, allowing one packet to be sent in response to an ack.
  EXPECT_EQ(congestion_window, bytes_in_flight);
  for (int i = 0; i < 10; ++i) {
    // Ack a packet.
    prr.OnPacketAcked(kMaxSegmentSize);
    bytes_in_flight -= kMaxSegmentSize;
    EXPECT_EQ(QuicTime::Delta::Zero(),
              prr.TimeUntilSend(congestion_window, bytes_in_flight,
                                ssthresh_after_loss));
    // Send a packet in response, since PRR allows it.
    prr.OnPacketSent(kMaxSegmentSize);
    bytes_in_flight += kMaxSegmentSize;

    // Since bytes_in_flight is equal to the congestion_window,
    // PRR disallows sending.
    EXPECT_EQ(congestion_window, bytes_in_flight);
    EXPECT_EQ(QuicTime::Delta::Infinite(),
              prr.TimeUntilSend(congestion_window, bytes_in_flight,
                                ssthresh_after_loss));
  }
}

TEST_F(PrrSenderTest, BurstLossResultsInSlowStart) {
  PrrSender prr;
  QuicByteCount bytes_in_flight = 20 * kMaxSegmentSize;
  const QuicPacketCount num_packets_lost = 13;
  const QuicPacketCount ssthresh_after_loss = 10;
  const QuicByteCount congestion_window = ssthresh_after_loss * kMaxSegmentSize;

  // Lose 13 packets.
  bytes_in_flight -= num_packets_lost * kMaxSegmentSize;
  prr.OnPacketLost(bytes_in_flight);

  // PRR-SSRB will allow the following 3 acks to send up to 2 packets.
  for (int i = 0; i < 3; ++i) {
    prr.OnPacketAcked(kMaxSegmentSize);
    bytes_in_flight -= kMaxSegmentSize;
    // PRR-SSRB should allow two packets to be sent.
    for (int j = 0; j < 2; ++j) {
      EXPECT_EQ(QuicTime::Delta::Zero(),
                prr.TimeUntilSend(congestion_window, bytes_in_flight,
                                  ssthresh_after_loss));
      // Send a packet in response.
      prr.OnPacketSent(kMaxSegmentSize);
      bytes_in_flight += kMaxSegmentSize;
    }
    // PRR should allow no more than 2 packets in response to an ack.
    EXPECT_EQ(QuicTime::Delta::Infinite(),
              prr.TimeUntilSend(congestion_window, bytes_in_flight,
                                ssthresh_after_loss));
  }

  // Out of SSRB mode, PRR allows one send in response to each ack.
  for (int i = 0; i < 10; ++i) {
    prr.OnPacketAcked(kMaxSegmentSize);
    bytes_in_flight -= kMaxSegmentSize;
    EXPECT_EQ(QuicTime::Delta::Zero(),
              prr.TimeUntilSend(congestion_window, bytes_in_flight,
                                ssthresh_after_loss));
    // Send a packet in response.
    prr.OnPacketSent(kMaxSegmentSize);
    bytes_in_flight += kMaxSegmentSize;
  }
}

}  // namespace test
}  // namespace net
