OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/basictypes.h" | 5 #include "base/basictypes.h" |
6 #include "base/logging.h" | 6 #include "base/logging.h" |
7 #include "base/memory/scoped_ptr.h" | |
8 #include "net/quic/congestion_control/cubic.h" | 7 #include "net/quic/congestion_control/cubic.h" |
9 #include "net/quic/test_tools/mock_clock.h" | 8 #include "net/quic/test_tools/mock_clock.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
11 | 10 |
12 namespace net { | 11 namespace net { |
13 namespace test { | 12 namespace test { |
14 | 13 |
15 class CubicPeer : public Cubic { | |
16 public: | |
17 explicit CubicPeer(QuicClock* clock) | |
18 : Cubic(clock) { | |
19 } | |
20 using Cubic::CubeRoot; | |
21 }; | |
22 | |
23 class CubicTest : public ::testing::Test { | 14 class CubicTest : public ::testing::Test { |
24 protected: | 15 protected: |
25 CubicTest() | 16 CubicTest() |
26 : one_ms_(QuicTime::Delta::FromMilliseconds(1)), | 17 : one_ms_(QuicTime::Delta::FromMilliseconds(1)), |
27 hundred_ms_(QuicTime::Delta::FromMilliseconds(100)) { | 18 hundred_ms_(QuicTime::Delta::FromMilliseconds(100)), |
28 } | 19 cubic_(&clock_) { |
29 virtual void SetUp() { | |
30 cubic_.reset(new CubicPeer(&clock_)); | |
31 } | 20 } |
32 const QuicTime::Delta one_ms_; | 21 const QuicTime::Delta one_ms_; |
33 const QuicTime::Delta hundred_ms_; | 22 const QuicTime::Delta hundred_ms_; |
34 MockClock clock_; | 23 MockClock clock_; |
35 scoped_ptr<CubicPeer> cubic_; | 24 Cubic cubic_; |
36 }; | 25 }; |
37 | 26 |
38 TEST_F(CubicTest, CubeRootLow) { | |
39 for (uint32 i = 1; i < 256; ++i) { | |
40 uint64 cube = i * i * i; | |
41 uint8 cube_root = cubic_->CubeRoot(cube); | |
42 EXPECT_EQ(i, cube_root); | |
43 } | |
44 } | |
45 | |
46 TEST_F(CubicTest, CubeRootHigh) { | |
47 // Test the range we will opperate in, 1300 to 130 000. | |
48 // We expect some loss in accuracy, accepting +-0.2%. | |
49 for (uint64 i = 1300; i < 20000; i += 100) { | |
50 uint64 cube = i * i * i; | |
51 uint32 cube_root = cubic_->CubeRoot(cube); | |
52 uint32 margin = cube_root >> 9; // Calculate 0.2% roughly by | |
53 // dividing by 512. | |
54 EXPECT_LE(i - margin, cube_root); | |
55 EXPECT_GE(i + margin, cube_root); | |
56 } | |
57 for (uint64 i = 20000; i < 130000; i *= 2) { | |
58 uint64 cube = i * i * i; | |
59 uint32 cube_root = cubic_->CubeRoot(cube); | |
60 uint32 margin = cube_root >> 9; | |
61 EXPECT_LE(i - margin, cube_root); | |
62 EXPECT_GE(i + margin, cube_root); | |
63 } | |
64 } | |
65 | |
66 TEST_F(CubicTest, AboveOrgin) { | 27 TEST_F(CubicTest, AboveOrgin) { |
67 // Convex growth. | 28 // Convex growth. |
68 const QuicTime::Delta rtt_min = hundred_ms_; | 29 const QuicTime::Delta rtt_min = hundred_ms_; |
69 uint32 current_cwnd = 10; | 30 uint32 current_cwnd = 10; |
70 uint32 expected_cwnd = current_cwnd + 1; | 31 uint32 expected_cwnd = current_cwnd + 1; |
71 // Initialize the state. | 32 // Initialize the state. |
72 clock_.AdvanceTime(one_ms_); | 33 clock_.AdvanceTime(one_ms_); |
73 EXPECT_EQ(expected_cwnd, | 34 EXPECT_EQ(expected_cwnd, |
74 cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min)); | 35 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min)); |
75 current_cwnd = expected_cwnd; | 36 current_cwnd = expected_cwnd; |
76 // Normal TCP phase. | 37 // Normal TCP phase. |
77 for (int i = 0; i < 48; ++i) { | 38 for (int i = 0; i < 48; ++i) { |
78 for (uint32 n = 1; n < current_cwnd; ++n) { | 39 for (uint32 n = 1; n < current_cwnd; ++n) { |
79 // Call once per ACK. | 40 // Call once per ACK. |
80 EXPECT_EQ(current_cwnd, | 41 EXPECT_EQ(current_cwnd, |
81 cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min)); | 42 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min)); |
82 } | 43 } |
83 clock_.AdvanceTime(hundred_ms_); | 44 clock_.AdvanceTime(hundred_ms_); |
84 current_cwnd = cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min); | 45 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min); |
85 EXPECT_EQ(expected_cwnd, current_cwnd); | 46 EXPECT_EQ(expected_cwnd, current_cwnd); |
86 expected_cwnd++; | 47 expected_cwnd++; |
87 } | 48 } |
88 // Cubic phase. | 49 // Cubic phase. |
89 for (int j = 48; j < 100; ++j) { | 50 for (int j = 48; j < 100; ++j) { |
90 for (uint32 n = 1; n < current_cwnd; ++n) { | 51 for (uint32 n = 1; n < current_cwnd; ++n) { |
91 // Call once per ACK. | 52 // Call once per ACK. |
92 EXPECT_EQ(current_cwnd, | 53 EXPECT_EQ(current_cwnd, |
93 cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min)); | 54 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min)); |
94 } | 55 } |
95 clock_.AdvanceTime(hundred_ms_); | 56 clock_.AdvanceTime(hundred_ms_); |
96 current_cwnd = cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min); | 57 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min); |
97 } | 58 } |
98 float elapsed_time_s = 10.0f + 0.1f; // We need to add the RTT here. | 59 float elapsed_time_s = 10.0f + 0.1f; // We need to add the RTT here. |
99 expected_cwnd = 11 + (elapsed_time_s * elapsed_time_s * elapsed_time_s * 410) | 60 expected_cwnd = 11 + (elapsed_time_s * elapsed_time_s * elapsed_time_s * 410) |
100 / 1024; | 61 / 1024; |
101 EXPECT_EQ(expected_cwnd, current_cwnd); | 62 EXPECT_EQ(expected_cwnd, current_cwnd); |
102 } | 63 } |
103 | 64 |
104 TEST_F(CubicTest, LossEvents) { | 65 TEST_F(CubicTest, LossEvents) { |
105 const QuicTime::Delta rtt_min = hundred_ms_; | 66 const QuicTime::Delta rtt_min = hundred_ms_; |
106 uint32 current_cwnd = 422; | 67 uint32 current_cwnd = 422; |
107 uint32 expected_cwnd = current_cwnd + 1; | 68 uint32 expected_cwnd = current_cwnd + 1; |
108 // Initialize the state. | 69 // Initialize the state. |
109 clock_.AdvanceTime(one_ms_); | 70 clock_.AdvanceTime(one_ms_); |
110 EXPECT_EQ(expected_cwnd, | 71 EXPECT_EQ(expected_cwnd, |
111 cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min)); | 72 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min)); |
112 expected_cwnd = current_cwnd * 939 / 1024; | 73 expected_cwnd = current_cwnd * 939 / 1024; |
113 EXPECT_EQ(expected_cwnd, | 74 EXPECT_EQ(expected_cwnd, |
114 cubic_->CongestionWindowAfterPacketLoss(current_cwnd)); | 75 cubic_.CongestionWindowAfterPacketLoss(current_cwnd)); |
115 expected_cwnd = current_cwnd * 939 / 1024; | 76 expected_cwnd = current_cwnd * 939 / 1024; |
116 EXPECT_EQ(expected_cwnd, | 77 EXPECT_EQ(expected_cwnd, |
117 cubic_->CongestionWindowAfterPacketLoss(current_cwnd)); | 78 cubic_.CongestionWindowAfterPacketLoss(current_cwnd)); |
118 } | 79 } |
119 | 80 |
120 TEST_F(CubicTest, BelowOrgin) { | 81 TEST_F(CubicTest, BelowOrgin) { |
121 // Concave growth. | 82 // Concave growth. |
122 const QuicTime::Delta rtt_min = hundred_ms_; | 83 const QuicTime::Delta rtt_min = hundred_ms_; |
123 uint32 current_cwnd = 422; | 84 uint32 current_cwnd = 422; |
124 uint32 expected_cwnd = current_cwnd + 1; | 85 uint32 expected_cwnd = current_cwnd + 1; |
125 // Initialize the state. | 86 // Initialize the state. |
126 clock_.AdvanceTime(one_ms_); | 87 clock_.AdvanceTime(one_ms_); |
127 EXPECT_EQ(expected_cwnd, | 88 EXPECT_EQ(expected_cwnd, |
128 cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min)); | 89 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min)); |
129 expected_cwnd = current_cwnd * 939 / 1024; | 90 expected_cwnd = current_cwnd * 939 / 1024; |
130 EXPECT_EQ(expected_cwnd, | 91 EXPECT_EQ(expected_cwnd, |
131 cubic_->CongestionWindowAfterPacketLoss(current_cwnd)); | 92 cubic_.CongestionWindowAfterPacketLoss(current_cwnd)); |
132 current_cwnd = expected_cwnd; | 93 current_cwnd = expected_cwnd; |
133 // First update after epoch. | 94 // First update after epoch. |
134 current_cwnd = cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min); | 95 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min); |
135 // Cubic phase. | 96 // Cubic phase. |
136 for (int i = 0; i < 54; ++i) { | 97 for (int i = 0; i < 54; ++i) { |
137 for (uint32 n = 1; n < current_cwnd; ++n) { | 98 for (uint32 n = 1; n < current_cwnd; ++n) { |
138 // Call once per ACK. | 99 // Call once per ACK. |
139 EXPECT_EQ(current_cwnd, | 100 EXPECT_EQ(current_cwnd, |
140 cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min)); | 101 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min)); |
141 } | 102 } |
142 clock_.AdvanceTime(hundred_ms_); | 103 clock_.AdvanceTime(hundred_ms_); |
143 current_cwnd = cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min); | 104 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min); |
144 } | 105 } |
145 expected_cwnd = 440; | 106 expected_cwnd = 440; |
146 EXPECT_EQ(expected_cwnd, current_cwnd); | 107 EXPECT_EQ(expected_cwnd, current_cwnd); |
147 } | 108 } |
148 | 109 |
149 } // namespace testing | 110 } // namespace test |
150 } // namespace net | 111 } // namespace net |
OLD | NEW |