diff options
Diffstat (limited to 'chromium/net/quic/congestion_control/cubic_test.cc')
-rw-r--r-- | chromium/net/quic/congestion_control/cubic_test.cc | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/chromium/net/quic/congestion_control/cubic_test.cc b/chromium/net/quic/congestion_control/cubic_test.cc new file mode 100644 index 00000000000..84f2a7bb53d --- /dev/null +++ b/chromium/net/quic/congestion_control/cubic_test.cc @@ -0,0 +1,150 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/basictypes.h" +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "net/quic/congestion_control/cubic.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; +}; + +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_)); + } + const QuicTime::Delta one_ms_; + const QuicTime::Delta hundred_ms_; + MockClock clock_; + scoped_ptr<CubicPeer> 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) { + // Convex growth. + const QuicTime::Delta rtt_min = hundred_ms_; + uint32 current_cwnd = 10; + uint32 expected_cwnd = current_cwnd + 1; + // Initialize the state. + clock_.AdvanceTime(one_ms_); + EXPECT_EQ(expected_cwnd, + 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) { + // Call once per ACK. + EXPECT_EQ(current_cwnd, + cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min)); + } + clock_.AdvanceTime(hundred_ms_); + current_cwnd = cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min); + EXPECT_EQ(expected_cwnd, current_cwnd); + expected_cwnd++; + } + // Cubic phase. + for (int j = 48; j < 100; ++j) { + for (uint32 n = 1; n < current_cwnd; ++n) { + // Call once per ACK. + EXPECT_EQ(current_cwnd, + cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min)); + } + clock_.AdvanceTime(hundred_ms_); + current_cwnd = cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min); + } + float elapsed_time_s = 10.0f + 0.1f; // We need to add the RTT here. + expected_cwnd = 11 + (elapsed_time_s * elapsed_time_s * elapsed_time_s * 410) + / 1024; + EXPECT_EQ(expected_cwnd, current_cwnd); +} + +TEST_F(CubicTest, LossEvents) { + const QuicTime::Delta rtt_min = hundred_ms_; + uint32 current_cwnd = 422; + uint32 expected_cwnd = current_cwnd + 1; + // Initialize the state. + clock_.AdvanceTime(one_ms_); + EXPECT_EQ(expected_cwnd, + cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min)); + expected_cwnd = current_cwnd * 717 / 1024; + EXPECT_EQ(expected_cwnd, + cubic_->CongestionWindowAfterPacketLoss(current_cwnd)); + expected_cwnd = current_cwnd * 717 / 1024; + EXPECT_EQ(expected_cwnd, + cubic_->CongestionWindowAfterPacketLoss(current_cwnd)); +} + +TEST_F(CubicTest, BelowOrgin) { + // Concave growth. + const QuicTime::Delta rtt_min = hundred_ms_; + uint32 current_cwnd = 422; + uint32 expected_cwnd = current_cwnd + 1; + // Initialize the state. + clock_.AdvanceTime(one_ms_); + EXPECT_EQ(expected_cwnd, + cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min)); + expected_cwnd = current_cwnd * 717 / 1024; + EXPECT_EQ(expected_cwnd, + cubic_->CongestionWindowAfterPacketLoss(current_cwnd)); + current_cwnd = expected_cwnd; + // First update after epoch. + current_cwnd = cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min); + // 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)); + } + clock_.AdvanceTime(hundred_ms_); + current_cwnd = cubic_->CongestionWindowAfterAck(current_cwnd, rtt_min); + } + expected_cwnd = 422; + EXPECT_EQ(expected_cwnd, current_cwnd); +} + +} // namespace testing +} // namespace net |