Add cross trafic emulation api
Bug: webrtc:12344
Change-Id: I958dc4deda4af4576818600c31aecdf48285172f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/200981
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Commit-Queue: Andrey Logvin <landrey@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32989}
diff --git a/api/test/network_emulation/BUILD.gn b/api/test/network_emulation/BUILD.gn
index fb7bedc..58cd27d 100644
--- a/api/test/network_emulation/BUILD.gn
+++ b/api/test/network_emulation/BUILD.gn
@@ -12,6 +12,7 @@
visibility = [ "*" ]
sources = [
+ "cross_traffic.h",
"network_emulation_interfaces.cc",
"network_emulation_interfaces.h",
]
@@ -22,9 +23,28 @@
"../../../rtc_base:checks",
"../../../rtc_base:rtc_base_approved",
"../../numerics",
+ "../../task_queue",
"../../units:data_rate",
"../../units:data_size",
+ "../../units:time_delta",
"../../units:timestamp",
]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}
+
+rtc_library("create_cross_traffic") {
+ visibility = [ "*" ]
+ testonly = true
+
+ sources = [
+ "create_cross_traffic.cc",
+ "create_cross_traffic.h",
+ ]
+
+ deps = [
+ ":network_emulation",
+ "../..:network_emulation_manager_api",
+ "../../../rtc_base/task_utils:repeating_task",
+ "../../../test/network:emulated_network",
+ ]
+}
diff --git a/api/test/network_emulation/create_cross_traffic.cc b/api/test/network_emulation/create_cross_traffic.cc
new file mode 100644
index 0000000..36a535c
--- /dev/null
+++ b/api/test/network_emulation/create_cross_traffic.cc
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2021 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 "api/test/network_emulation/create_cross_traffic.h"
+
+#include <memory>
+
+#include "rtc_base/task_utils/repeating_task.h"
+#include "test/network/cross_traffic.h"
+
+namespace webrtc {
+
+std::unique_ptr<CrossTrafficGenerator> CreateRandomWalkCrossTraffic(
+ CrossTrafficRoute* traffic_route,
+ RandomWalkConfig config) {
+ return std::make_unique<test::RandomWalkCrossTraffic>(config, traffic_route);
+}
+
+std::unique_ptr<CrossTrafficGenerator> CreatePulsedPeaksCrossTraffic(
+ CrossTrafficRoute* traffic_route,
+ PulsedPeaksConfig config) {
+ return std::make_unique<test::PulsedPeaksCrossTraffic>(config, traffic_route);
+}
+
+std::unique_ptr<CrossTrafficGenerator> CreateFakeTcpCrossTraffic(
+ EmulatedRoute* send_route,
+ EmulatedRoute* ret_route,
+ FakeTcpConfig config) {
+ return std::make_unique<test::FakeTcpCrossTraffic>(config, send_route,
+ ret_route);
+}
+
+} // namespace webrtc
diff --git a/api/test/network_emulation/create_cross_traffic.h b/api/test/network_emulation/create_cross_traffic.h
new file mode 100644
index 0000000..42fc855
--- /dev/null
+++ b/api/test/network_emulation/create_cross_traffic.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021 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.
+ */
+#ifndef API_TEST_NETWORK_EMULATION_CREATE_CROSS_TRAFFIC_H_
+#define API_TEST_NETWORK_EMULATION_CREATE_CROSS_TRAFFIC_H_
+
+#include <memory>
+
+#include "api/test/network_emulation/cross_traffic.h"
+#include "api/test/network_emulation_manager.h"
+
+namespace webrtc {
+
+// This API is still in development and can be changed without prior notice.
+
+std::unique_ptr<CrossTrafficGenerator> CreateRandomWalkCrossTraffic(
+ CrossTrafficRoute* traffic_route,
+ RandomWalkConfig config);
+
+std::unique_ptr<CrossTrafficGenerator> CreatePulsedPeaksCrossTraffic(
+ CrossTrafficRoute* traffic_route,
+ PulsedPeaksConfig config);
+
+std::unique_ptr<CrossTrafficGenerator> CreateFakeTcpCrossTraffic(
+ EmulatedRoute* send_route,
+ EmulatedRoute* ret_route,
+ FakeTcpConfig config);
+
+} // namespace webrtc
+
+#endif // API_TEST_NETWORK_EMULATION_CREATE_CROSS_TRAFFIC_H_
diff --git a/api/test/network_emulation/cross_traffic.h b/api/test/network_emulation/cross_traffic.h
new file mode 100644
index 0000000..85343e4
--- /dev/null
+++ b/api/test/network_emulation/cross_traffic.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2021 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.
+ */
+#ifndef API_TEST_NETWORK_EMULATION_CROSS_TRAFFIC_H_
+#define API_TEST_NETWORK_EMULATION_CROSS_TRAFFIC_H_
+
+#include "api/task_queue/task_queue_base.h"
+#include "api/test/network_emulation/network_emulation_interfaces.h"
+#include "api/units/data_rate.h"
+#include "api/units/data_size.h"
+#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
+
+namespace webrtc {
+
+// This API is still in development and can be changed without prior notice.
+
+// Represents the endpoint for cross traffic that is going through the network.
+// It can be used to emulate unexpected network load.
+class CrossTrafficRoute {
+ public:
+ virtual ~CrossTrafficRoute() = default;
+
+ // Triggers sending of dummy packets with size |packet_size| bytes.
+ virtual void TriggerPacketBurst(size_t num_packets, size_t packet_size) = 0;
+ // Sends a packet over the nodes. The content of the packet is unspecified;
+ // only the size metter for the emulation purposes.
+ virtual void SendPacket(size_t packet_size) = 0;
+ // Sends a packet over the nodes and runs |action| when it has been delivered.
+ virtual void NetworkDelayedAction(size_t packet_size,
+ std::function<void()> action) = 0;
+};
+
+// Describes a way of generating cross traffic on some route. Used by
+// NetworkEmulationManager to produce cross traffic during some period of time.
+class CrossTrafficGenerator {
+ public:
+ virtual ~CrossTrafficGenerator() = default;
+
+ // Time between Process calls.
+ virtual TimeDelta GetProcessInterval() const = 0;
+
+ // Called periodically by NetworkEmulationManager. Generates traffic on the
+ // route.
+ virtual void Process(Timestamp at_time) = 0;
+};
+
+// Config of a cross traffic generator. Generated traffic rises and falls
+// randomly.
+struct RandomWalkConfig {
+ int random_seed = 1;
+ DataRate peak_rate = DataRate::KilobitsPerSec(100);
+ DataSize min_packet_size = DataSize::Bytes(200);
+ TimeDelta min_packet_interval = TimeDelta::Millis(1);
+ TimeDelta update_interval = TimeDelta::Millis(200);
+ double variance = 0.6;
+ double bias = -0.1;
+};
+
+// Config of a cross traffic generator. Generated traffic has form of periodic
+// peaks alternating with periods of silence.
+struct PulsedPeaksConfig {
+ DataRate peak_rate = DataRate::KilobitsPerSec(100);
+ DataSize min_packet_size = DataSize::Bytes(200);
+ TimeDelta min_packet_interval = TimeDelta::Millis(1);
+ TimeDelta send_duration = TimeDelta::Millis(100);
+ TimeDelta hold_duration = TimeDelta::Millis(2000);
+};
+
+struct FakeTcpConfig {
+ DataSize packet_size = DataSize::Bytes(1200);
+ DataSize send_limit = DataSize::PlusInfinity();
+ TimeDelta process_interval = TimeDelta::Millis(200);
+ TimeDelta packet_timeout = TimeDelta::Seconds(1);
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_NETWORK_EMULATION_CROSS_TRAFFIC_H_
diff --git a/api/test/network_emulation_manager.h b/api/test/network_emulation_manager.h
index 80efb0e..4857c87 100644
--- a/api/test/network_emulation_manager.h
+++ b/api/test/network_emulation_manager.h
@@ -17,6 +17,7 @@
#include <vector>
#include "api/array_view.h"
+#include "api/test/network_emulation/cross_traffic.h"
#include "api/test/network_emulation/network_emulation_interfaces.h"
#include "api/test/simulated_network.h"
#include "api/test/time_controller.h"
@@ -223,7 +224,8 @@
// Removes route previously created by CreateRoute(...).
// Caller mustn't call this function with route, that have been already
- // removed earlier.
+ // removed earlier. Removing a route that is currently in use will lead to
+ // packets being dropped.
virtual void ClearRoute(EmulatedRoute* route) = 0;
// Creates a simulated TCP connection using |send_route| for traffic and
@@ -233,6 +235,20 @@
virtual TcpMessageRoute* CreateTcpRoute(EmulatedRoute* send_route,
EmulatedRoute* ret_route) = 0;
+ // Creates a route over the given |via_nodes|. Returns an object that can be
+ // used to emulate network load with cross traffic over the created route.
+ virtual CrossTrafficRoute* CreateCrossTrafficRoute(
+ const std::vector<EmulatedNetworkNode*>& via_nodes) = 0;
+
+ // Starts generating cross traffic using given |generator|. Takes ownership
+ // over the generator.
+ virtual CrossTrafficGenerator* StartCrossTraffic(
+ std::unique_ptr<CrossTrafficGenerator> generator) = 0;
+
+ // Stops generating cross traffic that was started using given |generator|.
+ // The |generator| shouldn't be used after and the reference may be invalid.
+ virtual void StopCrossTraffic(CrossTrafficGenerator* generator) = 0;
+
// Creates EmulatedNetworkManagerInterface which can be used then to inject
// network emulation layer into PeerConnection. |endpoints| - are available
// network interfaces for PeerConnection. If endpoint is enabled, it will be
diff --git a/modules/congestion_controller/BUILD.gn b/modules/congestion_controller/BUILD.gn
index 231ff5e..750e910 100644
--- a/modules/congestion_controller/BUILD.gn
+++ b/modules/congestion_controller/BUILD.gn
@@ -46,6 +46,8 @@
sources = [ "receive_side_congestion_controller_unittest.cc" ]
deps = [
":congestion_controller",
+ "../../api/test/network_emulation",
+ "../../api/test/network_emulation:create_cross_traffic",
"../../system_wrappers",
"../../test:test_support",
"../../test/scenario",
diff --git a/modules/congestion_controller/goog_cc/BUILD.gn b/modules/congestion_controller/goog_cc/BUILD.gn
index e3be246..a5bcf57 100644
--- a/modules/congestion_controller/goog_cc/BUILD.gn
+++ b/modules/congestion_controller/goog_cc/BUILD.gn
@@ -283,6 +283,8 @@
":probe_controller",
":pushback_controller",
"../../../api/rtc_event_log",
+ "../../../api/test/network_emulation",
+ "../../../api/test/network_emulation:create_cross_traffic",
"../../../api/transport:field_trial_based_config",
"../../../api/transport:goog_cc",
"../../../api/transport:network_control",
diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc b/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc
index 0510cb9..8eb4a00 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc
@@ -10,6 +10,8 @@
#include <queue>
+#include "api/test/network_emulation/create_cross_traffic.h"
+#include "api/test/network_emulation/cross_traffic.h"
#include "api/transport/goog_cc_factory.h"
#include "api/units/data_rate.h"
#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
@@ -547,8 +549,9 @@
s.RunFor(TimeDelta::Seconds(10));
for (int i = 0; i < 4; ++i) {
// Sends TCP cross traffic inducing loss.
- auto* tcp_traffic =
- s.net()->StartFakeTcpCrossTraffic(send_net, ret_net, FakeTcpConfig());
+ auto* tcp_traffic = s.net()->StartCrossTraffic(CreateFakeTcpCrossTraffic(
+ s.net()->CreateRoute(send_net), s.net()->CreateRoute(ret_net),
+ FakeTcpConfig()));
s.RunFor(TimeDelta::Seconds(2));
// Allow the ccongestion controller to recover.
s.net()->StopCrossTraffic(tcp_traffic);
@@ -836,7 +839,9 @@
auto* route = s.CreateRoutes(
client, send_net, s.CreateClient("return", CallClientConfig()), ret_net);
s.CreateVideoStream(route->forward(), VideoStreamConfig());
- s.net()->StartFakeTcpCrossTraffic(send_net, ret_net, FakeTcpConfig());
+ s.net()->StartCrossTraffic(CreateFakeTcpCrossTraffic(
+ s.net()->CreateRoute(send_net), s.net()->CreateRoute(ret_net),
+ FakeTcpConfig()));
s.RunFor(TimeDelta::Seconds(10));
// Currently only testing for the upper limit as we in practice back out
diff --git a/modules/congestion_controller/receive_side_congestion_controller_unittest.cc b/modules/congestion_controller/receive_side_congestion_controller_unittest.cc
index b584623..5622c84 100644
--- a/modules/congestion_controller/receive_side_congestion_controller_unittest.cc
+++ b/modules/congestion_controller/receive_side_congestion_controller_unittest.cc
@@ -10,6 +10,8 @@
#include "modules/congestion_controller/include/receive_side_congestion_controller.h"
+#include "api/test/network_emulation/create_cross_traffic.h"
+#include "api/test/network_emulation/cross_traffic.h"
#include "modules/pacing/packet_router.h"
#include "system_wrappers/include/clock.h"
#include "test/gmock.h"
@@ -109,7 +111,9 @@
VideoStreamConfig video;
video.stream.packet_feedback = false;
s.CreateVideoStream(route->forward(), video);
- s.net()->StartFakeTcpCrossTraffic(send_net, ret_net, FakeTcpConfig());
+ s.net()->StartCrossTraffic(CreateFakeTcpCrossTraffic(
+ s.net()->CreateRoute(send_net), s.net()->CreateRoute(ret_net),
+ FakeTcpConfig()));
s.RunFor(TimeDelta::Seconds(30));
// For some reason we get outcompeted by TCP here, this should probably be
// fixed and a lower bound should be added to the test.
diff --git a/test/network/BUILD.gn b/test/network/BUILD.gn
index 383f149..e250ccb 100644
--- a/test/network/BUILD.gn
+++ b/test/network/BUILD.gn
@@ -12,6 +12,7 @@
visibility = [
":*",
"../../api:create_network_emulation_manager",
+ "../../api/test/network_emulation:create_cross_traffic",
]
if (rtc_include_tests) {
visibility += [
diff --git a/test/network/cross_traffic.cc b/test/network/cross_traffic.cc
index 56e7635..ae5b156 100644
--- a/test/network/cross_traffic.cc
+++ b/test/network/cross_traffic.cc
@@ -24,7 +24,7 @@
namespace test {
RandomWalkCrossTraffic::RandomWalkCrossTraffic(RandomWalkConfig config,
- TrafficRoute* traffic_route)
+ CrossTrafficRoute* traffic_route)
: config_(config),
traffic_route_(traffic_route),
random_(config_.random_seed) {
@@ -56,6 +56,10 @@
}
}
+TimeDelta RandomWalkCrossTraffic::GetProcessInterval() const {
+ return config_.min_packet_interval;
+}
+
DataRate RandomWalkCrossTraffic::TrafficRate() const {
RTC_DCHECK_RUN_ON(&sequence_checker_);
return config_.peak_rate * intensity_;
@@ -70,8 +74,9 @@
32);
}
-PulsedPeaksCrossTraffic::PulsedPeaksCrossTraffic(PulsedPeaksConfig config,
- TrafficRoute* traffic_route)
+PulsedPeaksCrossTraffic::PulsedPeaksCrossTraffic(
+ PulsedPeaksConfig config,
+ CrossTrafficRoute* traffic_route)
: config_(config), traffic_route_(traffic_route) {
sequence_checker_.Detach();
}
@@ -102,6 +107,10 @@
}
}
+TimeDelta PulsedPeaksCrossTraffic::GetProcessInterval() const {
+ return config_.min_packet_interval;
+}
+
DataRate PulsedPeaksCrossTraffic::TrafficRate() const {
RTC_DCHECK_RUN_ON(&sequence_checker_);
return sending_ ? config_.peak_rate : DataRate::Zero();
@@ -240,21 +249,13 @@
}
}
-FakeTcpCrossTraffic::FakeTcpCrossTraffic(Clock* clock,
- FakeTcpConfig config,
+FakeTcpCrossTraffic::FakeTcpCrossTraffic(FakeTcpConfig config,
EmulatedRoute* send_route,
EmulatedRoute* ret_route)
- : clock_(clock), conf_(config), route_(this, send_route, ret_route) {}
+ : conf_(config), route_(this, send_route, ret_route) {}
-void FakeTcpCrossTraffic::Start(TaskQueueBase* task_queue) {
- repeating_task_handle_ = RepeatingTaskHandle::Start(task_queue, [this] {
- Process(clock_->CurrentTime());
- return conf_.process_interval;
- });
-}
-
-void FakeTcpCrossTraffic::Stop() {
- repeating_task_handle_.Stop();
+TimeDelta FakeTcpCrossTraffic::GetProcessInterval() const {
+ return conf_.process_interval;
}
void FakeTcpCrossTraffic::Process(Timestamp at_time) {
diff --git a/test/network/cross_traffic.h b/test/network/cross_traffic.h
index 942b863..9ed41a9 100644
--- a/test/network/cross_traffic.h
+++ b/test/network/cross_traffic.h
@@ -15,41 +15,34 @@
#include <map>
#include <memory>
+#include "api/test/network_emulation_manager.h"
#include "api/units/data_rate.h"
#include "api/units/data_size.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "rtc_base/random.h"
#include "rtc_base/synchronization/sequence_checker.h"
-#include "test/network/traffic_route.h"
+#include "test/network/network_emulation.h"
#include "test/scenario/column_printer.h"
namespace webrtc {
namespace test {
-struct RandomWalkConfig {
- int random_seed = 1;
- DataRate peak_rate = DataRate::KilobitsPerSec(100);
- DataSize min_packet_size = DataSize::Bytes(200);
- TimeDelta min_packet_interval = TimeDelta::Millis(1);
- TimeDelta update_interval = TimeDelta::Millis(200);
- double variance = 0.6;
- double bias = -0.1;
-};
-
-class RandomWalkCrossTraffic {
+class RandomWalkCrossTraffic final : public CrossTrafficGenerator {
public:
- RandomWalkCrossTraffic(RandomWalkConfig config, TrafficRoute* traffic_route);
+ RandomWalkCrossTraffic(RandomWalkConfig config,
+ CrossTrafficRoute* traffic_route);
~RandomWalkCrossTraffic();
- void Process(Timestamp at_time);
+ void Process(Timestamp at_time) override;
+ TimeDelta GetProcessInterval() const override;
DataRate TrafficRate() const;
ColumnPrinter StatsPrinter();
private:
SequenceChecker sequence_checker_;
const RandomWalkConfig config_;
- TrafficRoute* const traffic_route_ RTC_PT_GUARDED_BY(sequence_checker_);
+ CrossTrafficRoute* const traffic_route_ RTC_PT_GUARDED_BY(sequence_checker_);
webrtc::Random random_ RTC_GUARDED_BY(sequence_checker_);
Timestamp last_process_time_ RTC_GUARDED_BY(sequence_checker_) =
@@ -62,28 +55,21 @@
DataSize pending_size_ RTC_GUARDED_BY(sequence_checker_) = DataSize::Zero();
};
-struct PulsedPeaksConfig {
- DataRate peak_rate = DataRate::KilobitsPerSec(100);
- DataSize min_packet_size = DataSize::Bytes(200);
- TimeDelta min_packet_interval = TimeDelta::Millis(1);
- TimeDelta send_duration = TimeDelta::Millis(100);
- TimeDelta hold_duration = TimeDelta::Millis(2000);
-};
-
-class PulsedPeaksCrossTraffic {
+class PulsedPeaksCrossTraffic final : public CrossTrafficGenerator {
public:
PulsedPeaksCrossTraffic(PulsedPeaksConfig config,
- TrafficRoute* traffic_route);
+ CrossTrafficRoute* traffic_route);
~PulsedPeaksCrossTraffic();
- void Process(Timestamp at_time);
+ void Process(Timestamp at_time) override;
+ TimeDelta GetProcessInterval() const override;
DataRate TrafficRate() const;
ColumnPrinter StatsPrinter();
private:
SequenceChecker sequence_checker_;
const PulsedPeaksConfig config_;
- TrafficRoute* const traffic_route_ RTC_PT_GUARDED_BY(sequence_checker_);
+ CrossTrafficRoute* const traffic_route_ RTC_PT_GUARDED_BY(sequence_checker_);
Timestamp last_update_time_ RTC_GUARDED_BY(sequence_checker_) =
Timestamp::MinusInfinity();
@@ -149,23 +135,17 @@
TimeDelta last_rtt_ = TimeDelta::Zero();
};
-struct FakeTcpConfig {
- DataSize packet_size = DataSize::Bytes(1200);
- DataSize send_limit = DataSize::PlusInfinity();
- TimeDelta process_interval = TimeDelta::Millis(200);
- TimeDelta packet_timeout = TimeDelta::Seconds(1);
-};
-
class FakeTcpCrossTraffic
- : public TwoWayFakeTrafficRoute<int, int>::TrafficHandlerInterface {
+ : public TwoWayFakeTrafficRoute<int, int>::TrafficHandlerInterface,
+ public CrossTrafficGenerator {
public:
- FakeTcpCrossTraffic(Clock* clock,
- FakeTcpConfig config,
+ FakeTcpCrossTraffic(FakeTcpConfig config,
EmulatedRoute* send_route,
EmulatedRoute* ret_route);
- void Start(TaskQueueBase* task_queue);
- void Stop();
- void Process(Timestamp at_time);
+
+ TimeDelta GetProcessInterval() const override;
+ void Process(Timestamp at_time) override;
+
void OnRequest(int sequence_number, Timestamp at_time) override;
void OnResponse(int sequence_number, Timestamp at_time) override;
@@ -174,7 +154,6 @@
void SendPackets(Timestamp at_time);
private:
- Clock* const clock_;
const FakeTcpConfig conf_;
TwoWayFakeTrafficRoute<int, int> route_;
@@ -187,7 +166,6 @@
Timestamp last_reduction_time_ = Timestamp::MinusInfinity();
TimeDelta last_rtt_ = TimeDelta::Zero();
DataSize total_sent_ = DataSize::Zero();
- RepeatingTaskHandle repeating_task_handle_;
};
} // namespace test
diff --git a/test/network/cross_traffic_unittest.cc b/test/network/cross_traffic_unittest.cc
index c8d848f..c8191a3 100644
--- a/test/network/cross_traffic_unittest.cc
+++ b/test/network/cross_traffic_unittest.cc
@@ -25,6 +25,7 @@
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/network/network_emulation_manager.h"
+#include "test/network/traffic_route.h"
#include "test/time_controller/simulated_time_controller.h"
namespace webrtc {
@@ -61,7 +62,8 @@
TEST(CrossTrafficTest, TriggerPacketBurst) {
TrafficCounterFixture fixture;
- TrafficRoute traffic(&fixture.clock, &fixture.counter, &fixture.endpoint);
+ CrossTrafficRouteImpl traffic(&fixture.clock, &fixture.counter,
+ &fixture.endpoint);
traffic.TriggerPacketBurst(100, 1000);
EXPECT_EQ(fixture.counter.packets_count_, 100);
@@ -70,7 +72,8 @@
TEST(CrossTrafficTest, PulsedPeaksCrossTraffic) {
TrafficCounterFixture fixture;
- TrafficRoute traffic(&fixture.clock, &fixture.counter, &fixture.endpoint);
+ CrossTrafficRouteImpl traffic(&fixture.clock, &fixture.counter,
+ &fixture.endpoint);
PulsedPeaksConfig config;
config.peak_rate = DataRate::KilobitsPerSec(1000);
@@ -95,7 +98,8 @@
TEST(CrossTrafficTest, RandomWalkCrossTraffic) {
TrafficCounterFixture fixture;
- TrafficRoute traffic(&fixture.clock, &fixture.counter, &fixture.endpoint);
+ CrossTrafficRouteImpl traffic(&fixture.clock, &fixture.counter,
+ &fixture.endpoint);
RandomWalkConfig config;
config.peak_rate = DataRate::KilobitsPerSec(1000);
diff --git a/test/network/network_emulation_manager.cc b/test/network/network_emulation_manager.cc
index 57706fc..9ffe9e3 100644
--- a/test/network/network_emulation_manager.cc
+++ b/test/network/network_emulation_manager.cc
@@ -18,6 +18,7 @@
#include "call/simulated_network.h"
#include "rtc_base/fake_network.h"
#include "test/network/emulated_turn_server.h"
+#include "test/network/traffic_route.h"
#include "test/time_controller/real_time_controller.h"
#include "test/time_controller/simulated_time_controller.h"
@@ -175,7 +176,19 @@
RTC_FROM_HERE);
}
-TrafficRoute* NetworkEmulationManagerImpl::CreateTrafficRoute(
+TcpMessageRoute* NetworkEmulationManagerImpl::CreateTcpRoute(
+ EmulatedRoute* send_route,
+ EmulatedRoute* ret_route) {
+ auto tcp_route = std::make_unique<TcpMessageRouteImpl>(
+ clock_, task_queue_.Get(), send_route, ret_route);
+ auto* route_ptr = tcp_route.get();
+ task_queue_.PostTask([this, tcp_route = std::move(tcp_route)]() mutable {
+ tcp_message_routes_.push_back(std::move(tcp_route));
+ });
+ return route_ptr;
+}
+
+CrossTrafficRoute* NetworkEmulationManagerImpl::CreateCrossTrafficRoute(
const std::vector<EmulatedNetworkNode*>& via_nodes) {
RTC_CHECK(!via_nodes.empty());
EmulatedEndpoint* endpoint = CreateEndpoint(EmulatedEndpointConfig());
@@ -189,88 +202,40 @@
}
cur_node->router()->SetReceiver(endpoint->GetPeerLocalAddress(), endpoint);
- std::unique_ptr<TrafficRoute> traffic_route =
- std::make_unique<TrafficRoute>(clock_, via_nodes[0], endpoint);
- TrafficRoute* out = traffic_route.get();
+ std::unique_ptr<CrossTrafficRoute> traffic_route =
+ std::make_unique<CrossTrafficRouteImpl>(clock_, via_nodes[0], endpoint);
+ CrossTrafficRoute* out = traffic_route.get();
traffic_routes_.push_back(std::move(traffic_route));
return out;
}
-RandomWalkCrossTraffic*
-NetworkEmulationManagerImpl::CreateRandomWalkCrossTraffic(
- TrafficRoute* traffic_route,
- RandomWalkConfig config) {
- auto traffic =
- std::make_unique<RandomWalkCrossTraffic>(config, traffic_route);
- RandomWalkCrossTraffic* out = traffic.get();
+CrossTrafficGenerator* NetworkEmulationManagerImpl::StartCrossTraffic(
+ std::unique_ptr<CrossTrafficGenerator> generator) {
+ CrossTrafficGenerator* out = generator.get();
+ task_queue_.PostTask([this, generator = std::move(generator)]() mutable {
+ auto* generator_ptr = generator.get();
- task_queue_.PostTask(
- [this, config, traffic = std::move(traffic)]() mutable {
- auto* traffic_ptr = traffic.get();
- random_cross_traffics_.push_back(std::move(traffic));
- RepeatingTaskHandle::Start(task_queue_.Get(),
- [this, config, traffic_ptr] {
- traffic_ptr->Process(Now());
- return config.min_packet_interval;
- });
- });
- return out;
-}
+ auto repeating_task_handle =
+ RepeatingTaskHandle::Start(task_queue_.Get(), [this, generator_ptr] {
+ generator_ptr->Process(Now());
+ return generator_ptr->GetProcessInterval();
+ });
-PulsedPeaksCrossTraffic*
-NetworkEmulationManagerImpl::CreatePulsedPeaksCrossTraffic(
- TrafficRoute* traffic_route,
- PulsedPeaksConfig config) {
- auto traffic =
- std::make_unique<PulsedPeaksCrossTraffic>(config, traffic_route);
- PulsedPeaksCrossTraffic* out = traffic.get();
- task_queue_.PostTask(
- [this, config, traffic = std::move(traffic)]() mutable {
- auto* traffic_ptr = traffic.get();
- pulsed_cross_traffics_.push_back(std::move(traffic));
- RepeatingTaskHandle::Start(task_queue_.Get(),
- [this, config, traffic_ptr] {
- traffic_ptr->Process(Now());
- return config.min_packet_interval;
- });
- });
- return out;
-}
-
-FakeTcpCrossTraffic* NetworkEmulationManagerImpl::StartFakeTcpCrossTraffic(
- std::vector<EmulatedNetworkNode*> send_link,
- std::vector<EmulatedNetworkNode*> ret_link,
- FakeTcpConfig config) {
- auto traffic = std::make_unique<FakeTcpCrossTraffic>(
- clock_, config, CreateRoute(send_link), CreateRoute(ret_link));
- auto* traffic_ptr = traffic.get();
- task_queue_.PostTask([this, traffic = std::move(traffic)]() mutable {
- traffic->Start(task_queue_.Get());
- tcp_cross_traffics_.push_back(std::move(traffic));
+ cross_traffics_.push_back(CrossTrafficSource(
+ std::move(generator), std::move(repeating_task_handle)));
});
- return traffic_ptr;
-}
-
-TcpMessageRoute* NetworkEmulationManagerImpl::CreateTcpRoute(
- EmulatedRoute* send_route,
- EmulatedRoute* ret_route) {
- auto tcp_route = std::make_unique<TcpMessageRouteImpl>(
- clock_, task_queue_.Get(), send_route, ret_route);
- auto* route_ptr = tcp_route.get();
- task_queue_.PostTask([this, tcp_route = std::move(tcp_route)]() mutable {
- tcp_message_routes_.push_back(std::move(tcp_route));
- });
- return route_ptr;
+ return out;
}
void NetworkEmulationManagerImpl::StopCrossTraffic(
- FakeTcpCrossTraffic* traffic) {
+ CrossTrafficGenerator* generator) {
task_queue_.PostTask([=]() {
- traffic->Stop();
- tcp_cross_traffics_.remove_if(
- [=](const std::unique_ptr<FakeTcpCrossTraffic>& ptr) {
- return ptr.get() == traffic;
- });
+ auto it = std::find_if(cross_traffics_.begin(), cross_traffics_.end(),
+ [=](const CrossTrafficSource& el) {
+ return el.first.get() == generator;
+ });
+ it->second.Stop();
+ cross_traffics_.erase(it);
});
}
diff --git a/test/network/network_emulation_manager.h b/test/network/network_emulation_manager.h
index b2b41b3..d6e8786 100644
--- a/test/network/network_emulation_manager.h
+++ b/test/network/network_emulation_manager.h
@@ -34,7 +34,6 @@
#include "test/network/emulated_turn_server.h"
#include "test/network/fake_network_socket_server.h"
#include "test/network/network_emulation.h"
-#include "test/network/traffic_route.h"
namespace webrtc {
namespace test {
@@ -64,23 +63,15 @@
void ClearRoute(EmulatedRoute* route) override;
- TrafficRoute* CreateTrafficRoute(
- const std::vector<EmulatedNetworkNode*>& via_nodes);
- RandomWalkCrossTraffic* CreateRandomWalkCrossTraffic(
- TrafficRoute* traffic_route,
- RandomWalkConfig config);
- PulsedPeaksCrossTraffic* CreatePulsedPeaksCrossTraffic(
- TrafficRoute* traffic_route,
- PulsedPeaksConfig config);
- FakeTcpCrossTraffic* StartFakeTcpCrossTraffic(
- std::vector<EmulatedNetworkNode*> send_link,
- std::vector<EmulatedNetworkNode*> ret_link,
- FakeTcpConfig config);
-
TcpMessageRoute* CreateTcpRoute(EmulatedRoute* send_route,
EmulatedRoute* ret_route) override;
- void StopCrossTraffic(FakeTcpCrossTraffic* traffic);
+ CrossTrafficRoute* CreateCrossTrafficRoute(
+ const std::vector<EmulatedNetworkNode*>& via_nodes) override;
+
+ CrossTrafficGenerator* StartCrossTraffic(
+ std::unique_ptr<CrossTrafficGenerator> generator) override;
+ void StopCrossTraffic(CrossTrafficGenerator* generator) override;
EmulatedNetworkManagerInterface* CreateEmulatedNetworkManagerInterface(
const std::vector<EmulatedEndpoint*>& endpoints) override;
@@ -97,6 +88,9 @@
EmulatedTURNServerConfig config) override;
private:
+ using CrossTrafficSource =
+ std::pair<std::unique_ptr<CrossTrafficGenerator>, RepeatingTaskHandle>;
+
absl::optional<rtc::IPAddress> GetNextIPv4Address();
const std::unique_ptr<TimeController> time_controller_;
Clock* const clock_;
@@ -111,10 +105,8 @@
std::vector<std::unique_ptr<EmulatedEndpoint>> endpoints_;
std::vector<std::unique_ptr<EmulatedNetworkNode>> network_nodes_;
std::vector<std::unique_ptr<EmulatedRoute>> routes_;
- std::vector<std::unique_ptr<TrafficRoute>> traffic_routes_;
- std::vector<std::unique_ptr<RandomWalkCrossTraffic>> random_cross_traffics_;
- std::vector<std::unique_ptr<PulsedPeaksCrossTraffic>> pulsed_cross_traffics_;
- std::list<std::unique_ptr<FakeTcpCrossTraffic>> tcp_cross_traffics_;
+ std::vector<std::unique_ptr<CrossTrafficRoute>> traffic_routes_;
+ std::vector<CrossTrafficSource> cross_traffics_;
std::list<std::unique_ptr<TcpMessageRouteImpl>> tcp_message_routes_;
std::vector<std::unique_ptr<EndpointsContainer>> endpoints_containers_;
std::vector<std::unique_ptr<EmulatedNetworkManager>> network_managers_;
diff --git a/test/network/traffic_route.cc b/test/network/traffic_route.cc
index 9858633..d42d8e2 100644
--- a/test/network/traffic_route.cc
+++ b/test/network/traffic_route.cc
@@ -53,9 +53,10 @@
} // namespace
-TrafficRoute::TrafficRoute(Clock* clock,
- EmulatedNetworkReceiverInterface* receiver,
- EmulatedEndpoint* endpoint)
+CrossTrafficRouteImpl::CrossTrafficRouteImpl(
+ Clock* clock,
+ EmulatedNetworkReceiverInterface* receiver,
+ EmulatedEndpoint* endpoint)
: clock_(clock), receiver_(receiver), endpoint_(endpoint) {
null_receiver_ = std::make_unique<NullReceiver>();
absl::optional<uint16_t> port =
@@ -63,16 +64,17 @@
RTC_DCHECK(port);
null_receiver_port_ = port.value();
}
-TrafficRoute::~TrafficRoute() = default;
+CrossTrafficRouteImpl::~CrossTrafficRouteImpl() = default;
-void TrafficRoute::TriggerPacketBurst(size_t num_packets, size_t packet_size) {
+void CrossTrafficRouteImpl::TriggerPacketBurst(size_t num_packets,
+ size_t packet_size) {
for (size_t i = 0; i < num_packets; ++i) {
SendPacket(packet_size);
}
}
-void TrafficRoute::NetworkDelayedAction(size_t packet_size,
- std::function<void()> action) {
+void CrossTrafficRouteImpl::NetworkDelayedAction(size_t packet_size,
+ std::function<void()> action) {
auto action_receiver = std::make_unique<ActionReceiver>(action, endpoint_);
absl::optional<uint16_t> port =
endpoint_->BindReceiver(0, action_receiver.get());
@@ -82,11 +84,11 @@
SendPacket(packet_size, port.value());
}
-void TrafficRoute::SendPacket(size_t packet_size) {
+void CrossTrafficRouteImpl::SendPacket(size_t packet_size) {
SendPacket(packet_size, null_receiver_port_);
}
-void TrafficRoute::SendPacket(size_t packet_size, uint16_t dest_port) {
+void CrossTrafficRouteImpl::SendPacket(size_t packet_size, uint16_t dest_port) {
rtc::CopyOnWriteBuffer data(packet_size);
std::fill_n(data.MutableData(), data.size(), 0);
receiver_->OnPacketReceived(EmulatedIpPacket(
diff --git a/test/network/traffic_route.h b/test/network/traffic_route.h
index 1bb34c6..513f487 100644
--- a/test/network/traffic_route.h
+++ b/test/network/traffic_route.h
@@ -14,6 +14,7 @@
#include <memory>
#include <vector>
+#include "api/test/network_emulation_manager.h"
#include "rtc_base/copy_on_write_buffer.h"
#include "system_wrappers/include/clock.h"
#include "test/network/network_emulation.h"
@@ -23,19 +24,20 @@
// Represents the endpoint for cross traffic that is going through the network.
// It can be used to emulate unexpected network load.
-class TrafficRoute {
+class CrossTrafficRouteImpl final : public CrossTrafficRoute {
public:
- TrafficRoute(Clock* clock,
- EmulatedNetworkReceiverInterface* receiver,
- EmulatedEndpoint* endpoint);
- ~TrafficRoute();
+ CrossTrafficRouteImpl(Clock* clock,
+ EmulatedNetworkReceiverInterface* receiver,
+ EmulatedEndpoint* endpoint);
+ ~CrossTrafficRouteImpl();
// Triggers sending of dummy packets with size |packet_size| bytes.
- void TriggerPacketBurst(size_t num_packets, size_t packet_size);
+ void TriggerPacketBurst(size_t num_packets, size_t packet_size) override;
// Sends a packet over the nodes and runs |action| when it has been delivered.
- void NetworkDelayedAction(size_t packet_size, std::function<void()> action);
+ void NetworkDelayedAction(size_t packet_size,
+ std::function<void()> action) override;
- void SendPacket(size_t packet_size);
+ void SendPacket(size_t packet_size) override;
private:
void SendPacket(size_t packet_size, uint16_t dest_port);
diff --git a/test/peer_scenario/peer_scenario.cc b/test/peer_scenario/peer_scenario.cc
index c3443aa..ea959c9 100644
--- a/test/peer_scenario/peer_scenario.cc
+++ b/test/peer_scenario/peer_scenario.cc
@@ -77,8 +77,8 @@
PeerScenarioClient* callee,
std::vector<EmulatedNetworkNode*> send_link,
std::vector<EmulatedNetworkNode*> ret_link) {
- return SignalingRoute(caller, callee, net_.CreateTrafficRoute(send_link),
- net_.CreateTrafficRoute(ret_link));
+ return SignalingRoute(caller, callee, net_.CreateCrossTrafficRoute(send_link),
+ net_.CreateCrossTrafficRoute(ret_link));
}
void PeerScenario::SimpleConnection(
diff --git a/test/peer_scenario/signaling_route.cc b/test/peer_scenario/signaling_route.cc
index 2e0213d..908d405 100644
--- a/test/peer_scenario/signaling_route.cc
+++ b/test/peer_scenario/signaling_route.cc
@@ -41,7 +41,7 @@
void StartIceSignalingForRoute(PeerScenarioClient* caller,
PeerScenarioClient* callee,
- TrafficRoute* send_route) {
+ CrossTrafficRoute* send_route) {
caller->handlers()->on_ice_candidate.push_back(
[=](const IceCandidateInterface* candidate) {
IceMessage msg(candidate);
@@ -56,8 +56,8 @@
void StartSdpNegotiation(
PeerScenarioClient* caller,
PeerScenarioClient* callee,
- TrafficRoute* send_route,
- TrafficRoute* ret_route,
+ CrossTrafficRoute* send_route,
+ CrossTrafficRoute* ret_route,
std::function<void(SessionDescriptionInterface* offer)> munge_offer,
std::function<void(SessionDescriptionInterface*)> modify_offer,
std::function<void(const SessionDescriptionInterface&)> exchange_finished) {
@@ -80,8 +80,8 @@
SignalingRoute::SignalingRoute(PeerScenarioClient* caller,
PeerScenarioClient* callee,
- TrafficRoute* send_route,
- TrafficRoute* ret_route)
+ CrossTrafficRoute* send_route,
+ CrossTrafficRoute* ret_route)
: caller_(caller),
callee_(callee),
send_route_(send_route),
diff --git a/test/peer_scenario/signaling_route.h b/test/peer_scenario/signaling_route.h
index 7434551..021fc49 100644
--- a/test/peer_scenario/signaling_route.h
+++ b/test/peer_scenario/signaling_route.h
@@ -25,8 +25,8 @@
public:
SignalingRoute(PeerScenarioClient* caller,
PeerScenarioClient* callee,
- TrafficRoute* send_route,
- TrafficRoute* ret_route);
+ CrossTrafficRoute* send_route,
+ CrossTrafficRoute* ret_route);
void StartIceSignaling();
@@ -57,8 +57,8 @@
private:
PeerScenarioClient* const caller_;
PeerScenarioClient* const callee_;
- TrafficRoute* const send_route_;
- TrafficRoute* const ret_route_;
+ CrossTrafficRoute* const send_route_;
+ CrossTrafficRoute* const ret_route_;
};
} // namespace test
diff --git a/test/scenario/BUILD.gn b/test/scenario/BUILD.gn
index f5c22fc..ede93c6 100644
--- a/test/scenario/BUILD.gn
+++ b/test/scenario/BUILD.gn
@@ -174,6 +174,8 @@
]
deps = [
":scenario",
+ "../../api/test/network_emulation",
+ "../../api/test/network_emulation:create_cross_traffic",
"../../logging:mocks",
"../../rtc_base:checks",
"../../rtc_base:rtc_base_approved",
diff --git a/test/scenario/scenario.cc b/test/scenario/scenario.cc
index c1c664a..239aad9 100644
--- a/test/scenario/scenario.cc
+++ b/test/scenario/scenario.cc
@@ -198,7 +198,7 @@
void Scenario::TriggerPacketBurst(std::vector<EmulatedNetworkNode*> over_nodes,
size_t num_packets,
size_t packet_size) {
- network_manager_.CreateTrafficRoute(over_nodes)
+ network_manager_.CreateCrossTrafficRoute(over_nodes)
->TriggerPacketBurst(num_packets, packet_size);
}
@@ -206,7 +206,7 @@
std::vector<EmulatedNetworkNode*> over_nodes,
size_t packet_size,
std::function<void()> action) {
- network_manager_.CreateTrafficRoute(over_nodes)
+ network_manager_.CreateCrossTrafficRoute(over_nodes)
->NetworkDelayedAction(packet_size, action);
}
diff --git a/test/scenario/scenario_unittest.cc b/test/scenario/scenario_unittest.cc
index 177ac27..fc370fb 100644
--- a/test/scenario/scenario_unittest.cc
+++ b/test/scenario/scenario_unittest.cc
@@ -11,6 +11,8 @@
#include <atomic>
+#include "api/test/network_emulation/create_cross_traffic.h"
+#include "api/test/network_emulation/cross_traffic.h"
#include "test/field_trial.h"
#include "test/gtest.h"
#include "test/logging/memory_log_writer.h"
@@ -44,8 +46,8 @@
s.CreateAudioStream(route->reverse(), audio_stream_config);
RandomWalkConfig cross_traffic_config;
- s.net()->CreateRandomWalkCrossTraffic(
- s.net()->CreateTrafficRoute({alice_net}), cross_traffic_config);
+ s.net()->StartCrossTraffic(CreateRandomWalkCrossTraffic(
+ s.net()->CreateCrossTrafficRoute({alice_net}), cross_traffic_config));
s.NetworkDelayedAction({alice_net, bob_net}, 100,
[&packet_received] { packet_received = true; });
diff --git a/test/scenario/video_stream_unittest.cc b/test/scenario/video_stream_unittest.cc
index 52be3f8..95936c7 100644
--- a/test/scenario/video_stream_unittest.cc
+++ b/test/scenario/video_stream_unittest.cc
@@ -9,6 +9,8 @@
*/
#include <atomic>
+#include "api/test/network_emulation/create_cross_traffic.h"
+#include "api/test/network_emulation/cross_traffic.h"
#include "test/field_trial.h"
#include "test/gtest.h"
#include "test/scenario/scenario.h"
@@ -217,8 +219,9 @@
// Trigger cross traffic, run until we have seen 3 consecutive
// seconds with no VGA frames due to reduced available bandwidth.
- auto cross_traffic =
- s.net()->StartFakeTcpCrossTraffic(send_net, ret_net, FakeTcpConfig());
+ auto cross_traffic = s.net()->StartCrossTraffic(CreateFakeTcpCrossTraffic(
+ s.net()->CreateRoute(send_net), s.net()->CreateRoute(ret_net),
+ FakeTcpConfig()));
int num_seconds_without_vga = 0;
int num_iterations = 0;