Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / net / quic / congestion_control / cubic_bytes_test.cc
blob3de1651076cf4f5e26dc1e74b7f18078b5ecc6da
1 // Copyright (c) 2015 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_bytes.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 CubicBytesTest : public ::testing::Test {
23 protected:
24 CubicBytesTest()
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 CubicBytes cubic_;
34 TEST_F(CubicBytesTest, AboveOrigin) {
35 // Convex growth.
36 const QuicTime::Delta rtt_min = hundred_ms_;
37 QuicByteCount current_cwnd = 10 * kDefaultTCPMSS;
38 QuicByteCount expected_cwnd = current_cwnd + kDefaultTCPMSS;
39 // Initialize the state.
40 clock_.AdvanceTime(one_ms_);
41 EXPECT_EQ(expected_cwnd, cubic_.CongestionWindowAfterAck(
42 kDefaultTCPMSS, 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;
47 n < current_cwnd / kDefaultTCPMSS / kNConnectionAlpha; ++n) {
48 // Call once per ACK.
49 EXPECT_NEAR(current_cwnd, cubic_.CongestionWindowAfterAck(
50 kDefaultTCPMSS, current_cwnd, rtt_min),
51 kDefaultTCPMSS);
53 clock_.AdvanceTime(hundred_ms_);
54 current_cwnd =
55 cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd, rtt_min);
56 EXPECT_NEAR(expected_cwnd, current_cwnd, kDefaultTCPMSS);
57 expected_cwnd += kDefaultTCPMSS;
59 // Cubic phase.
60 for (int i = 0; i < 52; ++i) {
61 for (QuicPacketCount n = 1; n < current_cwnd / kDefaultTCPMSS; ++n) {
62 // Call once per ACK.
63 EXPECT_NEAR(current_cwnd, cubic_.CongestionWindowAfterAck(
64 kDefaultTCPMSS, current_cwnd, rtt_min),
65 kDefaultTCPMSS);
67 clock_.AdvanceTime(hundred_ms_);
68 current_cwnd =
69 cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd, rtt_min);
71 // Total time elapsed so far; add min_rtt (0.1s) here as well.
72 float elapsed_time_s = 10.0f + 0.1f;
73 // |expected_cwnd| is initial value of cwnd + K * t^3, where K = 0.4.
74 expected_cwnd =
75 11 + (elapsed_time_s * elapsed_time_s * elapsed_time_s * 410) / 1024;
76 EXPECT_EQ(expected_cwnd, current_cwnd / kDefaultTCPMSS);
79 TEST_F(CubicBytesTest, CwndIncreaseStatsDuringConvexRegion) {
80 const QuicTime::Delta rtt_min = hundred_ms_;
81 QuicByteCount current_cwnd = 10 * kDefaultTCPMSS;
82 QuicByteCount expected_cwnd = current_cwnd + kDefaultTCPMSS;
83 // Initialize controller state.
84 clock_.AdvanceTime(one_ms_);
85 expected_cwnd =
86 cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd, rtt_min);
87 current_cwnd = expected_cwnd;
88 // Testing Reno mode increase.
89 for (int i = 0; i < 48; ++i) {
90 for (QuicPacketCount n = 1;
91 n < current_cwnd / kDefaultTCPMSS / kNConnectionAlpha; ++n) {
92 // Call once per ACK, causing cwnd growth in Reno mode.
93 cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd, rtt_min);
95 // Advance current time so that cwnd update is allowed to happen by Cubic.
96 clock_.AdvanceTime(hundred_ms_);
97 current_cwnd =
98 cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd, rtt_min);
99 expected_cwnd += kDefaultTCPMSS;
102 // Testing Cubic mode increase.
103 for (int i = 0; i < 52; ++i) {
104 for (QuicPacketCount n = 1; n < current_cwnd / kDefaultTCPMSS; ++n) {
105 // Call once per ACK.
106 cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd, rtt_min);
108 clock_.AdvanceTime(hundred_ms_);
109 current_cwnd =
110 cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd, rtt_min);
114 TEST_F(CubicBytesTest, LossEvents) {
115 const QuicTime::Delta rtt_min = hundred_ms_;
116 QuicByteCount current_cwnd = 422 * kDefaultTCPMSS;
117 QuicPacketCount expected_cwnd = current_cwnd + kDefaultTCPMSS;
118 // Initialize the state.
119 clock_.AdvanceTime(one_ms_);
120 EXPECT_EQ(expected_cwnd, cubic_.CongestionWindowAfterAck(
121 kDefaultTCPMSS, current_cwnd, rtt_min));
122 expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
123 EXPECT_EQ(expected_cwnd,
124 cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
125 expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
126 EXPECT_EQ(expected_cwnd,
127 cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
130 TEST_F(CubicBytesTest, BelowOrigin) {
131 // Concave growth.
132 const QuicTime::Delta rtt_min = hundred_ms_;
133 QuicByteCount current_cwnd = 422 * kDefaultTCPMSS;
134 QuicPacketCount expected_cwnd = current_cwnd + kDefaultTCPMSS;
135 // Initialize the state.
136 clock_.AdvanceTime(one_ms_);
137 EXPECT_EQ(expected_cwnd, cubic_.CongestionWindowAfterAck(
138 kDefaultTCPMSS, current_cwnd, rtt_min));
139 expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
140 EXPECT_EQ(expected_cwnd,
141 cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
142 current_cwnd = expected_cwnd;
143 // First update after loss to initialize the epoch.
144 current_cwnd =
145 cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd, rtt_min);
146 // Cubic phase.
147 for (int i = 0; i < 40; ++i) {
148 clock_.AdvanceTime(hundred_ms_);
149 current_cwnd =
150 cubic_.CongestionWindowAfterAck(kDefaultTCPMSS, current_cwnd, rtt_min);
152 expected_cwnd = 422 * kDefaultTCPMSS;
153 EXPECT_EQ(expected_cwnd, current_cwnd);
156 } // namespace test
157 } // namespace net