We started redesigning GpuMemoryBuffer interface to handle multiple buffers [0].
[chromium-blink-merge.git] / net / quic / congestion_control / cubic_test.cc
blob0ddbc229f64c47705ddf1661523f989cc04667f9
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/basictypes.h"
6 #include "base/logging.h"
7 #include "net/quic/congestion_control/cubic.h"
8 #include "net/quic/quic_connection_stats.h"
9 #include "net/quic/test_tools/mock_clock.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 namespace net {
13 namespace test {
15 const float kBeta = 0.7f; // Default Cubic backoff factor.
16 const uint32 kNumConnections = 2;
17 const float kNConnectionBeta = (kNumConnections - 1 + kBeta) / kNumConnections;
18 const float kNConnectionAlpha = 3 * kNumConnections * kNumConnections *
19 (1 - kNConnectionBeta) / (1 + kNConnectionBeta);
21 class CubicTest : public ::testing::Test {
22 protected:
23 CubicTest()
24 : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
25 hundred_ms_(QuicTime::Delta::FromMilliseconds(100)),
26 cubic_(&clock_) {}
27 const QuicTime::Delta one_ms_;
28 const QuicTime::Delta hundred_ms_;
29 MockClock clock_;
30 Cubic cubic_;
33 TEST_F(CubicTest, AboveOrigin) {
34 // Convex growth.
35 const QuicTime::Delta rtt_min = hundred_ms_;
36 QuicPacketCount current_cwnd = 10;
37 QuicPacketCount expected_cwnd = current_cwnd + 1;
38 // Initialize the state.
39 clock_.AdvanceTime(one_ms_);
40 EXPECT_EQ(expected_cwnd,
41 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min));
42 current_cwnd = expected_cwnd;
43 // Normal TCP phase.
44 for (int i = 0; i < 48; ++i) {
45 for (QuicPacketCount n = 1; n < current_cwnd / kNConnectionAlpha; ++n) {
46 // Call once per ACK.
47 EXPECT_NEAR(current_cwnd,
48 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min), 1);
50 clock_.AdvanceTime(hundred_ms_);
51 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
52 EXPECT_NEAR(expected_cwnd, current_cwnd, 1);
53 expected_cwnd++;
55 // Cubic phase.
56 for (int i = 0; i < 52; ++i) {
57 for (QuicPacketCount n = 1; n < current_cwnd; ++n) {
58 // Call once per ACK.
59 EXPECT_EQ(current_cwnd,
60 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min));
62 clock_.AdvanceTime(hundred_ms_);
63 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
65 // Total time elapsed so far; add min_rtt (0.1s) here as well.
66 float elapsed_time_s = 10.0f + 0.1f;
67 // |expected_cwnd| is initial value of cwnd + K * t^3, where K = 0.4.
68 expected_cwnd = 11 + (elapsed_time_s * elapsed_time_s * elapsed_time_s * 410)
69 / 1024;
70 EXPECT_EQ(expected_cwnd, current_cwnd);
73 TEST_F(CubicTest, CwndIncreaseStatsDuringConvexRegion) {
74 const QuicTime::Delta rtt_min = hundred_ms_;
75 QuicPacketCount current_cwnd = 10;
76 QuicPacketCount expected_cwnd = current_cwnd + 1;
77 // Initialize controller state.
78 clock_.AdvanceTime(one_ms_);
79 expected_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
80 current_cwnd = expected_cwnd;
81 // Testing Reno mode increase.
82 for (int i = 0; i < 48; ++i) {
83 for (QuicPacketCount n = 1; n < current_cwnd / kNConnectionAlpha; ++n) {
84 // Call once per ACK, causing cwnd growth in Reno mode.
85 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
87 // Advance current time so that cwnd update is allowed to happen by Cubic.
88 clock_.AdvanceTime(hundred_ms_);
89 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
90 expected_cwnd++;
93 // Testing Cubic mode increase.
94 for (int i = 0; i < 52; ++i) {
95 for (QuicPacketCount n = 1; n < current_cwnd; ++n) {
96 // Call once per ACK.
97 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
99 clock_.AdvanceTime(hundred_ms_);
100 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
105 TEST_F(CubicTest, LossEvents) {
106 const QuicTime::Delta rtt_min = hundred_ms_;
107 QuicPacketCount current_cwnd = 422;
108 QuicPacketCount expected_cwnd = current_cwnd + 1;
109 // Initialize the state.
110 clock_.AdvanceTime(one_ms_);
111 EXPECT_EQ(expected_cwnd,
112 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min));
113 expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
114 EXPECT_EQ(expected_cwnd,
115 cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
116 expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
117 EXPECT_EQ(expected_cwnd,
118 cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
121 TEST_F(CubicTest, BelowOrigin) {
122 // Concave growth.
123 const QuicTime::Delta rtt_min = hundred_ms_;
124 QuicPacketCount current_cwnd = 422;
125 QuicPacketCount expected_cwnd = current_cwnd + 1;
126 // Initialize the state.
127 clock_.AdvanceTime(one_ms_);
128 EXPECT_EQ(expected_cwnd,
129 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min));
130 expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
131 EXPECT_EQ(expected_cwnd,
132 cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
133 current_cwnd = expected_cwnd;
134 // First update after loss to initialize the epoch.
135 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
136 // Cubic phase.
137 for (int i = 0; i < 40 ; ++i) {
138 clock_.AdvanceTime(hundred_ms_);
139 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
141 expected_cwnd = 422;
142 EXPECT_EQ(expected_cwnd, current_cwnd);
145 } // namespace test
146 } // namespace net