OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/bbr_sender.h" | 5 #include "net/quic/core/congestion_control/bbr_sender.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 #include <memory> | 9 #include <memory> |
10 | 10 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 "BBR sender", | 83 "BBR sender", |
84 Perspective::IS_SERVER, | 84 Perspective::IS_SERVER, |
85 /*connection_id=*/GetPeerInMemoryConnectionId(42)), | 85 /*connection_id=*/GetPeerInMemoryConnectionId(42)), |
86 competing_receiver_(&simulator_, | 86 competing_receiver_(&simulator_, |
87 "Competing receiver", | 87 "Competing receiver", |
88 "Competing sender", | 88 "Competing sender", |
89 Perspective::IS_SERVER, | 89 Perspective::IS_SERVER, |
90 /*connection_id=*/GetPeerInMemoryConnectionId(43)), | 90 /*connection_id=*/GetPeerInMemoryConnectionId(43)), |
91 receiver_multiplexer_("Receiver multiplexer", | 91 receiver_multiplexer_("Receiver multiplexer", |
92 {&receiver_, &competing_receiver_}) { | 92 {&receiver_, &competing_receiver_}) { |
| 93 // These will be changed by the appropriate tests as necessary. |
| 94 FLAGS_quic_reloadable_flag_quic_bbr_keep_sending_at_recent_rate = false; |
| 95 FLAGS_quic_reloadable_flag_quic_bbr_slow_recent_delivery = false; |
| 96 FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd = false; |
93 // TODO(ianswett): Determine why tests become flaky with CWND based on SRTT. | 97 // TODO(ianswett): Determine why tests become flaky with CWND based on SRTT. |
94 FLAGS_quic_reloadable_flag_quic_bbr_base_cwnd_on_srtt = false; | 98 FLAGS_quic_reloadable_flag_quic_bbr_base_cwnd_on_srtt = false; |
95 FLAGS_quic_reloadable_flag_quic_bbr_extra_conservation = true; | 99 FLAGS_quic_reloadable_flag_quic_bbr_extra_conservation = true; |
| 100 FLAGS_quic_reloadable_flag_quic_bbr_fix_conservation = true; |
96 rtt_stats_ = bbr_sender_.connection()->sent_packet_manager().GetRttStats(); | 101 rtt_stats_ = bbr_sender_.connection()->sent_packet_manager().GetRttStats(); |
97 sender_ = SetupBbrSender(&bbr_sender_); | 102 sender_ = SetupBbrSender(&bbr_sender_); |
98 | 103 |
99 clock_ = simulator_.GetClock(); | 104 clock_ = simulator_.GetClock(); |
100 simulator_.set_random_generator(&random_); | 105 simulator_.set_random_generator(&random_); |
101 | 106 |
102 uint64_t seed = QuicRandom::GetInstance()->RandUint64(); | 107 uint64_t seed = QuicRandom::GetInstance()->RandUint64(); |
103 random_.set_seed(seed); | 108 random_.set_seed(seed); |
104 QUIC_LOG(INFO) << "BbrSenderTest simulator set up. Seed: " << seed; | 109 QUIC_LOG(INFO) << "BbrSenderTest simulator set up. Seed: " << seed; |
105 } | 110 } |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 // TODO(ianswett): Tighten this bound once we understand why BBR is | 313 // TODO(ianswett): Tighten this bound once we understand why BBR is |
309 // overestimating bandwidth with aggregation. b/36022633 | 314 // overestimating bandwidth with aggregation. b/36022633 |
310 EXPECT_GE(kTestLinkBandwidth * 1.5f, | 315 EXPECT_GE(kTestLinkBandwidth * 1.5f, |
311 sender_->ExportDebugState().max_bandwidth); | 316 sender_->ExportDebugState().max_bandwidth); |
312 // TODO(ianswett): Expect 0 packets are lost once BBR no longer measures | 317 // TODO(ianswett): Expect 0 packets are lost once BBR no longer measures |
313 // bandwidth higher than the link rate. | 318 // bandwidth higher than the link rate. |
314 EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited); | 319 EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited); |
315 // The margin here is high, because the aggregation greatly increases | 320 // The margin here is high, because the aggregation greatly increases |
316 // smoothed rtt. | 321 // smoothed rtt. |
317 EXPECT_GE(kTestRtt * 4, rtt_stats_->smoothed_rtt()); | 322 EXPECT_GE(kTestRtt * 4, rtt_stats_->smoothed_rtt()); |
318 ExpectApproxEq(kTestRtt, rtt_stats_->min_rtt(), 0.1f); | 323 ExpectApproxEq(kTestRtt, rtt_stats_->min_rtt(), 0.12f); |
319 } | 324 } |
320 | 325 |
321 TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationKeepSending) { | 326 TEST_F(BbrSenderTest, SimpleTransfer2RTTAggregationKeepSending) { |
322 FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes = false; | 327 FLAGS_quic_reloadable_flag_quic_bbr_ack_aggregation_bytes = false; |
323 FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd = false; | 328 FLAGS_quic_reloadable_flag_quic_bbr_add_tso_cwnd = false; |
324 FLAGS_quic_reloadable_flag_quic_bbr_keep_sending_at_recent_rate = true; | 329 FLAGS_quic_reloadable_flag_quic_bbr_keep_sending_at_recent_rate = true; |
325 CreateDefaultSetup(); | 330 CreateDefaultSetup(); |
326 // 2 RTTs of aggregation, with a max of 10kb. | 331 // 2 RTTs of aggregation, with a max of 10kb. |
327 EnableAggregation(10 * 1024, 2 * kTestRtt); | 332 EnableAggregation(10 * 1024, 2 * kTestRtt); |
328 | 333 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 sender_->ExportDebugState().max_bandwidth); | 445 sender_->ExportDebugState().max_bandwidth); |
441 // TODO(ianswett): Tighten this bound once we understand why BBR is | 446 // TODO(ianswett): Tighten this bound once we understand why BBR is |
442 // overestimating bandwidth with aggregation. b/36022633 | 447 // overestimating bandwidth with aggregation. b/36022633 |
443 EXPECT_GE(kTestLinkBandwidth * 1.5f, | 448 EXPECT_GE(kTestLinkBandwidth * 1.5f, |
444 sender_->ExportDebugState().max_bandwidth); | 449 sender_->ExportDebugState().max_bandwidth); |
445 // TODO(ianswett): Expect 0 packets are lost once BBR no longer measures | 450 // TODO(ianswett): Expect 0 packets are lost once BBR no longer measures |
446 // bandwidth higher than the link rate. | 451 // bandwidth higher than the link rate. |
447 EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited); | 452 EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited); |
448 // The margin here is high, because the aggregation greatly increases | 453 // The margin here is high, because the aggregation greatly increases |
449 // smoothed rtt. | 454 // smoothed rtt. |
450 EXPECT_GE(kTestRtt * 4, rtt_stats_->smoothed_rtt()); | 455 EXPECT_GE(kTestRtt * 5, rtt_stats_->smoothed_rtt()); |
451 ExpectApproxEq(kTestRtt, rtt_stats_->min_rtt(), 0.1f); | 456 ExpectApproxEq(kTestRtt, rtt_stats_->min_rtt(), 0.25f); |
452 } | 457 } |
453 | 458 |
454 // Test the number of losses incurred by the startup phase in a situation when | 459 // Test the number of losses incurred by the startup phase in a situation when |
455 // the buffer is less than BDP. | 460 // the buffer is less than BDP. |
456 TEST_F(BbrSenderTest, PacketLossOnSmallBufferStartup) { | 461 TEST_F(BbrSenderTest, PacketLossOnSmallBufferStartup) { |
457 CreateSmallBufferSetup(); | 462 CreateSmallBufferSetup(); |
458 | 463 |
459 DriveOutOfStartup(); | 464 DriveOutOfStartup(); |
460 float loss_rate = | 465 float loss_rate = |
461 static_cast<float>(bbr_sender_.connection()->GetStats().packets_lost) / | 466 static_cast<float>(bbr_sender_.connection()->GetStats().packets_lost) / |
462 bbr_sender_.connection()->GetStats().packets_sent; | 467 bbr_sender_.connection()->GetStats().packets_sent; |
463 EXPECT_LE(loss_rate, 0.27); | 468 EXPECT_LE(loss_rate, 0.31); |
464 } | 469 } |
465 | 470 |
466 // Ensures the code transitions loss recovery states correctly (NOT_IN_RECOVERY | 471 // Ensures the code transitions loss recovery states correctly (NOT_IN_RECOVERY |
467 // -> CONSERVATION -> GROWTH -> NOT_IN_RECOVERY). | 472 // -> CONSERVATION -> GROWTH -> NOT_IN_RECOVERY). |
468 TEST_F(BbrSenderTest, RecoveryStates) { | 473 TEST_F(BbrSenderTest, RecoveryStates) { |
469 // Set seed to the position where the gain cycling causes the sender go | 474 // Set seed to the position where the gain cycling causes the sender go |
470 // into conservation upon entering PROBE_BW. | 475 // into conservation upon entering PROBE_BW. |
471 // | 476 // |
472 // TODO(vasilvv): there should be a better way to test this. | 477 // TODO(vasilvv): there should be a better way to test this. |
473 random_.set_seed(UINT64_C(14719894707049085006)); | 478 random_.set_seed(UINT64_C(14719894707049085006)); |
474 | 479 |
475 const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10); | 480 const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10); |
476 bool simulator_result; | 481 bool simulator_result; |
477 CreateSmallBufferSetup(); | 482 CreateSmallBufferSetup(); |
478 | 483 |
479 bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024); | 484 bbr_sender_.AddBytesToTransfer(100 * 1024 * 1024); |
480 ASSERT_EQ(BbrSender::NOT_IN_RECOVERY, | 485 ASSERT_EQ(BbrSender::NOT_IN_RECOVERY, |
481 sender_->ExportDebugState().recovery_state); | 486 sender_->ExportDebugState().recovery_state); |
482 | 487 |
483 simulator_result = simulator_.RunUntilOrTimeout( | 488 simulator_result = simulator_.RunUntilOrTimeout( |
484 [this]() { | 489 [this]() { |
485 return sender_->ExportDebugState().recovery_state != | 490 return sender_->ExportDebugState().recovery_state != |
486 BbrSender::NOT_IN_RECOVERY; | 491 BbrSender::NOT_IN_RECOVERY; |
487 }, | 492 }, |
488 timeout); | 493 timeout); |
489 ASSERT_TRUE(simulator_result); | 494 ASSERT_TRUE(simulator_result); |
490 ASSERT_EQ(BbrSender::CONSERVATION, | 495 ASSERT_EQ(BbrSender::CONSERVATION, |
491 sender_->ExportDebugState().recovery_state); | 496 sender_->ExportDebugState().recovery_state); |
492 | 497 |
| 498 const QuicByteCount cwnd_at_recovery_start = sender_->GetCongestionWindow(); |
493 simulator_result = simulator_.RunUntilOrTimeout( | 499 simulator_result = simulator_.RunUntilOrTimeout( |
494 [this]() { | 500 [this, cwnd_at_recovery_start]() { |
| 501 // Ensure that the CWND never drops due to conservation. |
| 502 if (sender_->GetCongestionWindow() < cwnd_at_recovery_start) { |
| 503 return true; |
| 504 } |
495 return sender_->ExportDebugState().recovery_state != | 505 return sender_->ExportDebugState().recovery_state != |
496 BbrSender::CONSERVATION; | 506 BbrSender::CONSERVATION; |
497 }, | 507 }, |
498 timeout); | 508 timeout); |
| 509 ASSERT_GE(sender_->GetCongestionWindow(), cwnd_at_recovery_start); |
499 ASSERT_TRUE(simulator_result); | 510 ASSERT_TRUE(simulator_result); |
500 ASSERT_EQ(BbrSender::GROWTH, sender_->ExportDebugState().recovery_state); | 511 ASSERT_EQ(BbrSender::GROWTH, sender_->ExportDebugState().recovery_state); |
501 | 512 |
502 simulator_result = simulator_.RunUntilOrTimeout( | 513 simulator_result = simulator_.RunUntilOrTimeout( |
503 [this]() { | 514 [this]() { |
504 return sender_->ExportDebugState().recovery_state != BbrSender::GROWTH; | 515 return sender_->ExportDebugState().recovery_state != BbrSender::GROWTH; |
505 }, | 516 }, |
506 timeout); | 517 timeout); |
507 | 518 |
508 ASSERT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode); | 519 ASSERT_EQ(BbrSender::PROBE_BW, sender_->ExportDebugState().mode); |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 sender_->ResumeConnectionState(params, false); | 819 sender_->ResumeConnectionState(params, false); |
809 EXPECT_EQ(kTestLinkBandwidth, sender_->ExportDebugState().max_bandwidth); | 820 EXPECT_EQ(kTestLinkBandwidth, sender_->ExportDebugState().max_bandwidth); |
810 EXPECT_EQ(kTestLinkBandwidth, sender_->BandwidthEstimate()); | 821 EXPECT_EQ(kTestLinkBandwidth, sender_->BandwidthEstimate()); |
811 ExpectApproxEq(kTestRtt, sender_->ExportDebugState().min_rtt, 0.01f); | 822 ExpectApproxEq(kTestRtt, sender_->ExportDebugState().min_rtt, 0.01f); |
812 | 823 |
813 DriveOutOfStartup(); | 824 DriveOutOfStartup(); |
814 } | 825 } |
815 | 826 |
816 } // namespace test | 827 } // namespace test |
817 } // namespace net | 828 } // namespace net |
OLD | NEW |