summaryrefslogtreecommitdiffstats
path: root/chromium/net/quic/congestion_control/cubic_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/quic/congestion_control/cubic_test.cc')
-rw-r--r--chromium/net/quic/congestion_control/cubic_test.cc162
1 files changed, 90 insertions, 72 deletions
diff --git a/chromium/net/quic/congestion_control/cubic_test.cc b/chromium/net/quic/congestion_control/cubic_test.cc
index c01bb050643..915274a13d3 100644
--- a/chromium/net/quic/congestion_control/cubic_test.cc
+++ b/chromium/net/quic/congestion_control/cubic_test.cc
@@ -4,66 +4,35 @@
#include "base/basictypes.h"
#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
#include "net/quic/congestion_control/cubic.h"
+#include "net/quic/quic_connection_stats.h"
#include "net/quic/test_tools/mock_clock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
namespace test {
-class CubicPeer : public Cubic {
- public:
- explicit CubicPeer(QuicClock* clock)
- : Cubic(clock) {
- }
- using Cubic::CubeRoot;
-};
+const float kBeta = 0.7f; // Default Cubic backoff factor.
+const uint32 kNumConnections = 2;
+const float kNConnectionBeta = (kNumConnections - 1 + kBeta) / kNumConnections;
+const float kNConnectionAlpha = 3 * kNumConnections * kNumConnections *
+ (1 - kNConnectionBeta) / (1 + kNConnectionBeta);
class CubicTest : public ::testing::Test {
protected:
CubicTest()
: one_ms_(QuicTime::Delta::FromMilliseconds(1)),
- hundred_ms_(QuicTime::Delta::FromMilliseconds(100)) {
- }
- virtual void SetUp() {
- cubic_.reset(new CubicPeer(&clock_));
+ hundred_ms_(QuicTime::Delta::FromMilliseconds(100)),
+ cubic_(&clock_, &stats_) {
}
const QuicTime::Delta one_ms_;
const QuicTime::Delta hundred_ms_;
MockClock clock_;
- scoped_ptr<CubicPeer> cubic_;
+ QuicConnectionStats stats_;
+ Cubic cubic_;
};
-TEST_F(CubicTest, CubeRootLow) {
- for (uint32 i = 1; i < 256; ++i) {
- uint64 cube = i * i * i;
- uint8 cube_root = cubic_->CubeRoot(cube);
- EXPECT_EQ(i, cube_root);
- }
-}
-
-TEST_F(CubicTest, CubeRootHigh) {
- // Test the range we will opperate in, 1300 to 130 000.
- // We expect some loss in accuracy, accepting +-0.2%.
- for (uint64 i = 1300; i < 20000; i += 100) {
- uint64 cube = i * i * i;
- uint32 cube_root = cubic_->CubeRoot(cube);
- uint32 margin = cube_root >> 9; // Calculate 0.2% roughly by
- // dividing by 512.
- EXPECT_LE(i - margin, cube_root);
- EXPECT_GE(i + margin, cube_root);
- }
- for (uint64 i = 20000; i < 130000; i *= 2) {
- uint64 cube = i * i * i;
- uint32 cube_root = cubic_->CubeRoot(cube);
- uint32 margin = cube_root >> 9;
- EXPECT_LE(i - margin, cube_root);
- EXPECT_GE(i + margin, cube_root);
- }
-}
-
-TEST_F(CubicTest, AboveOrgin) {
+TEST_F(CubicTest, AboveOrigin) {
// Convex growth.
const QuicTime::Delta rtt_min = hundred_ms_;
uint32 current_cwnd = 10;
@@ -71,36 +40,84 @@ TEST_F(CubicTest, AboveOrgin) {
// Initialize the state.
clock_.AdvanceTime(one_ms_);
EXPECT_EQ(expected_cwnd,
- cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min));
+ cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min));
current_cwnd = expected_cwnd;
// Normal TCP phase.
for (int i = 0; i < 48; ++i) {
- for (uint32 n = 1; n < current_cwnd; ++n) {
+ for (uint32 n = 1; n < current_cwnd / kNConnectionAlpha; ++n) {
// Call once per ACK.
- EXPECT_EQ(current_cwnd,
- cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min));
+ EXPECT_NEAR(current_cwnd,
+ cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min), 1);
}
clock_.AdvanceTime(hundred_ms_);
- current_cwnd = cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min);
- EXPECT_EQ(expected_cwnd, current_cwnd);
+ current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
+ EXPECT_NEAR(expected_cwnd, current_cwnd, 1);
expected_cwnd++;
}
// Cubic phase.
- for (int j = 48; j < 100; ++j) {
+ for (int i = 0; i < 52; ++i) {
for (uint32 n = 1; n < current_cwnd; ++n) {
// Call once per ACK.
EXPECT_EQ(current_cwnd,
- cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min));
+ cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min));
}
clock_.AdvanceTime(hundred_ms_);
- current_cwnd = cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min);
+ current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
}
- float elapsed_time_s = 10.0f + 0.1f; // We need to add the RTT here.
+ // Total time elapsed so far; add min_rtt (0.1s) here as well.
+ float elapsed_time_s = 10.0f + 0.1f;
+ // |expected_cwnd| is initial value of cwnd + K * t^3, where K = 0.4.
expected_cwnd = 11 + (elapsed_time_s * elapsed_time_s * elapsed_time_s * 410)
/ 1024;
EXPECT_EQ(expected_cwnd, current_cwnd);
}
+TEST_F(CubicTest, CwndIncreaseStatsDuringConvexRegion) {
+ const QuicTime::Delta rtt_min = hundred_ms_;
+ uint32 current_cwnd = 10;
+ uint32 expected_cwnd = current_cwnd + 1;
+ // Initialize controller state.
+ clock_.AdvanceTime(one_ms_);
+ expected_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
+ current_cwnd = expected_cwnd;
+ // Testing Reno mode increase.
+ for (int i = 0; i < 48; ++i) {
+ for (uint32 n = 1; n < current_cwnd / kNConnectionAlpha; ++n) {
+ // Call once per ACK, causing cwnd growth in Reno mode.
+ cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
+ }
+ // Advance current time so that cwnd update is allowed to happen by Cubic.
+ clock_.AdvanceTime(hundred_ms_);
+ current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
+ EXPECT_NEAR(expected_cwnd - 10, stats_.cwnd_increase_congestion_avoidance,
+ 1);
+ EXPECT_NEAR(1u, stats_.cwnd_increase_cubic_mode, 1);
+ expected_cwnd++;
+ }
+ uint32 old_cwnd = current_cwnd;
+ stats_.cwnd_increase_cubic_mode = 0;
+ stats_.cwnd_increase_congestion_avoidance = 0;
+
+ // Testing Cubic mode increase.
+ for (int i = 0; i < 52; ++i) {
+ for (uint32 n = 1; n < current_cwnd; ++n) {
+ // Call once per ACK.
+ cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
+ }
+ clock_.AdvanceTime(hundred_ms_);
+ current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
+ }
+ // Total time elapsed so far; add min_rtt (0.1s) here as well.
+ float elapsed_time_s = 10.0f + 0.1f;
+ // |expected_cwnd| is initial value of cwnd + K * t^3, where K = 0.4.
+ expected_cwnd = 11 + (elapsed_time_s * elapsed_time_s * elapsed_time_s * 410)
+ / 1024;
+ EXPECT_EQ(expected_cwnd - old_cwnd, stats_.cwnd_increase_cubic_mode);
+ EXPECT_EQ(expected_cwnd - old_cwnd,
+ stats_.cwnd_increase_congestion_avoidance);
+}
+
+
TEST_F(CubicTest, LossEvents) {
const QuicTime::Delta rtt_min = hundred_ms_;
uint32 current_cwnd = 422;
@@ -108,16 +125,16 @@ TEST_F(CubicTest, LossEvents) {
// Initialize the state.
clock_.AdvanceTime(one_ms_);
EXPECT_EQ(expected_cwnd,
- cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min));
- expected_cwnd = current_cwnd * 939 / 1024;
+ cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min));
+ expected_cwnd = static_cast<int>(current_cwnd * kNConnectionBeta);
EXPECT_EQ(expected_cwnd,
- cubic_->CongestionWindowAfterPacketLoss(current_cwnd));
- expected_cwnd = current_cwnd * 939 / 1024;
+ cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
+ expected_cwnd = static_cast<int>(current_cwnd * kNConnectionBeta);
EXPECT_EQ(expected_cwnd,
- cubic_->CongestionWindowAfterPacketLoss(current_cwnd));
+ cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
}
-TEST_F(CubicTest, BelowOrgin) {
+TEST_F(CubicTest, BelowOrigin) {
// Concave growth.
const QuicTime::Delta rtt_min = hundred_ms_;
uint32 current_cwnd = 422;
@@ -125,26 +142,27 @@ TEST_F(CubicTest, BelowOrgin) {
// Initialize the state.
clock_.AdvanceTime(one_ms_);
EXPECT_EQ(expected_cwnd,
- cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min));
- expected_cwnd = current_cwnd * 939 / 1024;
+ cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min));
+ expected_cwnd = static_cast<int>(current_cwnd * kNConnectionBeta);
EXPECT_EQ(expected_cwnd,
- cubic_->CongestionWindowAfterPacketLoss(current_cwnd));
+ cubic_.CongestionWindowAfterPacketLoss(current_cwnd));
current_cwnd = expected_cwnd;
- // First update after epoch.
- current_cwnd = cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min);
+ // First update after loss to initialize the epoch.
+ current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
+ uint32 old_cwnd = current_cwnd;
// Cubic phase.
- for (int i = 0; i < 54; ++i) {
- for (uint32 n = 1; n < current_cwnd; ++n) {
- // Call once per ACK.
- EXPECT_EQ(current_cwnd,
- cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min));
- }
+ stats_.cwnd_increase_cubic_mode = 0;
+ stats_.cwnd_increase_congestion_avoidance = 0;
+ for (int i = 0; i < 40 ; ++i) {
clock_.AdvanceTime(hundred_ms_);
- current_cwnd = cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min);
+ current_cwnd = cubic_.CongestionWindowAfterAck(current_cwnd, rtt_min);
}
- expected_cwnd = 440;
+ expected_cwnd = 422;
EXPECT_EQ(expected_cwnd, current_cwnd);
+ EXPECT_EQ(expected_cwnd - old_cwnd, stats_.cwnd_increase_cubic_mode);
+ EXPECT_EQ(expected_cwnd - old_cwnd,
+ stats_.cwnd_increase_congestion_avoidance);
}
-} // namespace testing
+} // namespace test
} // namespace net