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 |