Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: net/quic/core/congestion_control/cubic_test.cc

Issue 2550453002: Fixed integer signing bug in cubic bytes/packet implementation (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "net/quic/core/congestion_control/cubic.h" 5 #include "net/quic/core/congestion_control/cubic.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "net/quic/core/quic_flags.h" 8 #include "net/quic/core/quic_flags.h"
9 #include "net/quic/test_tools/mock_clock.h" 9 #include "net/quic/test_tools/mock_clock.h"
10 #include "testing/gtest/include/gtest/gtest.h" 10 #include "testing/gtest/include/gtest/gtest.h"
11 11
12 namespace net { 12 namespace net {
13 namespace test { 13 namespace test {
14 14
15 const float kBeta = 0.7f; // Default Cubic backoff factor. 15 const float kBeta = 0.7f; // Default Cubic backoff factor.
16 const uint32_t kNumConnections = 2; 16 const uint32_t kNumConnections = 2;
17 const float kNConnectionBeta = (kNumConnections - 1 + kBeta) / kNumConnections; 17 const float kNConnectionBeta = (kNumConnections - 1 + kBeta) / kNumConnections;
18 const float kNConnectionAlpha = 3 * kNumConnections * kNumConnections * 18 const float kNConnectionAlpha = 3 * kNumConnections * kNumConnections *
19 (1 - kNConnectionBeta) / (1 + kNConnectionBeta); 19 (1 - kNConnectionBeta) / (1 + kNConnectionBeta);
20 20
21 class CubicTest : public ::testing::Test { 21 // TODO(jokulik): Once we've rolled out the cubic convex fix, we will
22 // no longer need a parameterized test.
23 class CubicTest : public ::testing::TestWithParam<bool> {
22 protected: 24 protected:
23 CubicTest() 25 CubicTest()
24 : one_ms_(QuicTime::Delta::FromMilliseconds(1)), 26 : one_ms_(QuicTime::Delta::FromMilliseconds(1)),
25 hundred_ms_(QuicTime::Delta::FromMilliseconds(100)), 27 hundred_ms_(QuicTime::Delta::FromMilliseconds(100)),
26 cubic_(&clock_) {} 28 cubic_(&clock_) {
29 fix_convex_mode_ = GetParam();
30 cubic_.SetFixConvexMode(fix_convex_mode_);
31 }
27 const QuicTime::Delta one_ms_; 32 const QuicTime::Delta one_ms_;
28 const QuicTime::Delta hundred_ms_; 33 const QuicTime::Delta hundred_ms_;
29 MockClock clock_; 34 MockClock clock_;
30 Cubic cubic_; 35 Cubic cubic_;
36 bool fix_convex_mode_;
31 }; 37 };
32 38
33 TEST_F(CubicTest, AboveOrigin) { 39 INSTANTIATE_TEST_CASE_P(CubicTests, CubicTest, testing::Bool());
40
41 TEST_P(CubicTest, AboveOrigin) {
34 // Convex growth. 42 // Convex growth.
35 const QuicTime::Delta rtt_min = hundred_ms_; 43 const QuicTime::Delta rtt_min = hundred_ms_;
44 const float rtt_min_s = rtt_min.ToMilliseconds() / 1000.0;
36 QuicPacketCount current_cwnd = 10; 45 QuicPacketCount current_cwnd = 10;
37 QuicPacketCount expected_cwnd = current_cwnd + 1; 46 // Without the signed-integer, cubic-convex fix, we mistakenly
47 // increment cwnd after only one_ms_ and a single ack.
48 QuicPacketCount expected_cwnd =
49 fix_convex_mode_ ? current_cwnd : current_cwnd + 1;
38 // Initialize the state. 50 // Initialize the state.
39 clock_.AdvanceTime(one_ms_); 51 clock_.AdvanceTime(one_ms_);
40 EXPECT_EQ(expected_cwnd, 52 const QuicTime initial_time = clock_.ApproximateNow();
41 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min)); 53 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
42 current_cwnd = expected_cwnd; 54 ASSERT_EQ(expected_cwnd, current_cwnd);
55 const QuicPacketCount initial_cwnd = current_cwnd;
43 // Normal TCP phase. 56 // Normal TCP phase.
44 for (int i = 0; i < 48; ++i) { 57 // The maximum number of expected reno RTTs can be calculated by
45 for (QuicPacketCount n = 1; n < current_cwnd / kNConnectionAlpha; ++n) { 58 // finding the point where the cubic curve and the reno curve meet.
59 const int max_reno_rtts =
60 std::sqrt(kNConnectionAlpha / (.4 * rtt_min_s * rtt_min_s * rtt_min_s)) -
61 1;
62 for (int i = 0; i < max_reno_rtts; ++i) {
63 const QuicByteCount max_per_ack_cwnd = current_cwnd;
64 for (QuicPacketCount n = 1; n < max_per_ack_cwnd / kNConnectionAlpha; ++n) {
46 // Call once per ACK. 65 // Call once per ACK.
47 EXPECT_NEAR(current_cwnd, 66 const QuicByteCount next_cwnd =
48 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min), 1); 67 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
68 ASSERT_EQ(current_cwnd, next_cwnd);
49 } 69 }
50 clock_.AdvanceTime(hundred_ms_); 70 clock_.AdvanceTime(hundred_ms_);
51 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min); 71 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
52 EXPECT_NEAR(expected_cwnd, current_cwnd, 1); 72 if (fix_convex_mode_) {
53 expected_cwnd++; 73 // When we fix convex mode and the uint64 arithmetic, we
74 // increase the expected_cwnd only after after the first 100ms,
75 // rather than after the initial 1ms.
76 expected_cwnd++;
77 ASSERT_EQ(expected_cwnd, current_cwnd);
78 } else {
79 ASSERT_EQ(expected_cwnd, current_cwnd);
80 expected_cwnd++;
81 }
54 } 82 }
55 // Cubic phase. 83 // Cubic phase.
56 for (int i = 0; i < 52; ++i) { 84 for (int i = 0; i < 52; ++i) {
57 for (QuicPacketCount n = 1; n < current_cwnd; ++n) { 85 for (QuicPacketCount n = 1; n < current_cwnd; ++n) {
58 // Call once per ACK. 86 // Call once per ACK.
59 EXPECT_EQ(current_cwnd, 87 ASSERT_EQ(current_cwnd,
60 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min)); 88 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min));
61 } 89 }
62 clock_.AdvanceTime(hundred_ms_); 90 clock_.AdvanceTime(hundred_ms_);
63 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min); 91 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
64 } 92 }
65 // Total time elapsed so far; add min_rtt (0.1s) here as well. 93 // Total time elapsed so far; add min_rtt (0.1s) here as well.
66 float elapsed_time_s = 10.0f + 0.1f; 94 const float elapsed_time_ms =
95 (clock_.ApproximateNow() - initial_time).ToMilliseconds() +
96 rtt_min.ToMilliseconds();
97 const float elapsed_time_s = elapsed_time_ms / 1000.0;
67 // |expected_cwnd| is initial value of cwnd + K * t^3, where K = 0.4. 98 // |expected_cwnd| is initial value of cwnd + K * t^3, where K = 0.4.
68 expected_cwnd = 99 expected_cwnd =
69 11 + (elapsed_time_s * elapsed_time_s * elapsed_time_s * 410) / 1024; 100 initial_cwnd +
101 (elapsed_time_s * elapsed_time_s * elapsed_time_s * 410) / 1024;
70 EXPECT_EQ(expected_cwnd, current_cwnd); 102 EXPECT_EQ(expected_cwnd, current_cwnd);
71 } 103 }
72 104
73 TEST_F(CubicTest, LossEvents) { 105 TEST_P(CubicTest, LossEvents) {
74 const QuicTime::Delta rtt_min = hundred_ms_; 106 const QuicTime::Delta rtt_min = hundred_ms_;
75 QuicPacketCount current_cwnd = 422; 107 QuicPacketCount current_cwnd = 422;
76 QuicPacketCount expected_cwnd = current_cwnd + 1; 108 // Without the signed-integer, cubic-convex fix, we mistakenly
109 // increment cwnd after only one_ms_ and a single ack.
110 QuicPacketCount expected_cwnd =
111 fix_convex_mode_ ? current_cwnd : current_cwnd + 1;
77 // Initialize the state. 112 // Initialize the state.
78 clock_.AdvanceTime(one_ms_); 113 clock_.AdvanceTime(one_ms_);
79 EXPECT_EQ(expected_cwnd, 114 EXPECT_EQ(expected_cwnd,
80 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min)); 115 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min));
81 expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta); 116 expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
82 EXPECT_EQ(expected_cwnd, 117 EXPECT_EQ(expected_cwnd,
83 cubic_.CongestionWindowAfterPacketLoss(current_cwnd)); 118 cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
84 expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta); 119 expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
85 EXPECT_EQ(expected_cwnd, 120 EXPECT_EQ(expected_cwnd,
86 cubic_.CongestionWindowAfterPacketLoss(current_cwnd)); 121 cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
87 } 122 }
88 123
89 TEST_F(CubicTest, BelowOrigin) { 124 TEST_P(CubicTest, BelowOrigin) {
90 // Concave growth. 125 // Concave growth.
91 const QuicTime::Delta rtt_min = hundred_ms_; 126 const QuicTime::Delta rtt_min = hundred_ms_;
92 QuicPacketCount current_cwnd = 422; 127 QuicPacketCount current_cwnd = 422;
93 QuicPacketCount expected_cwnd = current_cwnd + 1; 128 // Without the signed-integer, cubic-convex fix, we mistakenly
129 // increment cwnd after only one_ms_ and a single ack.
130 QuicPacketCount expected_cwnd =
131 fix_convex_mode_ ? current_cwnd : current_cwnd + 1;
94 // Initialize the state. 132 // Initialize the state.
95 clock_.AdvanceTime(one_ms_); 133 clock_.AdvanceTime(one_ms_);
96 EXPECT_EQ(expected_cwnd, 134 EXPECT_EQ(expected_cwnd,
97 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min)); 135 cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min));
98 expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta); 136 expected_cwnd = static_cast<QuicPacketCount>(current_cwnd * kNConnectionBeta);
99 EXPECT_EQ(expected_cwnd, 137 EXPECT_EQ(expected_cwnd,
100 cubic_.CongestionWindowAfterPacketLoss(current_cwnd)); 138 cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
101 current_cwnd = expected_cwnd; 139 current_cwnd = expected_cwnd;
102 // First update after loss to initialize the epoch. 140 // First update after loss to initialize the epoch.
103 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min); 141 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
104 // Cubic phase. 142 // Cubic phase.
105 for (int i = 0; i < 40; ++i) { 143 for (int i = 0; i < 40; ++i) {
106 clock_.AdvanceTime(hundred_ms_); 144 clock_.AdvanceTime(hundred_ms_);
107 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min); 145 current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
108 } 146 }
109 expected_cwnd = 399; 147 expected_cwnd = 399;
110 EXPECT_EQ(expected_cwnd, current_cwnd); 148 EXPECT_EQ(expected_cwnd, current_cwnd);
111 } 149 }
112 150
113 } // namespace test 151 } // namespace test
114 } // namespace net 152 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698