| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2013 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. | |
| 4 | |
| 5 #include "net/quic/congestion_control/pacing_sender.h" | |
| 6 | |
| 7 #include <memory> | |
| 8 | |
| 9 #include "base/logging.h" | |
| 10 #include "net/quic/quic_protocol.h" | |
| 11 #include "net/quic/test_tools/mock_clock.h" | |
| 12 #include "net/quic/test_tools/quic_test_utils.h" | |
| 13 #include "testing/gtest/include/gtest/gtest.h" | |
| 14 | |
| 15 using testing::Return; | |
| 16 using testing::StrictMock; | |
| 17 using testing::_; | |
| 18 | |
| 19 namespace net { | |
| 20 namespace test { | |
| 21 | |
| 22 const QuicByteCount kBytesInFlight = 1024; | |
| 23 const int kInitialBurstPackets = 10; | |
| 24 | |
| 25 class PacingSenderTest : public ::testing::Test { | |
| 26 protected: | |
| 27 PacingSenderTest() | |
| 28 : zero_time_(QuicTime::Delta::Zero()), | |
| 29 infinite_time_(QuicTime::Delta::Infinite()), | |
| 30 packet_number_(1), | |
| 31 mock_sender_(new StrictMock<MockSendAlgorithm>()), | |
| 32 pacing_sender_(new PacingSender(mock_sender_, | |
| 33 QuicTime::Delta::FromMilliseconds(1), | |
| 34 0)) { | |
| 35 // Pick arbitrary time. | |
| 36 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(9)); | |
| 37 } | |
| 38 | |
| 39 ~PacingSenderTest() override {} | |
| 40 | |
| 41 void InitPacingRate(QuicPacketCount burst_size, QuicBandwidth bandwidth) { | |
| 42 pacing_sender_.reset(); | |
| 43 mock_sender_ = new StrictMock<MockSendAlgorithm>(); | |
| 44 pacing_sender_.reset(new PacingSender( | |
| 45 mock_sender_, QuicTime::Delta::FromMilliseconds(1), burst_size)); | |
| 46 EXPECT_CALL(*mock_sender_, PacingRate(_)).WillRepeatedly(Return(bandwidth)); | |
| 47 } | |
| 48 | |
| 49 void CheckPacketIsSentImmediately(HasRetransmittableData retransmittable_data, | |
| 50 QuicByteCount bytes_in_flight, | |
| 51 bool in_recovery) { | |
| 52 // In order for the packet to be sendable, the underlying sender must | |
| 53 // permit it to be sent immediately. | |
| 54 for (int i = 0; i < 2; ++i) { | |
| 55 EXPECT_CALL(*mock_sender_, TimeUntilSend(clock_.Now(), bytes_in_flight)) | |
| 56 .WillOnce(Return(zero_time_)); | |
| 57 // Verify that the packet can be sent immediately. | |
| 58 EXPECT_EQ(zero_time_, | |
| 59 pacing_sender_->TimeUntilSend(clock_.Now(), bytes_in_flight)); | |
| 60 } | |
| 61 | |
| 62 // Actually send the packet. | |
| 63 if (bytes_in_flight == 0) { | |
| 64 EXPECT_CALL(*mock_sender_, InRecovery()).WillOnce(Return(in_recovery)); | |
| 65 } | |
| 66 EXPECT_CALL(*mock_sender_, | |
| 67 OnPacketSent(clock_.Now(), bytes_in_flight, packet_number_, | |
| 68 kMaxPacketSize, retransmittable_data)); | |
| 69 pacing_sender_->OnPacketSent(clock_.Now(), bytes_in_flight, | |
| 70 packet_number_++, kMaxPacketSize, | |
| 71 retransmittable_data); | |
| 72 } | |
| 73 | |
| 74 void CheckPacketIsSentImmediately() { | |
| 75 CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, kBytesInFlight, | |
| 76 false); | |
| 77 } | |
| 78 | |
| 79 void CheckPacketIsDelayed(QuicTime::Delta delay) { | |
| 80 // In order for the packet to be sendable, the underlying sender must | |
| 81 // permit it to be sent immediately. | |
| 82 for (int i = 0; i < 2; ++i) { | |
| 83 EXPECT_CALL(*mock_sender_, TimeUntilSend(clock_.Now(), kBytesInFlight)) | |
| 84 .WillOnce(Return(zero_time_)); | |
| 85 // Verify that the packet is delayed. | |
| 86 EXPECT_EQ(delay.ToMicroseconds(), | |
| 87 pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight) | |
| 88 .ToMicroseconds()); | |
| 89 } | |
| 90 } | |
| 91 | |
| 92 void UpdateRtt() { | |
| 93 EXPECT_CALL(*mock_sender_, OnCongestionEvent(true, kBytesInFlight, _, _)); | |
| 94 SendAlgorithmInterface::CongestionVector empty_map; | |
| 95 pacing_sender_->OnCongestionEvent(true, kBytesInFlight, empty_map, | |
| 96 empty_map); | |
| 97 } | |
| 98 | |
| 99 const QuicTime::Delta zero_time_; | |
| 100 const QuicTime::Delta infinite_time_; | |
| 101 MockClock clock_; | |
| 102 QuicPacketNumber packet_number_; | |
| 103 StrictMock<MockSendAlgorithm>* mock_sender_; | |
| 104 std::unique_ptr<PacingSender> pacing_sender_; | |
| 105 }; | |
| 106 | |
| 107 TEST_F(PacingSenderTest, NoSend) { | |
| 108 for (int i = 0; i < 2; ++i) { | |
| 109 EXPECT_CALL(*mock_sender_, TimeUntilSend(clock_.Now(), kBytesInFlight)) | |
| 110 .WillOnce(Return(infinite_time_)); | |
| 111 EXPECT_EQ(infinite_time_, | |
| 112 pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight)); | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 TEST_F(PacingSenderTest, SendNow) { | |
| 117 for (int i = 0; i < 2; ++i) { | |
| 118 EXPECT_CALL(*mock_sender_, TimeUntilSend(clock_.Now(), kBytesInFlight)) | |
| 119 .WillOnce(Return(zero_time_)); | |
| 120 EXPECT_EQ(zero_time_, | |
| 121 pacing_sender_->TimeUntilSend(clock_.Now(), kBytesInFlight)); | |
| 122 } | |
| 123 } | |
| 124 | |
| 125 TEST_F(PacingSenderTest, VariousSending) { | |
| 126 // Configure pacing rate of 1 packet per 1 ms, no initial burst. | |
| 127 InitPacingRate(0, QuicBandwidth::FromBytesAndTimeDelta( | |
| 128 kMaxPacketSize, QuicTime::Delta::FromMilliseconds(1))); | |
| 129 | |
| 130 // Now update the RTT and verify that packets are actually paced. | |
| 131 UpdateRtt(); | |
| 132 | |
| 133 CheckPacketIsSentImmediately(); | |
| 134 CheckPacketIsSentImmediately(); | |
| 135 | |
| 136 // The first packet was a "make up", then we sent two packets "into the | |
| 137 // future", so the delay should be 2. | |
| 138 CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2)); | |
| 139 | |
| 140 // Wake up on time. | |
| 141 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(2)); | |
| 142 CheckPacketIsSentImmediately(); | |
| 143 CheckPacketIsSentImmediately(); | |
| 144 CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2)); | |
| 145 | |
| 146 // Wake up late. | |
| 147 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(4)); | |
| 148 CheckPacketIsSentImmediately(); | |
| 149 CheckPacketIsSentImmediately(); | |
| 150 CheckPacketIsSentImmediately(); | |
| 151 CheckPacketIsSentImmediately(); | |
| 152 CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2)); | |
| 153 | |
| 154 // Wake up really late. | |
| 155 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(8)); | |
| 156 CheckPacketIsSentImmediately(); | |
| 157 CheckPacketIsSentImmediately(); | |
| 158 CheckPacketIsSentImmediately(); | |
| 159 CheckPacketIsSentImmediately(); | |
| 160 CheckPacketIsSentImmediately(); | |
| 161 CheckPacketIsSentImmediately(); | |
| 162 CheckPacketIsSentImmediately(); | |
| 163 CheckPacketIsSentImmediately(); | |
| 164 CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2)); | |
| 165 | |
| 166 // Wake up really late again, but application pause partway through. | |
| 167 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(8)); | |
| 168 CheckPacketIsSentImmediately(); | |
| 169 CheckPacketIsSentImmediately(); | |
| 170 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100)); | |
| 171 CheckPacketIsSentImmediately(); | |
| 172 CheckPacketIsSentImmediately(); | |
| 173 CheckPacketIsSentImmediately(); | |
| 174 CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2)); | |
| 175 | |
| 176 // Wake up too early. | |
| 177 CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2)); | |
| 178 | |
| 179 // Wake up early, but after enough time has passed to permit a send. | |
| 180 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1)); | |
| 181 CheckPacketIsSentImmediately(); | |
| 182 CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2)); | |
| 183 } | |
| 184 | |
| 185 TEST_F(PacingSenderTest, InitialBurst) { | |
| 186 // Configure pacing rate of 1 packet per 1 ms. | |
| 187 InitPacingRate(10, QuicBandwidth::FromBytesAndTimeDelta( | |
| 188 kMaxPacketSize, QuicTime::Delta::FromMilliseconds(1))); | |
| 189 | |
| 190 EXPECT_CALL(*mock_sender_, GetCongestionWindow()) | |
| 191 .WillOnce(Return(10 * kDefaultTCPMSS)); | |
| 192 // Update the RTT and verify that the first 10 packets aren't paced. | |
| 193 UpdateRtt(); | |
| 194 | |
| 195 // Send 10 packets, and verify that they are not paced. | |
| 196 for (int i = 0; i < kInitialBurstPackets; ++i) { | |
| 197 CheckPacketIsSentImmediately(); | |
| 198 } | |
| 199 | |
| 200 // The first packet was a "make up", then we sent two packets "into the | |
| 201 // future", so the delay should be 2ms. | |
| 202 CheckPacketIsSentImmediately(); | |
| 203 CheckPacketIsSentImmediately(); | |
| 204 CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2)); | |
| 205 | |
| 206 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5)); | |
| 207 CheckPacketIsSentImmediately(); | |
| 208 | |
| 209 // Next time TimeUntilSend is called with no bytes in flight, pacing should | |
| 210 // allow a packet to be sent, and when it's sent, the tokens are refilled. | |
| 211 CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, false); | |
| 212 for (int i = 0; i < kInitialBurstPackets - 1; ++i) { | |
| 213 CheckPacketIsSentImmediately(); | |
| 214 } | |
| 215 | |
| 216 // The first packet was a "make up", then we sent two packets "into the | |
| 217 // future", so the delay should be 2ms. | |
| 218 CheckPacketIsSentImmediately(); | |
| 219 CheckPacketIsSentImmediately(); | |
| 220 CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2)); | |
| 221 } | |
| 222 | |
| 223 TEST_F(PacingSenderTest, InitialBurstNoRttMeasurement) { | |
| 224 // Configure pacing rate of 1 packet per 1 ms. | |
| 225 InitPacingRate(10, QuicBandwidth::FromBytesAndTimeDelta( | |
| 226 kMaxPacketSize, QuicTime::Delta::FromMilliseconds(1))); | |
| 227 | |
| 228 EXPECT_CALL(*mock_sender_, GetCongestionWindow()) | |
| 229 .WillOnce(Return(10 * kDefaultTCPMSS)); | |
| 230 // Send 10 packets, and verify that they are not paced. | |
| 231 for (int i = 0; i < kInitialBurstPackets; ++i) { | |
| 232 CheckPacketIsSentImmediately(); | |
| 233 } | |
| 234 | |
| 235 // The first packet was a "make up", then we sent two packets "into the | |
| 236 // future", so the delay should be 2ms. | |
| 237 CheckPacketIsSentImmediately(); | |
| 238 CheckPacketIsSentImmediately(); | |
| 239 CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2)); | |
| 240 | |
| 241 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5)); | |
| 242 CheckPacketIsSentImmediately(); | |
| 243 | |
| 244 // Next time TimeUntilSend is called with no bytes in flight, the tokens | |
| 245 // should be refilled and there should be no delay. | |
| 246 CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, false); | |
| 247 // Send 10 packets, and verify that they are not paced. | |
| 248 for (int i = 0; i < kInitialBurstPackets - 1; ++i) { | |
| 249 CheckPacketIsSentImmediately(); | |
| 250 } | |
| 251 | |
| 252 // The first packet was a "make up", then we sent two packets "into the | |
| 253 // future", so the delay should be 2ms. | |
| 254 CheckPacketIsSentImmediately(); | |
| 255 CheckPacketIsSentImmediately(); | |
| 256 CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2)); | |
| 257 } | |
| 258 | |
| 259 TEST_F(PacingSenderTest, FastSending) { | |
| 260 // Ensure the pacing sender paces, even when the inter-packet spacing is less | |
| 261 // than the pacing granularity. | |
| 262 InitPacingRate(10, | |
| 263 QuicBandwidth::FromBytesAndTimeDelta( | |
| 264 2 * kMaxPacketSize, QuicTime::Delta::FromMilliseconds(1))); | |
| 265 | |
| 266 EXPECT_CALL(*mock_sender_, GetCongestionWindow()) | |
| 267 .WillOnce(Return(10 * kDefaultTCPMSS)); | |
| 268 // Update the RTT and verify that the first 10 packets aren't paced. | |
| 269 UpdateRtt(); | |
| 270 | |
| 271 // Send 10 packets, and verify that they are not paced. | |
| 272 for (int i = 0; i < kInitialBurstPackets; ++i) { | |
| 273 CheckPacketIsSentImmediately(); | |
| 274 } | |
| 275 | |
| 276 // The first packet was a "make up", then we sent two packets "into the | |
| 277 // future", since it's 2 packets/ms, so the delay should be 1.5ms. | |
| 278 CheckPacketIsSentImmediately(); | |
| 279 CheckPacketIsSentImmediately(); | |
| 280 CheckPacketIsSentImmediately(); | |
| 281 CheckPacketIsDelayed(QuicTime::Delta::FromMicroseconds(1500)); | |
| 282 | |
| 283 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5)); | |
| 284 CheckPacketIsSentImmediately(); | |
| 285 | |
| 286 // Next time TimeUntilSend is called with no bytes in flight, the tokens | |
| 287 // should be refilled and there should be no delay. | |
| 288 CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, false); | |
| 289 for (int i = 0; i < kInitialBurstPackets - 1; ++i) { | |
| 290 CheckPacketIsSentImmediately(); | |
| 291 } | |
| 292 | |
| 293 // The first packet was a "make up", then we sent two packets "into the | |
| 294 // future", so the delay should be 1.5ms. | |
| 295 CheckPacketIsSentImmediately(); | |
| 296 CheckPacketIsSentImmediately(); | |
| 297 CheckPacketIsSentImmediately(); | |
| 298 CheckPacketIsDelayed(QuicTime::Delta::FromMicroseconds(1500)); | |
| 299 } | |
| 300 | |
| 301 TEST_F(PacingSenderTest, NoBurstEnteringRecovery) { | |
| 302 // Configure pacing rate of 1 packet per 1 ms with no burst tokens. | |
| 303 InitPacingRate(0, QuicBandwidth::FromBytesAndTimeDelta( | |
| 304 kMaxPacketSize, QuicTime::Delta::FromMilliseconds(1))); | |
| 305 // Sending a packet will set burst tokens. | |
| 306 CheckPacketIsSentImmediately(); | |
| 307 | |
| 308 // Losing a packet will set clear burst tokens. | |
| 309 SendAlgorithmInterface::CongestionVector lost_packets; | |
| 310 lost_packets.push_back(std::make_pair(1, kMaxPacketSize)); | |
| 311 SendAlgorithmInterface::CongestionVector empty; | |
| 312 EXPECT_CALL(*mock_sender_, | |
| 313 OnCongestionEvent(true, kMaxPacketSize, empty, lost_packets)); | |
| 314 pacing_sender_->OnCongestionEvent(true, kMaxPacketSize, empty, lost_packets); | |
| 315 // One packet is sent immediately, because of 1ms pacing granularity. | |
| 316 CheckPacketIsSentImmediately(); | |
| 317 // Ensure packets are immediately paced. | |
| 318 EXPECT_CALL(*mock_sender_, TimeUntilSend(clock_.Now(), kDefaultTCPMSS)) | |
| 319 .WillOnce(Return(zero_time_)); | |
| 320 // Verify the next packet is paced and delayed 2ms due to granularity. | |
| 321 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2), | |
| 322 pacing_sender_->TimeUntilSend(clock_.Now(), kDefaultTCPMSS)); | |
| 323 CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2)); | |
| 324 } | |
| 325 | |
| 326 TEST_F(PacingSenderTest, NoBurstInRecovery) { | |
| 327 // Configure pacing rate of 1 packet per 1 ms with no burst tokens. | |
| 328 InitPacingRate(0, QuicBandwidth::FromBytesAndTimeDelta( | |
| 329 kMaxPacketSize, QuicTime::Delta::FromMilliseconds(1))); | |
| 330 | |
| 331 UpdateRtt(); | |
| 332 | |
| 333 // Ensure only one packet is sent immediately and the rest are paced. | |
| 334 CheckPacketIsSentImmediately(HAS_RETRANSMITTABLE_DATA, 0, true); | |
| 335 CheckPacketIsSentImmediately(); | |
| 336 CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2)); | |
| 337 } | |
| 338 | |
| 339 TEST_F(PacingSenderTest, VerifyInnerSenderCalled) { | |
| 340 QuicBandwidth kBandwidth = QuicBandwidth::FromBitsPerSecond(1000); | |
| 341 QuicTime kTime = QuicTime::Infinite(); | |
| 342 QuicTime::Delta kTimeDelta = QuicTime::Delta::Infinite(); | |
| 343 QuicByteCount kBytes = 12345u; | |
| 344 | |
| 345 EXPECT_CALL(*mock_sender_, SetFromConfig(_, Perspective::IS_SERVER)); | |
| 346 QuicConfig config; | |
| 347 pacing_sender_->SetFromConfig(config, Perspective::IS_SERVER); | |
| 348 | |
| 349 EXPECT_CALL(*mock_sender_, ResumeConnectionState(_, true)); | |
| 350 CachedNetworkParameters cached_network_params; | |
| 351 pacing_sender_->ResumeConnectionState(cached_network_params, true); | |
| 352 | |
| 353 EXPECT_CALL(*mock_sender_, SetNumEmulatedConnections(2)); | |
| 354 pacing_sender_->SetNumEmulatedConnections(2); | |
| 355 | |
| 356 SendAlgorithmInterface::CongestionVector packets; | |
| 357 EXPECT_CALL(*mock_sender_, OnCongestionEvent(true, kBytes, packets, packets)); | |
| 358 pacing_sender_->OnCongestionEvent(true, kBytes, packets, packets); | |
| 359 | |
| 360 EXPECT_CALL(*mock_sender_, OnPacketSent(kTime, kBytes, 123u, kBytes, | |
| 361 HAS_RETRANSMITTABLE_DATA)); | |
| 362 EXPECT_CALL(*mock_sender_, PacingRate(_)).WillOnce(Return(kBandwidth)); | |
| 363 pacing_sender_->OnPacketSent(kTime, kBytes, 123u, kBytes, | |
| 364 HAS_RETRANSMITTABLE_DATA); | |
| 365 | |
| 366 EXPECT_CALL(*mock_sender_, OnRetransmissionTimeout(true)); | |
| 367 pacing_sender_->OnRetransmissionTimeout(true); | |
| 368 | |
| 369 EXPECT_CALL(*mock_sender_, OnConnectionMigration()); | |
| 370 pacing_sender_->OnConnectionMigration(); | |
| 371 | |
| 372 EXPECT_CALL(*mock_sender_, TimeUntilSend(kTime, kBytes)) | |
| 373 .WillOnce(Return(kTimeDelta)); | |
| 374 pacing_sender_->TimeUntilSend(kTime, kBytes); | |
| 375 | |
| 376 EXPECT_CALL(*mock_sender_, PacingRate(_)).WillOnce(Return(kBandwidth)); | |
| 377 EXPECT_EQ(kBandwidth, pacing_sender_->PacingRate(0)); | |
| 378 | |
| 379 EXPECT_CALL(*mock_sender_, BandwidthEstimate()).WillOnce(Return(kBandwidth)); | |
| 380 EXPECT_EQ(kBandwidth, pacing_sender_->BandwidthEstimate()); | |
| 381 | |
| 382 EXPECT_CALL(*mock_sender_, RetransmissionDelay()) | |
| 383 .WillOnce(Return(kTimeDelta)); | |
| 384 EXPECT_EQ(kTimeDelta, pacing_sender_->RetransmissionDelay()); | |
| 385 | |
| 386 EXPECT_CALL(*mock_sender_, GetCongestionWindow()).WillOnce(Return(kBytes)); | |
| 387 EXPECT_EQ(kBytes, pacing_sender_->GetCongestionWindow()); | |
| 388 | |
| 389 EXPECT_CALL(*mock_sender_, InSlowStart()).WillOnce(Return(true)); | |
| 390 EXPECT_TRUE(pacing_sender_->InSlowStart()); | |
| 391 | |
| 392 EXPECT_CALL(*mock_sender_, InRecovery()).WillOnce(Return(true)); | |
| 393 EXPECT_TRUE(pacing_sender_->InRecovery()); | |
| 394 | |
| 395 EXPECT_CALL(*mock_sender_, GetSlowStartThreshold()).WillOnce(Return(kBytes)); | |
| 396 EXPECT_EQ(kBytes, pacing_sender_->GetSlowStartThreshold()); | |
| 397 | |
| 398 EXPECT_CALL(*mock_sender_, GetCongestionControlType()) | |
| 399 .WillOnce(Return(kReno)); | |
| 400 EXPECT_EQ(kReno, pacing_sender_->GetCongestionControlType()); | |
| 401 } | |
| 402 | |
| 403 } // namespace test | |
| 404 } // namespace net | |
| OLD | NEW |