1 /*
2  *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include <queue>
12 
13 #include "api/transport/goog_cc_factory.h"
14 #include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
15 #include "test/field_trial.h"
16 #include "test/gtest.h"
17 #include "test/scenario/scenario.h"
18 
19 using ::testing::_;
20 using ::testing::Field;
21 using ::testing::Matcher;
22 using ::testing::NiceMock;
23 using ::testing::Property;
24 
25 namespace webrtc {
26 namespace test {
27 namespace {
28 // Count dips from a constant high bandwidth level within a short window.
CountBandwidthDips(std::queue<DataRate> bandwidth_history,DataRate threshold)29 int CountBandwidthDips(std::queue<DataRate> bandwidth_history,
30                        DataRate threshold) {
31   if (bandwidth_history.empty())
32     return true;
33   DataRate first = bandwidth_history.front();
34   bandwidth_history.pop();
35 
36   int dips = 0;
37   bool state_high = true;
38   while (!bandwidth_history.empty()) {
39     if (bandwidth_history.front() + threshold < first && state_high) {
40       ++dips;
41       state_high = false;
42     } else if (bandwidth_history.front() == first) {
43       state_high = true;
44     } else if (bandwidth_history.front() > first) {
45       // If this is toggling we will catch it later when front becomes first.
46       state_high = false;
47     }
48     bandwidth_history.pop();
49   }
50   return dips;
51 }
CreateFeedbackOnlyFactory()52 GoogCcNetworkControllerFactory CreateFeedbackOnlyFactory() {
53   GoogCcFactoryConfig config;
54   config.feedback_only = true;
55   return GoogCcNetworkControllerFactory(std::move(config));
56 }
57 
58 const uint32_t kInitialBitrateKbps = 60;
59 const DataRate kInitialBitrate = DataRate::KilobitsPerSec(kInitialBitrateKbps);
60 const float kDefaultPacingRate = 2.5f;
61 
CreateVideoSendingClient(Scenario * s,CallClientConfig config,std::vector<EmulatedNetworkNode * > send_link,std::vector<EmulatedNetworkNode * > return_link)62 CallClient* CreateVideoSendingClient(
63     Scenario* s,
64     CallClientConfig config,
65     std::vector<EmulatedNetworkNode*> send_link,
66     std::vector<EmulatedNetworkNode*> return_link) {
67   auto* client = s->CreateClient("send", std::move(config));
68   auto* route = s->CreateRoutes(client, send_link,
69                                 s->CreateClient("return", CallClientConfig()),
70                                 return_link);
71   s->CreateVideoStream(route->forward(), VideoStreamConfig());
72   return client;
73 }
74 
UpdatesTargetRateBasedOnLinkCapacity(std::string test_name="")75 void UpdatesTargetRateBasedOnLinkCapacity(std::string test_name = "") {
76   ScopedFieldTrials trial("WebRTC-SendSideBwe-WithOverhead/Enabled/");
77   auto factory = CreateFeedbackOnlyFactory();
78   Scenario s("googcc_unit/target_capacity" + test_name, false);
79   CallClientConfig config;
80   config.transport.cc_factory = &factory;
81   config.transport.rates.min_rate = DataRate::KilobitsPerSec(10);
82   config.transport.rates.max_rate = DataRate::KilobitsPerSec(1500);
83   config.transport.rates.start_rate = DataRate::KilobitsPerSec(300);
84   auto send_net = s.CreateMutableSimulationNode([](NetworkSimulationConfig* c) {
85     c->bandwidth = DataRate::KilobitsPerSec(500);
86     c->delay = TimeDelta::Millis(100);
87     c->loss_rate = 0.0;
88   });
89   auto ret_net = s.CreateMutableSimulationNode(
90       [](NetworkSimulationConfig* c) { c->delay = TimeDelta::Millis(100); });
91   StatesPrinter* truth = s.CreatePrinter(
92       "send.truth.txt", TimeDelta::PlusInfinity(), {send_net->ConfigPrinter()});
93 
94   auto* client = CreateVideoSendingClient(&s, config, {send_net->node()},
95                                           {ret_net->node()});
96 
97   truth->PrintRow();
98   s.RunFor(TimeDelta::Seconds(25));
99   truth->PrintRow();
100   EXPECT_NEAR(client->target_rate().kbps(), 450, 100);
101 
102   send_net->UpdateConfig([](NetworkSimulationConfig* c) {
103     c->bandwidth = DataRate::KilobitsPerSec(800);
104     c->delay = TimeDelta::Millis(100);
105   });
106 
107   truth->PrintRow();
108   s.RunFor(TimeDelta::Seconds(20));
109   truth->PrintRow();
110   EXPECT_NEAR(client->target_rate().kbps(), 750, 150);
111 
112   send_net->UpdateConfig([](NetworkSimulationConfig* c) {
113     c->bandwidth = DataRate::KilobitsPerSec(100);
114     c->delay = TimeDelta::Millis(200);
115   });
116   ret_net->UpdateConfig(
117       [](NetworkSimulationConfig* c) { c->delay = TimeDelta::Millis(200); });
118 
119   truth->PrintRow();
120   s.RunFor(TimeDelta::Seconds(50));
121   truth->PrintRow();
122   EXPECT_NEAR(client->target_rate().kbps(), 90, 25);
123 }
124 }  // namespace
125 
126 class GoogCcNetworkControllerTest : public ::testing::Test {
127  protected:
GoogCcNetworkControllerTest()128   GoogCcNetworkControllerTest()
129       : current_time_(Timestamp::Millis(123456)), factory_() {}
~GoogCcNetworkControllerTest()130   ~GoogCcNetworkControllerTest() override {}
131 
SetUp()132   void SetUp() override {
133     controller_ = factory_.Create(InitialConfig());
134     NetworkControlUpdate update =
135         controller_->OnProcessInterval(DefaultInterval());
136     EXPECT_EQ(update.target_rate->target_rate, kInitialBitrate);
137     EXPECT_EQ(update.pacer_config->data_rate(),
138               kInitialBitrate * kDefaultPacingRate);
139 
140     EXPECT_EQ(update.probe_cluster_configs[0].target_data_rate,
141               kInitialBitrate * 3);
142     EXPECT_EQ(update.probe_cluster_configs[1].target_data_rate,
143               kInitialBitrate * 5);
144   }
145   // Custom setup - use an observer that tracks the target bitrate, without
146   // prescribing on which iterations it must change (like a mock would).
TargetBitrateTrackingSetup()147   void TargetBitrateTrackingSetup() {
148     controller_ = factory_.Create(InitialConfig());
149     OnUpdate(controller_->OnProcessInterval(DefaultInterval()));
150   }
151 
InitialConfig(int starting_bandwidth_kbps=kInitialBitrateKbps,int min_data_rate_kbps=0,int max_data_rate_kbps=5* kInitialBitrateKbps)152   NetworkControllerConfig InitialConfig(
153       int starting_bandwidth_kbps = kInitialBitrateKbps,
154       int min_data_rate_kbps = 0,
155       int max_data_rate_kbps = 5 * kInitialBitrateKbps) {
156     NetworkControllerConfig config;
157     config.constraints.at_time = current_time_;
158     config.constraints.min_data_rate =
159         DataRate::KilobitsPerSec(min_data_rate_kbps);
160     config.constraints.max_data_rate =
161         DataRate::KilobitsPerSec(max_data_rate_kbps);
162     config.constraints.starting_rate =
163         DataRate::KilobitsPerSec(starting_bandwidth_kbps);
164     config.event_log = &event_log_;
165     return config;
166   }
DefaultInterval()167   ProcessInterval DefaultInterval() {
168     ProcessInterval interval;
169     interval.at_time = current_time_;
170     return interval;
171   }
CreateBitrateReport(DataRate rate)172   RemoteBitrateReport CreateBitrateReport(DataRate rate) {
173     RemoteBitrateReport report;
174     report.receive_time = current_time_;
175     report.bandwidth = rate;
176     return report;
177   }
CreateResult(int64_t arrival_time_ms,int64_t send_time_ms,size_t payload_size,PacedPacketInfo pacing_info)178   PacketResult CreateResult(int64_t arrival_time_ms,
179                             int64_t send_time_ms,
180                             size_t payload_size,
181                             PacedPacketInfo pacing_info) {
182     PacketResult packet_result;
183     packet_result.sent_packet = SentPacket();
184     packet_result.sent_packet.send_time = Timestamp::Millis(send_time_ms);
185     packet_result.sent_packet.size = DataSize::Bytes(payload_size);
186     packet_result.sent_packet.pacing_info = pacing_info;
187     packet_result.receive_time = Timestamp::Millis(arrival_time_ms);
188     return packet_result;
189   }
190 
CreateRouteChange(absl::optional<DataRate> start_rate=absl::nullopt,absl::optional<DataRate> min_rate=absl::nullopt,absl::optional<DataRate> max_rate=absl::nullopt)191   NetworkRouteChange CreateRouteChange(
192       absl::optional<DataRate> start_rate = absl::nullopt,
193       absl::optional<DataRate> min_rate = absl::nullopt,
194       absl::optional<DataRate> max_rate = absl::nullopt) {
195     NetworkRouteChange route_change;
196     route_change.at_time = current_time_;
197     route_change.constraints.at_time = current_time_;
198     route_change.constraints.min_data_rate = min_rate;
199     route_change.constraints.max_data_rate = max_rate;
200     route_change.constraints.starting_rate = start_rate;
201     return route_change;
202   }
203 
AdvanceTimeMilliseconds(int timedelta_ms)204   void AdvanceTimeMilliseconds(int timedelta_ms) {
205     current_time_ += TimeDelta::Millis(timedelta_ms);
206   }
207 
OnUpdate(NetworkControlUpdate update)208   void OnUpdate(NetworkControlUpdate update) {
209     if (update.target_rate)
210       target_bitrate_ = update.target_rate->target_rate;
211   }
212 
PacketTransmissionAndFeedbackBlock(int64_t runtime_ms,int64_t delay)213   void PacketTransmissionAndFeedbackBlock(int64_t runtime_ms, int64_t delay) {
214     int64_t delay_buildup = 0;
215     int64_t start_time_ms = current_time_.ms();
216     while (current_time_.ms() - start_time_ms < runtime_ms) {
217       constexpr size_t kPayloadSize = 1000;
218       PacketResult packet =
219           CreateResult(current_time_.ms() + delay_buildup, current_time_.ms(),
220                        kPayloadSize, PacedPacketInfo());
221       delay_buildup += delay;
222       OnUpdate(controller_->OnSentPacket(packet.sent_packet));
223       TransportPacketsFeedback feedback;
224       feedback.feedback_time = packet.receive_time;
225       feedback.packet_feedbacks.push_back(packet);
226       OnUpdate(controller_->OnTransportPacketsFeedback(feedback));
227       AdvanceTimeMilliseconds(50);
228       OnUpdate(controller_->OnProcessInterval(DefaultInterval()));
229     }
230   }
231   Timestamp current_time_;
232   absl::optional<DataRate> target_bitrate_;
233   NiceMock<MockRtcEventLog> event_log_;
234   GoogCcNetworkControllerFactory factory_;
235   std::unique_ptr<NetworkControllerInterface> controller_;
236 };
237 
TEST_F(GoogCcNetworkControllerTest,ReactsToChangedNetworkConditions)238 TEST_F(GoogCcNetworkControllerTest, ReactsToChangedNetworkConditions) {
239   // Test no change.
240   AdvanceTimeMilliseconds(25);
241   OnUpdate(controller_->OnProcessInterval(DefaultInterval()));
242 
243   NetworkControlUpdate update;
244   OnUpdate(controller_->OnRemoteBitrateReport(
245       CreateBitrateReport(kInitialBitrate * 2)));
246   AdvanceTimeMilliseconds(25);
247   update = controller_->OnProcessInterval(DefaultInterval());
248   EXPECT_EQ(update.target_rate->target_rate, kInitialBitrate * 2);
249   EXPECT_EQ(update.pacer_config->data_rate(),
250             kInitialBitrate * 2 * kDefaultPacingRate);
251 
252   OnUpdate(
253       controller_->OnRemoteBitrateReport(CreateBitrateReport(kInitialBitrate)));
254   AdvanceTimeMilliseconds(25);
255   update = controller_->OnProcessInterval(DefaultInterval());
256   EXPECT_EQ(update.target_rate->target_rate, kInitialBitrate);
257   EXPECT_EQ(update.pacer_config->data_rate(),
258             kInitialBitrate * kDefaultPacingRate);
259 }
260 
261 // Test congestion window pushback on network delay happens.
TEST_F(GoogCcNetworkControllerTest,CongestionWindowPushbackOnNetworkDelay)262 TEST_F(GoogCcNetworkControllerTest, CongestionWindowPushbackOnNetworkDelay) {
263   auto factory = CreateFeedbackOnlyFactory();
264   ScopedFieldTrials trial(
265       "WebRTC-CongestionWindow/QueueSize:800,MinBitrate:30000/");
266   Scenario s("googcc_unit/cwnd_on_delay", false);
267   auto send_net =
268       s.CreateMutableSimulationNode([=](NetworkSimulationConfig* c) {
269         c->bandwidth = DataRate::KilobitsPerSec(1000);
270         c->delay = TimeDelta::Millis(100);
271       });
272   auto ret_net = s.CreateSimulationNode(
273       [](NetworkSimulationConfig* c) { c->delay = TimeDelta::Millis(100); });
274   CallClientConfig config;
275   config.transport.cc_factory = &factory;
276   // Start high so bandwidth drop has max effect.
277   config.transport.rates.start_rate = DataRate::KilobitsPerSec(300);
278   config.transport.rates.max_rate = DataRate::KilobitsPerSec(2000);
279   config.transport.rates.min_rate = DataRate::KilobitsPerSec(10);
280 
281   auto* client = CreateVideoSendingClient(&s, std::move(config),
282                                           {send_net->node()}, {ret_net});
283 
284   s.RunFor(TimeDelta::Seconds(10));
285   send_net->PauseTransmissionUntil(s.Now() + TimeDelta::Seconds(10));
286   s.RunFor(TimeDelta::Seconds(3));
287 
288   // After 3 seconds without feedback from any sent packets, we expect that the
289   // target rate is reduced to the minimum pushback threshold
290   // kDefaultMinPushbackTargetBitrateBps, which is defined as 30 kbps in
291   // congestion_window_pushback_controller.
292   EXPECT_LT(client->target_rate().kbps(), 40);
293 }
294 
295 // Test congestion window pushback on network delay happens.
TEST_F(GoogCcNetworkControllerTest,CongestionWindowPushbackDropFrameOnNetworkDelay)296 TEST_F(GoogCcNetworkControllerTest,
297        CongestionWindowPushbackDropFrameOnNetworkDelay) {
298   auto factory = CreateFeedbackOnlyFactory();
299   ScopedFieldTrials trial(
300       "WebRTC-CongestionWindow/QueueSize:800,MinBitrate:30000,DropFrame:true/");
301   Scenario s("googcc_unit/cwnd_on_delay", false);
302   auto send_net =
303       s.CreateMutableSimulationNode([=](NetworkSimulationConfig* c) {
304         c->bandwidth = DataRate::KilobitsPerSec(1000);
305         c->delay = TimeDelta::Millis(100);
306       });
307   auto ret_net = s.CreateSimulationNode(
308       [](NetworkSimulationConfig* c) { c->delay = TimeDelta::Millis(100); });
309   CallClientConfig config;
310   config.transport.cc_factory = &factory;
311   // Start high so bandwidth drop has max effect.
312   config.transport.rates.start_rate = DataRate::KilobitsPerSec(300);
313   config.transport.rates.max_rate = DataRate::KilobitsPerSec(2000);
314   config.transport.rates.min_rate = DataRate::KilobitsPerSec(10);
315 
316   auto* client = CreateVideoSendingClient(&s, std::move(config),
317                                           {send_net->node()}, {ret_net});
318 
319   s.RunFor(TimeDelta::Seconds(10));
320   send_net->PauseTransmissionUntil(s.Now() + TimeDelta::Seconds(10));
321   s.RunFor(TimeDelta::Seconds(3));
322 
323   // As the dropframe is set, after 3 seconds without feedback from any sent
324   // packets, we expect that the target rate is not reduced by congestion
325   // window.
326   EXPECT_GT(client->target_rate().kbps(), 300);
327 }
328 
TEST_F(GoogCcNetworkControllerTest,OnNetworkRouteChanged)329 TEST_F(GoogCcNetworkControllerTest, OnNetworkRouteChanged) {
330   NetworkControlUpdate update;
331   DataRate new_bitrate = DataRate::BitsPerSec(200000);
332   update = controller_->OnNetworkRouteChange(CreateRouteChange(new_bitrate));
333   EXPECT_EQ(update.target_rate->target_rate, new_bitrate);
334   EXPECT_EQ(update.pacer_config->data_rate(), new_bitrate * kDefaultPacingRate);
335   EXPECT_EQ(update.probe_cluster_configs.size(), 2u);
336 
337   // If the bitrate is reset to -1, the new starting bitrate will be
338   // the minimum default bitrate.
339   const DataRate kDefaultMinBitrate = DataRate::KilobitsPerSec(5);
340   update = controller_->OnNetworkRouteChange(CreateRouteChange());
341   EXPECT_EQ(update.target_rate->target_rate, kDefaultMinBitrate);
342   EXPECT_NEAR(update.pacer_config->data_rate().bps<double>(),
343               kDefaultMinBitrate.bps<double>() * kDefaultPacingRate, 10);
344   EXPECT_EQ(update.probe_cluster_configs.size(), 2u);
345 }
346 
TEST_F(GoogCcNetworkControllerTest,ProbeOnRouteChange)347 TEST_F(GoogCcNetworkControllerTest, ProbeOnRouteChange) {
348   NetworkControlUpdate update;
349   update = controller_->OnNetworkRouteChange(CreateRouteChange(
350       2 * kInitialBitrate, DataRate::Zero(), 20 * kInitialBitrate));
351 
352   EXPECT_TRUE(update.pacer_config.has_value());
353   EXPECT_EQ(update.target_rate->target_rate, kInitialBitrate * 2);
354   EXPECT_EQ(update.probe_cluster_configs.size(), 2u);
355   EXPECT_EQ(update.probe_cluster_configs[0].target_data_rate,
356             kInitialBitrate * 6);
357   EXPECT_EQ(update.probe_cluster_configs[1].target_data_rate,
358             kInitialBitrate * 12);
359 
360   update = controller_->OnProcessInterval(DefaultInterval());
361 }
362 
363 // Bandwidth estimation is updated when feedbacks are received.
364 // Feedbacks which show an increasing delay cause the estimation to be reduced.
TEST_F(GoogCcNetworkControllerTest,UpdatesDelayBasedEstimate)365 TEST_F(GoogCcNetworkControllerTest, UpdatesDelayBasedEstimate) {
366   TargetBitrateTrackingSetup();
367   const int64_t kRunTimeMs = 6000;
368 
369   // The test must run and insert packets/feedback long enough that the
370   // BWE computes a valid estimate. This is first done in an environment which
371   // simulates no bandwidth limitation, and therefore not built-up delay.
372   PacketTransmissionAndFeedbackBlock(kRunTimeMs, 0);
373   ASSERT_TRUE(target_bitrate_.has_value());
374 
375   // Repeat, but this time with a building delay, and make sure that the
376   // estimation is adjusted downwards.
377   DataRate bitrate_before_delay = *target_bitrate_;
378   PacketTransmissionAndFeedbackBlock(kRunTimeMs, 50);
379   EXPECT_LT(*target_bitrate_, bitrate_before_delay);
380 }
381 
TEST_F(GoogCcNetworkControllerTest,PaddingRateLimitedByCongestionWindowInTrial)382 TEST_F(GoogCcNetworkControllerTest,
383        PaddingRateLimitedByCongestionWindowInTrial) {
384   ScopedFieldTrials trial(
385       "WebRTC-CongestionWindow/QueueSize:200,MinBitrate:30000/");
386 
387   Scenario s("googcc_unit/padding_limited", false);
388   auto send_net =
389       s.CreateMutableSimulationNode([=](NetworkSimulationConfig* c) {
390         c->bandwidth = DataRate::KilobitsPerSec(1000);
391         c->delay = TimeDelta::Millis(100);
392       });
393   auto ret_net = s.CreateSimulationNode(
394       [](NetworkSimulationConfig* c) { c->delay = TimeDelta::Millis(100); });
395   CallClientConfig config;
396   // Start high so bandwidth drop has max effect.
397   config.transport.rates.start_rate = DataRate::KilobitsPerSec(1000);
398   config.transport.rates.max_rate = DataRate::KilobitsPerSec(2000);
399   auto* client = s.CreateClient("send", config);
400   auto* route =
401       s.CreateRoutes(client, {send_net->node()},
402                      s.CreateClient("return", CallClientConfig()), {ret_net});
403   VideoStreamConfig video;
404   video.stream.pad_to_rate = config.transport.rates.max_rate;
405   s.CreateVideoStream(route->forward(), video);
406 
407   // Run for a few seconds to allow the controller to stabilize.
408   s.RunFor(TimeDelta::Seconds(10));
409 
410   // Check that padding rate matches target rate.
411   EXPECT_NEAR(client->padding_rate().kbps(), client->target_rate().kbps(), 1);
412 
413   // Check this is also the case when congestion window pushback kicks in.
414   send_net->PauseTransmissionUntil(s.Now() + TimeDelta::Seconds(1));
415   EXPECT_NEAR(client->padding_rate().kbps(), client->target_rate().kbps(), 1);
416 }
417 
TEST_F(GoogCcNetworkControllerTest,LimitsToFloorIfRttIsHighInTrial)418 TEST_F(GoogCcNetworkControllerTest, LimitsToFloorIfRttIsHighInTrial) {
419   // The field trial limits maximum RTT to 2 seconds, higher RTT means that the
420   // controller backs off until it reaches the minimum configured bitrate. This
421   // allows the RTT to recover faster than the regular control mechanism would
422   // achieve.
423   const DataRate kBandwidthFloor = DataRate::KilobitsPerSec(50);
424   ScopedFieldTrials trial("WebRTC-Bwe-MaxRttLimit/limit:2s,floor:" +
425                           std::to_string(kBandwidthFloor.kbps()) + "kbps/");
426   // In the test case, we limit the capacity and add a cross traffic packet
427   // burst that blocks media from being sent. This causes the RTT to quickly
428   // increase above the threshold in the trial.
429   const DataRate kLinkCapacity = DataRate::KilobitsPerSec(100);
430   const TimeDelta kBufferBloatDuration = TimeDelta::Seconds(10);
431   Scenario s("googcc_unit/limit_trial", false);
432   auto send_net = s.CreateSimulationNode([=](NetworkSimulationConfig* c) {
433     c->bandwidth = kLinkCapacity;
434     c->delay = TimeDelta::Millis(100);
435   });
436   auto ret_net = s.CreateSimulationNode(
437       [](NetworkSimulationConfig* c) { c->delay = TimeDelta::Millis(100); });
438   CallClientConfig config;
439   config.transport.rates.start_rate = kLinkCapacity;
440 
441   auto* client = CreateVideoSendingClient(&s, config, {send_net}, {ret_net});
442   // Run for a few seconds to allow the controller to stabilize.
443   s.RunFor(TimeDelta::Seconds(10));
444   const DataSize kBloatPacketSize = DataSize::Bytes(1000);
445   const int kBloatPacketCount =
446       static_cast<int>(kBufferBloatDuration * kLinkCapacity / kBloatPacketSize);
447   // This will cause the RTT to be large for a while.
448   s.TriggerPacketBurst({send_net}, kBloatPacketCount, kBloatPacketSize.bytes());
449   // Wait to allow the high RTT to be detected and acted upon.
450   s.RunFor(TimeDelta::Seconds(6));
451   // By now the target rate should have dropped to the minimum configured rate.
452   EXPECT_NEAR(client->target_rate().kbps(), kBandwidthFloor.kbps(), 5);
453 }
454 
TEST_F(GoogCcNetworkControllerTest,UpdatesTargetRateBasedOnLinkCapacity)455 TEST_F(GoogCcNetworkControllerTest, UpdatesTargetRateBasedOnLinkCapacity) {
456   UpdatesTargetRateBasedOnLinkCapacity();
457 }
458 
TEST_F(GoogCcNetworkControllerTest,StableEstimateDoesNotVaryInSteadyState)459 TEST_F(GoogCcNetworkControllerTest, StableEstimateDoesNotVaryInSteadyState) {
460   auto factory = CreateFeedbackOnlyFactory();
461   Scenario s("googcc_unit/stable_target", false);
462   CallClientConfig config;
463   config.transport.cc_factory = &factory;
464   NetworkSimulationConfig net_conf;
465   net_conf.bandwidth = DataRate::KilobitsPerSec(500);
466   net_conf.delay = TimeDelta::Millis(100);
467   auto send_net = s.CreateSimulationNode(net_conf);
468   auto ret_net = s.CreateSimulationNode(net_conf);
469 
470   auto* client = CreateVideoSendingClient(&s, config, {send_net}, {ret_net});
471   // Run for a while to allow the estimate to stabilize.
472   s.RunFor(TimeDelta::Seconds(30));
473   DataRate min_stable_target = DataRate::PlusInfinity();
474   DataRate max_stable_target = DataRate::MinusInfinity();
475   DataRate min_target = DataRate::PlusInfinity();
476   DataRate max_target = DataRate::MinusInfinity();
477 
478   // Measure variation in steady state.
479   for (int i = 0; i < 20; ++i) {
480     auto stable_target_rate = client->stable_target_rate();
481     auto target_rate = client->target_rate();
482     EXPECT_LE(stable_target_rate, target_rate);
483 
484     min_stable_target = std::min(min_stable_target, stable_target_rate);
485     max_stable_target = std::max(max_stable_target, stable_target_rate);
486     min_target = std::min(min_target, target_rate);
487     max_target = std::max(max_target, target_rate);
488     s.RunFor(TimeDelta::Seconds(1));
489   }
490   // We should expect drops by at least 15% (default backoff.)
491   EXPECT_LT(min_target / max_target, 0.85);
492   // We should expect the stable target to be more stable than the immediate one
493   EXPECT_GE(min_stable_target / max_stable_target, min_target / max_target);
494 }
495 
TEST_F(GoogCcNetworkControllerTest,LossBasedControlUpdatesTargetRateBasedOnLinkCapacity)496 TEST_F(GoogCcNetworkControllerTest,
497        LossBasedControlUpdatesTargetRateBasedOnLinkCapacity) {
498   ScopedFieldTrials trial("WebRTC-Bwe-LossBasedControl/Enabled/");
499   // TODO(srte): Should the behavior be unaffected at low loss rates?
500   UpdatesTargetRateBasedOnLinkCapacity("_loss_based");
501 }
502 
TEST_F(GoogCcNetworkControllerTest,LossBasedControlDoesModestBackoffToHighLoss)503 TEST_F(GoogCcNetworkControllerTest,
504        LossBasedControlDoesModestBackoffToHighLoss) {
505   ScopedFieldTrials trial("WebRTC-Bwe-LossBasedControl/Enabled/");
506   Scenario s("googcc_unit/high_loss_channel", false);
507   CallClientConfig config;
508   config.transport.rates.min_rate = DataRate::KilobitsPerSec(10);
509   config.transport.rates.max_rate = DataRate::KilobitsPerSec(1500);
510   config.transport.rates.start_rate = DataRate::KilobitsPerSec(300);
511   auto send_net = s.CreateSimulationNode([](NetworkSimulationConfig* c) {
512     c->bandwidth = DataRate::KilobitsPerSec(2000);
513     c->delay = TimeDelta::Millis(200);
514     c->loss_rate = 0.1;
515   });
516   auto ret_net = s.CreateSimulationNode(
517       [](NetworkSimulationConfig* c) { c->delay = TimeDelta::Millis(200); });
518 
519   auto* client = CreateVideoSendingClient(&s, config, {send_net}, {ret_net});
520 
521   s.RunFor(TimeDelta::Seconds(120));
522   // Without LossBasedControl trial, bandwidth drops to ~10 kbps.
523   EXPECT_GT(client->target_rate().kbps(), 100);
524 }
525 
AverageBitrateAfterCrossInducedLoss(std::string name)526 DataRate AverageBitrateAfterCrossInducedLoss(std::string name) {
527   Scenario s(name, false);
528   NetworkSimulationConfig net_conf;
529   net_conf.bandwidth = DataRate::KilobitsPerSec(1000);
530   net_conf.delay = TimeDelta::Millis(100);
531   // Short queue length means that we'll induce loss when sudden TCP traffic
532   // spikes are induced. This corresponds to ca 200 ms for a packet size of 1000
533   // bytes. Such limited buffers are common on for instance wifi routers.
534   net_conf.packet_queue_length_limit = 25;
535 
536   auto send_net = {s.CreateSimulationNode(net_conf)};
537   auto ret_net = {s.CreateSimulationNode(net_conf)};
538 
539   auto* client = s.CreateClient("send", CallClientConfig());
540   auto* callee = s.CreateClient("return", CallClientConfig());
541   auto* route = s.CreateRoutes(client, send_net, callee, ret_net);
542   // TODO(srte): Make this work with RTX enabled or remove it.
543   auto* video = s.CreateVideoStream(route->forward(), [](VideoStreamConfig* c) {
544     c->stream.use_rtx = false;
545   });
546   s.RunFor(TimeDelta::Seconds(10));
547   for (int i = 0; i < 4; ++i) {
548     // Sends TCP cross traffic inducing loss.
549     auto* tcp_traffic =
550         s.net()->StartFakeTcpCrossTraffic(send_net, ret_net, FakeTcpConfig());
551     s.RunFor(TimeDelta::Seconds(2));
552     // Allow the ccongestion controller to recover.
553     s.net()->StopCrossTraffic(tcp_traffic);
554     s.RunFor(TimeDelta::Seconds(20));
555   }
556 
557   // Querying the video stats from within the expected runtime environment
558   // (i.e. the TQ that belongs to the CallClient, not the Scenario TQ that
559   // we're currently on).
560   VideoReceiveStream::Stats video_receive_stats;
561   auto* video_stream = video->receive();
562   callee->SendTask([&video_stream, &video_receive_stats]() {
563     video_receive_stats = video_stream->GetStats();
564   });
565   return DataSize::Bytes(
566              video_receive_stats.rtp_stats.packet_counter.TotalBytes()) /
567          s.TimeSinceStart();
568 }
569 
TEST_F(GoogCcNetworkControllerTest,NoLossBasedRecoversSlowerAfterCrossInducedLoss)570 TEST_F(GoogCcNetworkControllerTest,
571        NoLossBasedRecoversSlowerAfterCrossInducedLoss) {
572   // This test acts as a reference for the test below, showing that without the
573   // trial, we have worse behavior.
574   DataRate average_bitrate =
575       AverageBitrateAfterCrossInducedLoss("googcc_unit/no_cross_loss_based");
576   RTC_DCHECK_LE(average_bitrate, DataRate::KilobitsPerSec(650));
577 }
578 
TEST_F(GoogCcNetworkControllerTest,LossBasedRecoversFasterAfterCrossInducedLoss)579 TEST_F(GoogCcNetworkControllerTest,
580        LossBasedRecoversFasterAfterCrossInducedLoss) {
581   // We recover bitrate better when subject to loss spikes from cross traffic
582   // when loss based controller is used.
583   ScopedFieldTrials trial("WebRTC-Bwe-LossBasedControl/Enabled/");
584   DataRate average_bitrate =
585       AverageBitrateAfterCrossInducedLoss("googcc_unit/cross_loss_based");
586   RTC_DCHECK_GE(average_bitrate, DataRate::KilobitsPerSec(750));
587 }
588 
TEST_F(GoogCcNetworkControllerTest,LossBasedEstimatorCapsRateAtModerateLoss)589 TEST_F(GoogCcNetworkControllerTest, LossBasedEstimatorCapsRateAtModerateLoss) {
590   ScopedFieldTrials trial("WebRTC-Bwe-LossBasedControl/Enabled/");
591   Scenario s("googcc_unit/moderate_loss_channel", false);
592   CallClientConfig config;
593   config.transport.rates.min_rate = DataRate::KilobitsPerSec(10);
594   config.transport.rates.max_rate = DataRate::KilobitsPerSec(5000);
595   config.transport.rates.start_rate = DataRate::KilobitsPerSec(1000);
596 
597   NetworkSimulationConfig network;
598   network.bandwidth = DataRate::KilobitsPerSec(2000);
599   network.delay = TimeDelta::Millis(100);
600   // 3% loss rate is in the moderate loss rate region at 2000 kbps, limiting the
601   // bitrate increase.
602   network.loss_rate = 0.03;
603   auto send_net = s.CreateMutableSimulationNode(network);
604   auto* client = s.CreateClient("send", std::move(config));
605   auto* route = s.CreateRoutes(client, {send_net->node()},
606                                s.CreateClient("return", CallClientConfig()),
607                                {s.CreateSimulationNode(network)});
608   s.CreateVideoStream(route->forward(), VideoStreamConfig());
609   // Allow the controller to stabilize at the lower bitrate.
610   s.RunFor(TimeDelta::Seconds(1));
611   // This increase in capacity would cause the target bitrate to increase to
612   // over 4000 kbps without LossBasedControl.
613   send_net->UpdateConfig([](NetworkSimulationConfig* c) {
614     c->bandwidth = DataRate::KilobitsPerSec(5000);
615   });
616   s.RunFor(TimeDelta::Seconds(20));
617   // Using LossBasedControl, the bitrate will not increase over 2500 kbps since
618   // we have detected moderate loss.
619   EXPECT_LT(client->target_rate().kbps(), 2500);
620 }
621 
TEST_F(GoogCcNetworkControllerTest,MaintainsLowRateInSafeResetTrial)622 TEST_F(GoogCcNetworkControllerTest, MaintainsLowRateInSafeResetTrial) {
623   const DataRate kLinkCapacity = DataRate::KilobitsPerSec(200);
624   const DataRate kStartRate = DataRate::KilobitsPerSec(300);
625 
626   ScopedFieldTrials trial("WebRTC-Bwe-SafeResetOnRouteChange/Enabled/");
627   Scenario s("googcc_unit/safe_reset_low");
628   auto* send_net = s.CreateSimulationNode([&](NetworkSimulationConfig* c) {
629     c->bandwidth = kLinkCapacity;
630     c->delay = TimeDelta::Millis(10);
631   });
632   auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
633     c->transport.rates.start_rate = kStartRate;
634   });
635   auto* route = s.CreateRoutes(
636       client, {send_net}, s.CreateClient("return", CallClientConfig()),
637       {s.CreateSimulationNode(NetworkSimulationConfig())});
638   s.CreateVideoStream(route->forward(), VideoStreamConfig());
639   // Allow the controller to stabilize.
640   s.RunFor(TimeDelta::Millis(500));
641   EXPECT_NEAR(client->send_bandwidth().kbps(), kLinkCapacity.kbps(), 50);
642   s.ChangeRoute(route->forward(), {send_net});
643   // Allow new settings to propagate.
644   s.RunFor(TimeDelta::Millis(100));
645   // Under the trial, the target should be unchanged for low rates.
646   EXPECT_NEAR(client->send_bandwidth().kbps(), kLinkCapacity.kbps(), 50);
647 }
648 
TEST_F(GoogCcNetworkControllerTest,CutsHighRateInSafeResetTrial)649 TEST_F(GoogCcNetworkControllerTest, CutsHighRateInSafeResetTrial) {
650   const DataRate kLinkCapacity = DataRate::KilobitsPerSec(1000);
651   const DataRate kStartRate = DataRate::KilobitsPerSec(300);
652 
653   ScopedFieldTrials trial("WebRTC-Bwe-SafeResetOnRouteChange/Enabled/");
654   Scenario s("googcc_unit/safe_reset_high_cut");
655   auto send_net = s.CreateSimulationNode([&](NetworkSimulationConfig* c) {
656     c->bandwidth = kLinkCapacity;
657     c->delay = TimeDelta::Millis(50);
658   });
659   auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
660     c->transport.rates.start_rate = kStartRate;
661   });
662   auto* route = s.CreateRoutes(
663       client, {send_net}, s.CreateClient("return", CallClientConfig()),
664       {s.CreateSimulationNode(NetworkSimulationConfig())});
665   s.CreateVideoStream(route->forward(), VideoStreamConfig());
666   // Allow the controller to stabilize.
667   s.RunFor(TimeDelta::Millis(500));
668   EXPECT_NEAR(client->send_bandwidth().kbps(), kLinkCapacity.kbps(), 300);
669   s.ChangeRoute(route->forward(), {send_net});
670   // Allow new settings to propagate.
671   s.RunFor(TimeDelta::Millis(50));
672   // Under the trial, the target should be reset from high values.
673   EXPECT_NEAR(client->send_bandwidth().kbps(), kStartRate.kbps(), 30);
674 }
675 
TEST_F(GoogCcNetworkControllerTest,DetectsHighRateInSafeResetTrial)676 TEST_F(GoogCcNetworkControllerTest, DetectsHighRateInSafeResetTrial) {
677   ScopedFieldTrials trial(
678       "WebRTC-Bwe-SafeResetOnRouteChange/Enabled,ack/"
679       "WebRTC-SendSideBwe-WithOverhead/Enabled/");
680   const DataRate kInitialLinkCapacity = DataRate::KilobitsPerSec(200);
681   const DataRate kNewLinkCapacity = DataRate::KilobitsPerSec(800);
682   const DataRate kStartRate = DataRate::KilobitsPerSec(300);
683 
684   Scenario s("googcc_unit/safe_reset_high_detect");
685   auto* initial_net = s.CreateSimulationNode([&](NetworkSimulationConfig* c) {
686     c->bandwidth = kInitialLinkCapacity;
687     c->delay = TimeDelta::Millis(50);
688   });
689   auto* new_net = s.CreateSimulationNode([&](NetworkSimulationConfig* c) {
690     c->bandwidth = kNewLinkCapacity;
691     c->delay = TimeDelta::Millis(50);
692   });
693   auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
694     c->transport.rates.start_rate = kStartRate;
695   });
696   auto* route = s.CreateRoutes(
697       client, {initial_net}, s.CreateClient("return", CallClientConfig()),
698       {s.CreateSimulationNode(NetworkSimulationConfig())});
699   s.CreateVideoStream(route->forward(), VideoStreamConfig());
700   // Allow the controller to stabilize.
701   s.RunFor(TimeDelta::Millis(1000));
702   EXPECT_NEAR(client->send_bandwidth().kbps(), kInitialLinkCapacity.kbps(), 50);
703   s.ChangeRoute(route->forward(), {new_net});
704   // Allow new settings to propagate, but not probes to be received.
705   s.RunFor(TimeDelta::Millis(50));
706   // Under the field trial, the target rate should be unchanged since it's lower
707   // than the starting rate.
708   EXPECT_NEAR(client->send_bandwidth().kbps(), kInitialLinkCapacity.kbps(), 50);
709   // However, probing should have made us detect the higher rate.
710   // NOTE: This test causes high loss rate, and the loss-based estimator reduces
711   // the bitrate, making the test fail if we wait longer than one second here.
712   s.RunFor(TimeDelta::Millis(1000));
713   EXPECT_GT(client->send_bandwidth().kbps(), kNewLinkCapacity.kbps() - 300);
714 }
715 
TEST_F(GoogCcNetworkControllerTest,TargetRateReducedOnPacingBufferBuildupInTrial)716 TEST_F(GoogCcNetworkControllerTest,
717        TargetRateReducedOnPacingBufferBuildupInTrial) {
718   // Configure strict pacing to ensure build-up.
719   ScopedFieldTrials trial(
720       "WebRTC-CongestionWindow/QueueSize:100,MinBitrate:30000/"
721       "WebRTC-Video-Pacing/factor:1.0/"
722       "WebRTC-AddPacingToCongestionWindowPushback/Enabled/");
723 
724   const DataRate kLinkCapacity = DataRate::KilobitsPerSec(1000);
725   const DataRate kStartRate = DataRate::KilobitsPerSec(1000);
726 
727   Scenario s("googcc_unit/pacing_buffer_buildup");
728   auto* net = s.CreateSimulationNode([&](NetworkSimulationConfig* c) {
729     c->bandwidth = kLinkCapacity;
730     c->delay = TimeDelta::Millis(50);
731   });
732   auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
733     c->transport.rates.start_rate = kStartRate;
734   });
735   auto* route = s.CreateRoutes(
736       client, {net}, s.CreateClient("return", CallClientConfig()),
737       {s.CreateSimulationNode(NetworkSimulationConfig())});
738   s.CreateVideoStream(route->forward(), VideoStreamConfig());
739   // Allow some time for the buffer to build up.
740   s.RunFor(TimeDelta::Seconds(5));
741 
742   // Without trial, pacer delay reaches ~250 ms.
743   EXPECT_LT(client->GetStats().pacer_delay_ms, 150);
744 }
745 
TEST_F(GoogCcNetworkControllerTest,NoBandwidthTogglingInLossControlTrial)746 TEST_F(GoogCcNetworkControllerTest, NoBandwidthTogglingInLossControlTrial) {
747   ScopedFieldTrials trial("WebRTC-Bwe-LossBasedControl/Enabled/");
748   Scenario s("googcc_unit/no_toggling");
749   auto* send_net = s.CreateSimulationNode([&](NetworkSimulationConfig* c) {
750     c->bandwidth = DataRate::KilobitsPerSec(2000);
751     c->loss_rate = 0.2;
752     c->delay = TimeDelta::Millis(10);
753   });
754 
755   auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
756     c->transport.rates.start_rate = DataRate::KilobitsPerSec(300);
757   });
758   auto* route = s.CreateRoutes(
759       client, {send_net}, s.CreateClient("return", CallClientConfig()),
760       {s.CreateSimulationNode(NetworkSimulationConfig())});
761   s.CreateVideoStream(route->forward(), VideoStreamConfig());
762   // Allow the controller to initialize.
763   s.RunFor(TimeDelta::Millis(250));
764 
765   std::queue<DataRate> bandwidth_history;
766   const TimeDelta step = TimeDelta::Millis(50);
767   for (TimeDelta time = TimeDelta::Zero(); time < TimeDelta::Millis(2000);
768        time += step) {
769     s.RunFor(step);
770     const TimeDelta window = TimeDelta::Millis(500);
771     if (bandwidth_history.size() >= window / step)
772       bandwidth_history.pop();
773     bandwidth_history.push(client->send_bandwidth());
774     EXPECT_LT(
775         CountBandwidthDips(bandwidth_history, DataRate::KilobitsPerSec(100)),
776         2);
777   }
778 }
779 
TEST_F(GoogCcNetworkControllerTest,NoRttBackoffCollapseWhenVideoStops)780 TEST_F(GoogCcNetworkControllerTest, NoRttBackoffCollapseWhenVideoStops) {
781   ScopedFieldTrials trial("WebRTC-Bwe-MaxRttLimit/limit:2s/");
782   Scenario s("googcc_unit/rttbackoff_video_stop");
783   auto* send_net = s.CreateSimulationNode([&](NetworkSimulationConfig* c) {
784     c->bandwidth = DataRate::KilobitsPerSec(2000);
785     c->delay = TimeDelta::Millis(100);
786   });
787 
788   auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
789     c->transport.rates.start_rate = DataRate::KilobitsPerSec(1000);
790   });
791   auto* route = s.CreateRoutes(
792       client, {send_net}, s.CreateClient("return", CallClientConfig()),
793       {s.CreateSimulationNode(NetworkSimulationConfig())});
794   auto* video = s.CreateVideoStream(route->forward(), VideoStreamConfig());
795   // Allow the controller to initialize, then stop video.
796   s.RunFor(TimeDelta::Seconds(1));
797   video->send()->Stop();
798   s.RunFor(TimeDelta::Seconds(4));
799   EXPECT_GT(client->send_bandwidth().kbps(), 1000);
800 }
801 
TEST_F(GoogCcNetworkControllerTest,NoCrashOnVeryLateFeedback)802 TEST_F(GoogCcNetworkControllerTest, NoCrashOnVeryLateFeedback) {
803   Scenario s;
804   auto ret_net = s.CreateMutableSimulationNode(NetworkSimulationConfig());
805   auto* route = s.CreateRoutes(
806       s.CreateClient("send", CallClientConfig()),
807       {s.CreateSimulationNode(NetworkSimulationConfig())},
808       s.CreateClient("return", CallClientConfig()), {ret_net->node()});
809   auto* video = s.CreateVideoStream(route->forward(), VideoStreamConfig());
810   s.RunFor(TimeDelta::Seconds(5));
811   // Delay feedback by several minutes. This will cause removal of the send time
812   // history for the packets as long as kSendTimeHistoryWindow is configured for
813   // a shorter time span.
814   ret_net->PauseTransmissionUntil(s.Now() + TimeDelta::Seconds(300));
815   // Stopping video stream while waiting to save test execution time.
816   video->send()->Stop();
817   s.RunFor(TimeDelta::Seconds(299));
818   // Starting to cause addition of new packet to history, which cause old
819   // packets to be removed.
820   video->send()->Start();
821   // Runs until the lost packets are received. We expect that this will run
822   // without causing any runtime failures.
823   s.RunFor(TimeDelta::Seconds(2));
824 }
825 
TEST_F(GoogCcNetworkControllerTest,IsFairToTCP)826 TEST_F(GoogCcNetworkControllerTest, IsFairToTCP) {
827   Scenario s("googcc_unit/tcp_fairness");
828   NetworkSimulationConfig net_conf;
829   net_conf.bandwidth = DataRate::KilobitsPerSec(1000);
830   net_conf.delay = TimeDelta::Millis(50);
831   auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
832     c->transport.rates.start_rate = DataRate::KilobitsPerSec(1000);
833   });
834   auto send_net = {s.CreateSimulationNode(net_conf)};
835   auto ret_net = {s.CreateSimulationNode(net_conf)};
836   auto* route = s.CreateRoutes(
837       client, send_net, s.CreateClient("return", CallClientConfig()), ret_net);
838   s.CreateVideoStream(route->forward(), VideoStreamConfig());
839   s.net()->StartFakeTcpCrossTraffic(send_net, ret_net, FakeTcpConfig());
840   s.RunFor(TimeDelta::Seconds(10));
841 
842   // Currently only testing for the upper limit as we in practice back out
843   // quite a lot in this scenario. If this behavior is fixed, we should add a
844   // lower bound to ensure it stays fixed.
845   EXPECT_LT(client->send_bandwidth().kbps(), 750);
846 }
847 
848 }  // namespace test
849 }  // namespace webrtc
850