From d3666b2d983d684521a5a9242665eeae9e2d6d7a Mon Sep 17 00:00:00 2001 From: Artem Titov Date: Mon, 11 Feb 2019 14:40:17 +0100 Subject: [PATCH] Introduce cross traffic for emulated network layer. This CL contains cross traffic and is a second part of landing CL https://webrtc-review.googlesource.com/c/src/+/116663 Bug: webrtc:10138 Change-Id: Ibe0614f80127e93ee8a92b85685cacbf079dee21 Reviewed-on: https://webrtc-review.googlesource.com/c/120925 Commit-Queue: Artem Titov Reviewed-by: Sebastian Jansson Cr-Commit-Position: refs/heads/master@{#26649} --- test/scenario/BUILD.gn | 16 +- test/scenario/network/BUILD.gn | 22 +++ test/scenario/network/cross_traffic.cc | 110 ++++++++++++ test/scenario/network/cross_traffic.h | 88 ++++++++++ .../network/cross_traffic_unittest.cc | 156 ++++++++++++++++++ .../network/network_emulation_manager.cc | 60 +++++++ .../network/network_emulation_manager.h | 13 ++ test/scenario/network/traffic_route.cc | 97 +++++++++++ test/scenario/network/traffic_route.h | 55 ++++++ 9 files changed, 615 insertions(+), 2 deletions(-) create mode 100644 test/scenario/network/cross_traffic.cc create mode 100644 test/scenario/network/cross_traffic.h create mode 100644 test/scenario/network/cross_traffic_unittest.cc create mode 100644 test/scenario/network/traffic_route.cc create mode 100644 test/scenario/network/traffic_route.h diff --git a/test/scenario/BUILD.gn b/test/scenario/BUILD.gn index ff7ada60f8..533e43a5f4 100644 --- a/test/scenario/BUILD.gn +++ b/test/scenario/BUILD.gn @@ -8,6 +8,19 @@ import("../../webrtc.gni") +rtc_source_set("column_printer") { + testonly = true + sources = [ + "column_printer.cc", + "column_printer.h", + ] + deps = [ + "../../rtc_base:macromagic", + "../../rtc_base:stringutils", + "../logging:log_writer", + ] +} + if (rtc_include_tests) { rtc_source_set("scenario") { testonly = true @@ -17,8 +30,6 @@ if (rtc_include_tests) { "call_client.cc", "call_client.h", "call_client.h", - "column_printer.cc", - "column_printer.h", "hardware_codecs.cc", "hardware_codecs.h", "network_node.cc", @@ -36,6 +47,7 @@ if (rtc_include_tests) { "video_stream.h", ] deps = [ + ":column_printer", "../:fake_video_codecs", "../:fileutils", "../:test_common", diff --git a/test/scenario/network/BUILD.gn b/test/scenario/network/BUILD.gn index c73a88967f..1e33a330bb 100644 --- a/test/scenario/network/BUILD.gn +++ b/test/scenario/network/BUILD.gn @@ -11,6 +11,8 @@ import("../../../webrtc.gni") rtc_source_set("emulated_network") { testonly = true sources = [ + "cross_traffic.cc", + "cross_traffic.h", "fake_network_socket.cc", "fake_network_socket.h", "fake_network_socket_server.cc", @@ -19,8 +21,11 @@ rtc_source_set("emulated_network") { "network_emulation.h", "network_emulation_manager.cc", "network_emulation_manager.h", + "traffic_route.cc", + "traffic_route.h", ] deps = [ + "../:column_printer", "../../../api:simulated_network_api", "../../../api/units:data_rate", "../../../api/units:data_size", @@ -90,9 +95,26 @@ rtc_source_set("network_emulation_pc_unittest") { } } +rtc_source_set("cross_traffic_unittest") { + testonly = true + sources = [ + "cross_traffic_unittest.cc", + ] + deps = [ + ":emulated_network", + "../../../api:simulated_network_api", + "../../../call:simulated_network", + "../../../rtc_base:logging", + "../../../rtc_base:rtc_event", + "../../../test:test_support", + "//third_party/abseil-cpp/absl/memory:memory", + ] +} + rtc_source_set("network_emulation_unittests") { testonly = true deps = [ + ":cross_traffic_unittest", ":network_emulation_pc_unittest", ":network_emulation_unittest", ] diff --git a/test/scenario/network/cross_traffic.cc b/test/scenario/network/cross_traffic.cc new file mode 100644 index 0000000000..bd63a08c1a --- /dev/null +++ b/test/scenario/network/cross_traffic.cc @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2019 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 "test/scenario/network/cross_traffic.h" + +#include +#include + +#include "absl/memory/memory.h" +#include "absl/types/optional.h" +#include "rtc_base/logging.h" +#include "rtc_base/numerics/safe_minmax.h" + +namespace webrtc { +namespace test { + +RandomWalkCrossTraffic::RandomWalkCrossTraffic(RandomWalkConfig config, + TrafficRoute* traffic_route) + : config_(config), + traffic_route_(traffic_route), + random_(config_.random_seed) {} +RandomWalkCrossTraffic::~RandomWalkCrossTraffic() = default; + +void RandomWalkCrossTraffic::Process(Timestamp at_time) { + if (last_process_time_.IsMinusInfinity()) { + last_process_time_ = at_time; + } + TimeDelta delta = at_time - last_process_time_; + last_process_time_ = at_time; + + if (at_time - last_update_time_ >= config_.update_interval) { + intensity_ += random_.Gaussian(config_.bias, config_.variance) * + sqrt((at_time - last_update_time_).seconds()); + intensity_ = rtc::SafeClamp(intensity_, 0.0, 1.0); + last_update_time_ = at_time; + } + pending_size_ += TrafficRate() * delta; + + if (pending_size_ >= config_.min_packet_size && + at_time >= last_send_time_ + config_.min_packet_interval) { + traffic_route_->SendPacket(pending_size_.bytes()); + pending_size_ = DataSize::Zero(); + last_send_time_ = at_time; + } +} + +DataRate RandomWalkCrossTraffic::TrafficRate() const { + return config_.peak_rate * intensity_; +} + +ColumnPrinter RandomWalkCrossTraffic::StatsPrinter() { + return ColumnPrinter::Lambda( + "random_walk_cross_traffic_rate", + [this](rtc::SimpleStringBuilder& sb) { + sb.AppendFormat("%.0lf", TrafficRate().bps() / 8.0); + }, + 32); +} + +PulsedPeaksCrossTraffic::PulsedPeaksCrossTraffic(PulsedPeaksConfig config, + TrafficRoute* traffic_route) + : config_(config), traffic_route_(traffic_route) {} +PulsedPeaksCrossTraffic::~PulsedPeaksCrossTraffic() = default; + +void PulsedPeaksCrossTraffic::Process(Timestamp at_time) { + TimeDelta time_since_toggle = at_time - last_update_time_; + if (time_since_toggle.IsInfinite() || + (sending_ && time_since_toggle >= config_.send_duration)) { + sending_ = false; + last_update_time_ = at_time; + } else if (!sending_ && time_since_toggle >= config_.hold_duration) { + sending_ = true; + last_update_time_ = at_time; + // Start sending period. + last_send_time_ = at_time; + } + + if (sending_) { + DataSize pending_size = config_.peak_rate * (at_time - last_send_time_); + + if (pending_size >= config_.min_packet_size && + at_time >= last_send_time_ + config_.min_packet_interval) { + traffic_route_->SendPacket(pending_size.bytes()); + last_send_time_ = at_time; + } + } +} + +DataRate PulsedPeaksCrossTraffic::TrafficRate() const { + return sending_ ? config_.peak_rate : DataRate::Zero(); +} + +ColumnPrinter PulsedPeaksCrossTraffic::StatsPrinter() { + return ColumnPrinter::Lambda( + "pulsed_peaks_cross_traffic_rate", + [this](rtc::SimpleStringBuilder& sb) { + sb.AppendFormat("%.0lf", TrafficRate().bps() / 8.0); + }, + 32); +} + +} // namespace test +} // namespace webrtc diff --git a/test/scenario/network/cross_traffic.h b/test/scenario/network/cross_traffic.h new file mode 100644 index 0000000000..b5a65fb23e --- /dev/null +++ b/test/scenario/network/cross_traffic.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2019 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 TEST_SCENARIO_NETWORK_CROSS_TRAFFIC_H_ +#define TEST_SCENARIO_NETWORK_CROSS_TRAFFIC_H_ + +#include + +#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 "test/scenario/column_printer.h" +#include "test/scenario/network/traffic_route.h" + +namespace webrtc { +namespace test { + +struct RandomWalkConfig { + int random_seed = 1; + DataRate peak_rate = DataRate::kbps(100); + DataSize min_packet_size = DataSize::bytes(200); + TimeDelta min_packet_interval = TimeDelta::ms(1); + TimeDelta update_interval = TimeDelta::ms(200); + double variance = 0.6; + double bias = -0.1; +}; + +class RandomWalkCrossTraffic { + public: + RandomWalkCrossTraffic(RandomWalkConfig config, TrafficRoute* traffic_route); + ~RandomWalkCrossTraffic(); + + void Process(Timestamp at_time); + DataRate TrafficRate() const; + ColumnPrinter StatsPrinter(); + + private: + RandomWalkConfig config_; + TrafficRoute* const traffic_route_; + webrtc::Random random_; + + Timestamp last_process_time_ = Timestamp::MinusInfinity(); + Timestamp last_update_time_ = Timestamp::MinusInfinity(); + Timestamp last_send_time_ = Timestamp::MinusInfinity(); + double intensity_ = 0; + DataSize pending_size_ = DataSize::Zero(); +}; + +struct PulsedPeaksConfig { + DataRate peak_rate = DataRate::kbps(100); + DataSize min_packet_size = DataSize::bytes(200); + TimeDelta min_packet_interval = TimeDelta::ms(1); + TimeDelta send_duration = TimeDelta::ms(100); + TimeDelta hold_duration = TimeDelta::ms(2000); +}; + +class PulsedPeaksCrossTraffic { + public: + PulsedPeaksCrossTraffic(PulsedPeaksConfig config, + TrafficRoute* traffic_route); + ~PulsedPeaksCrossTraffic(); + + void Process(Timestamp at_time); + DataRate TrafficRate() const; + ColumnPrinter StatsPrinter(); + + private: + PulsedPeaksConfig config_; + TrafficRoute* const traffic_route_; + + Timestamp last_update_time_ = Timestamp::MinusInfinity(); + Timestamp last_send_time_ = Timestamp::MinusInfinity(); + bool sending_ = false; +}; + +} // namespace test +} // namespace webrtc + +#endif // TEST_SCENARIO_NETWORK_CROSS_TRAFFIC_H_ diff --git a/test/scenario/network/cross_traffic_unittest.cc b/test/scenario/network/cross_traffic_unittest.cc new file mode 100644 index 0000000000..98f2d3cf86 --- /dev/null +++ b/test/scenario/network/cross_traffic_unittest.cc @@ -0,0 +1,156 @@ +/* + * Copyright 2019 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 +#include +#include +#include + +#include "absl/memory/memory.h" +#include "api/test/simulated_network.h" +#include "call/simulated_network.h" +#include "rtc_base/event.h" +#include "rtc_base/logging.h" +#include "test/gmock.h" +#include "test/gtest.h" +#include "test/scenario/network/cross_traffic.h" +#include "test/scenario/network/network_emulation.h" +#include "test/scenario/network/network_emulation_manager.h" + +namespace webrtc { +namespace test { +namespace { + +class CountingBehavior : public NetworkBehaviorInterface { + public: + bool EnqueuePacket(PacketInFlightInfo packet_info) override { + packets_to_send_.push_back(packet_info); + return true; + } + + std::vector DequeueDeliverablePackets( + int64_t receive_time_us) override { + std::vector out; + for (auto packet : packets_to_send_) { + // we want to count packets, that went through this behavior. + packets_count_++; + total_packets_size_ += packet.size; + out.push_back(PacketDeliveryInfo(packet, receive_time_us)); + } + packets_to_send_.clear(); + return out; + } + + absl::optional NextDeliveryTimeUs() const override { return 1000; } + + int packets_count() const { return packets_count_; } + uint64_t total_packets_size() const { return total_packets_size_; } + + private: + std::vector packets_to_send_; + + std::atomic packets_count_{0}; + std::atomic total_packets_size_{0}; +}; + +} // namespace + +TEST(CrossTrafficTest, TriggerPacketBurst) { + NetworkEmulationManager network_manager; + + std::unique_ptr behavior = + absl::make_unique(); + CountingBehavior* counter = behavior.get(); + + EmulatedNetworkNode* node_a = network_manager.CreateEmulatedNode( + absl::make_unique(BuiltInNetworkBehaviorConfig())); + EmulatedNetworkNode* node_b = + network_manager.CreateEmulatedNode(std::move(behavior)); + + TrafficRoute* traffic = network_manager.CreateTrafficRoute({node_a, node_b}); + + traffic->TriggerPacketBurst(100, 1000); + + rtc::Event event; + event.Wait(1000); + + EXPECT_EQ(counter->packets_count(), 100); + EXPECT_EQ(counter->total_packets_size(), 100 * 1000ul); +} + +TEST(CrossTrafficTest, PulsedPeaksCrossTraffic) { + NetworkEmulationManager network_manager; + + std::unique_ptr behavior = + absl::make_unique(); + CountingBehavior* counter = behavior.get(); + + EmulatedNetworkNode* node_a = network_manager.CreateEmulatedNode( + absl::make_unique(BuiltInNetworkBehaviorConfig())); + EmulatedNetworkNode* node_b = + network_manager.CreateEmulatedNode(std::move(behavior)); + + PulsedPeaksConfig config; + config.peak_rate = DataRate::kbps(1000); + config.min_packet_size = DataSize::bytes(1); + config.min_packet_interval = TimeDelta::ms(25); + config.send_duration = TimeDelta::ms(500); + config.hold_duration = TimeDelta::ms(250); + TrafficRoute* traffic = network_manager.CreateTrafficRoute({node_a, node_b}); + network_manager.CreatePulsedPeaksCrossTraffic(traffic, config); + const auto kRunTime = TimeDelta::seconds(1); + + rtc::Event event; + event.Wait(kRunTime.ms()); + + RTC_LOG(INFO) << counter->packets_count() << " packets; " + << counter->total_packets_size() << " bytes"; + // Using 50% duty cycle. + const auto kExpectedDataSent = kRunTime * config.peak_rate * 0.5; + EXPECT_NEAR(counter->total_packets_size(), kExpectedDataSent.bytes(), + kExpectedDataSent.bytes() * 0.1); +} + +TEST(CrossTrafficTest, RandomWalkCrossTraffic) { + NetworkEmulationManager network_manager; + + std::unique_ptr behavior = + absl::make_unique(); + CountingBehavior* counter = behavior.get(); + + EmulatedNetworkNode* node_a = network_manager.CreateEmulatedNode( + absl::make_unique(BuiltInNetworkBehaviorConfig())); + EmulatedNetworkNode* node_b = + network_manager.CreateEmulatedNode(std::move(behavior)); + + RandomWalkConfig config; + config.peak_rate = DataRate::kbps(1000); + config.min_packet_size = DataSize::bytes(1); + config.min_packet_interval = TimeDelta::ms(25); + config.update_interval = TimeDelta::ms(500); + config.variance = 0.0; + config.bias = 1.0; + TrafficRoute* traffic = network_manager.CreateTrafficRoute({node_a, node_b}); + network_manager.CreateRandomWalkCrossTraffic(traffic, config); + const auto kRunTime = TimeDelta::seconds(1); + + rtc::Event event; + event.Wait(kRunTime.ms()); + + RTC_LOG(INFO) << counter->packets_count() << " packets; " + << counter->total_packets_size() << " bytes"; + // Sending at peak rate since bias = 1. + const auto kExpectedDataSent = kRunTime * config.peak_rate; + EXPECT_NEAR(counter->total_packets_size(), kExpectedDataSent.bytes(), + kExpectedDataSent.bytes() * 0.1); +} + +} // namespace test +} // namespace webrtc diff --git a/test/scenario/network/network_emulation_manager.cc b/test/scenario/network/network_emulation_manager.cc index 489529b350..2d83936481 100644 --- a/test/scenario/network/network_emulation_manager.cc +++ b/test/scenario/network/network_emulation_manager.cc @@ -95,6 +95,60 @@ void NetworkEmulationManager::ClearRoute( } } +TrafficRoute* NetworkEmulationManager::CreateTrafficRoute( + std::vector via_nodes) { + RTC_CHECK(!via_nodes.empty()); + EndpointNode* endpoint = CreateEndpoint(rtc::IPAddress(next_node_id_++)); + + // Setup a route via specified nodes. + EmulatedNetworkNode* cur_node = via_nodes[0]; + for (size_t i = 1; i < via_nodes.size(); ++i) { + cur_node->SetReceiver(endpoint->GetId(), via_nodes[i]); + cur_node = via_nodes[i]; + } + cur_node->SetReceiver(endpoint->GetId(), endpoint); + + std::unique_ptr traffic_route = + absl::make_unique(clock_, via_nodes[0], endpoint); + TrafficRoute* out = traffic_route.get(); + traffic_routes_.push_back(std::move(traffic_route)); + return out; +} + +RandomWalkCrossTraffic* NetworkEmulationManager::CreateRandomWalkCrossTraffic( + TrafficRoute* traffic_route, + RandomWalkConfig config) { + auto traffic = absl::make_unique(std::move(config), + traffic_route); + RandomWalkCrossTraffic* out = traffic.get(); + struct Closure { + void operator()() { + manager->random_cross_traffics_.push_back(std::move(traffic)); + } + NetworkEmulationManager* manager; + std::unique_ptr traffic; + }; + task_queue_.PostTask(Closure{this, std::move(traffic)}); + return out; +} + +PulsedPeaksCrossTraffic* NetworkEmulationManager::CreatePulsedPeaksCrossTraffic( + TrafficRoute* traffic_route, + PulsedPeaksConfig config) { + auto traffic = absl::make_unique(std::move(config), + traffic_route); + PulsedPeaksCrossTraffic* out = traffic.get(); + struct Closure { + void operator()() { + manager->pulsed_cross_traffics_.push_back(std::move(traffic)); + } + NetworkEmulationManager* manager; + std::unique_ptr traffic; + }; + task_queue_.PostTask(Closure{this, std::move(traffic)}); + return out; +} + rtc::Thread* NetworkEmulationManager::CreateNetworkThread( std::vector endpoints) { FakeNetworkSocketServer* socket_server = CreateSocketServer(endpoints); @@ -119,6 +173,12 @@ FakeNetworkSocketServer* NetworkEmulationManager::CreateSocketServer( void NetworkEmulationManager::ProcessNetworkPackets() { Timestamp current_time = Now(); + for (auto& traffic : random_cross_traffics_) { + traffic->Process(current_time); + } + for (auto& traffic : pulsed_cross_traffics_) { + traffic->Process(current_time); + } for (auto& node : network_nodes_) { node->Process(current_time); } diff --git a/test/scenario/network/network_emulation_manager.h b/test/scenario/network/network_emulation_manager.h index 6d42ed7db9..47189676c6 100644 --- a/test/scenario/network/network_emulation_manager.h +++ b/test/scenario/network/network_emulation_manager.h @@ -23,8 +23,10 @@ #include "rtc_base/task_utils/repeating_task.h" #include "rtc_base/thread.h" #include "system_wrappers/include/clock.h" +#include "test/scenario/network/cross_traffic.h" #include "test/scenario/network/fake_network_socket_server.h" #include "test/scenario/network/network_emulation.h" +#include "test/scenario/network/traffic_route.h" namespace webrtc { namespace test { @@ -48,6 +50,14 @@ class NetworkEmulationManager { std::vector via_nodes, EndpointNode* to); + TrafficRoute* CreateTrafficRoute(std::vector via_nodes); + RandomWalkCrossTraffic* CreateRandomWalkCrossTraffic( + TrafficRoute* traffic_route, + RandomWalkConfig config); + PulsedPeaksCrossTraffic* CreatePulsedPeaksCrossTraffic( + TrafficRoute* traffic_route, + PulsedPeaksConfig config); + rtc::Thread* CreateNetworkThread(std::vector endpoints); private: @@ -64,6 +74,9 @@ class NetworkEmulationManager { // All objects can be added to the manager only when it is idle. std::vector> endpoints_; std::vector> network_nodes_; + std::vector> traffic_routes_; + std::vector> random_cross_traffics_; + std::vector> pulsed_cross_traffics_; std::vector> socket_servers_; std::vector> threads_; diff --git a/test/scenario/network/traffic_route.cc b/test/scenario/network/traffic_route.cc new file mode 100644 index 0000000000..67a2cb349d --- /dev/null +++ b/test/scenario/network/traffic_route.cc @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2019 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 "test/scenario/network/traffic_route.h" + +#include + +#include "absl/memory/memory.h" +#include "absl/types/optional.h" +#include "rtc_base/logging.h" +#include "rtc_base/numerics/safe_minmax.h" + +namespace webrtc { +namespace test { +namespace { + +class NullReceiver : public EmulatedNetworkReceiverInterface { + public: + void OnPacketReceived(EmulatedIpPacket packet) override{}; +}; + +class ActionReceiver : public EmulatedNetworkReceiverInterface { + public: + ActionReceiver(std::function action, EndpointNode* endpoint) + : action_(action), endpoint_(endpoint) {} + ~ActionReceiver() override = default; + + void OnPacketReceived(EmulatedIpPacket packet) override { + RTC_DCHECK(port_); + action_(); + endpoint_->UnbindReceiver(port_.value()); + }; + + // We can't set port in constructor, because port will be provided by + // endpoint, when this receiver will be binded to that endpoint. + void SetPort(uint16_t port) { port_ = port; } + + private: + std::function action_; + // Endpoint and port will be used to free port in the endpoint after action + // will be done. + EndpointNode* endpoint_; + absl::optional port_ = absl::nullopt; +}; + +} // namespace + +TrafficRoute::TrafficRoute(Clock* clock, + EmulatedNetworkReceiverInterface* receiver, + EndpointNode* endpoint) + : clock_(clock), receiver_(receiver), endpoint_(endpoint) { + null_receiver_ = absl::make_unique(); + absl::optional port = + endpoint_->BindReceiver(0, null_receiver_.get()); + RTC_DCHECK(port); + null_receiver_port_ = port.value(); +} +TrafficRoute::~TrafficRoute() = default; + +void TrafficRoute::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 action) { + auto action_receiver = absl::make_unique(action, endpoint_); + absl::optional port = + endpoint_->BindReceiver(0, action_receiver.get()); + RTC_DCHECK(port); + action_receiver->SetPort(port.value()); + actions_.push_back(std::move(action_receiver)); + SendPacket(packet_size, port.value()); +} + +void TrafficRoute::SendPacket(size_t packet_size) { + SendPacket(packet_size, null_receiver_port_); +} + +void TrafficRoute::SendPacket(size_t packet_size, uint16_t dest_port) { + receiver_->OnPacketReceived(EmulatedIpPacket( + /*from=*/rtc::SocketAddress(), + rtc::SocketAddress(endpoint_->GetPeerLocalAddress(), dest_port), + endpoint_->GetId(), rtc::CopyOnWriteBuffer(packet_size), + Timestamp::us(clock_->TimeInMicroseconds()))); +} + +} // namespace test +} // namespace webrtc diff --git a/test/scenario/network/traffic_route.h b/test/scenario/network/traffic_route.h new file mode 100644 index 0000000000..42210b9679 --- /dev/null +++ b/test/scenario/network/traffic_route.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019 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 TEST_SCENARIO_NETWORK_TRAFFIC_ROUTE_H_ +#define TEST_SCENARIO_NETWORK_TRAFFIC_ROUTE_H_ + +#include +#include + +#include "rtc_base/copy_on_write_buffer.h" +#include "system_wrappers/include/clock.h" +#include "test/scenario/network/network_emulation.h" + +namespace webrtc { +namespace test { + +// Represents the endpoint for cross traffic that is going through the network. +// It can be used to emulate unexpected network load. +class TrafficRoute { + public: + TrafficRoute(Clock* clock, + EmulatedNetworkReceiverInterface* receiver, + EndpointNode* endpoint); + ~TrafficRoute(); + + // Triggers sending of dummy packets with size |packet_size| bytes. + void TriggerPacketBurst(size_t num_packets, size_t packet_size); + // Sends a packet over the nodes and runs |action| when it has been delivered. + void NetworkDelayedAction(size_t packet_size, std::function action); + + void SendPacket(size_t packet_size); + + private: + void SendPacket(size_t packet_size, uint16_t dest_port); + + Clock* const clock_; + EmulatedNetworkReceiverInterface* const receiver_; + EndpointNode* const endpoint_; + + uint16_t null_receiver_port_; + std::unique_ptr null_receiver_; + std::vector> actions_; +}; + +} // namespace test +} // namespace webrtc + +#endif // TEST_SCENARIO_NETWORK_TRAFFIC_ROUTE_H_