Using NetworkEmulationManager in Scenario tests.
Bug: webrtc:9510
Change-Id: Ib619526269c58f0c46c0c1f01ba6c0efa5f79ba5
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132781
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27635}
diff --git a/test/scenario/network_node.cc b/test/scenario/network_node.cc
index e8f325b..e8b7646 100644
--- a/test/scenario/network_node.cc
+++ b/test/scenario/network_node.cc
@@ -33,35 +33,26 @@
}
} // namespace
-void NullReceiver::OnPacketReceived(EmulatedIpPacket packet) {}
+SimulationNode::SimulationNode(NetworkSimulationConfig config,
+ SimulatedNetwork* behavior,
+ EmulatedNetworkNode* network_node)
+ : config_(config), simulation_(behavior), network_node_(network_node) {}
-ActionReceiver::ActionReceiver(std::function<void()> action)
- : action_(action) {}
-
-void ActionReceiver::OnPacketReceived(EmulatedIpPacket packet) {
- action_();
-}
-
-std::unique_ptr<SimulationNode> SimulationNode::Create(
- Clock* clock,
- rtc::TaskQueue* task_queue,
+std::unique_ptr<SimulatedNetwork> SimulationNode::CreateBehavior(
NetworkSimulationConfig config) {
SimulatedNetwork::Config sim_config = CreateSimulationConfig(config);
- auto network = absl::make_unique<SimulatedNetwork>(sim_config);
- SimulatedNetwork* simulation_ptr = network.get();
- return std::unique_ptr<SimulationNode>(new SimulationNode(
- clock, task_queue, config, std::move(network), simulation_ptr));
+ return absl::make_unique<SimulatedNetwork>(sim_config);
}
void SimulationNode::UpdateConfig(
std::function<void(NetworkSimulationConfig*)> modifier) {
modifier(&config_);
SimulatedNetwork::Config sim_config = CreateSimulationConfig(config_);
- simulated_network_->SetConfig(sim_config);
+ simulation_->SetConfig(sim_config);
}
void SimulationNode::PauseTransmissionUntil(Timestamp until) {
- simulated_network_->PauseTransmissionUntil(until.us());
+ simulation_->PauseTransmissionUntil(until.us());
}
ColumnPrinter SimulationNode::ConfigPrinter() const {
@@ -73,15 +64,6 @@
});
}
-SimulationNode::SimulationNode(
- Clock* clock,
- rtc::TaskQueue* task_queue,
- NetworkSimulationConfig config,
- std::unique_ptr<NetworkBehaviorInterface> behavior,
- SimulatedNetwork* simulation)
- : EmulatedNetworkNode(clock, task_queue, std::move(behavior)),
- simulated_network_(simulation),
- config_(config) {}
NetworkNodeTransport::NetworkNodeTransport(Clock* sender_clock,
Call* sender_call)
@@ -162,57 +144,5 @@
send_net_ = nullptr;
}
-CrossTrafficSource::CrossTrafficSource(EmulatedNetworkReceiverInterface* target,
- rtc::IPAddress receiver_ip,
- CrossTrafficConfig config)
- : target_(target),
- receiver_address_(receiver_ip, 0),
- config_(config),
- random_(config.random_seed) {}
-
-CrossTrafficSource::~CrossTrafficSource() = default;
-
-DataRate CrossTrafficSource::TrafficRate() const {
- return config_.peak_rate * intensity_;
-}
-
-void CrossTrafficSource::Process(Timestamp at_time, TimeDelta delta) {
- time_since_update_ += delta;
- if (config_.mode == CrossTrafficConfig::Mode::kRandomWalk) {
- if (time_since_update_ >= config_.random_walk.update_interval) {
- intensity_ += random_.Gaussian(config_.random_walk.bias,
- config_.random_walk.variance) *
- time_since_update_.seconds<double>();
- intensity_ = rtc::SafeClamp(intensity_, 0.0, 1.0);
- time_since_update_ = TimeDelta::Zero();
- }
- } else if (config_.mode == CrossTrafficConfig::Mode::kPulsedPeaks) {
- if (intensity_ == 0 && time_since_update_ >= config_.pulsed.hold_duration) {
- intensity_ = 1;
- time_since_update_ = TimeDelta::Zero();
- } else if (intensity_ == 1 &&
- time_since_update_ >= config_.pulsed.send_duration) {
- intensity_ = 0;
- time_since_update_ = TimeDelta::Zero();
- }
- }
- pending_size_ += TrafficRate() * delta;
- if (pending_size_ > config_.min_packet_size) {
- target_->OnPacketReceived(EmulatedIpPacket(
- /*from=*/rtc::SocketAddress(), receiver_address_,
- rtc::CopyOnWriteBuffer(pending_size_.bytes()), at_time));
- pending_size_ = DataSize::Zero();
- }
-}
-
-ColumnPrinter CrossTrafficSource::StatsPrinter() {
- return ColumnPrinter::Lambda("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_node.h b/test/scenario/network_node.h
index e324eba..5dcfa52 100644
--- a/test/scenario/network_node.h
+++ b/test/scenario/network_node.h
@@ -30,42 +30,23 @@
namespace webrtc {
namespace test {
-class NullReceiver : public EmulatedNetworkReceiverInterface {
+class SimulationNode {
public:
- void OnPacketReceived(EmulatedIpPacket packet) override;
-};
-class ActionReceiver : public EmulatedNetworkReceiverInterface {
- public:
- explicit ActionReceiver(std::function<void()> action);
- virtual ~ActionReceiver() = default;
+ SimulationNode(NetworkSimulationConfig config,
+ SimulatedNetwork* behavior,
+ EmulatedNetworkNode* network_node);
+ static std::unique_ptr<SimulatedNetwork> CreateBehavior(
+ NetworkSimulationConfig config);
- void OnPacketReceived(EmulatedIpPacket packet) override;
-
- private:
- std::function<void()> action_;
-};
-
-class SimulationNode : public EmulatedNetworkNode {
- public:
void UpdateConfig(std::function<void(NetworkSimulationConfig*)> modifier);
void PauseTransmissionUntil(Timestamp until);
ColumnPrinter ConfigPrinter() const;
- EmulatedNetworkNode* node() { return this; }
+ EmulatedNetworkNode* node() { return network_node_; }
private:
- friend class Scenario;
-
- SimulationNode(Clock* clock,
- rtc::TaskQueue* task_queue,
- NetworkSimulationConfig config,
- std::unique_ptr<NetworkBehaviorInterface> behavior,
- SimulatedNetwork* simulation);
- static std::unique_ptr<SimulationNode> Create(Clock* clock,
- rtc::TaskQueue* task_queue,
- NetworkSimulationConfig config);
-
- SimulatedNetwork* const simulated_network_;
NetworkSimulationConfig config_;
+ SimulatedNetwork* const simulation_;
+ EmulatedNetworkNode* const network_node_;
};
class NetworkNodeTransport : public Transport {
@@ -99,31 +80,6 @@
DataSize packet_overhead_ RTC_GUARDED_BY(crit_sect_) = DataSize::Zero();
rtc::NetworkRoute current_network_route_ RTC_GUARDED_BY(crit_sect_);
};
-
-// CrossTrafficSource is created by a Scenario and generates cross traffic. It
-// provides methods to access and print internal state.
-class CrossTrafficSource {
- public:
- DataRate TrafficRate() const;
- ColumnPrinter StatsPrinter();
- ~CrossTrafficSource();
-
- private:
- friend class Scenario;
- CrossTrafficSource(EmulatedNetworkReceiverInterface* target,
- rtc::IPAddress receiver_ip,
- CrossTrafficConfig config);
- void Process(Timestamp at_time, TimeDelta delta);
-
- EmulatedNetworkReceiverInterface* const target_;
- const rtc::SocketAddress receiver_address_;
- CrossTrafficConfig config_;
- webrtc::Random random_;
-
- TimeDelta time_since_update_ = TimeDelta::Zero();
- double intensity_ = 0;
- DataSize pending_size_ = DataSize::Zero();
-};
} // namespace test
} // namespace webrtc
#endif // TEST_SCENARIO_NETWORK_NODE_H_
diff --git a/test/scenario/scenario.cc b/test/scenario/scenario.cc
index 11ff29d..e469fc6 100644
--- a/test/scenario/scenario.cc
+++ b/test/scenario/scenario.cc
@@ -73,6 +73,7 @@
clock_(time_controller_->GetClock()),
audio_decoder_factory_(CreateBuiltinAudioDecoderFactory()),
audio_encoder_factory_(CreateBuiltinAudioEncoderFactory()),
+ network_manager_(time_controller_.get()),
task_queue_(time_controller_->GetTaskQueueFactory()->CreateTaskQueue(
"Scenario",
TaskQueueFactory::Priority::NORMAL)) {}
@@ -192,6 +193,7 @@
simulated_time_clients_.emplace_back(client);
return client;
}
+
EmulatedNetworkNode* Scenario::CreateSimulationNode(
std::function<void(NetworkSimulationConfig*)> config_modifier) {
NetworkSimulationConfig config;
@@ -201,7 +203,8 @@
EmulatedNetworkNode* Scenario::CreateSimulationNode(
NetworkSimulationConfig config) {
- return CreateMutableSimulationNode(config);
+ return network_manager_.CreateEmulatedNode(
+ SimulationNode::CreateBehavior(config));
}
SimulationNode* Scenario::CreateMutableSimulationNode(
@@ -213,55 +216,29 @@
SimulationNode* Scenario::CreateMutableSimulationNode(
NetworkSimulationConfig config) {
- auto network_node = SimulationNode::Create(clock_, &task_queue_, config);
- SimulationNode* sim_node = network_node.get();
- network_nodes_.emplace_back(std::move(network_node));
- return sim_node;
+ std::unique_ptr<SimulatedNetwork> behavior =
+ SimulationNode::CreateBehavior(config);
+ SimulatedNetwork* behavior_ptr = behavior.get();
+ auto* emulated_node =
+ network_manager_.CreateEmulatedNode(std::move(behavior));
+ simulation_nodes_.emplace_back(
+ new SimulationNode(config, behavior_ptr, emulated_node));
+ return simulation_nodes_.back().get();
}
void Scenario::TriggerPacketBurst(std::vector<EmulatedNetworkNode*> over_nodes,
size_t num_packets,
size_t packet_size) {
- rtc::IPAddress route_ip(next_route_id_++);
- EmulatedNetworkNode::CreateRoute(route_ip, over_nodes, &null_receiver_);
- for (size_t i = 0; i < num_packets; ++i)
- over_nodes[0]->OnPacketReceived(EmulatedIpPacket(
- /*from=*/rtc::SocketAddress(), /*to=*/rtc::SocketAddress(route_ip, 0),
- rtc::CopyOnWriteBuffer(packet_size), Now()));
+ network_manager_.CreateTrafficRoute(over_nodes)
+ ->TriggerPacketBurst(num_packets, packet_size);
}
void Scenario::NetworkDelayedAction(
std::vector<EmulatedNetworkNode*> over_nodes,
size_t packet_size,
std::function<void()> action) {
- rtc::IPAddress route_ip(next_route_id_++);
- action_receivers_.emplace_back(new ActionReceiver(action));
- EmulatedNetworkNode::CreateRoute(route_ip, over_nodes,
- action_receivers_.back().get());
- over_nodes[0]->OnPacketReceived(EmulatedIpPacket(
- /*from=*/rtc::SocketAddress(), /*to=*/rtc::SocketAddress(route_ip, 0),
- rtc::CopyOnWriteBuffer(packet_size), Now()));
-}
-
-CrossTrafficSource* Scenario::CreateCrossTraffic(
- std::vector<EmulatedNetworkNode*> over_nodes,
- std::function<void(CrossTrafficConfig*)> config_modifier) {
- CrossTrafficConfig cross_config;
- config_modifier(&cross_config);
- return CreateCrossTraffic(over_nodes, cross_config);
-}
-
-CrossTrafficSource* Scenario::CreateCrossTraffic(
- std::vector<EmulatedNetworkNode*> over_nodes,
- CrossTrafficConfig config) {
- rtc::IPAddress route_ip(next_route_id_++);
- cross_traffic_sources_.emplace_back(
- new CrossTrafficSource(over_nodes.front(), route_ip, config));
- CrossTrafficSource* node = cross_traffic_sources_.back().get();
- EmulatedNetworkNode::CreateRoute(route_ip, over_nodes, &null_receiver_);
- Every(config.min_packet_interval,
- [this, node](TimeDelta delta) { node->Process(Now(), delta); });
- return node;
+ network_manager_.CreateTrafficRoute(over_nodes)
+ ->NetworkDelayedAction(packet_size, action);
}
VideoStreamPair* Scenario::CreateVideoStream(
diff --git a/test/scenario/scenario.h b/test/scenario/scenario.h
index fb4f0bb..1799ef3 100644
--- a/test/scenario/scenario.h
+++ b/test/scenario/scenario.h
@@ -23,6 +23,7 @@
#include "test/scenario/audio_stream.h"
#include "test/scenario/call_client.h"
#include "test/scenario/column_printer.h"
+#include "test/scenario/network/network_emulation_manager.h"
#include "test/scenario/network_node.h"
#include "test/scenario/scenario_config.h"
#include "test/scenario/simulated_time.h"
@@ -48,6 +49,7 @@
bool real_time);
RTC_DISALLOW_COPY_AND_ASSIGN(Scenario);
~Scenario();
+ NetworkEmulationManagerImpl* net() { return &network_manager_; }
EmulatedNetworkNode* CreateSimulationNode(NetworkSimulationConfig config);
EmulatedNetworkNode* CreateSimulationNode(
@@ -102,13 +104,6 @@
std::pair<CallClient*, CallClient*> clients,
AudioStreamConfig config);
- CrossTrafficSource* CreateCrossTraffic(
- std::vector<EmulatedNetworkNode*> over_nodes,
- std::function<void(CrossTrafficConfig*)> config_modifier);
- CrossTrafficSource* CreateCrossTraffic(
- std::vector<EmulatedNetworkNode*> over_nodes,
- CrossTrafficConfig config);
-
// Runs the provided function with a fixed interval. For real time tests,
// |function| starts being called after |interval| from the call to Every().
void Every(TimeDelta interval, std::function<void(TimeDelta)> function);
@@ -168,21 +163,16 @@
private:
TimeDelta TimeUntilTarget(TimeDelta target_time_offset);
- NullReceiver null_receiver_;
const std::unique_ptr<LogWriterFactoryInterface> log_writer_factory_;
std::unique_ptr<TimeController> time_controller_;
Clock* clock_;
std::vector<std::unique_ptr<CallClient>> clients_;
std::vector<std::unique_ptr<CallClientPair>> client_pairs_;
- std::vector<std::unique_ptr<EmulatedNetworkNode>> network_nodes_;
- std::vector<std::unique_ptr<CrossTrafficSource>> cross_traffic_sources_;
std::vector<std::unique_ptr<VideoStreamPair>> video_streams_;
std::vector<std::unique_ptr<AudioStreamPair>> audio_streams_;
-
std::vector<std::unique_ptr<SimulatedTimeClient>> simulated_time_clients_;
-
- std::vector<std::unique_ptr<ActionReceiver>> action_receivers_;
+ std::vector<std::unique_ptr<SimulationNode>> simulation_nodes_;
std::vector<std::unique_ptr<StatesPrinter>> printers_;
int64_t next_route_id_ = 40000;
@@ -190,6 +180,7 @@
rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory_;
Timestamp start_time_ = Timestamp::PlusInfinity();
+ NetworkEmulationManagerImpl network_manager_;
// Defined last so it's destroyed first.
rtc::TaskQueue task_queue_;
};
diff --git a/test/scenario/scenario_config.cc b/test/scenario/scenario_config.cc
index 82c82c2..3f8a70a 100644
--- a/test/scenario/scenario_config.cc
+++ b/test/scenario/scenario_config.cc
@@ -43,9 +43,5 @@
AudioStreamConfig::Stream::Stream(const AudioStreamConfig::Stream&) = default;
AudioStreamConfig::Stream::~Stream() = default;
-CrossTrafficConfig::CrossTrafficConfig() = default;
-CrossTrafficConfig::CrossTrafficConfig(const CrossTrafficConfig&) = default;
-CrossTrafficConfig::~CrossTrafficConfig() = default;
-
} // namespace test
} // namespace webrtc
diff --git a/test/scenario/scenario_config.h b/test/scenario/scenario_config.h
index d530d30..18e34a7 100644
--- a/test/scenario/scenario_config.h
+++ b/test/scenario/scenario_config.h
@@ -237,26 +237,6 @@
bool codel_active_queue_management = false;
DataSize packet_overhead = DataSize::Zero();
};
-
-struct CrossTrafficConfig {
- CrossTrafficConfig();
- CrossTrafficConfig(const CrossTrafficConfig&);
- ~CrossTrafficConfig();
- enum Mode { kRandomWalk, kPulsedPeaks } mode = kRandomWalk;
- int random_seed = 1;
- DataRate peak_rate = DataRate::kbps(100);
- DataSize min_packet_size = DataSize::bytes(200);
- TimeDelta min_packet_interval = TimeDelta::ms(1);
- struct RandomWalk {
- TimeDelta update_interval = TimeDelta::ms(200);
- double variance = 0.6;
- double bias = -0.1;
- } random_walk;
- struct PulsedPeaks {
- TimeDelta send_duration = TimeDelta::ms(100);
- TimeDelta hold_duration = TimeDelta::ms(2000);
- } pulsed;
-};
} // namespace test
} // namespace webrtc
diff --git a/test/scenario/scenario_tests/bbr_performance.cc b/test/scenario/scenario_tests/bbr_performance.cc
index 8ab22f8..2e2efa2 100644
--- a/test/scenario/scenario_tests/bbr_performance.cc
+++ b/test/scenario/scenario_tests/bbr_performance.cc
@@ -191,11 +191,11 @@
}
});
}
- CrossTrafficConfig cross_config;
+ RandomWalkConfig cross_config;
cross_config.peak_rate = conf_.scenario.cross_traffic;
cross_config.random_seed = conf_.scenario.random_seed;
- CrossTrafficSource* cross_traffic =
- s.CreateCrossTraffic({send_net}, cross_config);
+ auto* cross_traffic = s.net()->CreateRandomWalkCrossTraffic(
+ s.net()->CreateTrafficRoute({send_net->node()}), cross_config);
s.CreatePrinter("send.stats.txt", TimeDelta::ms(100),
{alice->StatsPrinter(), alice_video->send()->StatsPrinter(),
diff --git a/test/scenario/scenario_unittest.cc b/test/scenario/scenario_unittest.cc
index eafb4c8..eea8d59 100644
--- a/test/scenario/scenario_unittest.cc
+++ b/test/scenario/scenario_unittest.cc
@@ -40,8 +40,9 @@
s.CreateAudioStream(route->forward(), audio_stream_config);
s.CreateAudioStream(route->reverse(), audio_stream_config);
- CrossTrafficConfig cross_traffic_config;
- s.CreateCrossTraffic({alice_net}, cross_traffic_config);
+ RandomWalkConfig cross_traffic_config;
+ s.net()->CreateRandomWalkCrossTraffic(
+ s.net()->CreateTrafficRoute({alice_net}), cross_traffic_config);
s.NetworkDelayedAction({alice_net, bob_net}, 100,
[&packet_received] { packet_received = true; });