1 // Copyright 2019 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 <memory>
6 #include <optional>
7 #include <sstream>
8 #include <utility>
9
10 #include "absl/strings/str_cat.h"
11 #include "quiche/quic/core/congestion_control/bbr2_misc.h"
12 #include "quiche/quic/core/congestion_control/bbr2_sender.h"
13 #include "quiche/quic/core/congestion_control/bbr_sender.h"
14 #include "quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.h"
15 #include "quiche/quic/core/quic_bandwidth.h"
16 #include "quiche/quic/core/quic_packet_number.h"
17 #include "quiche/quic/core/quic_types.h"
18 #include "quiche/quic/platform/api/quic_flags.h"
19 #include "quiche/quic/platform/api/quic_logging.h"
20 #include "quiche/quic/platform/api/quic_test.h"
21 #include "quiche/quic/test_tools/quic_config_peer.h"
22 #include "quiche/quic/test_tools/quic_connection_peer.h"
23 #include "quiche/quic/test_tools/quic_sent_packet_manager_peer.h"
24 #include "quiche/quic/test_tools/quic_test_utils.h"
25 #include "quiche/quic/test_tools/send_algorithm_test_result.pb.h"
26 #include "quiche/quic/test_tools/send_algorithm_test_utils.h"
27 #include "quiche/quic/test_tools/simulator/link.h"
28 #include "quiche/quic/test_tools/simulator/quic_endpoint.h"
29 #include "quiche/quic/test_tools/simulator/simulator.h"
30 #include "quiche/quic/test_tools/simulator/switch.h"
31 #include "quiche/quic/test_tools/simulator/traffic_policer.h"
32 #include "quiche/common/platform/api/quiche_command_line_flags.h"
33
34 using testing::AllOf;
35 using testing::Ge;
36 using testing::Le;
37
38 DEFINE_QUICHE_COMMAND_LINE_FLAG(
39 std::string, quic_bbr2_test_regression_mode, "",
40 "One of a) 'record' to record test result (one file per test), or "
41 "b) 'regress' to regress against recorded results, or "
42 "c) <anything else> for non-regression mode.");
43
44 namespace quic {
45
46 using CyclePhase = Bbr2ProbeBwMode::CyclePhase;
47
48 namespace test {
49
50 // Use the initial CWND of 10, as 32 is too much for the test network.
51 const uint32_t kDefaultInitialCwndPackets = 10;
52 const uint32_t kDefaultInitialCwndBytes =
53 kDefaultInitialCwndPackets * kDefaultTCPMSS;
54
55 struct LinkParams {
LinkParamsquic::test::LinkParams56 LinkParams(int64_t kilo_bits_per_sec, int64_t delay_us)
57 : bandwidth(QuicBandwidth::FromKBitsPerSecond(kilo_bits_per_sec)),
58 delay(QuicTime::Delta::FromMicroseconds(delay_us)) {}
59 QuicBandwidth bandwidth;
60 QuicTime::Delta delay;
61 };
62
63 struct TrafficPolicerParams {
64 std::string name = "policer";
65 QuicByteCount initial_burst_size;
66 QuicByteCount max_bucket_size;
67 QuicBandwidth target_bandwidth = QuicBandwidth::Zero();
68 };
69
70 // All Bbr2DefaultTopologyTests uses the default network topology:
71 //
72 // Sender
73 // |
74 // | <-- local_link
75 // |
76 // Network switch
77 // * <-- the bottleneck queue in the direction
78 // | of the receiver
79 // |
80 // | <-- test_link
81 // |
82 // |
83 // Receiver
84 class DefaultTopologyParams {
85 public:
86 LinkParams local_link = {10000, 2000};
87 LinkParams test_link = {4000, 30000};
88
89 const simulator::SwitchPortNumber switch_port_count = 2;
90 // Network switch queue capacity, in number of BDPs.
91 float switch_queue_capacity_in_bdp = 2;
92
93 std::optional<TrafficPolicerParams> sender_policer_params;
94
BottleneckBandwidth() const95 QuicBandwidth BottleneckBandwidth() const {
96 return std::min(local_link.bandwidth, test_link.bandwidth);
97 }
98
99 // Round trip time of a single full size packet.
RTT() const100 QuicTime::Delta RTT() const {
101 return 2 * (local_link.delay + test_link.delay +
102 local_link.bandwidth.TransferTime(kMaxOutgoingPacketSize) +
103 test_link.bandwidth.TransferTime(kMaxOutgoingPacketSize));
104 }
105
BDP() const106 QuicByteCount BDP() const { return BottleneckBandwidth() * RTT(); }
107
SwitchQueueCapacity() const108 QuicByteCount SwitchQueueCapacity() const {
109 return switch_queue_capacity_in_bdp * BDP();
110 }
111
ToString() const112 std::string ToString() const {
113 std::ostringstream os;
114 os << "{ BottleneckBandwidth: " << BottleneckBandwidth()
115 << " RTT: " << RTT() << " BDP: " << BDP()
116 << " BottleneckQueueSize: " << SwitchQueueCapacity() << "}";
117 return os.str();
118 }
119 };
120
121 class Bbr2SimulatorTest : public QuicTest {
122 protected:
Bbr2SimulatorTest()123 Bbr2SimulatorTest() : simulator_(&random_) {
124 // Prevent the server(receiver), which only sends acks, from closing
125 // connection due to too many outstanding packets.
126 SetQuicFlag(quic_max_tracked_packet_count, 1000000);
127 }
128
SetUp()129 void SetUp() override {
130 if (quiche::GetQuicheCommandLineFlag(
131 FLAGS_quic_bbr2_test_regression_mode) == "regress") {
132 SendAlgorithmTestResult expected;
133 ASSERT_TRUE(LoadSendAlgorithmTestResult(&expected));
134 random_seed_ = expected.random_seed();
135 } else {
136 random_seed_ = QuicRandom::GetInstance()->RandUint64();
137 }
138 random_.set_seed(random_seed_);
139 QUIC_LOG(INFO) << "Using random seed: " << random_seed_;
140 }
141
~Bbr2SimulatorTest()142 ~Bbr2SimulatorTest() override {
143 const std::string regression_mode =
144 quiche::GetQuicheCommandLineFlag(FLAGS_quic_bbr2_test_regression_mode);
145 const QuicTime::Delta simulated_duration =
146 SimulatedNow() - QuicTime::Zero();
147 if (regression_mode == "record") {
148 RecordSendAlgorithmTestResult(random_seed_,
149 simulated_duration.ToMicroseconds());
150 } else if (regression_mode == "regress") {
151 CompareSendAlgorithmTestResult(simulated_duration.ToMicroseconds());
152 }
153 }
154
SimulatedNow() const155 QuicTime SimulatedNow() const { return simulator_.GetClock()->Now(); }
156
157 uint64_t random_seed_;
158 SimpleRandom random_;
159 simulator::Simulator simulator_;
160 };
161
162 class Bbr2DefaultTopologyTest : public Bbr2SimulatorTest {
163 protected:
Bbr2DefaultTopologyTest()164 Bbr2DefaultTopologyTest()
165 : sender_endpoint_(&simulator_, "Sender", "Receiver",
166 Perspective::IS_CLIENT, TestConnectionId(42)),
167 receiver_endpoint_(&simulator_, "Receiver", "Sender",
168 Perspective::IS_SERVER, TestConnectionId(42)) {
169 sender_ = SetupBbr2Sender(&sender_endpoint_, /*old_sender=*/nullptr);
170 }
171
~Bbr2DefaultTopologyTest()172 ~Bbr2DefaultTopologyTest() {
173 const auto* test_info =
174 ::testing::UnitTest::GetInstance()->current_test_info();
175 const Bbr2Sender::DebugState& debug_state = sender_->ExportDebugState();
176 QUIC_LOG(INFO) << "Bbr2DefaultTopologyTest." << test_info->name()
177 << " completed at simulated time: "
178 << SimulatedNow().ToDebuggingValue() / 1e6
179 << " sec. packet loss:"
180 << sender_loss_rate_in_packets() * 100
181 << "%, bw_hi:" << debug_state.bandwidth_hi;
182 }
183
GetUnackedMap(QuicConnection * connection)184 QuicUnackedPacketMap* GetUnackedMap(QuicConnection* connection) {
185 return QuicSentPacketManagerPeer::GetUnackedPacketMap(
186 QuicConnectionPeer::GetSentPacketManager(connection));
187 }
188
SetupBbr2Sender(simulator::QuicEndpoint * endpoint,BbrSender * old_sender)189 Bbr2Sender* SetupBbr2Sender(simulator::QuicEndpoint* endpoint,
190 BbrSender* old_sender) {
191 // Ownership of the sender will be overtaken by the endpoint.
192 Bbr2Sender* sender = new Bbr2Sender(
193 endpoint->connection()->clock()->Now(),
194 endpoint->connection()->sent_packet_manager().GetRttStats(),
195 GetUnackedMap(endpoint->connection()), kDefaultInitialCwndPackets,
196 GetQuicFlag(quic_max_congestion_window), &random_,
197 QuicConnectionPeer::GetStats(endpoint->connection()), old_sender);
198 QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
199 const int kTestMaxPacketSize = 1350;
200 endpoint->connection()->SetMaxPacketLength(kTestMaxPacketSize);
201 endpoint->RecordTrace();
202 return sender;
203 }
204
CreateNetwork(const DefaultTopologyParams & params)205 void CreateNetwork(const DefaultTopologyParams& params) {
206 QUIC_LOG(INFO) << "CreateNetwork with parameters: " << params.ToString();
207 switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch",
208 params.switch_port_count,
209 params.SwitchQueueCapacity());
210
211 // WARNING: The order to add links to network_links_ matters, because some
212 // tests adjusts the link bandwidth on the fly.
213
214 // Local link connects sender and port 1.
215 network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
216 &sender_endpoint_, switch_->port(1), params.local_link.bandwidth,
217 params.local_link.delay));
218
219 // Test link connects receiver and port 2.
220 if (params.sender_policer_params.has_value()) {
221 const TrafficPolicerParams& policer_params =
222 params.sender_policer_params.value();
223 sender_policer_ = std::make_unique<simulator::TrafficPolicer>(
224 &simulator_, policer_params.name, policer_params.initial_burst_size,
225 policer_params.max_bucket_size, policer_params.target_bandwidth,
226 switch_->port(2));
227 network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
228 &receiver_endpoint_, sender_policer_.get(),
229 params.test_link.bandwidth, params.test_link.delay));
230 } else {
231 network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
232 &receiver_endpoint_, switch_->port(2), params.test_link.bandwidth,
233 params.test_link.delay));
234 }
235 }
236
TestLink()237 simulator::SymmetricLink* TestLink() { return network_links_[1].get(); }
238
DoSimpleTransfer(QuicByteCount transfer_size,QuicTime::Delta timeout)239 void DoSimpleTransfer(QuicByteCount transfer_size, QuicTime::Delta timeout) {
240 sender_endpoint_.AddBytesToTransfer(transfer_size);
241 // TODO(wub): consider rewriting this to run until the receiver actually
242 // receives the intended amount of bytes.
243 bool simulator_result = simulator_.RunUntilOrTimeout(
244 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
245 timeout);
246 EXPECT_TRUE(simulator_result)
247 << "Simple transfer failed. Bytes remaining: "
248 << sender_endpoint_.bytes_to_transfer();
249 QUIC_LOG(INFO) << "Simple transfer state: " << sender_->ExportDebugState();
250 }
251
252 // Drive the simulator by sending enough data to enter PROBE_BW.
DriveOutOfStartup(const DefaultTopologyParams & params)253 void DriveOutOfStartup(const DefaultTopologyParams& params) {
254 ASSERT_FALSE(sender_->ExportDebugState().startup.full_bandwidth_reached);
255 DoSimpleTransfer(1024 * 1024, QuicTime::Delta::FromSeconds(15));
256 EXPECT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
257 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
258 sender_->ExportDebugState().bandwidth_hi, 0.02f);
259 }
260
261 // Send |bytes|-sized bursts of data |number_of_bursts| times, waiting for
262 // |wait_time| between each burst.
SendBursts(const DefaultTopologyParams & params,size_t number_of_bursts,QuicByteCount bytes,QuicTime::Delta wait_time)263 void SendBursts(const DefaultTopologyParams& params, size_t number_of_bursts,
264 QuicByteCount bytes, QuicTime::Delta wait_time) {
265 ASSERT_EQ(0u, sender_endpoint_.bytes_to_transfer());
266 for (size_t i = 0; i < number_of_bursts; i++) {
267 sender_endpoint_.AddBytesToTransfer(bytes);
268
269 // Transfer data and wait for three seconds between each transfer.
270 simulator_.RunFor(wait_time);
271
272 // Ensure the connection did not time out.
273 ASSERT_TRUE(sender_endpoint_.connection()->connected());
274 ASSERT_TRUE(receiver_endpoint_.connection()->connected());
275 }
276
277 simulator_.RunFor(wait_time + params.RTT());
278 ASSERT_EQ(0u, sender_endpoint_.bytes_to_transfer());
279 }
280
281 template <class TerminationPredicate>
SendUntilOrTimeout(TerminationPredicate termination_predicate,QuicTime::Delta timeout)282 bool SendUntilOrTimeout(TerminationPredicate termination_predicate,
283 QuicTime::Delta timeout) {
284 EXPECT_EQ(0u, sender_endpoint_.bytes_to_transfer());
285 const QuicTime deadline = SimulatedNow() + timeout;
286 do {
287 sender_endpoint_.AddBytesToTransfer(4 * kDefaultTCPMSS);
288 if (simulator_.RunUntilOrTimeout(
289 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
290 deadline - SimulatedNow()) &&
291 termination_predicate()) {
292 return true;
293 }
294 } while (SimulatedNow() < deadline);
295 return false;
296 }
297
EnableAggregation(QuicByteCount aggregation_bytes,QuicTime::Delta aggregation_timeout)298 void EnableAggregation(QuicByteCount aggregation_bytes,
299 QuicTime::Delta aggregation_timeout) {
300 switch_->port_queue(1)->EnableAggregation(aggregation_bytes,
301 aggregation_timeout);
302 }
303
SetConnectionOption(QuicTag option)304 void SetConnectionOption(QuicTag option) {
305 SetConnectionOption(std::move(option), sender_);
306 }
307
SetConnectionOption(QuicTag option,Bbr2Sender * sender)308 void SetConnectionOption(QuicTag option, Bbr2Sender* sender) {
309 QuicConfig config;
310 QuicTagVector options;
311 options.push_back(option);
312 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
313 sender->SetFromConfig(config, Perspective::IS_SERVER);
314 }
315
Bbr2ModeIsOneOf(const std::vector<Bbr2Mode> & expected_modes) const316 bool Bbr2ModeIsOneOf(const std::vector<Bbr2Mode>& expected_modes) const {
317 const Bbr2Mode mode = sender_->ExportDebugState().mode;
318 for (Bbr2Mode expected_mode : expected_modes) {
319 if (mode == expected_mode) {
320 return true;
321 }
322 }
323 return false;
324 }
325
rtt_stats()326 const RttStats* rtt_stats() {
327 return sender_endpoint_.connection()->sent_packet_manager().GetRttStats();
328 }
329
sender_connection()330 QuicConnection* sender_connection() { return sender_endpoint_.connection(); }
331
sender_debug_state() const332 Bbr2Sender::DebugState sender_debug_state() const {
333 return sender_->ExportDebugState();
334 }
335
sender_connection_stats()336 const QuicConnectionStats& sender_connection_stats() {
337 return sender_connection()->GetStats();
338 }
339
sender_unacked_map()340 QuicUnackedPacketMap* sender_unacked_map() {
341 return GetUnackedMap(sender_connection());
342 }
343
sender_loss_rate_in_packets()344 float sender_loss_rate_in_packets() {
345 return static_cast<float>(sender_connection_stats().packets_lost) /
346 sender_connection_stats().packets_sent;
347 }
348
349 simulator::QuicEndpoint sender_endpoint_;
350 simulator::QuicEndpoint receiver_endpoint_;
351 Bbr2Sender* sender_;
352
353 std::unique_ptr<simulator::Switch> switch_;
354 std::unique_ptr<simulator::TrafficPolicer> sender_policer_;
355 std::vector<std::unique_ptr<simulator::SymmetricLink>> network_links_;
356 };
357
TEST_F(Bbr2DefaultTopologyTest,NormalStartup)358 TEST_F(Bbr2DefaultTopologyTest, NormalStartup) {
359 DefaultTopologyParams params;
360 CreateNetwork(params);
361
362 // Run until the full bandwidth is reached and check how many rounds it was.
363 sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
364 QuicRoundTripCount max_bw_round = 0;
365 QuicBandwidth max_bw(QuicBandwidth::Zero());
366 bool simulator_result = simulator_.RunUntilOrTimeout(
367 [this, &max_bw, &max_bw_round]() {
368 if (max_bw * 1.001 < sender_->ExportDebugState().bandwidth_hi) {
369 max_bw = sender_->ExportDebugState().bandwidth_hi;
370 max_bw_round = sender_->ExportDebugState().round_trip_count;
371 }
372 return sender_->ExportDebugState().startup.full_bandwidth_reached;
373 },
374 QuicTime::Delta::FromSeconds(5));
375 ASSERT_TRUE(simulator_result);
376 EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
377 EXPECT_EQ(3u, sender_->ExportDebugState().round_trip_count - max_bw_round);
378 EXPECT_EQ(
379 3u,
380 sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
381 EXPECT_EQ(0u, sender_connection_stats().packets_lost);
382 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
383 sender_->ExportDebugState().bandwidth_hi, 0.01f);
384 EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
385 }
386
TEST_F(Bbr2DefaultTopologyTest,NormalStartupB207)387 TEST_F(Bbr2DefaultTopologyTest, NormalStartupB207) {
388 SetConnectionOption(kB207);
389 DefaultTopologyParams params;
390 CreateNetwork(params);
391
392 // Run until the full bandwidth is reached and check how many rounds it was.
393 sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
394 QuicRoundTripCount max_bw_round = 0;
395 QuicBandwidth max_bw(QuicBandwidth::Zero());
396 bool simulator_result = simulator_.RunUntilOrTimeout(
397 [this, &max_bw, &max_bw_round]() {
398 if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
399 max_bw = sender_->ExportDebugState().bandwidth_hi;
400 max_bw_round = sender_->ExportDebugState().round_trip_count;
401 }
402 return sender_->ExportDebugState().startup.full_bandwidth_reached;
403 },
404 QuicTime::Delta::FromSeconds(5));
405 ASSERT_TRUE(simulator_result);
406 EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
407 EXPECT_EQ(1u, sender_->ExportDebugState().round_trip_count - max_bw_round);
408 EXPECT_EQ(
409 1u,
410 sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
411 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
412 sender_->ExportDebugState().bandwidth_hi, 0.01f);
413 EXPECT_EQ(0u, sender_connection_stats().packets_lost);
414 }
415
416 // Add extra_acked to CWND in STARTUP and exit STARTUP on a persistent queue.
TEST_F(Bbr2DefaultTopologyTest,NormalStartupB207andB205)417 TEST_F(Bbr2DefaultTopologyTest, NormalStartupB207andB205) {
418 SetConnectionOption(kB205);
419 SetConnectionOption(kB207);
420 DefaultTopologyParams params;
421 CreateNetwork(params);
422
423 // Run until the full bandwidth is reached and check how many rounds it was.
424 sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
425 QuicRoundTripCount max_bw_round = 0;
426 QuicBandwidth max_bw(QuicBandwidth::Zero());
427 bool simulator_result = simulator_.RunUntilOrTimeout(
428 [this, &max_bw, &max_bw_round]() {
429 if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
430 max_bw = sender_->ExportDebugState().bandwidth_hi;
431 max_bw_round = sender_->ExportDebugState().round_trip_count;
432 }
433 return sender_->ExportDebugState().startup.full_bandwidth_reached;
434 },
435 QuicTime::Delta::FromSeconds(5));
436 ASSERT_TRUE(simulator_result);
437 EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
438 EXPECT_EQ(1u, sender_->ExportDebugState().round_trip_count - max_bw_round);
439 EXPECT_EQ(
440 2u,
441 sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
442 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
443 sender_->ExportDebugState().bandwidth_hi, 0.01f);
444 EXPECT_EQ(0u, sender_connection_stats().packets_lost);
445 }
446
447 // Add extra_acked to CWND in STARTUP and exit STARTUP on a persistent queue.
TEST_F(Bbr2DefaultTopologyTest,NormalStartupBB2S)448 TEST_F(Bbr2DefaultTopologyTest, NormalStartupBB2S) {
449 SetQuicReloadableFlag(quic_bbr2_probe_two_rounds, true);
450 SetConnectionOption(kBB2S);
451 DefaultTopologyParams params;
452 CreateNetwork(params);
453
454 // Run until the full bandwidth is reached and check how many rounds it was.
455 sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
456 QuicRoundTripCount max_bw_round = 0;
457 QuicBandwidth max_bw(QuicBandwidth::Zero());
458 bool simulator_result = simulator_.RunUntilOrTimeout(
459 [this, &max_bw, &max_bw_round]() {
460 if (max_bw * 1.001 < sender_->ExportDebugState().bandwidth_hi) {
461 max_bw = sender_->ExportDebugState().bandwidth_hi;
462 max_bw_round = sender_->ExportDebugState().round_trip_count;
463 }
464 return sender_->ExportDebugState().startup.full_bandwidth_reached;
465 },
466 QuicTime::Delta::FromSeconds(5));
467 ASSERT_TRUE(simulator_result);
468 EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
469 // BB2S reduces 3 rounds without bandwidth growth to 2.
470 EXPECT_EQ(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
471 EXPECT_EQ(
472 2u,
473 sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
474 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
475 sender_->ExportDebugState().bandwidth_hi, 0.01f);
476 EXPECT_EQ(0u, sender_connection_stats().packets_lost);
477 }
478
479 // Test a simple long data transfer in the default setup.
TEST_F(Bbr2DefaultTopologyTest,SimpleTransfer)480 TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer) {
481 DefaultTopologyParams params;
482 CreateNetwork(params);
483
484 // At startup make sure we are at the default.
485 EXPECT_EQ(kDefaultInitialCwndBytes, sender_->GetCongestionWindow());
486 // At startup make sure we can send.
487 EXPECT_TRUE(sender_->CanSend(0));
488 // And that window is un-affected.
489 EXPECT_EQ(kDefaultInitialCwndBytes, sender_->GetCongestionWindow());
490
491 // Verify that Sender is in slow start.
492 EXPECT_TRUE(sender_->InSlowStart());
493
494 // Verify that pacing rate is based on the initial RTT.
495 QuicBandwidth expected_pacing_rate = QuicBandwidth::FromBytesAndTimeDelta(
496 2.885 * kDefaultInitialCwndBytes, rtt_stats()->initial_rtt());
497 EXPECT_APPROX_EQ(expected_pacing_rate.ToBitsPerSecond(),
498 sender_->PacingRate(0).ToBitsPerSecond(), 0.01f);
499
500 ASSERT_GE(params.BDP(), kDefaultInitialCwndBytes + kDefaultTCPMSS);
501
502 DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
503 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
504 EXPECT_EQ(0u, sender_connection_stats().packets_lost);
505 EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
506
507 // The margin here is quite high, since there exists a possibility that the
508 // connection just exited high gain cycle.
509 EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->smoothed_rtt(), 1.0f);
510 }
511
TEST_F(Bbr2DefaultTopologyTest,SimpleTransferB2RC)512 TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB2RC) {
513 SetConnectionOption(kB2RC);
514 DefaultTopologyParams params;
515 CreateNetwork(params);
516
517 // Transfer 12MB.
518 DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
519 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
520
521 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
522 sender_->ExportDebugState().bandwidth_hi, 0.01f);
523
524 EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
525 // The margin here is high, because the aggregation greatly increases
526 // smoothed rtt.
527 EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
528 EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
529 }
530
TEST_F(Bbr2DefaultTopologyTest,SimpleTransferB201)531 TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB201) {
532 SetConnectionOption(kB201);
533 DefaultTopologyParams params;
534 CreateNetwork(params);
535
536 // Transfer 12MB.
537 DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
538 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
539
540 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
541 sender_->ExportDebugState().bandwidth_hi, 0.01f);
542
543 EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
544 // The margin here is high, because the aggregation greatly increases
545 // smoothed rtt.
546 EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
547 EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
548 }
549
TEST_F(Bbr2DefaultTopologyTest,SimpleTransferB206)550 TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB206) {
551 SetConnectionOption(kB206);
552 DefaultTopologyParams params;
553 CreateNetwork(params);
554
555 // Transfer 12MB.
556 DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
557 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
558
559 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
560 sender_->ExportDebugState().bandwidth_hi, 0.01f);
561
562 EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
563 // The margin here is high, because the aggregation greatly increases
564 // smoothed rtt.
565 EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
566 EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
567 }
568
TEST_F(Bbr2DefaultTopologyTest,SimpleTransferB207)569 TEST_F(Bbr2DefaultTopologyTest, SimpleTransferB207) {
570 SetConnectionOption(kB207);
571 DefaultTopologyParams params;
572 CreateNetwork(params);
573
574 // Transfer 12MB.
575 DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
576 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
577
578 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
579 sender_->ExportDebugState().bandwidth_hi, 0.01f);
580
581 EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
582 // The margin here is high, because the aggregation greatly increases
583 // smoothed rtt.
584 EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
585 EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
586 }
587
TEST_F(Bbr2DefaultTopologyTest,SimpleTransferBBRB)588 TEST_F(Bbr2DefaultTopologyTest, SimpleTransferBBRB) {
589 SetConnectionOption(kBBRB);
590 DefaultTopologyParams params;
591 CreateNetwork(params);
592
593 // Transfer 12MB.
594 DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
595 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
596
597 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
598 sender_->ExportDebugState().bandwidth_hi, 0.01f);
599
600 EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
601 // The margin here is high, because the aggregation greatly increases
602 // smoothed rtt.
603 EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
604 EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
605 }
606
TEST_F(Bbr2DefaultTopologyTest,SimpleTransferBBR4)607 TEST_F(Bbr2DefaultTopologyTest, SimpleTransferBBR4) {
608 SetQuicReloadableFlag(quic_bbr2_extra_acked_window, true);
609 SetConnectionOption(kBBR4);
610 DefaultTopologyParams params;
611 CreateNetwork(params);
612
613 // Transfer 12MB.
614 DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
615 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
616
617 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
618 sender_->ExportDebugState().bandwidth_hi, 0.01f);
619
620 EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
621 // The margin here is high, because the aggregation greatly increases
622 // smoothed rtt.
623 EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
624 EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
625 }
626
TEST_F(Bbr2DefaultTopologyTest,SimpleTransferBBR5)627 TEST_F(Bbr2DefaultTopologyTest, SimpleTransferBBR5) {
628 SetQuicReloadableFlag(quic_bbr2_extra_acked_window, true);
629 SetConnectionOption(kBBR5);
630 DefaultTopologyParams params;
631 CreateNetwork(params);
632
633 // Transfer 12MB.
634 DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
635 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
636
637 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
638 sender_->ExportDebugState().bandwidth_hi, 0.01f);
639
640 EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
641 // The margin here is high, because the aggregation greatly increases
642 // smoothed rtt.
643 EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
644 EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
645 }
646
TEST_F(Bbr2DefaultTopologyTest,SimpleTransferBBQ1)647 TEST_F(Bbr2DefaultTopologyTest, SimpleTransferBBQ1) {
648 SetConnectionOption(kBBQ1);
649 DefaultTopologyParams params;
650 CreateNetwork(params);
651
652 // Transfer 12MB.
653 DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
654 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
655
656 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
657 sender_->ExportDebugState().bandwidth_hi, 0.01f);
658
659 EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
660 // The margin here is high, because the aggregation greatly increases
661 // smoothed rtt.
662 EXPECT_GE(params.RTT() * 4, rtt_stats()->smoothed_rtt());
663 EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
664 }
665
TEST_F(Bbr2DefaultTopologyTest,SimpleTransferSmallBuffer)666 TEST_F(Bbr2DefaultTopologyTest, SimpleTransferSmallBuffer) {
667 DefaultTopologyParams params;
668 params.switch_queue_capacity_in_bdp = 0.5;
669 CreateNetwork(params);
670
671 DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
672 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
673 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
674 sender_->ExportDebugState().bandwidth_hi, 0.02f);
675 EXPECT_GE(sender_connection_stats().packets_lost, 0u);
676 EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
677 }
678
TEST_F(Bbr2DefaultTopologyTest,SimpleTransferSmallBufferB2H2)679 TEST_F(Bbr2DefaultTopologyTest, SimpleTransferSmallBufferB2H2) {
680 SetConnectionOption(kB2H2);
681 DefaultTopologyParams params;
682 params.switch_queue_capacity_in_bdp = 0.5;
683 CreateNetwork(params);
684
685 DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
686 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
687 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
688 sender_->ExportDebugState().bandwidth_hi, 0.02f);
689 EXPECT_GE(sender_connection_stats().packets_lost, 0u);
690 EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
691 }
692
TEST_F(Bbr2DefaultTopologyTest,SimpleTransfer2RTTAggregationBytes)693 TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer2RTTAggregationBytes) {
694 SetConnectionOption(kBSAO);
695 DefaultTopologyParams params;
696 CreateNetwork(params);
697 // 2 RTTs of aggregation, with a max of 10kb.
698 EnableAggregation(10 * 1024, 2 * params.RTT());
699
700 // Transfer 12MB.
701 DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
702 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
703
704 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
705 sender_->ExportDebugState().bandwidth_hi, 0.01f);
706
707 EXPECT_EQ(sender_loss_rate_in_packets(), 0);
708 // The margin here is high, because both link level aggregation and ack
709 // decimation can greatly increase smoothed rtt.
710 EXPECT_GE(params.RTT() * 5, rtt_stats()->smoothed_rtt());
711 EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
712 }
713
TEST_F(Bbr2DefaultTopologyTest,SimpleTransfer2RTTAggregationBytesB201)714 TEST_F(Bbr2DefaultTopologyTest, SimpleTransfer2RTTAggregationBytesB201) {
715 SetConnectionOption(kB201);
716 DefaultTopologyParams params;
717 CreateNetwork(params);
718 // 2 RTTs of aggregation, with a max of 10kb.
719 EnableAggregation(10 * 1024, 2 * params.RTT());
720
721 // Transfer 12MB.
722 DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
723 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
724
725 // TODO(wub): Tighten the error bound once BSAO is default enabled.
726 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
727 sender_->ExportDebugState().bandwidth_hi, 0.5f);
728
729 EXPECT_LE(sender_loss_rate_in_packets(), 0.01);
730 // The margin here is high, because both link level aggregation and ack
731 // decimation can greatly increase smoothed rtt.
732 EXPECT_GE(params.RTT() * 5, rtt_stats()->smoothed_rtt());
733 EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.2f);
734 }
735
TEST_F(Bbr2DefaultTopologyTest,SimpleTransferAckDecimation)736 TEST_F(Bbr2DefaultTopologyTest, SimpleTransferAckDecimation) {
737 SetConnectionOption(kBSAO);
738 DefaultTopologyParams params;
739 CreateNetwork(params);
740
741 // Transfer 12MB.
742 DoSimpleTransfer(12 * 1024 * 1024, QuicTime::Delta::FromSeconds(35));
743 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
744
745 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
746 sender_->ExportDebugState().bandwidth_hi, 0.01f);
747
748 EXPECT_LE(sender_loss_rate_in_packets(), 0.001);
749 EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
750 // The margin here is high, because the aggregation greatly increases
751 // smoothed rtt.
752 EXPECT_GE(params.RTT() * 3, rtt_stats()->smoothed_rtt());
753 EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->min_rtt(), 0.1f);
754 }
755
756 // Test Bbr2's reaction to a 100x bandwidth decrease during a transfer.
TEST_F(Bbr2DefaultTopologyTest,QUIC_SLOW_TEST (BandwidthDecrease))757 TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthDecrease)) {
758 DefaultTopologyParams params;
759 params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
760 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
761 CreateNetwork(params);
762
763 sender_endpoint_.AddBytesToTransfer(20 * 1024 * 1024);
764
765 // We can transfer ~12MB in the first 10 seconds. The rest ~8MB needs about
766 // 640 seconds.
767 simulator_.RunFor(QuicTime::Delta::FromSeconds(10));
768 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
769 QUIC_LOG(INFO) << "Bandwidth decreasing at time " << SimulatedNow();
770
771 EXPECT_APPROX_EQ(params.test_link.bandwidth,
772 sender_->ExportDebugState().bandwidth_est, 0.1f);
773 EXPECT_EQ(0u, sender_connection_stats().packets_lost);
774
775 // Now decrease the bottleneck bandwidth from 10Mbps to 100Kbps.
776 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
777 TestLink()->set_bandwidth(params.test_link.bandwidth);
778
779 bool simulator_result = simulator_.RunUntilOrTimeout(
780 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
781 QuicTime::Delta::FromSeconds(800));
782 EXPECT_TRUE(simulator_result);
783 }
784
785 // Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B203
TEST_F(Bbr2DefaultTopologyTest,QUIC_SLOW_TEST (BandwidthIncreaseB203))786 TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB203)) {
787 SetConnectionOption(kB203);
788 DefaultTopologyParams params;
789 params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
790 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
791 CreateNetwork(params);
792
793 sender_endpoint_.AddBytesToTransfer(20 * 1024 * 1024);
794
795 simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
796 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
797 QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
798
799 EXPECT_APPROX_EQ(params.test_link.bandwidth,
800 sender_->ExportDebugState().bandwidth_est, 0.1f);
801 EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
802
803 // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
804 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
805 TestLink()->set_bandwidth(params.test_link.bandwidth);
806
807 bool simulator_result = simulator_.RunUntilOrTimeout(
808 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
809 QuicTime::Delta::FromSeconds(50));
810 EXPECT_TRUE(simulator_result);
811 // Ensure the full bandwidth is discovered.
812 EXPECT_APPROX_EQ(params.test_link.bandwidth,
813 sender_->ExportDebugState().bandwidth_hi, 0.02f);
814 }
815
816 // Test Bbr2's reaction to a 100x bandwidth increase during a transfer with BBQ0
TEST_F(Bbr2DefaultTopologyTest,QUIC_SLOW_TEST (BandwidthIncreaseBBQ0))817 TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseBBQ0)) {
818 SetConnectionOption(kBBQ0);
819 DefaultTopologyParams params;
820 params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
821 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
822 CreateNetwork(params);
823
824 sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
825
826 simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
827 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
828 QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
829
830 EXPECT_APPROX_EQ(params.test_link.bandwidth,
831 sender_->ExportDebugState().bandwidth_est, 0.1f);
832 EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
833
834 // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
835 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
836 TestLink()->set_bandwidth(params.test_link.bandwidth);
837
838 bool simulator_result = simulator_.RunUntilOrTimeout(
839 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
840 QuicTime::Delta::FromSeconds(50));
841 EXPECT_TRUE(simulator_result);
842 // Ensure the full bandwidth is discovered.
843 EXPECT_APPROX_EQ(params.test_link.bandwidth,
844 sender_->ExportDebugState().bandwidth_hi, 0.02f);
845 }
846
847 // Test Bbr2's reaction to a 100x bandwidth increase during a transfer with BBQ0
848 // in the presence of ACK aggregation.
TEST_F(Bbr2DefaultTopologyTest,QUIC_SLOW_TEST (BandwidthIncreaseBBQ0Aggregation))849 TEST_F(Bbr2DefaultTopologyTest,
850 QUIC_SLOW_TEST(BandwidthIncreaseBBQ0Aggregation)) {
851 SetConnectionOption(kBBQ0);
852 DefaultTopologyParams params;
853 params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
854 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
855 CreateNetwork(params);
856
857 // 2 RTTs of aggregation, with a max of 10kb.
858 EnableAggregation(10 * 1024, 2 * params.RTT());
859
860 // Reduce the payload to 2MB because 10MB takes too long.
861 sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
862
863 simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
864 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
865 QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
866
867 // This is much farther off when aggregation is present,
868 // Ideally BSAO or another option would fix this.
869 // TODO(ianswett) Make these bound tighter once overestimation is reduced.
870 EXPECT_APPROX_EQ(params.test_link.bandwidth,
871 sender_->ExportDebugState().bandwidth_est, 0.6f);
872 EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
873
874 // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
875 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
876 TestLink()->set_bandwidth(params.test_link.bandwidth);
877
878 bool simulator_result = simulator_.RunUntilOrTimeout(
879 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
880 QuicTime::Delta::FromSeconds(50));
881 EXPECT_TRUE(simulator_result);
882 // Ensure at least 10% of full bandwidth is discovered.
883 EXPECT_APPROX_EQ(params.test_link.bandwidth,
884 sender_->ExportDebugState().bandwidth_hi, 0.90f);
885 }
886
887 // Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B202
TEST_F(Bbr2DefaultTopologyTest,QUIC_SLOW_TEST (BandwidthIncreaseB202))888 TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB202)) {
889 SetConnectionOption(kB202);
890 DefaultTopologyParams params;
891 params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
892 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
893 CreateNetwork(params);
894
895 sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
896
897 simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
898 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
899 QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
900
901 EXPECT_APPROX_EQ(params.test_link.bandwidth,
902 sender_->ExportDebugState().bandwidth_est, 0.1f);
903 EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
904
905 // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
906 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
907 TestLink()->set_bandwidth(params.test_link.bandwidth);
908
909 bool simulator_result = simulator_.RunUntilOrTimeout(
910 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
911 QuicTime::Delta::FromSeconds(50));
912 EXPECT_TRUE(simulator_result);
913 // Ensure the full bandwidth is discovered.
914 EXPECT_APPROX_EQ(params.test_link.bandwidth,
915 sender_->ExportDebugState().bandwidth_hi, 0.1f);
916 }
917
918 // Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B202
919 // in the presence of ACK aggregation.
TEST_F(Bbr2DefaultTopologyTest,QUIC_SLOW_TEST (BandwidthIncreaseB202Aggregation))920 TEST_F(Bbr2DefaultTopologyTest,
921 QUIC_SLOW_TEST(BandwidthIncreaseB202Aggregation)) {
922 SetConnectionOption(kB202);
923 DefaultTopologyParams params;
924 params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
925 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
926 CreateNetwork(params);
927
928 // 2 RTTs of aggregation, with a max of 10kb.
929 EnableAggregation(10 * 1024, 2 * params.RTT());
930
931 // Reduce the payload to 2MB because 10MB takes too long.
932 sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
933
934 simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
935 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
936 QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
937
938 // This is much farther off when aggregation is present,
939 // Ideally BSAO or another option would fix this.
940 EXPECT_APPROX_EQ(params.test_link.bandwidth,
941 sender_->ExportDebugState().bandwidth_est, 0.6f);
942 EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
943
944 // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
945 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
946 TestLink()->set_bandwidth(params.test_link.bandwidth);
947
948 bool simulator_result = simulator_.RunUntilOrTimeout(
949 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
950 QuicTime::Delta::FromSeconds(50));
951 EXPECT_TRUE(simulator_result);
952 // Ensure at least 10% of full bandwidth is discovered.
953 EXPECT_APPROX_EQ(params.test_link.bandwidth,
954 sender_->ExportDebugState().bandwidth_hi, 0.92f);
955 }
956
957 // Test Bbr2's reaction to a 100x bandwidth increase during a transfer.
TEST_F(Bbr2DefaultTopologyTest,QUIC_SLOW_TEST (BandwidthIncrease))958 TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncrease)) {
959 DefaultTopologyParams params;
960 params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
961 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
962 CreateNetwork(params);
963
964 sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
965
966 simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
967 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
968 QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
969
970 EXPECT_APPROX_EQ(params.test_link.bandwidth,
971 sender_->ExportDebugState().bandwidth_est, 0.1f);
972 EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
973
974 // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
975 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
976 TestLink()->set_bandwidth(params.test_link.bandwidth);
977
978 bool simulator_result = simulator_.RunUntilOrTimeout(
979 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
980 QuicTime::Delta::FromSeconds(50));
981 EXPECT_TRUE(simulator_result);
982 // Ensure the full bandwidth is discovered.
983 EXPECT_APPROX_EQ(params.test_link.bandwidth,
984 sender_->ExportDebugState().bandwidth_hi, 0.02f);
985 }
986
987 // Test Bbr2's reaction to a 100x bandwidth increase during a transfer in the
988 // presence of ACK aggregation.
TEST_F(Bbr2DefaultTopologyTest,QUIC_SLOW_TEST (BandwidthIncreaseAggregation))989 TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseAggregation)) {
990 DefaultTopologyParams params;
991 params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
992 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
993 CreateNetwork(params);
994
995 // 2 RTTs of aggregation, with a max of 10kb.
996 EnableAggregation(10 * 1024, 2 * params.RTT());
997
998 // Reduce the payload to 2MB because 10MB takes too long.
999 sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
1000
1001 simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
1002 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
1003 QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
1004
1005 // This is much farther off when aggregation is present,
1006 // Ideally BSAO or another option would fix this.
1007 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1008 sender_->ExportDebugState().bandwidth_est, 0.60f);
1009 EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
1010
1011 // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
1012 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
1013 TestLink()->set_bandwidth(params.test_link.bandwidth);
1014
1015 bool simulator_result = simulator_.RunUntilOrTimeout(
1016 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
1017 QuicTime::Delta::FromSeconds(50));
1018 EXPECT_TRUE(simulator_result);
1019 // Ensure at least 10% of full bandwidth is discovered.
1020 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1021 sender_->ExportDebugState().bandwidth_hi, 0.91f);
1022 }
1023
1024 // Test Bbr2's reaction to a 100x bandwidth increase during a transfer with BBHI
TEST_F(Bbr2DefaultTopologyTest,QUIC_SLOW_TEST (BandwidthIncreaseBBHI))1025 TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseBBHI)) {
1026 SetQuicReloadableFlag(quic_bbr2_simplify_inflight_hi, true);
1027 SetConnectionOption(kBBHI);
1028 DefaultTopologyParams params;
1029 params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
1030 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
1031 CreateNetwork(params);
1032
1033 sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
1034
1035 simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
1036 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
1037 QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
1038
1039 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1040 sender_->ExportDebugState().bandwidth_est, 0.1f);
1041 EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
1042
1043 // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
1044 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
1045 TestLink()->set_bandwidth(params.test_link.bandwidth);
1046
1047 bool simulator_result = simulator_.RunUntilOrTimeout(
1048 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
1049 QuicTime::Delta::FromSeconds(50));
1050 EXPECT_TRUE(simulator_result);
1051 // Ensure the full bandwidth is discovered.
1052 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1053 sender_->ExportDebugState().bandwidth_hi, 0.02f);
1054 }
1055
1056 // Test Bbr2's reaction to a 100x bandwidth increase during a transfer with BBHI
1057 // in the presence of ACK aggregation.
TEST_F(Bbr2DefaultTopologyTest,QUIC_SLOW_TEST (BandwidthIncreaseBBHIAggregation))1058 TEST_F(Bbr2DefaultTopologyTest,
1059 QUIC_SLOW_TEST(BandwidthIncreaseBBHIAggregation)) {
1060 SetQuicReloadableFlag(quic_bbr2_simplify_inflight_hi, true);
1061 SetConnectionOption(kBBHI);
1062 DefaultTopologyParams params;
1063 params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
1064 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
1065 CreateNetwork(params);
1066
1067 // 2 RTTs of aggregation, with a max of 10kb.
1068 EnableAggregation(10 * 1024, 2 * params.RTT());
1069
1070 // Reduce the payload to 2MB because 10MB takes too long.
1071 sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
1072
1073 simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
1074 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
1075 QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
1076
1077 // This is much farther off when aggregation is present,
1078 // Ideally BSAO or another option would fix this.
1079 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1080 sender_->ExportDebugState().bandwidth_est, 0.60f);
1081 EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
1082
1083 // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
1084 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
1085 TestLink()->set_bandwidth(params.test_link.bandwidth);
1086
1087 bool simulator_result = simulator_.RunUntilOrTimeout(
1088 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
1089 QuicTime::Delta::FromSeconds(50));
1090 EXPECT_TRUE(simulator_result);
1091 // Ensure the full bandwidth is discovered.
1092 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1093 sender_->ExportDebugState().bandwidth_hi, 0.90f);
1094 }
1095
1096 // Test Bbr2's reaction to a 100x bandwidth increase during a transfer with BBHI
1097 // and B202, which changes the exit criteria to be based on
1098 // min_bytes_in_flight_in_round, in the presence of ACK aggregation.
TEST_F(Bbr2DefaultTopologyTest,QUIC_SLOW_TEST (BandwidthIncreaseBBHI_B202Aggregation))1099 TEST_F(Bbr2DefaultTopologyTest,
1100 QUIC_SLOW_TEST(BandwidthIncreaseBBHI_B202Aggregation)) {
1101 SetQuicReloadableFlag(quic_bbr2_simplify_inflight_hi, true);
1102 SetConnectionOption(kBBHI);
1103 SetConnectionOption(kB202);
1104 DefaultTopologyParams params;
1105 params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
1106 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
1107 CreateNetwork(params);
1108
1109 // 2 RTTs of aggregation, with a max of 10kb.
1110 EnableAggregation(10 * 1024, 2 * params.RTT());
1111
1112 // Reduce the payload to 2MB because 10MB takes too long.
1113 sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
1114
1115 simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
1116 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
1117 QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
1118
1119 // This is much farther off when aggregation is present,
1120 // Ideally BSAO or another option would fix this.
1121 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1122 sender_->ExportDebugState().bandwidth_est, 0.60f);
1123 EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
1124
1125 // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
1126 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
1127 TestLink()->set_bandwidth(params.test_link.bandwidth);
1128
1129 bool simulator_result = simulator_.RunUntilOrTimeout(
1130 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
1131 QuicTime::Delta::FromSeconds(50));
1132 EXPECT_TRUE(simulator_result);
1133 // Ensure at least 18% of the bandwidth is discovered.
1134 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1135 sender_->ExportDebugState().bandwidth_hi, 0.85f);
1136 }
1137
1138 // Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B204
TEST_F(Bbr2DefaultTopologyTest,QUIC_SLOW_TEST (BandwidthIncreaseB204))1139 TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB204)) {
1140 SetConnectionOption(kB204);
1141 DefaultTopologyParams params;
1142 params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
1143 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
1144 CreateNetwork(params);
1145
1146 sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
1147
1148 simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
1149 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
1150 QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
1151
1152 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1153 sender_->ExportDebugState().bandwidth_est, 0.1f);
1154 EXPECT_LE(sender_loss_rate_in_packets(), 0.25);
1155 EXPECT_LE(sender_->ExportDebugState().max_ack_height, 2000u);
1156
1157 // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
1158 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
1159 TestLink()->set_bandwidth(params.test_link.bandwidth);
1160
1161 bool simulator_result = simulator_.RunUntilOrTimeout(
1162 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
1163 QuicTime::Delta::FromSeconds(50));
1164 EXPECT_TRUE(simulator_result);
1165 // Ensure the full bandwidth is discovered.
1166 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1167 sender_->ExportDebugState().bandwidth_hi, 0.02f);
1168 }
1169
1170 // Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B204
1171 // in the presence of ACK aggregation.
TEST_F(Bbr2DefaultTopologyTest,QUIC_SLOW_TEST (BandwidthIncreaseB204Aggregation))1172 TEST_F(Bbr2DefaultTopologyTest,
1173 QUIC_SLOW_TEST(BandwidthIncreaseB204Aggregation)) {
1174 SetConnectionOption(kB204);
1175 DefaultTopologyParams params;
1176 params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
1177 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
1178 CreateNetwork(params);
1179
1180 // 2 RTTs of aggregation, with a max of 10kb.
1181 EnableAggregation(10 * 1024, 2 * params.RTT());
1182
1183 // Reduce the payload to 2MB because 10MB takes too long.
1184 sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
1185
1186 simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
1187 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
1188 QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
1189
1190 // This is much farther off when aggregation is present, and B204 actually
1191 // is increasing overestimation, which is surprising.
1192 // Ideally BSAO or another option would fix this.
1193 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1194 sender_->ExportDebugState().bandwidth_est, 0.60f);
1195 EXPECT_LE(sender_loss_rate_in_packets(), 0.35);
1196 EXPECT_LE(sender_->ExportDebugState().max_ack_height, 10000u);
1197
1198 // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
1199 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
1200 TestLink()->set_bandwidth(params.test_link.bandwidth);
1201
1202 bool simulator_result = simulator_.RunUntilOrTimeout(
1203 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
1204 QuicTime::Delta::FromSeconds(50));
1205 EXPECT_TRUE(simulator_result);
1206 // Ensure at least 10% of full bandwidth is discovered.
1207 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1208 sender_->ExportDebugState().bandwidth_hi, 0.95f);
1209 }
1210
1211 // Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B205
TEST_F(Bbr2DefaultTopologyTest,QUIC_SLOW_TEST (BandwidthIncreaseB205))1212 TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseB205)) {
1213 SetConnectionOption(kB205);
1214 DefaultTopologyParams params;
1215 params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
1216 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
1217 CreateNetwork(params);
1218
1219 sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
1220
1221 simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
1222 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
1223 QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
1224
1225 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1226 sender_->ExportDebugState().bandwidth_est, 0.1f);
1227 EXPECT_LE(sender_loss_rate_in_packets(), 0.10);
1228
1229 // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
1230 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
1231 TestLink()->set_bandwidth(params.test_link.bandwidth);
1232
1233 bool simulator_result = simulator_.RunUntilOrTimeout(
1234 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
1235 QuicTime::Delta::FromSeconds(50));
1236 EXPECT_TRUE(simulator_result);
1237 // Ensure the full bandwidth is discovered.
1238 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1239 sender_->ExportDebugState().bandwidth_hi, 0.1f);
1240 }
1241
1242 // Test Bbr2's reaction to a 100x bandwidth increase during a transfer with B205
1243 // in the presence of ACK aggregation.
TEST_F(Bbr2DefaultTopologyTest,QUIC_SLOW_TEST (BandwidthIncreaseB205Aggregation))1244 TEST_F(Bbr2DefaultTopologyTest,
1245 QUIC_SLOW_TEST(BandwidthIncreaseB205Aggregation)) {
1246 SetConnectionOption(kB205);
1247 DefaultTopologyParams params;
1248 params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
1249 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
1250 CreateNetwork(params);
1251
1252 // 2 RTTs of aggregation, with a max of 10kb.
1253 EnableAggregation(10 * 1024, 2 * params.RTT());
1254
1255 // Reduce the payload to 2MB because 10MB takes too long.
1256 sender_endpoint_.AddBytesToTransfer(2 * 1024 * 1024);
1257
1258 simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
1259 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
1260 QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
1261
1262 // This is much farther off when aggregation is present,
1263 // Ideally BSAO or another option would fix this.
1264 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1265 sender_->ExportDebugState().bandwidth_est, 0.45f);
1266 EXPECT_LE(sender_loss_rate_in_packets(), 0.15);
1267
1268 // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
1269 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
1270 TestLink()->set_bandwidth(params.test_link.bandwidth);
1271
1272 bool simulator_result = simulator_.RunUntilOrTimeout(
1273 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
1274 QuicTime::Delta::FromSeconds(50));
1275 EXPECT_TRUE(simulator_result);
1276 // Ensure at least 5% of full bandwidth is discovered.
1277 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1278 sender_->ExportDebugState().bandwidth_hi, 0.9f);
1279 }
1280
1281 // Test Bbr2's reaction to a 100x bandwidth increase during a transfer with BB2U
TEST_F(Bbr2DefaultTopologyTest,QUIC_SLOW_TEST (BandwidthIncreaseBB2U))1282 TEST_F(Bbr2DefaultTopologyTest, QUIC_SLOW_TEST(BandwidthIncreaseBB2U)) {
1283 SetQuicReloadableFlag(quic_bbr2_probe_two_rounds, true);
1284 SetConnectionOption(kBB2U);
1285 DefaultTopologyParams params;
1286 params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
1287 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
1288 CreateNetwork(params);
1289
1290 sender_endpoint_.AddBytesToTransfer(10 * 1024 * 1024);
1291
1292 simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
1293 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
1294 QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
1295
1296 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1297 sender_->ExportDebugState().bandwidth_est, 0.1f);
1298 EXPECT_LE(sender_loss_rate_in_packets(), 0.25);
1299
1300 // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
1301 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
1302 TestLink()->set_bandwidth(params.test_link.bandwidth);
1303
1304 bool simulator_result = simulator_.RunUntilOrTimeout(
1305 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
1306 QuicTime::Delta::FromSeconds(50));
1307 EXPECT_TRUE(simulator_result);
1308 // Ensure the full bandwidth is discovered.
1309 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1310 sender_->ExportDebugState().bandwidth_hi, 0.1f);
1311 }
1312
1313 // Test Bbr2's reaction to a 100x bandwidth increase during a transfer with BB2U
1314 // in the presence of ACK aggregation.
TEST_F(Bbr2DefaultTopologyTest,QUIC_SLOW_TEST (BandwidthIncreaseBB2UAggregation))1315 TEST_F(Bbr2DefaultTopologyTest,
1316 QUIC_SLOW_TEST(BandwidthIncreaseBB2UAggregation)) {
1317 SetQuicReloadableFlag(quic_bbr2_probe_two_rounds, true);
1318 SetConnectionOption(kBB2U);
1319 DefaultTopologyParams params;
1320 params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
1321 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
1322 CreateNetwork(params);
1323
1324 // 2 RTTs of aggregation, with a max of 10kb.
1325 EnableAggregation(10 * 1024, 2 * params.RTT());
1326
1327 // Reduce the payload to 5MB because 10MB takes too long.
1328 sender_endpoint_.AddBytesToTransfer(5 * 1024 * 1024);
1329
1330 simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
1331 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
1332 QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
1333
1334 // This is much farther off when aggregation is present,
1335 // Ideally BSAO or another option would fix this.
1336 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1337 sender_->ExportDebugState().bandwidth_est, 0.45f);
1338 EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
1339
1340 // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
1341 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
1342 TestLink()->set_bandwidth(params.test_link.bandwidth);
1343
1344 bool simulator_result = simulator_.RunUntilOrTimeout(
1345 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
1346 QuicTime::Delta::FromSeconds(50));
1347 EXPECT_TRUE(simulator_result);
1348 // Ensure at least 15% of the full bandwidth is observed.
1349 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1350 sender_->ExportDebugState().bandwidth_hi, 0.85f);
1351 }
1352
1353 // Test Bbr2's reaction to a 100x bandwidth increase during a transfer with BB2U
1354 // and BBHI in the presence of ACK aggregation.
TEST_F(Bbr2DefaultTopologyTest,QUIC_SLOW_TEST (BandwidthIncreaseBB2UandBBHIAggregation))1355 TEST_F(Bbr2DefaultTopologyTest,
1356 QUIC_SLOW_TEST(BandwidthIncreaseBB2UandBBHIAggregation)) {
1357 SetQuicReloadableFlag(quic_bbr2_probe_two_rounds, true);
1358 SetConnectionOption(kBB2U);
1359 SetQuicReloadableFlag(quic_bbr2_simplify_inflight_hi, true);
1360 SetConnectionOption(kBBHI);
1361 DefaultTopologyParams params;
1362 params.local_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(15000);
1363 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(100);
1364 CreateNetwork(params);
1365
1366 // 2 RTTs of aggregation, with a max of 10kb.
1367 EnableAggregation(10 * 1024, 2 * params.RTT());
1368
1369 // Reduce the payload to 5MB because 10MB takes too long.
1370 sender_endpoint_.AddBytesToTransfer(5 * 1024 * 1024);
1371
1372 simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
1373 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
1374 QUIC_LOG(INFO) << "Bandwidth increasing at time " << SimulatedNow();
1375
1376 // This is much farther off when aggregation is present,
1377 // Ideally BSAO or another option would fix this.
1378 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1379 sender_->ExportDebugState().bandwidth_est, 0.45f);
1380 EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
1381
1382 // Now increase the bottleneck bandwidth from 100Kbps to 10Mbps.
1383 params.test_link.bandwidth = QuicBandwidth::FromKBitsPerSecond(10000);
1384 TestLink()->set_bandwidth(params.test_link.bandwidth);
1385
1386 bool simulator_result = simulator_.RunUntilOrTimeout(
1387 [this]() { return sender_endpoint_.bytes_to_transfer() == 0; },
1388 QuicTime::Delta::FromSeconds(50));
1389 EXPECT_TRUE(simulator_result);
1390 // Ensure at least 15% of the full bandwidth is observed.
1391 EXPECT_APPROX_EQ(params.test_link.bandwidth,
1392 sender_->ExportDebugState().bandwidth_hi, 0.85f);
1393 }
1394
1395 // Test the number of losses incurred by the startup phase in a situation when
1396 // the buffer is less than BDP.
TEST_F(Bbr2DefaultTopologyTest,PacketLossOnSmallBufferStartup)1397 TEST_F(Bbr2DefaultTopologyTest, PacketLossOnSmallBufferStartup) {
1398 DefaultTopologyParams params;
1399 params.switch_queue_capacity_in_bdp = 0.5;
1400 CreateNetwork(params);
1401
1402 DriveOutOfStartup(params);
1403 // Packet loss is smaller with a CWND gain of 2 than 2.889.
1404 EXPECT_LE(sender_loss_rate_in_packets(), 0.05);
1405 }
1406
1407 // Test the number of losses decreases with packet-conservation pacing.
TEST_F(Bbr2DefaultTopologyTest,PacketLossBBQ6SmallBufferStartup)1408 TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ6SmallBufferStartup) {
1409 SetConnectionOption(kBBQ2); // Increase CWND gain.
1410 SetConnectionOption(kBBQ6);
1411 DefaultTopologyParams params;
1412 params.switch_queue_capacity_in_bdp = 0.5;
1413 CreateNetwork(params);
1414
1415 DriveOutOfStartup(params);
1416 EXPECT_LE(sender_loss_rate_in_packets(), 0.0575);
1417 // bandwidth_lo is cleared exiting STARTUP.
1418 EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
1419 QuicBandwidth::Infinite());
1420 }
1421
1422 // Test the number of losses decreases with min_rtt packet-conservation pacing.
TEST_F(Bbr2DefaultTopologyTest,PacketLossBBQ7SmallBufferStartup)1423 TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ7SmallBufferStartup) {
1424 SetConnectionOption(kBBQ2); // Increase CWND gain.
1425 SetConnectionOption(kBBQ7);
1426 DefaultTopologyParams params;
1427 params.switch_queue_capacity_in_bdp = 0.5;
1428 CreateNetwork(params);
1429
1430 DriveOutOfStartup(params);
1431 EXPECT_LE(sender_loss_rate_in_packets(), 0.06);
1432 // bandwidth_lo is cleared exiting STARTUP.
1433 EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
1434 QuicBandwidth::Infinite());
1435 }
1436
1437 // Test the number of losses decreases with Inflight packet-conservation pacing.
TEST_F(Bbr2DefaultTopologyTest,PacketLossBBQ8SmallBufferStartup)1438 TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ8SmallBufferStartup) {
1439 SetConnectionOption(kBBQ2); // Increase CWND gain.
1440 SetConnectionOption(kBBQ8);
1441 DefaultTopologyParams params;
1442 params.switch_queue_capacity_in_bdp = 0.5;
1443 CreateNetwork(params);
1444
1445 DriveOutOfStartup(params);
1446 EXPECT_LE(sender_loss_rate_in_packets(), 0.065);
1447 // bandwidth_lo is cleared exiting STARTUP.
1448 EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
1449 QuicBandwidth::Infinite());
1450 }
1451
1452 // Test the number of losses decreases with CWND packet-conservation pacing.
TEST_F(Bbr2DefaultTopologyTest,PacketLossBBQ9SmallBufferStartup)1453 TEST_F(Bbr2DefaultTopologyTest, PacketLossBBQ9SmallBufferStartup) {
1454 SetConnectionOption(kBBQ2); // Increase CWND gain.
1455 SetConnectionOption(kBBQ9);
1456 DefaultTopologyParams params;
1457 params.switch_queue_capacity_in_bdp = 0.5;
1458 CreateNetwork(params);
1459
1460 DriveOutOfStartup(params);
1461 EXPECT_LE(sender_loss_rate_in_packets(), 0.065);
1462 // bandwidth_lo is cleared exiting STARTUP.
1463 EXPECT_EQ(sender_->ExportDebugState().bandwidth_lo,
1464 QuicBandwidth::Infinite());
1465 }
1466
1467 // Verify the behavior of the algorithm in the case when the connection sends
1468 // small bursts of data after sending continuously for a while.
TEST_F(Bbr2DefaultTopologyTest,ApplicationLimitedBursts)1469 TEST_F(Bbr2DefaultTopologyTest, ApplicationLimitedBursts) {
1470 DefaultTopologyParams params;
1471 CreateNetwork(params);
1472
1473 EXPECT_FALSE(sender_->HasGoodBandwidthEstimateForResumption());
1474 DriveOutOfStartup(params);
1475 EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
1476 EXPECT_TRUE(sender_->HasGoodBandwidthEstimateForResumption());
1477
1478 SendBursts(params, 20, 512, QuicTime::Delta::FromSeconds(3));
1479 EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
1480 EXPECT_TRUE(sender_->HasGoodBandwidthEstimateForResumption());
1481 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
1482 sender_->ExportDebugState().bandwidth_hi, 0.01f);
1483 }
1484
1485 // Verify the behavior of the algorithm in the case when the connection sends
1486 // small bursts of data and then starts sending continuously.
TEST_F(Bbr2DefaultTopologyTest,ApplicationLimitedBurstsWithoutPrior)1487 TEST_F(Bbr2DefaultTopologyTest, ApplicationLimitedBurstsWithoutPrior) {
1488 DefaultTopologyParams params;
1489 CreateNetwork(params);
1490
1491 SendBursts(params, 40, 512, QuicTime::Delta::FromSeconds(3));
1492 EXPECT_TRUE(sender_->ExportDebugState().last_sample_is_app_limited);
1493
1494 DriveOutOfStartup(params);
1495 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
1496 sender_->ExportDebugState().bandwidth_hi, 0.01f);
1497 EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
1498 }
1499
1500 // Verify that the DRAIN phase works correctly.
TEST_F(Bbr2DefaultTopologyTest,Drain)1501 TEST_F(Bbr2DefaultTopologyTest, Drain) {
1502 DefaultTopologyParams params;
1503 CreateNetwork(params);
1504
1505 const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
1506 // Get the queue at the bottleneck, which is the outgoing queue at the port to
1507 // which the receiver is connected.
1508 const simulator::Queue* queue = switch_->port_queue(2);
1509 bool simulator_result;
1510
1511 // We have no intention of ever finishing this transfer.
1512 sender_endpoint_.AddBytesToTransfer(100 * 1024 * 1024);
1513
1514 // Run the startup, and verify that it fills up the queue.
1515 ASSERT_EQ(Bbr2Mode::STARTUP, sender_->ExportDebugState().mode);
1516 simulator_result = simulator_.RunUntilOrTimeout(
1517 [this]() {
1518 return sender_->ExportDebugState().mode != Bbr2Mode::STARTUP;
1519 },
1520 timeout);
1521 ASSERT_TRUE(simulator_result);
1522 ASSERT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
1523 EXPECT_APPROX_EQ(sender_->BandwidthEstimate() * (1 / 2.885f),
1524 sender_->PacingRate(0), 0.01f);
1525
1526 // BBR uses CWND gain of 2 during STARTUP, hence it will fill the buffer with
1527 // approximately 1 BDP. Here, we use 0.95 to give some margin for error.
1528 EXPECT_GE(queue->bytes_queued(), 0.95 * params.BDP());
1529
1530 // Observe increased RTT due to bufferbloat.
1531 const QuicTime::Delta queueing_delay =
1532 params.test_link.bandwidth.TransferTime(queue->bytes_queued());
1533 EXPECT_APPROX_EQ(params.RTT() + queueing_delay, rtt_stats()->latest_rtt(),
1534 0.1f);
1535
1536 // Transition to the drain phase and verify that it makes the queue
1537 // have at most a BDP worth of packets.
1538 simulator_result = simulator_.RunUntilOrTimeout(
1539 [this]() { return sender_->ExportDebugState().mode != Bbr2Mode::DRAIN; },
1540 timeout);
1541 ASSERT_TRUE(simulator_result);
1542 ASSERT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
1543 EXPECT_LE(queue->bytes_queued(), params.BDP());
1544
1545 // Wait for a few round trips and ensure we're in appropriate phase of gain
1546 // cycling before taking an RTT measurement.
1547 const QuicRoundTripCount start_round_trip =
1548 sender_->ExportDebugState().round_trip_count;
1549 simulator_result = simulator_.RunUntilOrTimeout(
1550 [this, start_round_trip]() {
1551 const auto& debug_state = sender_->ExportDebugState();
1552 QuicRoundTripCount rounds_passed =
1553 debug_state.round_trip_count - start_round_trip;
1554 return rounds_passed >= 4 && debug_state.mode == Bbr2Mode::PROBE_BW &&
1555 debug_state.probe_bw.phase == CyclePhase::PROBE_REFILL;
1556 },
1557 timeout);
1558 ASSERT_TRUE(simulator_result);
1559
1560 // Observe the bufferbloat go away.
1561 EXPECT_APPROX_EQ(params.RTT(), rtt_stats()->smoothed_rtt(), 0.1f);
1562 }
1563
1564 // Ensure that a connection that is app-limited and is at sufficiently low
1565 // bandwidth will not exit high gain phase, and similarly ensure that the
1566 // connection will exit low gain early if the number of bytes in flight is low.
TEST_F(Bbr2DefaultTopologyTest,InFlightAwareGainCycling)1567 TEST_F(Bbr2DefaultTopologyTest, InFlightAwareGainCycling) {
1568 DefaultTopologyParams params;
1569 CreateNetwork(params);
1570 DriveOutOfStartup(params);
1571
1572 const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
1573 bool simulator_result;
1574
1575 // Start a few cycles prior to the high gain one.
1576 simulator_result = SendUntilOrTimeout(
1577 [this]() {
1578 return sender_->ExportDebugState().probe_bw.phase ==
1579 CyclePhase::PROBE_REFILL;
1580 },
1581 timeout);
1582 ASSERT_TRUE(simulator_result);
1583
1584 // Send at 10% of available rate. Run for 3 seconds, checking in the middle
1585 // and at the end. The pacing gain should be high throughout.
1586 QuicBandwidth target_bandwidth = 0.1f * params.BottleneckBandwidth();
1587 QuicTime::Delta burst_interval = QuicTime::Delta::FromMilliseconds(300);
1588 for (int i = 0; i < 2; i++) {
1589 SendBursts(params, 5, target_bandwidth * burst_interval, burst_interval);
1590 EXPECT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
1591 EXPECT_EQ(CyclePhase::PROBE_UP, sender_->ExportDebugState().probe_bw.phase);
1592 EXPECT_APPROX_EQ(params.BottleneckBandwidth(),
1593 sender_->ExportDebugState().bandwidth_hi, 0.02f);
1594 }
1595
1596 if (GetQuicReloadableFlag(quic_pacing_remove_non_initial_burst)) {
1597 QuicSentPacketManagerPeer::GetPacingSender(
1598 &sender_connection()->sent_packet_manager())
1599 ->SetBurstTokens(10);
1600 }
1601
1602 // Now that in-flight is almost zero and the pacing gain is still above 1,
1603 // send approximately 1.4 BDPs worth of data. This should cause the PROBE_BW
1604 // mode to enter low gain cycle(PROBE_DOWN), and exit it earlier than one
1605 // min_rtt due to running out of data to send.
1606 sender_endpoint_.AddBytesToTransfer(1.4 * params.BDP());
1607 simulator_result = simulator_.RunUntilOrTimeout(
1608 [this]() {
1609 return sender_->ExportDebugState().probe_bw.phase ==
1610 CyclePhase::PROBE_DOWN;
1611 },
1612 timeout);
1613 ASSERT_TRUE(simulator_result);
1614 simulator_.RunFor(0.75 * sender_->ExportDebugState().min_rtt);
1615 EXPECT_EQ(Bbr2Mode::PROBE_BW, sender_->ExportDebugState().mode);
1616 EXPECT_EQ(CyclePhase::PROBE_CRUISE,
1617 sender_->ExportDebugState().probe_bw.phase);
1618 }
1619
1620 // Test exiting STARTUP earlier upon loss due to loss.
TEST_F(Bbr2DefaultTopologyTest,ExitStartupDueToLoss)1621 TEST_F(Bbr2DefaultTopologyTest, ExitStartupDueToLoss) {
1622 DefaultTopologyParams params;
1623 params.switch_queue_capacity_in_bdp = 0.5;
1624 CreateNetwork(params);
1625
1626 // Run until the full bandwidth is reached and check how many rounds it was.
1627 sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
1628 QuicRoundTripCount max_bw_round = 0;
1629 QuicBandwidth max_bw(QuicBandwidth::Zero());
1630 bool simulator_result = simulator_.RunUntilOrTimeout(
1631 [this, &max_bw, &max_bw_round]() {
1632 if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
1633 max_bw = sender_->ExportDebugState().bandwidth_hi;
1634 max_bw_round = sender_->ExportDebugState().round_trip_count;
1635 }
1636 return sender_->ExportDebugState().startup.full_bandwidth_reached;
1637 },
1638 QuicTime::Delta::FromSeconds(5));
1639 ASSERT_TRUE(simulator_result);
1640 EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
1641 EXPECT_GE(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
1642 EXPECT_EQ(
1643 1u,
1644 sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
1645 EXPECT_NE(0u, sender_connection_stats().packets_lost);
1646 EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
1647
1648 EXPECT_GT(sender_->ExportDebugState().inflight_hi, 1.2f * params.BDP());
1649 }
1650
1651 // Test exiting STARTUP earlier upon loss due to loss when connection option
1652 // B2SL is used.
TEST_F(Bbr2DefaultTopologyTest,ExitStartupDueToLossB2SL)1653 TEST_F(Bbr2DefaultTopologyTest, ExitStartupDueToLossB2SL) {
1654 SetConnectionOption(kB2SL);
1655 DefaultTopologyParams params;
1656 params.switch_queue_capacity_in_bdp = 0.5;
1657 CreateNetwork(params);
1658
1659 // Run until the full bandwidth is reached and check how many rounds it was.
1660 sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
1661 QuicRoundTripCount max_bw_round = 0;
1662 QuicBandwidth max_bw(QuicBandwidth::Zero());
1663 bool simulator_result = simulator_.RunUntilOrTimeout(
1664 [this, &max_bw, &max_bw_round]() {
1665 if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
1666 max_bw = sender_->ExportDebugState().bandwidth_hi;
1667 max_bw_round = sender_->ExportDebugState().round_trip_count;
1668 }
1669 return sender_->ExportDebugState().startup.full_bandwidth_reached;
1670 },
1671 QuicTime::Delta::FromSeconds(5));
1672 ASSERT_TRUE(simulator_result);
1673 EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
1674 EXPECT_GE(2u, sender_->ExportDebugState().round_trip_count - max_bw_round);
1675 EXPECT_EQ(
1676 1u,
1677 sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
1678 EXPECT_NE(0u, sender_connection_stats().packets_lost);
1679 EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
1680
1681 EXPECT_APPROX_EQ(sender_->ExportDebugState().inflight_hi, params.BDP(), 0.1f);
1682 }
1683
1684 // Verifies that in STARTUP, if we exceed loss threshold in a round, we exit
1685 // STARTUP at the end of the round even if there's enough bandwidth growth.
TEST_F(Bbr2DefaultTopologyTest,ExitStartupDueToLossB2NE)1686 TEST_F(Bbr2DefaultTopologyTest, ExitStartupDueToLossB2NE) {
1687 // Set up flags such that any loss will be considered "too high".
1688 SetQuicFlag(quic_bbr2_default_startup_full_loss_count, 0);
1689 SetQuicFlag(quic_bbr2_default_loss_threshold, 0.0);
1690
1691 sender_ = SetupBbr2Sender(&sender_endpoint_, /*old_sender=*/nullptr);
1692
1693 SetConnectionOption(kB2NE);
1694 DefaultTopologyParams params;
1695 params.switch_queue_capacity_in_bdp = 0.5;
1696 CreateNetwork(params);
1697
1698 // Run until the full bandwidth is reached and check how many rounds it was.
1699 sender_endpoint_.AddBytesToTransfer(12 * 1024 * 1024);
1700 QuicRoundTripCount max_bw_round = 0;
1701 QuicBandwidth max_bw(QuicBandwidth::Zero());
1702 bool simulator_result = simulator_.RunUntilOrTimeout(
1703 [this, &max_bw, &max_bw_round]() {
1704 if (max_bw < sender_->ExportDebugState().bandwidth_hi) {
1705 max_bw = sender_->ExportDebugState().bandwidth_hi;
1706 max_bw_round = sender_->ExportDebugState().round_trip_count;
1707 }
1708 return sender_->ExportDebugState().startup.full_bandwidth_reached;
1709 },
1710 QuicTime::Delta::FromSeconds(5));
1711 ASSERT_TRUE(simulator_result);
1712 EXPECT_EQ(Bbr2Mode::DRAIN, sender_->ExportDebugState().mode);
1713 EXPECT_EQ(sender_->ExportDebugState().round_trip_count, max_bw_round);
1714 EXPECT_EQ(
1715 0u,
1716 sender_->ExportDebugState().startup.round_trips_without_bandwidth_growth);
1717 EXPECT_NE(0u, sender_connection_stats().packets_lost);
1718 }
1719
TEST_F(Bbr2DefaultTopologyTest,SenderPoliced)1720 TEST_F(Bbr2DefaultTopologyTest, SenderPoliced) {
1721 DefaultTopologyParams params;
1722 params.sender_policer_params = TrafficPolicerParams();
1723 params.sender_policer_params->initial_burst_size = 1000 * 10;
1724 params.sender_policer_params->max_bucket_size = 1000 * 100;
1725 params.sender_policer_params->target_bandwidth =
1726 params.BottleneckBandwidth() * 0.25;
1727
1728 CreateNetwork(params);
1729
1730 ASSERT_GE(params.BDP(), kDefaultInitialCwndBytes + kDefaultTCPMSS);
1731
1732 DoSimpleTransfer(3 * 1024 * 1024, QuicTime::Delta::FromSeconds(30));
1733 EXPECT_TRUE(Bbr2ModeIsOneOf({Bbr2Mode::PROBE_BW, Bbr2Mode::PROBE_RTT}));
1734 // TODO(wub): Fix (long-term) bandwidth overestimation in policer mode, then
1735 // reduce the loss rate upper bound.
1736 EXPECT_LE(sender_loss_rate_in_packets(), 0.30);
1737 }
1738
1739 // TODO(wub): Add other slowstart stats to BBRv2.
TEST_F(Bbr2DefaultTopologyTest,StartupStats)1740 TEST_F(Bbr2DefaultTopologyTest, StartupStats) {
1741 DefaultTopologyParams params;
1742 CreateNetwork(params);
1743
1744 DriveOutOfStartup(params);
1745 ASSERT_FALSE(sender_->InSlowStart());
1746
1747 const QuicConnectionStats& stats = sender_connection_stats();
1748 // The test explicitly replaces the default-created send algorithm with the
1749 // one created by the test. slowstart_count increaments every time a BBR
1750 // sender is created.
1751 EXPECT_GE(stats.slowstart_count, 1u);
1752 EXPECT_FALSE(stats.slowstart_duration.IsRunning());
1753 EXPECT_THAT(stats.slowstart_duration.GetTotalElapsedTime(),
1754 AllOf(Ge(QuicTime::Delta::FromMilliseconds(500)),
1755 Le(QuicTime::Delta::FromMilliseconds(1500))));
1756 EXPECT_EQ(stats.slowstart_duration.GetTotalElapsedTime(),
1757 QuicConnectionPeer::GetSentPacketManager(sender_connection())
1758 ->GetSlowStartDuration());
1759 }
1760
TEST_F(Bbr2DefaultTopologyTest,ProbeUpAdaptInflightHiGradually)1761 TEST_F(Bbr2DefaultTopologyTest, ProbeUpAdaptInflightHiGradually) {
1762 DefaultTopologyParams params;
1763 CreateNetwork(params);
1764
1765 DriveOutOfStartup(params);
1766
1767 AckedPacketVector acked_packets;
1768 QuicPacketNumber acked_packet_number =
1769 sender_unacked_map()->GetLeastUnacked();
1770 for (auto& info : *sender_unacked_map()) {
1771 acked_packets.emplace_back(acked_packet_number++, info.bytes_sent,
1772 SimulatedNow());
1773 }
1774
1775 // Advance time significantly so the OnCongestionEvent enters PROBE_REFILL.
1776 QuicTime now = SimulatedNow() + QuicTime::Delta::FromSeconds(5);
1777 auto next_packet_number = sender_unacked_map()->largest_sent_packet() + 1;
1778 sender_->OnCongestionEvent(
1779 /*rtt_updated=*/true, sender_unacked_map()->bytes_in_flight(), now,
1780 acked_packets, {}, 0, 0);
1781 ASSERT_EQ(CyclePhase::PROBE_REFILL,
1782 sender_->ExportDebugState().probe_bw.phase);
1783
1784 // Send and Ack one packet to exit app limited and enter PROBE_UP.
1785 sender_->OnPacketSent(now, /*bytes_in_flight=*/0, next_packet_number++,
1786 kDefaultMaxPacketSize, HAS_RETRANSMITTABLE_DATA);
1787 now = now + params.RTT();
1788 sender_->OnCongestionEvent(
1789 /*rtt_updated=*/true, kDefaultMaxPacketSize, now,
1790 {AckedPacket(next_packet_number - 1, kDefaultMaxPacketSize, now)}, {}, 0,
1791 0);
1792 ASSERT_EQ(CyclePhase::PROBE_UP, sender_->ExportDebugState().probe_bw.phase);
1793
1794 // Send 2 packets and lose the first one(50% loss) to exit PROBE_UP.
1795 for (uint64_t i = 0; i < 2; ++i) {
1796 sender_->OnPacketSent(now, /*bytes_in_flight=*/i * kDefaultMaxPacketSize,
1797 next_packet_number++, kDefaultMaxPacketSize,
1798 HAS_RETRANSMITTABLE_DATA);
1799 }
1800 now = now + params.RTT();
1801 sender_->OnCongestionEvent(
1802 /*rtt_updated=*/true, kDefaultMaxPacketSize, now,
1803 {AckedPacket(next_packet_number - 1, kDefaultMaxPacketSize, now)},
1804 {LostPacket(next_packet_number - 2, kDefaultMaxPacketSize)}, 0, 0);
1805
1806 QuicByteCount inflight_hi = sender_->ExportDebugState().inflight_hi;
1807 EXPECT_LT(2 * kDefaultMaxPacketSize, inflight_hi);
1808 }
1809
1810 // Ensures bandwidth estimate does not change after a loss only event.
TEST_F(Bbr2DefaultTopologyTest,LossOnlyCongestionEvent)1811 TEST_F(Bbr2DefaultTopologyTest, LossOnlyCongestionEvent) {
1812 DefaultTopologyParams params;
1813 CreateNetwork(params);
1814
1815 DriveOutOfStartup(params);
1816 EXPECT_FALSE(sender_->ExportDebugState().last_sample_is_app_limited);
1817
1818 // Send some bursts, each burst increments round count by 1, since it only
1819 // generates small, app-limited samples, the max_bandwidth_filter_ will not be
1820 // updated.
1821 SendBursts(params, 20, 512, QuicTime::Delta::FromSeconds(3));
1822
1823 // Run until we have something in flight.
1824 sender_endpoint_.AddBytesToTransfer(50 * 1024 * 1024);
1825 bool simulator_result = simulator_.RunUntilOrTimeout(
1826 [&]() { return sender_unacked_map()->bytes_in_flight() > 0; },
1827 QuicTime::Delta::FromSeconds(5));
1828 ASSERT_TRUE(simulator_result);
1829
1830 const QuicBandwidth prior_bandwidth_estimate = sender_->BandwidthEstimate();
1831 EXPECT_APPROX_EQ(params.BottleneckBandwidth(), prior_bandwidth_estimate,
1832 0.01f);
1833
1834 // Lose the least unacked packet.
1835 LostPacketVector lost_packets;
1836 lost_packets.emplace_back(
1837 sender_connection()->sent_packet_manager().GetLeastUnacked(),
1838 kDefaultMaxPacketSize);
1839
1840 QuicTime now = simulator_.GetClock()->Now() + params.RTT() * 0.25;
1841 sender_->OnCongestionEvent(false, sender_unacked_map()->bytes_in_flight(),
1842 now, {}, lost_packets, 0, 0);
1843
1844 // Bandwidth estimate should not change for the loss only event.
1845 EXPECT_EQ(prior_bandwidth_estimate, sender_->BandwidthEstimate());
1846 }
1847
1848 // After quiescence, if the sender is in PROBE_RTT, it should transition to
1849 // PROBE_BW immediately on the first sent packet after quiescence.
TEST_F(Bbr2DefaultTopologyTest,ProbeRttAfterQuiescenceImmediatelyExits)1850 TEST_F(Bbr2DefaultTopologyTest, ProbeRttAfterQuiescenceImmediatelyExits) {
1851 DefaultTopologyParams params;
1852 CreateNetwork(params);
1853
1854 DriveOutOfStartup(params);
1855
1856 const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(15);
1857 bool simulator_result;
1858
1859 // Keep sending until reach PROBE_RTT.
1860 simulator_result = SendUntilOrTimeout(
1861 [this]() {
1862 return sender_->ExportDebugState().mode == Bbr2Mode::PROBE_RTT;
1863 },
1864 timeout);
1865 ASSERT_TRUE(simulator_result);
1866
1867 // Wait for entering a quiescence of 5 seconds.
1868 ASSERT_TRUE(simulator_.RunUntilOrTimeout(
1869 [this]() {
1870 return sender_unacked_map()->bytes_in_flight() == 0 &&
1871 sender_->ExportDebugState().mode == Bbr2Mode::PROBE_RTT;
1872 },
1873 timeout));
1874
1875 simulator_.RunFor(QuicTime::Delta::FromSeconds(5));
1876
1877 // Send one packet to exit quiescence.
1878 EXPECT_EQ(sender_->ExportDebugState().mode, Bbr2Mode::PROBE_RTT);
1879 sender_->OnPacketSent(SimulatedNow(), /*bytes_in_flight=*/0,
1880 sender_unacked_map()->largest_sent_packet() + 1,
1881 kDefaultMaxPacketSize, HAS_RETRANSMITTABLE_DATA);
1882
1883 EXPECT_EQ(sender_->ExportDebugState().mode, Bbr2Mode::PROBE_BW);
1884 }
1885
TEST_F(Bbr2DefaultTopologyTest,ProbeBwAfterQuiescencePostponeMinRttTimestamp)1886 TEST_F(Bbr2DefaultTopologyTest, ProbeBwAfterQuiescencePostponeMinRttTimestamp) {
1887 DefaultTopologyParams params;
1888 CreateNetwork(params);
1889
1890 DriveOutOfStartup(params);
1891
1892 const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
1893 bool simulator_result;
1894
1895 // Keep sending until reach PROBE_REFILL.
1896 simulator_result = SendUntilOrTimeout(
1897 [this]() {
1898 return sender_->ExportDebugState().probe_bw.phase ==
1899 CyclePhase::PROBE_REFILL;
1900 },
1901 timeout);
1902 ASSERT_TRUE(simulator_result);
1903
1904 const QuicTime min_rtt_timestamp_before_idle =
1905 sender_->ExportDebugState().min_rtt_timestamp;
1906
1907 // Wait for entering a quiescence of 15 seconds.
1908 ASSERT_TRUE(simulator_.RunUntilOrTimeout(
1909 [this]() { return sender_unacked_map()->bytes_in_flight() == 0; },
1910 params.RTT() + timeout));
1911
1912 simulator_.RunFor(QuicTime::Delta::FromSeconds(15));
1913
1914 // Send some data to exit quiescence.
1915 SendBursts(params, 1, kDefaultTCPMSS, QuicTime::Delta::Zero());
1916 const QuicTime min_rtt_timestamp_after_idle =
1917 sender_->ExportDebugState().min_rtt_timestamp;
1918
1919 EXPECT_LT(min_rtt_timestamp_before_idle + QuicTime::Delta::FromSeconds(14),
1920 min_rtt_timestamp_after_idle);
1921 }
1922
TEST_F(Bbr2DefaultTopologyTest,SwitchToBbr2MidConnection)1923 TEST_F(Bbr2DefaultTopologyTest, SwitchToBbr2MidConnection) {
1924 QuicTime now = QuicTime::Zero();
1925 BbrSender old_sender(sender_connection()->clock()->Now(),
1926 sender_connection()->sent_packet_manager().GetRttStats(),
1927 GetUnackedMap(sender_connection()),
1928 kDefaultInitialCwndPackets + 1,
1929 GetQuicFlag(quic_max_congestion_window), &random_,
1930 QuicConnectionPeer::GetStats(sender_connection()));
1931
1932 QuicPacketNumber next_packet_number(1);
1933
1934 // Send packets 1-4.
1935 while (next_packet_number < QuicPacketNumber(5)) {
1936 now = now + QuicTime::Delta::FromMilliseconds(10);
1937
1938 old_sender.OnPacketSent(now, /*bytes_in_flight=*/0, next_packet_number++,
1939 /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
1940 }
1941
1942 // Switch from |old_sender| to |sender_|.
1943 const QuicByteCount old_sender_cwnd = old_sender.GetCongestionWindow();
1944 sender_ = SetupBbr2Sender(&sender_endpoint_, &old_sender);
1945 EXPECT_EQ(old_sender_cwnd, sender_->GetCongestionWindow());
1946
1947 // Send packets 5-7.
1948 now = now + QuicTime::Delta::FromMilliseconds(10);
1949 sender_->OnPacketSent(now, /*bytes_in_flight=*/1350, next_packet_number++,
1950 /*bytes=*/23, NO_RETRANSMITTABLE_DATA);
1951
1952 now = now + QuicTime::Delta::FromMilliseconds(10);
1953 sender_->OnPacketSent(now, /*bytes_in_flight=*/1350, next_packet_number++,
1954 /*bytes=*/767, HAS_RETRANSMITTABLE_DATA);
1955
1956 QuicByteCount bytes_in_flight = 767;
1957 while (next_packet_number < QuicPacketNumber(30)) {
1958 now = now + QuicTime::Delta::FromMilliseconds(10);
1959 bytes_in_flight += 1350;
1960 sender_->OnPacketSent(now, bytes_in_flight, next_packet_number++,
1961 /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
1962 }
1963
1964 // Ack 1 & 2.
1965 AckedPacketVector acked = {
1966 AckedPacket(QuicPacketNumber(1), /*bytes_acked=*/0, QuicTime::Zero()),
1967 AckedPacket(QuicPacketNumber(2), /*bytes_acked=*/0, QuicTime::Zero()),
1968 };
1969 now = now + QuicTime::Delta::FromMilliseconds(2000);
1970 sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {}, 0, 0);
1971
1972 // Send 30-41.
1973 while (next_packet_number < QuicPacketNumber(42)) {
1974 now = now + QuicTime::Delta::FromMilliseconds(10);
1975 bytes_in_flight += 1350;
1976 sender_->OnPacketSent(now, bytes_in_flight, next_packet_number++,
1977 /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
1978 }
1979
1980 // Ack 3.
1981 acked = {
1982 AckedPacket(QuicPacketNumber(3), /*bytes_acked=*/0, QuicTime::Zero()),
1983 };
1984 now = now + QuicTime::Delta::FromMilliseconds(2000);
1985 sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {}, 0, 0);
1986
1987 // Send 42.
1988 now = now + QuicTime::Delta::FromMilliseconds(10);
1989 bytes_in_flight += 1350;
1990 sender_->OnPacketSent(now, bytes_in_flight, next_packet_number++,
1991 /*bytes=*/1350, HAS_RETRANSMITTABLE_DATA);
1992
1993 // Ack 4-7.
1994 acked = {
1995 AckedPacket(QuicPacketNumber(4), /*bytes_acked=*/0, QuicTime::Zero()),
1996 AckedPacket(QuicPacketNumber(5), /*bytes_acked=*/0, QuicTime::Zero()),
1997 AckedPacket(QuicPacketNumber(6), /*bytes_acked=*/767, QuicTime::Zero()),
1998 AckedPacket(QuicPacketNumber(7), /*bytes_acked=*/1350, QuicTime::Zero()),
1999 };
2000 now = now + QuicTime::Delta::FromMilliseconds(2000);
2001 sender_->OnCongestionEvent(true, bytes_in_flight, now, acked, {}, 0, 0);
2002 EXPECT_FALSE(sender_->BandwidthEstimate().IsZero());
2003 }
2004
TEST_F(Bbr2DefaultTopologyTest,AdjustNetworkParameters)2005 TEST_F(Bbr2DefaultTopologyTest, AdjustNetworkParameters) {
2006 DefaultTopologyParams params;
2007 CreateNetwork(params);
2008
2009 QUIC_LOG(INFO) << "Initial cwnd: " << sender_debug_state().congestion_window
2010 << "\nInitial pacing rate: " << sender_->PacingRate(0)
2011 << "\nInitial bandwidth estimate: "
2012 << sender_->BandwidthEstimate()
2013 << "\nInitial rtt: " << sender_debug_state().min_rtt;
2014
2015 sender_connection()->AdjustNetworkParameters(
2016 SendAlgorithmInterface::NetworkParams(params.BottleneckBandwidth(),
2017 params.RTT(),
2018 /*allow_cwnd_to_decrease=*/false));
2019
2020 EXPECT_EQ(params.BDP(), sender_->ExportDebugState().congestion_window);
2021
2022 EXPECT_EQ(params.BottleneckBandwidth(),
2023 sender_->PacingRate(/*bytes_in_flight=*/0));
2024 EXPECT_NE(params.BottleneckBandwidth(), sender_->BandwidthEstimate());
2025
2026 EXPECT_APPROX_EQ(params.RTT(), sender_->ExportDebugState().min_rtt, 0.01f);
2027
2028 DriveOutOfStartup(params);
2029 }
2030
2031 TEST_F(Bbr2DefaultTopologyTest,
2032 200InitialCongestionWindowWithNetworkParameterAdjusted) {
2033 DefaultTopologyParams params;
2034 CreateNetwork(params);
2035
2036 sender_endpoint_.AddBytesToTransfer(1 * 1024 * 1024);
2037
2038 // Wait until an ACK comes back.
2039 const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
2040 bool simulator_result = simulator_.RunUntilOrTimeout(
__anon162b1ffc2602() 2041 [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
2042 timeout);
2043 ASSERT_TRUE(simulator_result);
2044
2045 // Bootstrap cwnd by a overly large bandwidth sample.
2046 sender_connection()->AdjustNetworkParameters(
2047 SendAlgorithmInterface::NetworkParams(1024 * params.BottleneckBandwidth(),
2048 QuicTime::Delta::Zero(), false));
2049
2050 // Verify cwnd is capped at 200.
2051 EXPECT_EQ(200 * kDefaultTCPMSS,
2052 sender_->ExportDebugState().congestion_window);
2053 EXPECT_GT(1024 * params.BottleneckBandwidth(), sender_->PacingRate(0));
2054 }
2055
2056 TEST_F(Bbr2DefaultTopologyTest,
2057 100InitialCongestionWindowFromNetworkParameter) {
2058 DefaultTopologyParams params;
2059 CreateNetwork(params);
2060
2061 sender_endpoint_.AddBytesToTransfer(1 * 1024 * 1024);
2062 // Wait until an ACK comes back.
2063 const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
2064 bool simulator_result = simulator_.RunUntilOrTimeout(
__anon162b1ffc2702() 2065 [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
2066 timeout);
2067 ASSERT_TRUE(simulator_result);
2068
2069 // Bootstrap cwnd by a overly large bandwidth sample.
2070 SendAlgorithmInterface::NetworkParams network_params(
2071 1024 * params.BottleneckBandwidth(), QuicTime::Delta::Zero(), false);
2072 network_params.max_initial_congestion_window = 100;
2073 sender_connection()->AdjustNetworkParameters(network_params);
2074
2075 // Verify cwnd is capped at 100.
2076 EXPECT_EQ(100 * kDefaultTCPMSS,
2077 sender_->ExportDebugState().congestion_window);
2078 EXPECT_GT(1024 * params.BottleneckBandwidth(), sender_->PacingRate(0));
2079 }
2080
2081 TEST_F(Bbr2DefaultTopologyTest,
2082 100InitialCongestionWindowWithNetworkParameterAdjusted) {
2083 SetConnectionOption(kICW1);
2084 DefaultTopologyParams params;
2085 CreateNetwork(params);
2086
2087 sender_endpoint_.AddBytesToTransfer(1 * 1024 * 1024);
2088 // Wait until an ACK comes back.
2089 const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(5);
2090 bool simulator_result = simulator_.RunUntilOrTimeout(
__anon162b1ffc2802() 2091 [this]() { return !sender_->ExportDebugState().min_rtt.IsZero(); },
2092 timeout);
2093 ASSERT_TRUE(simulator_result);
2094
2095 // Bootstrap cwnd by a overly large bandwidth sample.
2096 sender_connection()->AdjustNetworkParameters(
2097 SendAlgorithmInterface::NetworkParams(1024 * params.BottleneckBandwidth(),
2098 QuicTime::Delta::Zero(), false));
2099
2100 // Verify cwnd is capped at 100.
2101 EXPECT_EQ(100 * kDefaultTCPMSS,
2102 sender_->ExportDebugState().congestion_window);
2103 EXPECT_GT(1024 * params.BottleneckBandwidth(), sender_->PacingRate(0));
2104 }
2105
2106 // All Bbr2MultiSenderTests uses the following network topology:
2107 //
2108 // Sender 0 (A Bbr2Sender)
2109 // |
2110 // | <-- local_links[0]
2111 // |
2112 // | Sender N (1 <= N < kNumLocalLinks) (May or may not be a Bbr2Sender)
2113 // | |
2114 // | | <-- local_links[N]
2115 // | |
2116 // Network switch
2117 // * <-- the bottleneck queue in the direction
2118 // | of the receiver
2119 // |
2120 // | <-- test_link
2121 // |
2122 // |
2123 // Receiver
2124 class MultiSenderTopologyParams {
2125 public:
2126 static constexpr size_t kNumLocalLinks = 8;
2127 std::array<LinkParams, kNumLocalLinks> local_links = {
2128 LinkParams(10000, 1987), LinkParams(10000, 1993), LinkParams(10000, 1997),
2129 LinkParams(10000, 1999), LinkParams(10000, 2003), LinkParams(10000, 2011),
2130 LinkParams(10000, 2017), LinkParams(10000, 2027),
2131 };
2132
2133 LinkParams test_link = LinkParams(4000, 30000);
2134
2135 const simulator::SwitchPortNumber switch_port_count = kNumLocalLinks + 1;
2136
2137 // Network switch queue capacity, in number of BDPs.
2138 float switch_queue_capacity_in_bdp = 2;
2139
BottleneckBandwidth() const2140 QuicBandwidth BottleneckBandwidth() const {
2141 // Make sure all local links have a higher bandwidth than the test link.
2142 for (size_t i = 0; i < local_links.size(); ++i) {
2143 QUICHE_CHECK_GT(local_links[i].bandwidth, test_link.bandwidth);
2144 }
2145 return test_link.bandwidth;
2146 }
2147
2148 // Sender n's round trip time of a single full size packet.
Rtt(size_t n) const2149 QuicTime::Delta Rtt(size_t n) const {
2150 return 2 * (local_links[n].delay + test_link.delay +
2151 local_links[n].bandwidth.TransferTime(kMaxOutgoingPacketSize) +
2152 test_link.bandwidth.TransferTime(kMaxOutgoingPacketSize));
2153 }
2154
Bdp(size_t n) const2155 QuicByteCount Bdp(size_t n) const { return BottleneckBandwidth() * Rtt(n); }
2156
SwitchQueueCapacity() const2157 QuicByteCount SwitchQueueCapacity() const {
2158 return switch_queue_capacity_in_bdp * Bdp(1);
2159 }
2160
ToString() const2161 std::string ToString() const {
2162 std::ostringstream os;
2163 os << "{ BottleneckBandwidth: " << BottleneckBandwidth();
2164 for (size_t i = 0; i < local_links.size(); ++i) {
2165 os << " RTT_" << i << ": " << Rtt(i) << " BDP_" << i << ": " << Bdp(i);
2166 }
2167 os << " BottleneckQueueSize: " << SwitchQueueCapacity() << "}";
2168 return os.str();
2169 }
2170 };
2171
2172 class Bbr2MultiSenderTest : public Bbr2SimulatorTest {
2173 protected:
Bbr2MultiSenderTest()2174 Bbr2MultiSenderTest() {
2175 uint64_t first_connection_id = 42;
2176 std::vector<simulator::QuicEndpointBase*> receiver_endpoint_pointers;
2177 for (size_t i = 0; i < MultiSenderTopologyParams::kNumLocalLinks; ++i) {
2178 std::string sender_name = absl::StrCat("Sender", i + 1);
2179 std::string receiver_name = absl::StrCat("Receiver", i + 1);
2180 sender_endpoints_.push_back(std::make_unique<simulator::QuicEndpoint>(
2181 &simulator_, sender_name, receiver_name, Perspective::IS_CLIENT,
2182 TestConnectionId(first_connection_id + i)));
2183 receiver_endpoints_.push_back(std::make_unique<simulator::QuicEndpoint>(
2184 &simulator_, receiver_name, sender_name, Perspective::IS_SERVER,
2185 TestConnectionId(first_connection_id + i)));
2186 receiver_endpoint_pointers.push_back(receiver_endpoints_.back().get());
2187 }
2188 receiver_multiplexer_ =
2189 std::make_unique<simulator::QuicEndpointMultiplexer>(
2190 "Receiver multiplexer", receiver_endpoint_pointers);
2191 sender_0_ = SetupBbr2Sender(sender_endpoints_[0].get());
2192 }
2193
~Bbr2MultiSenderTest()2194 ~Bbr2MultiSenderTest() {
2195 const auto* test_info =
2196 ::testing::UnitTest::GetInstance()->current_test_info();
2197 QUIC_LOG(INFO) << "Bbr2MultiSenderTest." << test_info->name()
2198 << " completed at simulated time: "
2199 << SimulatedNow().ToDebuggingValue() / 1e6
2200 << " sec. Per sender stats:";
2201 for (size_t i = 0; i < sender_endpoints_.size(); ++i) {
2202 QUIC_LOG(INFO) << "sender[" << i << "]: "
2203 << sender_connection(i)
2204 ->sent_packet_manager()
2205 .GetSendAlgorithm()
2206 ->GetCongestionControlType()
2207 << ", packet_loss:"
2208 << 100.0 * sender_loss_rate_in_packets(i) << "%";
2209 }
2210 }
2211
SetupBbr2Sender(simulator::QuicEndpoint * endpoint)2212 Bbr2Sender* SetupBbr2Sender(simulator::QuicEndpoint* endpoint) {
2213 // Ownership of the sender will be overtaken by the endpoint.
2214 Bbr2Sender* sender = new Bbr2Sender(
2215 endpoint->connection()->clock()->Now(),
2216 endpoint->connection()->sent_packet_manager().GetRttStats(),
2217 QuicSentPacketManagerPeer::GetUnackedPacketMap(
2218 QuicConnectionPeer::GetSentPacketManager(endpoint->connection())),
2219 kDefaultInitialCwndPackets, GetQuicFlag(quic_max_congestion_window),
2220 &random_, QuicConnectionPeer::GetStats(endpoint->connection()),
2221 nullptr);
2222 // TODO(ianswett): Add dedicated tests for this option until it becomes
2223 // the default behavior.
2224 SetConnectionOption(sender, kBBRA);
2225
2226 QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
2227 endpoint->RecordTrace();
2228 return sender;
2229 }
2230
SetupBbrSender(simulator::QuicEndpoint * endpoint)2231 BbrSender* SetupBbrSender(simulator::QuicEndpoint* endpoint) {
2232 // Ownership of the sender will be overtaken by the endpoint.
2233 BbrSender* sender = new BbrSender(
2234 endpoint->connection()->clock()->Now(),
2235 endpoint->connection()->sent_packet_manager().GetRttStats(),
2236 QuicSentPacketManagerPeer::GetUnackedPacketMap(
2237 QuicConnectionPeer::GetSentPacketManager(endpoint->connection())),
2238 kDefaultInitialCwndPackets, GetQuicFlag(quic_max_congestion_window),
2239 &random_, QuicConnectionPeer::GetStats(endpoint->connection()));
2240 QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
2241 endpoint->RecordTrace();
2242 return sender;
2243 }
2244
2245 // reno => Reno. !reno => Cubic.
SetupTcpSender(simulator::QuicEndpoint * endpoint,bool reno)2246 TcpCubicSenderBytes* SetupTcpSender(simulator::QuicEndpoint* endpoint,
2247 bool reno) {
2248 // Ownership of the sender will be overtaken by the endpoint.
2249 TcpCubicSenderBytes* sender = new TcpCubicSenderBytes(
2250 endpoint->connection()->clock(),
2251 endpoint->connection()->sent_packet_manager().GetRttStats(), reno,
2252 kDefaultInitialCwndPackets, GetQuicFlag(quic_max_congestion_window),
2253 QuicConnectionPeer::GetStats(endpoint->connection()));
2254 QuicConnectionPeer::SetSendAlgorithm(endpoint->connection(), sender);
2255 endpoint->RecordTrace();
2256 return sender;
2257 }
2258
SetConnectionOption(SendAlgorithmInterface * sender,QuicTag option)2259 void SetConnectionOption(SendAlgorithmInterface* sender, QuicTag option) {
2260 QuicConfig config;
2261 QuicTagVector options;
2262 options.push_back(option);
2263 QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
2264 sender->SetFromConfig(config, Perspective::IS_SERVER);
2265 }
2266
CreateNetwork(const MultiSenderTopologyParams & params)2267 void CreateNetwork(const MultiSenderTopologyParams& params) {
2268 QUIC_LOG(INFO) << "CreateNetwork with parameters: " << params.ToString();
2269 switch_ = std::make_unique<simulator::Switch>(&simulator_, "Switch",
2270 params.switch_port_count,
2271 params.SwitchQueueCapacity());
2272
2273 network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
2274 receiver_multiplexer_.get(), switch_->port(1),
2275 params.test_link.bandwidth, params.test_link.delay));
2276 for (size_t i = 0; i < MultiSenderTopologyParams::kNumLocalLinks; ++i) {
2277 simulator::SwitchPortNumber port_number = i + 2;
2278 network_links_.push_back(std::make_unique<simulator::SymmetricLink>(
2279 sender_endpoints_[i].get(), switch_->port(port_number),
2280 params.local_links[i].bandwidth, params.local_links[i].delay));
2281 }
2282 }
2283
sender_connection(size_t which)2284 QuicConnection* sender_connection(size_t which) {
2285 return sender_endpoints_[which]->connection();
2286 }
2287
sender_connection_stats(size_t which)2288 const QuicConnectionStats& sender_connection_stats(size_t which) {
2289 return sender_connection(which)->GetStats();
2290 }
2291
sender_loss_rate_in_packets(size_t which)2292 float sender_loss_rate_in_packets(size_t which) {
2293 return static_cast<float>(sender_connection_stats(which).packets_lost) /
2294 sender_connection_stats(which).packets_sent;
2295 }
2296
2297 std::vector<std::unique_ptr<simulator::QuicEndpoint>> sender_endpoints_;
2298 std::vector<std::unique_ptr<simulator::QuicEndpoint>> receiver_endpoints_;
2299 std::unique_ptr<simulator::QuicEndpointMultiplexer> receiver_multiplexer_;
2300 Bbr2Sender* sender_0_;
2301
2302 std::unique_ptr<simulator::Switch> switch_;
2303 std::vector<std::unique_ptr<simulator::SymmetricLink>> network_links_;
2304 };
2305
TEST_F(Bbr2MultiSenderTest,Bbr2VsBbr2)2306 TEST_F(Bbr2MultiSenderTest, Bbr2VsBbr2) {
2307 SetupBbr2Sender(sender_endpoints_[1].get());
2308
2309 MultiSenderTopologyParams params;
2310 CreateNetwork(params);
2311
2312 const QuicByteCount transfer_size = 10 * 1024 * 1024;
2313 const QuicTime::Delta transfer_time =
2314 params.BottleneckBandwidth().TransferTime(transfer_size);
2315 QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
2316
2317 // Transfer 10% of data in first transfer.
2318 sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
2319 bool simulator_result = simulator_.RunUntilOrTimeout(
2320 [this]() {
2321 return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
2322 },
2323 transfer_time);
2324 ASSERT_TRUE(simulator_result);
2325
2326 // Start the second transfer and wait until both finish.
2327 sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
2328 simulator_result = simulator_.RunUntilOrTimeout(
2329 [this]() {
2330 return receiver_endpoints_[0]->bytes_received() == transfer_size &&
2331 receiver_endpoints_[1]->bytes_received() == transfer_size;
2332 },
2333 3 * transfer_time);
2334 ASSERT_TRUE(simulator_result);
2335 }
2336
TEST_F(Bbr2MultiSenderTest,Bbr2VsBbr2BBPD)2337 TEST_F(Bbr2MultiSenderTest, Bbr2VsBbr2BBPD) {
2338 SetConnectionOption(sender_0_, kBBPD);
2339 Bbr2Sender* sender_1 = SetupBbr2Sender(sender_endpoints_[1].get());
2340 SetConnectionOption(sender_1, kBBPD);
2341
2342 MultiSenderTopologyParams params;
2343 CreateNetwork(params);
2344
2345 const QuicByteCount transfer_size = 10 * 1024 * 1024;
2346 const QuicTime::Delta transfer_time =
2347 params.BottleneckBandwidth().TransferTime(transfer_size);
2348 QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
2349
2350 // Transfer 10% of data in first transfer.
2351 sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
2352 bool simulator_result = simulator_.RunUntilOrTimeout(
2353 [this]() {
2354 return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
2355 },
2356 transfer_time);
2357 ASSERT_TRUE(simulator_result);
2358
2359 // Start the second transfer and wait until both finish.
2360 sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
2361 simulator_result = simulator_.RunUntilOrTimeout(
2362 [this]() {
2363 return receiver_endpoints_[0]->bytes_received() == transfer_size &&
2364 receiver_endpoints_[1]->bytes_received() == transfer_size;
2365 },
2366 3 * transfer_time);
2367 ASSERT_TRUE(simulator_result);
2368 }
2369
TEST_F(Bbr2MultiSenderTest,QUIC_SLOW_TEST (MultipleBbr2s))2370 TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(MultipleBbr2s)) {
2371 const int kTotalNumSenders = 6;
2372 for (int i = 1; i < kTotalNumSenders; ++i) {
2373 SetupBbr2Sender(sender_endpoints_[i].get());
2374 }
2375
2376 MultiSenderTopologyParams params;
2377 CreateNetwork(params);
2378
2379 const QuicByteCount transfer_size = 10 * 1024 * 1024;
2380 const QuicTime::Delta transfer_time =
2381 params.BottleneckBandwidth().TransferTime(transfer_size);
2382 QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time
2383 << ". Now: " << SimulatedNow();
2384
2385 // Start all transfers.
2386 for (int i = 0; i < kTotalNumSenders; ++i) {
2387 if (i != 0) {
2388 const QuicTime sender_start_time =
2389 SimulatedNow() + QuicTime::Delta::FromSeconds(2);
2390 bool simulator_result = simulator_.RunUntilOrTimeout(
2391 [&]() { return SimulatedNow() >= sender_start_time; }, transfer_time);
2392 ASSERT_TRUE(simulator_result);
2393 }
2394
2395 sender_endpoints_[i]->AddBytesToTransfer(transfer_size);
2396 }
2397
2398 // Wait for all transfers to finish.
2399 QuicTime::Delta expected_total_transfer_time_upper_bound =
2400 QuicTime::Delta::FromMicroseconds(kTotalNumSenders *
2401 transfer_time.ToMicroseconds() * 1.1);
2402 bool simulator_result = simulator_.RunUntilOrTimeout(
2403 [this]() {
2404 for (int i = 0; i < kTotalNumSenders; ++i) {
2405 if (receiver_endpoints_[i]->bytes_received() < transfer_size) {
2406 return false;
2407 }
2408 }
2409 return true;
2410 },
2411 expected_total_transfer_time_upper_bound);
2412 ASSERT_TRUE(simulator_result)
2413 << "Expected upper bound: " << expected_total_transfer_time_upper_bound;
2414 }
2415
2416 /* The first 11 packets are sent at the same time, but the duration between the
2417 * acks of the 1st and the 11th packet is 49 milliseconds, causing very low bw
2418 * samples. This happens for both large and small buffers.
2419 */
2420 /*
2421 TEST_F(Bbr2MultiSenderTest, Bbr2VsBbr2LargeRttTinyBuffer) {
2422 SetupBbr2Sender(sender_endpoints_[1].get());
2423
2424 MultiSenderTopologyParams params;
2425 params.switch_queue_capacity_in_bdp = 0.05;
2426 params.test_link.delay = QuicTime::Delta::FromSeconds(1);
2427 CreateNetwork(params);
2428
2429 const QuicByteCount transfer_size = 10 * 1024 * 1024;
2430 const QuicTime::Delta transfer_time =
2431 params.BottleneckBandwidth().TransferTime(transfer_size);
2432 QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
2433
2434 // Transfer 10% of data in first transfer.
2435 sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
2436 bool simulator_result = simulator_.RunUntilOrTimeout(
2437 [this]() {
2438 return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
2439 },
2440 transfer_time);
2441 ASSERT_TRUE(simulator_result);
2442
2443 // Start the second transfer and wait until both finish.
2444 sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
2445 simulator_result = simulator_.RunUntilOrTimeout(
2446 [this]() {
2447 return receiver_endpoints_[0]->bytes_received() == transfer_size &&
2448 receiver_endpoints_[1]->bytes_received() == transfer_size;
2449 },
2450 3 * transfer_time);
2451 ASSERT_TRUE(simulator_result);
2452 }
2453 */
2454
TEST_F(Bbr2MultiSenderTest,Bbr2VsBbr1)2455 TEST_F(Bbr2MultiSenderTest, Bbr2VsBbr1) {
2456 SetupBbrSender(sender_endpoints_[1].get());
2457
2458 MultiSenderTopologyParams params;
2459 CreateNetwork(params);
2460
2461 const QuicByteCount transfer_size = 10 * 1024 * 1024;
2462 const QuicTime::Delta transfer_time =
2463 params.BottleneckBandwidth().TransferTime(transfer_size);
2464 QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
2465
2466 // Transfer 10% of data in first transfer.
2467 sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
2468 bool simulator_result = simulator_.RunUntilOrTimeout(
2469 [this]() {
2470 return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
2471 },
2472 transfer_time);
2473 ASSERT_TRUE(simulator_result);
2474
2475 // Start the second transfer and wait until both finish.
2476 sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
2477 simulator_result = simulator_.RunUntilOrTimeout(
2478 [this]() {
2479 return receiver_endpoints_[0]->bytes_received() == transfer_size &&
2480 receiver_endpoints_[1]->bytes_received() == transfer_size;
2481 },
2482 3 * transfer_time);
2483 ASSERT_TRUE(simulator_result);
2484 }
2485
TEST_F(Bbr2MultiSenderTest,QUIC_SLOW_TEST (Bbr2VsReno))2486 TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(Bbr2VsReno)) {
2487 SetupTcpSender(sender_endpoints_[1].get(), /*reno=*/true);
2488
2489 MultiSenderTopologyParams params;
2490 CreateNetwork(params);
2491
2492 const QuicByteCount transfer_size = 10 * 1024 * 1024;
2493 const QuicTime::Delta transfer_time =
2494 params.BottleneckBandwidth().TransferTime(transfer_size);
2495 QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
2496
2497 // Transfer 10% of data in first transfer.
2498 sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
2499 bool simulator_result = simulator_.RunUntilOrTimeout(
2500 [this]() {
2501 return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
2502 },
2503 transfer_time);
2504 ASSERT_TRUE(simulator_result);
2505
2506 // Start the second transfer and wait until both finish.
2507 sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
2508 simulator_result = simulator_.RunUntilOrTimeout(
2509 [this]() {
2510 return receiver_endpoints_[0]->bytes_received() == transfer_size &&
2511 receiver_endpoints_[1]->bytes_received() == transfer_size;
2512 },
2513 3 * transfer_time);
2514 ASSERT_TRUE(simulator_result);
2515 }
2516
TEST_F(Bbr2MultiSenderTest,QUIC_SLOW_TEST (Bbr2VsRenoB2RC))2517 TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(Bbr2VsRenoB2RC)) {
2518 SetConnectionOption(sender_0_, kB2RC);
2519 SetupTcpSender(sender_endpoints_[1].get(), /*reno=*/true);
2520
2521 MultiSenderTopologyParams params;
2522 CreateNetwork(params);
2523
2524 const QuicByteCount transfer_size = 10 * 1024 * 1024;
2525 const QuicTime::Delta transfer_time =
2526 params.BottleneckBandwidth().TransferTime(transfer_size);
2527 QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
2528
2529 // Transfer 10% of data in first transfer.
2530 sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
2531 bool simulator_result = simulator_.RunUntilOrTimeout(
2532 [this]() {
2533 return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
2534 },
2535 transfer_time);
2536 ASSERT_TRUE(simulator_result);
2537
2538 // Start the second transfer and wait until both finish.
2539 sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
2540 simulator_result = simulator_.RunUntilOrTimeout(
2541 [this]() {
2542 return receiver_endpoints_[0]->bytes_received() == transfer_size &&
2543 receiver_endpoints_[1]->bytes_received() == transfer_size;
2544 },
2545 3 * transfer_time);
2546 ASSERT_TRUE(simulator_result);
2547 }
2548
TEST_F(Bbr2MultiSenderTest,QUIC_SLOW_TEST (Bbr2VsCubic))2549 TEST_F(Bbr2MultiSenderTest, QUIC_SLOW_TEST(Bbr2VsCubic)) {
2550 SetupTcpSender(sender_endpoints_[1].get(), /*reno=*/false);
2551
2552 MultiSenderTopologyParams params;
2553 CreateNetwork(params);
2554
2555 const QuicByteCount transfer_size = 50 * 1024 * 1024;
2556 const QuicTime::Delta transfer_time =
2557 params.BottleneckBandwidth().TransferTime(transfer_size);
2558 QUIC_LOG(INFO) << "Single flow transfer time: " << transfer_time;
2559
2560 // Transfer 10% of data in first transfer.
2561 sender_endpoints_[0]->AddBytesToTransfer(transfer_size);
2562 bool simulator_result = simulator_.RunUntilOrTimeout(
2563 [this]() {
2564 return receiver_endpoints_[0]->bytes_received() >= 0.1 * transfer_size;
2565 },
2566 transfer_time);
2567 ASSERT_TRUE(simulator_result);
2568
2569 // Start the second transfer and wait until both finish.
2570 sender_endpoints_[1]->AddBytesToTransfer(transfer_size);
2571 simulator_result = simulator_.RunUntilOrTimeout(
2572 [this]() {
2573 return receiver_endpoints_[0]->bytes_received() == transfer_size &&
2574 receiver_endpoints_[1]->bytes_received() == transfer_size;
2575 },
2576 3 * transfer_time);
2577 ASSERT_TRUE(simulator_result);
2578 }
2579
TEST(MinRttFilter,BadRttSample)2580 TEST(MinRttFilter, BadRttSample) {
2581 auto time_in_seconds = [](int64_t seconds) {
2582 return QuicTime::Zero() + QuicTime::Delta::FromSeconds(seconds);
2583 };
2584
2585 MinRttFilter filter(QuicTime::Delta::FromMilliseconds(10),
2586 time_in_seconds(100));
2587 ASSERT_EQ(filter.Get(), QuicTime::Delta::FromMilliseconds(10));
2588
2589 filter.Update(QuicTime::Delta::FromMilliseconds(-1), time_in_seconds(150));
2590
2591 EXPECT_EQ(filter.Get(), QuicTime::Delta::FromMilliseconds(10));
2592 EXPECT_EQ(filter.GetTimestamp(), time_in_seconds(100));
2593
2594 filter.ForceUpdate(QuicTime::Delta::FromMilliseconds(-2),
2595 time_in_seconds(200));
2596
2597 EXPECT_EQ(filter.Get(), QuicTime::Delta::FromMilliseconds(10));
2598 EXPECT_EQ(filter.GetTimestamp(), time_in_seconds(100));
2599 }
2600
2601 } // namespace test
2602 } // namespace quic
2603