Using simulated time for GoogCC tests.
Bug: webrtc:10365 Change-Id: I482e544f1585fdb54dc49740ba81870104dd58a0 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/130509 Commit-Queue: Sebastian Jansson <srte@webrtc.org> Reviewed-by: Christoffer Rodbro <crodbro@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27468}
This commit is contained in:
committed by
Commit Bot
parent
8f32b6c18c
commit
ebd94f6df1
@ -254,36 +254,8 @@ if (rtc_include_tests) {
|
||||
"//third_party/abseil-cpp/absl/memory",
|
||||
]
|
||||
}
|
||||
rtc_source_set("goog_cc_slow_tests") {
|
||||
testonly = true
|
||||
|
||||
sources = [
|
||||
"goog_cc_network_control_slowtest.cc",
|
||||
]
|
||||
deps = [
|
||||
":alr_detector",
|
||||
":delay_based_bwe",
|
||||
":estimators",
|
||||
":goog_cc",
|
||||
":probe_controller",
|
||||
":pushback_controller",
|
||||
"../../../api/transport:goog_cc",
|
||||
"../../../api/transport:network_control",
|
||||
"../../../api/transport:network_control_test",
|
||||
"../../../api/transport:webrtc_key_value_config",
|
||||
"../../../logging:mocks",
|
||||
"../../../rtc_base:checks",
|
||||
"../../../rtc_base:rtc_base_approved",
|
||||
"../../../rtc_base/experiments:alr_experiment",
|
||||
"../../../system_wrappers",
|
||||
"../../../test:field_trial",
|
||||
"../../../test:test_support",
|
||||
"../../../test/scenario",
|
||||
"../../pacing",
|
||||
"../../remote_bitrate_estimator",
|
||||
"../../rtp_rtcp:rtp_rtcp_format",
|
||||
"//testing/gmock",
|
||||
"//third_party/abseil-cpp/absl/memory",
|
||||
]
|
||||
# TODO(srte): Remove this target when dependency in root BUILD is gone.
|
||||
rtc_source_set("goog_cc_slow_tests") {
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,235 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include "api/transport/goog_cc_factory.h"
|
||||
#include "test/field_trial.h"
|
||||
#include "test/gtest.h"
|
||||
#include "test/scenario/scenario.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
namespace {
|
||||
// Count dips from a constant high bandwidth level within a short window.
|
||||
int CountBandwidthDips(std::queue<DataRate> bandwidth_history,
|
||||
DataRate threshold) {
|
||||
if (bandwidth_history.empty())
|
||||
return true;
|
||||
DataRate first = bandwidth_history.front();
|
||||
bandwidth_history.pop();
|
||||
|
||||
int dips = 0;
|
||||
bool state_high = true;
|
||||
while (!bandwidth_history.empty()) {
|
||||
if (bandwidth_history.front() + threshold < first && state_high) {
|
||||
++dips;
|
||||
state_high = false;
|
||||
} else if (bandwidth_history.front() == first) {
|
||||
state_high = true;
|
||||
} else if (bandwidth_history.front() > first) {
|
||||
// If this is toggling we will catch it later when front becomes first.
|
||||
state_high = false;
|
||||
}
|
||||
bandwidth_history.pop();
|
||||
}
|
||||
return dips;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(GoogCcNetworkControllerTest, MaintainsLowRateInSafeResetTrial) {
|
||||
const DataRate kLinkCapacity = DataRate::kbps(200);
|
||||
const DataRate kStartRate = DataRate::kbps(300);
|
||||
|
||||
ScopedFieldTrials trial("WebRTC-Bwe-SafeResetOnRouteChange/Enabled/");
|
||||
Scenario s("googcc_unit/safe_reset_low", true);
|
||||
auto* send_net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = kLinkCapacity;
|
||||
c->simulation.delay = TimeDelta::ms(10);
|
||||
});
|
||||
// TODO(srte): replace with SimulatedTimeClient when it supports probing.
|
||||
auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
|
||||
c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
|
||||
c->transport.rates.start_rate = kStartRate;
|
||||
});
|
||||
auto* route = s.CreateRoutes(client, {send_net},
|
||||
s.CreateClient("return", CallClientConfig()),
|
||||
{s.CreateSimulationNode(NetworkNodeConfig())});
|
||||
s.CreateVideoStream(route->forward(), VideoStreamConfig());
|
||||
// Allow the controller to stabilize.
|
||||
s.RunFor(TimeDelta::ms(500));
|
||||
EXPECT_NEAR(client->send_bandwidth().kbps(), kLinkCapacity.kbps(), 50);
|
||||
s.ChangeRoute(route->forward(), {send_net});
|
||||
// Allow new settings to propagate.
|
||||
s.RunFor(TimeDelta::ms(100));
|
||||
// Under the trial, the target should be unchanged for low rates.
|
||||
EXPECT_NEAR(client->send_bandwidth().kbps(), kLinkCapacity.kbps(), 50);
|
||||
}
|
||||
|
||||
TEST(GoogCcNetworkControllerTest, CutsHighRateInSafeResetTrial) {
|
||||
const DataRate kLinkCapacity = DataRate::kbps(1000);
|
||||
const DataRate kStartRate = DataRate::kbps(300);
|
||||
|
||||
ScopedFieldTrials trial("WebRTC-Bwe-SafeResetOnRouteChange/Enabled/");
|
||||
Scenario s("googcc_unit/safe_reset_high_cut", true);
|
||||
auto send_net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = kLinkCapacity;
|
||||
c->simulation.delay = TimeDelta::ms(50);
|
||||
});
|
||||
// TODO(srte): replace with SimulatedTimeClient when it supports probing.
|
||||
auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
|
||||
c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
|
||||
c->transport.rates.start_rate = kStartRate;
|
||||
});
|
||||
auto* route = s.CreateRoutes(client, {send_net},
|
||||
s.CreateClient("return", CallClientConfig()),
|
||||
{s.CreateSimulationNode(NetworkNodeConfig())});
|
||||
s.CreateVideoStream(route->forward(), VideoStreamConfig());
|
||||
// Allow the controller to stabilize.
|
||||
s.RunFor(TimeDelta::ms(500));
|
||||
EXPECT_NEAR(client->send_bandwidth().kbps(), kLinkCapacity.kbps(), 300);
|
||||
s.ChangeRoute(route->forward(), {send_net});
|
||||
// Allow new settings to propagate.
|
||||
s.RunFor(TimeDelta::ms(50));
|
||||
// Under the trial, the target should be reset from high values.
|
||||
EXPECT_NEAR(client->send_bandwidth().kbps(), kStartRate.kbps(), 30);
|
||||
}
|
||||
|
||||
TEST(GoogCcNetworkControllerTest, DetectsHighRateInSafeResetTrial) {
|
||||
ScopedFieldTrials trial(
|
||||
"WebRTC-Bwe-SafeResetOnRouteChange/Enabled,ack/"
|
||||
"WebRTC-Bwe-ProbeRateFallback/Enabled/");
|
||||
const DataRate kInitialLinkCapacity = DataRate::kbps(200);
|
||||
const DataRate kNewLinkCapacity = DataRate::kbps(800);
|
||||
const DataRate kStartRate = DataRate::kbps(300);
|
||||
|
||||
Scenario s("googcc_unit/safe_reset_high_detect", true);
|
||||
auto* initial_net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = kInitialLinkCapacity;
|
||||
c->simulation.delay = TimeDelta::ms(50);
|
||||
});
|
||||
auto* new_net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = kNewLinkCapacity;
|
||||
c->simulation.delay = TimeDelta::ms(50);
|
||||
});
|
||||
// TODO(srte): replace with SimulatedTimeClient when it supports probing.
|
||||
auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
|
||||
c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
|
||||
c->transport.rates.start_rate = kStartRate;
|
||||
});
|
||||
auto* route = s.CreateRoutes(client, {initial_net},
|
||||
s.CreateClient("return", CallClientConfig()),
|
||||
{s.CreateSimulationNode(NetworkNodeConfig())});
|
||||
s.CreateVideoStream(route->forward(), VideoStreamConfig());
|
||||
// Allow the controller to stabilize.
|
||||
s.RunFor(TimeDelta::ms(1000));
|
||||
EXPECT_NEAR(client->send_bandwidth().kbps(), kInitialLinkCapacity.kbps(), 50);
|
||||
s.ChangeRoute(route->forward(), {new_net});
|
||||
// Allow new settings to propagate, but not probes to be received.
|
||||
s.RunFor(TimeDelta::ms(50));
|
||||
// Under the field trial, the target rate should be unchanged since it's lower
|
||||
// than the starting rate.
|
||||
EXPECT_NEAR(client->send_bandwidth().kbps(), kInitialLinkCapacity.kbps(), 50);
|
||||
// However, probing should have made us detect the higher rate.
|
||||
s.RunFor(TimeDelta::ms(2000));
|
||||
EXPECT_GT(client->send_bandwidth().kbps(), kNewLinkCapacity.kbps() - 300);
|
||||
}
|
||||
|
||||
TEST(GoogCcNetworkControllerTest,
|
||||
TargetRateReducedOnPacingBufferBuildupInTrial) {
|
||||
// Configure strict pacing to ensure build-up.
|
||||
ScopedFieldTrials trial(
|
||||
"WebRTC-CongestionWindowPushback/Enabled/WebRTC-CwndExperiment/"
|
||||
"Enabled-100/WebRTC-Video-Pacing/factor:1.0/"
|
||||
"WebRTC-AddPacingToCongestionWindowPushback/Enabled/");
|
||||
|
||||
const DataRate kLinkCapacity = DataRate::kbps(1000);
|
||||
const DataRate kStartRate = DataRate::kbps(1000);
|
||||
|
||||
Scenario s("googcc_unit/pacing_buffer_buildup", true);
|
||||
auto* net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = kLinkCapacity;
|
||||
c->simulation.delay = TimeDelta::ms(50);
|
||||
});
|
||||
// TODO(srte): replace with SimulatedTimeClient when it supports pacing.
|
||||
auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
|
||||
c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
|
||||
c->transport.rates.start_rate = kStartRate;
|
||||
});
|
||||
auto* route = s.CreateRoutes(client, {net},
|
||||
s.CreateClient("return", CallClientConfig()),
|
||||
{s.CreateSimulationNode(NetworkNodeConfig())});
|
||||
s.CreateVideoStream(route->forward(), VideoStreamConfig());
|
||||
// Allow some time for the buffer to build up.
|
||||
s.RunFor(TimeDelta::seconds(5));
|
||||
|
||||
// Without trial, pacer delay reaches ~250 ms.
|
||||
EXPECT_LT(client->GetStats().pacer_delay_ms, 150);
|
||||
}
|
||||
|
||||
TEST(GoogCcNetworkControllerTest, NoBandwidthTogglingInLossControlTrial) {
|
||||
ScopedFieldTrials trial("WebRTC-Bwe-LossBasedControl/Enabled/");
|
||||
Scenario s("googcc_unit/no_toggling", true);
|
||||
auto* send_net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = DataRate::kbps(2000);
|
||||
c->simulation.loss_rate = 0.2;
|
||||
c->simulation.delay = TimeDelta::ms(10);
|
||||
});
|
||||
|
||||
// TODO(srte): replace with SimulatedTimeClient when it supports probing.
|
||||
auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
|
||||
c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
|
||||
c->transport.rates.start_rate = DataRate::kbps(300);
|
||||
});
|
||||
auto* route = s.CreateRoutes(client, {send_net},
|
||||
s.CreateClient("return", CallClientConfig()),
|
||||
{s.CreateSimulationNode(NetworkNodeConfig())});
|
||||
s.CreateVideoStream(route->forward(), VideoStreamConfig());
|
||||
// Allow the controller to initialize.
|
||||
s.RunFor(TimeDelta::ms(250));
|
||||
|
||||
std::queue<DataRate> bandwidth_history;
|
||||
const TimeDelta step = TimeDelta::ms(50);
|
||||
for (TimeDelta time = TimeDelta::Zero(); time < TimeDelta::ms(2000);
|
||||
time += step) {
|
||||
s.RunFor(step);
|
||||
const TimeDelta window = TimeDelta::ms(500);
|
||||
if (bandwidth_history.size() >= window / step)
|
||||
bandwidth_history.pop();
|
||||
bandwidth_history.push(client->send_bandwidth());
|
||||
EXPECT_LT(CountBandwidthDips(bandwidth_history, DataRate::kbps(100)), 2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(GoogCcNetworkControllerTest, NoRttBackoffCollapseWhenVideoStops) {
|
||||
ScopedFieldTrials trial("WebRTC-Bwe-MaxRttLimit/limit:2s/");
|
||||
Scenario s("googcc_unit/rttbackoff_video_stop", true);
|
||||
auto* send_net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = DataRate::kbps(2000);
|
||||
c->simulation.delay = TimeDelta::ms(100);
|
||||
});
|
||||
|
||||
auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
|
||||
c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
|
||||
c->transport.rates.start_rate = DataRate::kbps(1000);
|
||||
});
|
||||
auto* route = s.CreateRoutes(client, {send_net},
|
||||
s.CreateClient("return", CallClientConfig()),
|
||||
{s.CreateSimulationNode(NetworkNodeConfig())});
|
||||
auto* video = s.CreateVideoStream(route->forward(), VideoStreamConfig());
|
||||
// Allow the controller to initialize, then stop video.
|
||||
s.RunFor(TimeDelta::seconds(1));
|
||||
video->send()->Stop();
|
||||
s.RunFor(TimeDelta::seconds(4));
|
||||
EXPECT_GT(client->send_bandwidth().kbps(), 1000);
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
@ -8,6 +8,8 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include "api/transport/goog_cc_factory.h"
|
||||
#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
|
||||
#include "test/field_trial.h"
|
||||
@ -23,6 +25,30 @@ using testing::_;
|
||||
namespace webrtc {
|
||||
namespace test {
|
||||
namespace {
|
||||
// Count dips from a constant high bandwidth level within a short window.
|
||||
int CountBandwidthDips(std::queue<DataRate> bandwidth_history,
|
||||
DataRate threshold) {
|
||||
if (bandwidth_history.empty())
|
||||
return true;
|
||||
DataRate first = bandwidth_history.front();
|
||||
bandwidth_history.pop();
|
||||
|
||||
int dips = 0;
|
||||
bool state_high = true;
|
||||
while (!bandwidth_history.empty()) {
|
||||
if (bandwidth_history.front() + threshold < first && state_high) {
|
||||
++dips;
|
||||
state_high = false;
|
||||
} else if (bandwidth_history.front() == first) {
|
||||
state_high = true;
|
||||
} else if (bandwidth_history.front() > first) {
|
||||
// If this is toggling we will catch it later when front becomes first.
|
||||
state_high = false;
|
||||
}
|
||||
bandwidth_history.pop();
|
||||
}
|
||||
return dips;
|
||||
}
|
||||
|
||||
const uint32_t kInitialBitrateKbps = 60;
|
||||
const DataRate kInitialBitrate = DataRate::kbps(kInitialBitrateKbps);
|
||||
@ -505,5 +531,192 @@ TEST_F(GoogCcNetworkControllerTest, LossBasedEstimatorCapsRateAtModerateLoss) {
|
||||
EXPECT_LT(client->target_rate_kbps(), 3000);
|
||||
}
|
||||
|
||||
TEST_F(GoogCcNetworkControllerTest, MaintainsLowRateInSafeResetTrial) {
|
||||
const DataRate kLinkCapacity = DataRate::kbps(200);
|
||||
const DataRate kStartRate = DataRate::kbps(300);
|
||||
|
||||
ScopedFieldTrials trial("WebRTC-Bwe-SafeResetOnRouteChange/Enabled/");
|
||||
Scenario s("googcc_unit/safe_reset_low");
|
||||
auto* send_net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = kLinkCapacity;
|
||||
c->simulation.delay = TimeDelta::ms(10);
|
||||
});
|
||||
// TODO(srte): replace with SimulatedTimeClient when it supports probing.
|
||||
auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
|
||||
c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
|
||||
c->transport.rates.start_rate = kStartRate;
|
||||
});
|
||||
auto* route = s.CreateRoutes(client, {send_net},
|
||||
s.CreateClient("return", CallClientConfig()),
|
||||
{s.CreateSimulationNode(NetworkNodeConfig())});
|
||||
s.CreateVideoStream(route->forward(), VideoStreamConfig());
|
||||
// Allow the controller to stabilize.
|
||||
s.RunFor(TimeDelta::ms(500));
|
||||
EXPECT_NEAR(client->send_bandwidth().kbps(), kLinkCapacity.kbps(), 50);
|
||||
s.ChangeRoute(route->forward(), {send_net});
|
||||
// Allow new settings to propagate.
|
||||
s.RunFor(TimeDelta::ms(100));
|
||||
// Under the trial, the target should be unchanged for low rates.
|
||||
EXPECT_NEAR(client->send_bandwidth().kbps(), kLinkCapacity.kbps(), 50);
|
||||
}
|
||||
|
||||
TEST_F(GoogCcNetworkControllerTest, CutsHighRateInSafeResetTrial) {
|
||||
const DataRate kLinkCapacity = DataRate::kbps(1000);
|
||||
const DataRate kStartRate = DataRate::kbps(300);
|
||||
|
||||
ScopedFieldTrials trial("WebRTC-Bwe-SafeResetOnRouteChange/Enabled/");
|
||||
Scenario s("googcc_unit/safe_reset_high_cut");
|
||||
auto send_net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = kLinkCapacity;
|
||||
c->simulation.delay = TimeDelta::ms(50);
|
||||
});
|
||||
// TODO(srte): replace with SimulatedTimeClient when it supports probing.
|
||||
auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
|
||||
c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
|
||||
c->transport.rates.start_rate = kStartRate;
|
||||
});
|
||||
auto* route = s.CreateRoutes(client, {send_net},
|
||||
s.CreateClient("return", CallClientConfig()),
|
||||
{s.CreateSimulationNode(NetworkNodeConfig())});
|
||||
s.CreateVideoStream(route->forward(), VideoStreamConfig());
|
||||
// Allow the controller to stabilize.
|
||||
s.RunFor(TimeDelta::ms(500));
|
||||
EXPECT_NEAR(client->send_bandwidth().kbps(), kLinkCapacity.kbps(), 300);
|
||||
s.ChangeRoute(route->forward(), {send_net});
|
||||
// Allow new settings to propagate.
|
||||
s.RunFor(TimeDelta::ms(50));
|
||||
// Under the trial, the target should be reset from high values.
|
||||
EXPECT_NEAR(client->send_bandwidth().kbps(), kStartRate.kbps(), 30);
|
||||
}
|
||||
|
||||
TEST_F(GoogCcNetworkControllerTest, DetectsHighRateInSafeResetTrial) {
|
||||
ScopedFieldTrials trial(
|
||||
"WebRTC-Bwe-SafeResetOnRouteChange/Enabled,ack/"
|
||||
"WebRTC-Bwe-ProbeRateFallback/Enabled/");
|
||||
const DataRate kInitialLinkCapacity = DataRate::kbps(200);
|
||||
const DataRate kNewLinkCapacity = DataRate::kbps(800);
|
||||
const DataRate kStartRate = DataRate::kbps(300);
|
||||
|
||||
Scenario s("googcc_unit/safe_reset_high_detect");
|
||||
auto* initial_net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = kInitialLinkCapacity;
|
||||
c->simulation.delay = TimeDelta::ms(50);
|
||||
});
|
||||
auto* new_net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = kNewLinkCapacity;
|
||||
c->simulation.delay = TimeDelta::ms(50);
|
||||
});
|
||||
// TODO(srte): replace with SimulatedTimeClient when it supports probing.
|
||||
auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
|
||||
c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
|
||||
c->transport.rates.start_rate = kStartRate;
|
||||
});
|
||||
auto* route = s.CreateRoutes(client, {initial_net},
|
||||
s.CreateClient("return", CallClientConfig()),
|
||||
{s.CreateSimulationNode(NetworkNodeConfig())});
|
||||
s.CreateVideoStream(route->forward(), VideoStreamConfig());
|
||||
// Allow the controller to stabilize.
|
||||
s.RunFor(TimeDelta::ms(1000));
|
||||
EXPECT_NEAR(client->send_bandwidth().kbps(), kInitialLinkCapacity.kbps(), 50);
|
||||
s.ChangeRoute(route->forward(), {new_net});
|
||||
// Allow new settings to propagate, but not probes to be received.
|
||||
s.RunFor(TimeDelta::ms(50));
|
||||
// Under the field trial, the target rate should be unchanged since it's lower
|
||||
// than the starting rate.
|
||||
EXPECT_NEAR(client->send_bandwidth().kbps(), kInitialLinkCapacity.kbps(), 50);
|
||||
// However, probing should have made us detect the higher rate.
|
||||
s.RunFor(TimeDelta::ms(2000));
|
||||
EXPECT_GT(client->send_bandwidth().kbps(), kNewLinkCapacity.kbps() - 300);
|
||||
}
|
||||
|
||||
TEST_F(GoogCcNetworkControllerTest,
|
||||
TargetRateReducedOnPacingBufferBuildupInTrial) {
|
||||
// Configure strict pacing to ensure build-up.
|
||||
ScopedFieldTrials trial(
|
||||
"WebRTC-CongestionWindowPushback/Enabled/WebRTC-CwndExperiment/"
|
||||
"Enabled-100/WebRTC-Video-Pacing/factor:1.0/"
|
||||
"WebRTC-AddPacingToCongestionWindowPushback/Enabled/");
|
||||
|
||||
const DataRate kLinkCapacity = DataRate::kbps(1000);
|
||||
const DataRate kStartRate = DataRate::kbps(1000);
|
||||
|
||||
Scenario s("googcc_unit/pacing_buffer_buildup");
|
||||
auto* net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = kLinkCapacity;
|
||||
c->simulation.delay = TimeDelta::ms(50);
|
||||
});
|
||||
// TODO(srte): replace with SimulatedTimeClient when it supports pacing.
|
||||
auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
|
||||
c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
|
||||
c->transport.rates.start_rate = kStartRate;
|
||||
});
|
||||
auto* route = s.CreateRoutes(client, {net},
|
||||
s.CreateClient("return", CallClientConfig()),
|
||||
{s.CreateSimulationNode(NetworkNodeConfig())});
|
||||
s.CreateVideoStream(route->forward(), VideoStreamConfig());
|
||||
// Allow some time for the buffer to build up.
|
||||
s.RunFor(TimeDelta::seconds(5));
|
||||
|
||||
// Without trial, pacer delay reaches ~250 ms.
|
||||
EXPECT_LT(client->GetStats().pacer_delay_ms, 150);
|
||||
}
|
||||
|
||||
TEST_F(GoogCcNetworkControllerTest, NoBandwidthTogglingInLossControlTrial) {
|
||||
ScopedFieldTrials trial("WebRTC-Bwe-LossBasedControl/Enabled/");
|
||||
Scenario s("googcc_unit/no_toggling");
|
||||
auto* send_net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = DataRate::kbps(2000);
|
||||
c->simulation.loss_rate = 0.2;
|
||||
c->simulation.delay = TimeDelta::ms(10);
|
||||
});
|
||||
|
||||
// TODO(srte): replace with SimulatedTimeClient when it supports probing.
|
||||
auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
|
||||
c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
|
||||
c->transport.rates.start_rate = DataRate::kbps(300);
|
||||
});
|
||||
auto* route = s.CreateRoutes(client, {send_net},
|
||||
s.CreateClient("return", CallClientConfig()),
|
||||
{s.CreateSimulationNode(NetworkNodeConfig())});
|
||||
s.CreateVideoStream(route->forward(), VideoStreamConfig());
|
||||
// Allow the controller to initialize.
|
||||
s.RunFor(TimeDelta::ms(250));
|
||||
|
||||
std::queue<DataRate> bandwidth_history;
|
||||
const TimeDelta step = TimeDelta::ms(50);
|
||||
for (TimeDelta time = TimeDelta::Zero(); time < TimeDelta::ms(2000);
|
||||
time += step) {
|
||||
s.RunFor(step);
|
||||
const TimeDelta window = TimeDelta::ms(500);
|
||||
if (bandwidth_history.size() >= window / step)
|
||||
bandwidth_history.pop();
|
||||
bandwidth_history.push(client->send_bandwidth());
|
||||
EXPECT_LT(CountBandwidthDips(bandwidth_history, DataRate::kbps(100)), 2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(GoogCcNetworkControllerTest, NoRttBackoffCollapseWhenVideoStops) {
|
||||
ScopedFieldTrials trial("WebRTC-Bwe-MaxRttLimit/limit:2s/");
|
||||
Scenario s("googcc_unit/rttbackoff_video_stop");
|
||||
auto* send_net = s.CreateSimulationNode([&](NetworkNodeConfig* c) {
|
||||
c->simulation.bandwidth = DataRate::kbps(2000);
|
||||
c->simulation.delay = TimeDelta::ms(100);
|
||||
});
|
||||
|
||||
auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
|
||||
c->transport.cc = TransportControllerConfig::CongestionController::kGoogCc;
|
||||
c->transport.rates.start_rate = DataRate::kbps(1000);
|
||||
});
|
||||
auto* route = s.CreateRoutes(client, {send_net},
|
||||
s.CreateClient("return", CallClientConfig()),
|
||||
{s.CreateSimulationNode(NetworkNodeConfig())});
|
||||
auto* video = s.CreateVideoStream(route->forward(), VideoStreamConfig());
|
||||
// Allow the controller to initialize, then stop video.
|
||||
s.RunFor(TimeDelta::seconds(1));
|
||||
video->send()->Stop();
|
||||
s.RunFor(TimeDelta::seconds(4));
|
||||
EXPECT_GT(client->send_bandwidth().kbps(), 1000);
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
|
||||
@ -56,9 +56,11 @@ std::unique_ptr<TimeController> CreateTimeController(bool real_time) {
|
||||
}
|
||||
|
||||
Scenario::Scenario()
|
||||
: Scenario(std::unique_ptr<LogWriterFactoryInterface>(), true) {}
|
||||
: Scenario(std::unique_ptr<LogWriterFactoryInterface>(),
|
||||
/*real_time=*/false) {}
|
||||
|
||||
Scenario::Scenario(std::string file_name) : Scenario(file_name, true) {}
|
||||
Scenario::Scenario(std::string file_name)
|
||||
: Scenario(file_name, /*real_time=*/false) {}
|
||||
|
||||
Scenario::Scenario(std::string file_name, bool real_time)
|
||||
: Scenario(GetScenarioLogManager(file_name), real_time) {}
|
||||
|
||||
Reference in New Issue
Block a user