Roll src/third_party/WebKit eac3800:0237a66 (svn 202606:202607)
[chromium-blink-merge.git] / net / quic / congestion_control / cubic_test.cc
blob9be0d7907f3396526bfa60a59d561b54433654fc
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 "net/quic/congestion_control/cubic.h"
7 #include "base/basictypes.h"
8 #include "base/logging.h"
9 #include "net/quic/quic_connection_stats.h"
10 #include "net/quic/test_tools/mock_clock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 namespace net {
14 namespace test {
16 const float kBeta = 0.7f; // Default Cubic backoff factor.
17 const uint32 kNumConnections = 2;
18 const float kNConnectionBeta = (kNumConnections - 1 + kBeta) / kNumConnections;
19 const float kNConnectionAlpha = 3 * kNumConnections * kNumConnections *
20 (1 - kNConnectionBeta) / (1 + kNConnectionBeta);
22 class CubicTest : public ::testing::Test {
23 protected:
24 CubicTest()
25 : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
26 hundred_ms_(QuicTime::Delta::FromMilliseconds(100)),
27 cubic_(&clock_) {}
28 const QuicTime::Delta one_ms_;
29 const QuicTime::Delta hundred_ms_;
30 MockClock clock_;
31 Cubic cubic_;
34 TEST_F(CubicTest, AboveOrigin) {
35 // Convex growth.
36 const QuicTime::Delta rtt_min = hundred_ms_;
37 QuicPacketCount current_cwnd = 10;
38 QuicPacketCount expected_cwnd = current_cwnd + 1;
39 // Initialize the state.
40 clock_.AdvanceTime(one_ms_);
41 EXPECT_EQ(expected_cwnd,
42 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min));
43 current_cwnd = expected_cwnd;
44 // Normal TCP phase.
45 for (int i = 0; i < 48; ++i) {
46 for (QuicPacketCount n = 1; n < current_cwnd / kNConnectionAlpha; ++n) {
47 // Call once per ACK.
48 EXPECT_NEAR(current_cwnd,
49 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min), 1);
51 clock_.AdvanceTime(hundred_ms_);
52 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
53 EXPECT_NEAR(expected_cwnd, current_cwnd, 1);
54 expected_cwnd++;
56 // Cubic phase.
57 for (int i = 0; i < 52; ++i) {
58 for (QuicPacketCount n = 1; n < current_cwnd; ++n) {
59 // Call once per ACK.
60 EXPECT_EQ(current_cwnd,
61 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min));
63 clock_.AdvanceTime(hundred_ms_);
64 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
66 // Total time elapsed so far; add min_rtt (0.1s) here as well.
67 float elapsed_time_s = 10.0f + 0.1f;
68 // |expected_cwnd| is initial value of cwnd + K * t^3, where K = 0.4.
69 expected_cwnd = 11 + (elapsed_time_s * elapsed_time_s * elapsed_time_s * 410)
70 / 1024;
71 EXPECT_EQ(expected_cwnd, current_cwnd);
74 TEST_F(CubicTest, CwndIncreaseStatsDuringConvexRegion) {
75 const QuicTime::Delta rtt_min = hundred_ms_;
76 QuicPacketCount current_cwnd = 10;
77 QuicPacketCount expected_cwnd = current_cwnd + 1;
78 // Initialize controller state.
79 clock_.AdvanceTime(one_ms_);
80 expected_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
81 current_cwnd = expected_cwnd;
82 // Testing Reno mode increase.
83 for (int i = 0; i < 48; ++i) {
84 for (QuicPacketCount n = 1; n < current_cwnd / kNConnectionAlpha; ++n) {
85 // Call once per ACK, causing cwnd growth in Reno mode.
86 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
88 // Advance current time so that cwnd update is allowed to happen by Cubic.
89 clock_.AdvanceTime(hundred_ms_);
90 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
91 expected_cwnd++;
94 // Testing Cubic mode increase.
95 for (int i = 0; i < 52; ++i) {
96 for (QuicPacketCount n = 1; n < current_cwnd; ++n) {
97 // Call once per ACK.
98 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
100 clock_.AdvanceTime(hundred_ms_);
101 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
106 TEST_F(CubicTest, LossEvents) {
107 const QuicTime::Delta rtt_min = hundred_ms_;
108 QuicPacketCount current_cwnd = 422;
109 QuicPacketCount expected_cwnd = current_cwnd + 1;
110 // Initialize the state.
111 clock_.AdvanceTime(one_ms_);
112 EXPECT_EQ(expected_cwnd,
113 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min));
114 expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
115 EXPECT_EQ(expected_cwnd,
116 cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
117 expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
118 EXPECT_EQ(expected_cwnd,
119 cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
122 TEST_F(CubicTest, BelowOrigin) {
123 // Concave growth.
124 const QuicTime::Delta rtt_min = hundred_ms_;
125 QuicPacketCount current_cwnd = 422;
126 QuicPacketCount expected_cwnd = current_cwnd + 1;
127 // Initialize the state.
128 clock_.AdvanceTime(one_ms_);
129 EXPECT_EQ(expected_cwnd,
130 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min));
131 expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
132 EXPECT_EQ(expected_cwnd,
133 cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
134 current_cwnd = expected_cwnd;
135 // First update after loss to initialize the epoch.
136 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
137 // Cubic phase.
138 for (int i = 0; i < 40 ; ++i) {
139 clock_.AdvanceTime(hundred_ms_);
140 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
142 expected_cwnd = 422;
143 EXPECT_EQ(expected_cwnd, current_cwnd);
146 } // namespace test
147 } // namespace net