1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Test of the full congestion control chain.
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h"
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/congestion_control/quic_congestion_manager.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/quic_protocol.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/test_tools/mock_clock.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using std::max;
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace net {
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace test {
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicCongestionManagerPeer : public QuicCongestionManager {
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit QuicCongestionManagerPeer(const QuicClock* clock,
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     CongestionFeedbackType congestion_type)
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : QuicCongestionManager(clock, congestion_type) {
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  using QuicCongestionManager::BandwidthEstimate;
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicCongestionControlTest : public ::testing::Test {
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  QuicCongestionControlTest()
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : start_(clock_.ApproximateNow()) {
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void SetUpCongestionType(CongestionFeedbackType congestion_type) {
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    manager_.reset(new QuicCongestionManagerPeer(&clock_, congestion_type));
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockClock clock_;
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  QuicTime start_;
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<QuicCongestionManagerPeer> manager_;
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(QuicCongestionControlTest, FixedRateSenderAPI) {
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetUpCongestionType(kFixRate);
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  QuicCongestionFeedbackFrame congestion_feedback;
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  congestion_feedback.type = kFixRate;
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  congestion_feedback.fix_rate.bitrate = QuicBandwidth::FromKBytesPerSecond(30);
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  manager_->OnIncomingQuicCongestionFeedbackFrame(congestion_feedback,
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                  clock_.Now());
50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  EXPECT_TRUE(manager_->TimeUntilSend(clock_.Now(),
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  manager_->SentPacket(1, clock_.Now(), kMaxPacketSize, NOT_RETRANSMISSION);
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(40),
54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            manager_->TimeUntilSend(clock_.Now(),
55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE));
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(35));
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(QuicTime::Delta::Infinite(),
58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            manager_->TimeUntilSend(clock_.Now(),
59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE));
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(QuicTime::Delta::Infinite(),
62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            manager_->TimeUntilSend(clock_.Now(),
63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE));
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(QuicCongestionControlTest, FixedRatePacing) {
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetUpCongestionType(kFixRate);
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  QuicAckFrame ack;
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ack.received_info.largest_observed = 0;
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  manager_->OnIncomingAckFrame(ack, clock_.Now());
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  QuicCongestionFeedbackFrame feedback;
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  feedback.type = kFixRate;
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  feedback.fix_rate.bitrate = QuicBandwidth::FromKBytesPerSecond(100);
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  manager_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now());
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  QuicTime acc_advance_time(QuicTime::Zero());
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (QuicPacketSequenceNumber i = 1; i <= 100; ++i) {
79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    EXPECT_TRUE(manager_->TimeUntilSend(clock_.Now(),
80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    manager_->SentPacket(i, clock_.Now(), kMaxPacketSize, NOT_RETRANSMISSION);
82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    QuicTime::Delta advance_time = manager_->TimeUntilSend(clock_.Now(),
83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE);
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    clock_.AdvanceTime(advance_time);
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    acc_advance_time = acc_advance_time.Add(advance_time);
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Ack the packet we sent.
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ack.received_info.largest_observed = max(
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        i, ack.received_info.largest_observed);
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    manager_->OnIncomingAckFrame(ack, clock_.Now());
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(1200),
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            acc_advance_time.Subtract(start_));
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(QuicCongestionControlTest, Pacing) {
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetUpCongestionType(kFixRate);
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  QuicAckFrame ack;
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ack.received_info.largest_observed = 0;
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  manager_->OnIncomingAckFrame(ack, clock_.Now());
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  QuicCongestionFeedbackFrame feedback;
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  feedback.type = kFixRate;
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Test a high bitrate (8Mbit/s) to trigger pacing.
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  feedback.fix_rate.bitrate = QuicBandwidth::FromKBytesPerSecond(1000);
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  manager_->OnIncomingQuicCongestionFeedbackFrame(feedback, clock_.Now());
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  QuicTime acc_advance_time(QuicTime::Zero());
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (QuicPacketSequenceNumber i = 1; i <= 100;) {
109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    EXPECT_TRUE(manager_->TimeUntilSend(clock_.Now(),
110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    manager_->SentPacket(i++, clock_.Now(), kMaxPacketSize, NOT_RETRANSMISSION);
112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    EXPECT_TRUE(manager_->TimeUntilSend(clock_.Now(),
113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE).IsZero());
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    manager_->SentPacket(i++, clock_.Now(), kMaxPacketSize, NOT_RETRANSMISSION);
115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    QuicTime::Delta advance_time = manager_->TimeUntilSend(clock_.Now(),
116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA, NOT_HANDSHAKE);
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    clock_.AdvanceTime(advance_time);
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    acc_advance_time = acc_advance_time.Add(advance_time);
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Ack the packets we sent.
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ack.received_info.largest_observed = max(
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        i - 2, ack.received_info.largest_observed);
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    manager_->OnIncomingAckFrame(ack, clock_.Now());
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ack.received_info.largest_observed = max(
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        i - 1, ack.received_info.largest_observed);
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    manager_->OnIncomingAckFrame(ack, clock_.Now());
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(120),
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            acc_advance_time.Subtract(start_));
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TODO(pwestin): add TCP tests.
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TODO(pwestin): add InterArrival tests.
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace test
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace net
137