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 <titovartem@webrtc.org> Reviewed-by: Sebastian Jansson <srte@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26649}
This commit is contained in:
parent
5c4ddad059
commit
d3666b2d98
@ -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",
|
||||
|
||||
@ -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",
|
||||
]
|
||||
|
||||
110
test/scenario/network/cross_traffic.cc
Normal file
110
test/scenario/network/cross_traffic.cc
Normal file
@ -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 <math.h>
|
||||
#include <utility>
|
||||
|
||||
#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<double>());
|
||||
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
|
||||
88
test/scenario/network/cross_traffic.h
Normal file
88
test/scenario/network/cross_traffic.h
Normal file
@ -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 <memory>
|
||||
|
||||
#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_
|
||||
156
test/scenario/network/cross_traffic_unittest.cc
Normal file
156
test/scenario/network/cross_traffic_unittest.cc
Normal file
@ -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 <atomic>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#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<PacketDeliveryInfo> DequeueDeliverablePackets(
|
||||
int64_t receive_time_us) override {
|
||||
std::vector<PacketDeliveryInfo> 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<int64_t> 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<PacketInFlightInfo> packets_to_send_;
|
||||
|
||||
std::atomic<int> packets_count_{0};
|
||||
std::atomic<uint64_t> total_packets_size_{0};
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(CrossTrafficTest, TriggerPacketBurst) {
|
||||
NetworkEmulationManager network_manager;
|
||||
|
||||
std::unique_ptr<CountingBehavior> behavior =
|
||||
absl::make_unique<CountingBehavior>();
|
||||
CountingBehavior* counter = behavior.get();
|
||||
|
||||
EmulatedNetworkNode* node_a = network_manager.CreateEmulatedNode(
|
||||
absl::make_unique<SimulatedNetwork>(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<CountingBehavior> behavior =
|
||||
absl::make_unique<CountingBehavior>();
|
||||
CountingBehavior* counter = behavior.get();
|
||||
|
||||
EmulatedNetworkNode* node_a = network_manager.CreateEmulatedNode(
|
||||
absl::make_unique<SimulatedNetwork>(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<CountingBehavior> behavior =
|
||||
absl::make_unique<CountingBehavior>();
|
||||
CountingBehavior* counter = behavior.get();
|
||||
|
||||
EmulatedNetworkNode* node_a = network_manager.CreateEmulatedNode(
|
||||
absl::make_unique<SimulatedNetwork>(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
|
||||
@ -95,6 +95,60 @@ void NetworkEmulationManager::ClearRoute(
|
||||
}
|
||||
}
|
||||
|
||||
TrafficRoute* NetworkEmulationManager::CreateTrafficRoute(
|
||||
std::vector<EmulatedNetworkNode*> 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<TrafficRoute> traffic_route =
|
||||
absl::make_unique<TrafficRoute>(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<RandomWalkCrossTraffic>(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<RandomWalkCrossTraffic> traffic;
|
||||
};
|
||||
task_queue_.PostTask(Closure{this, std::move(traffic)});
|
||||
return out;
|
||||
}
|
||||
|
||||
PulsedPeaksCrossTraffic* NetworkEmulationManager::CreatePulsedPeaksCrossTraffic(
|
||||
TrafficRoute* traffic_route,
|
||||
PulsedPeaksConfig config) {
|
||||
auto traffic = absl::make_unique<PulsedPeaksCrossTraffic>(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<PulsedPeaksCrossTraffic> traffic;
|
||||
};
|
||||
task_queue_.PostTask(Closure{this, std::move(traffic)});
|
||||
return out;
|
||||
}
|
||||
|
||||
rtc::Thread* NetworkEmulationManager::CreateNetworkThread(
|
||||
std::vector<EndpointNode*> 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);
|
||||
}
|
||||
|
||||
@ -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<EmulatedNetworkNode*> via_nodes,
|
||||
EndpointNode* to);
|
||||
|
||||
TrafficRoute* CreateTrafficRoute(std::vector<EmulatedNetworkNode*> via_nodes);
|
||||
RandomWalkCrossTraffic* CreateRandomWalkCrossTraffic(
|
||||
TrafficRoute* traffic_route,
|
||||
RandomWalkConfig config);
|
||||
PulsedPeaksCrossTraffic* CreatePulsedPeaksCrossTraffic(
|
||||
TrafficRoute* traffic_route,
|
||||
PulsedPeaksConfig config);
|
||||
|
||||
rtc::Thread* CreateNetworkThread(std::vector<EndpointNode*> endpoints);
|
||||
|
||||
private:
|
||||
@ -64,6 +74,9 @@ class NetworkEmulationManager {
|
||||
// All objects can be added to the manager only when it is idle.
|
||||
std::vector<std::unique_ptr<EndpointNode>> endpoints_;
|
||||
std::vector<std::unique_ptr<EmulatedNetworkNode>> network_nodes_;
|
||||
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::vector<std::unique_ptr<FakeNetworkSocketServer>> socket_servers_;
|
||||
std::vector<std::unique_ptr<rtc::Thread>> threads_;
|
||||
|
||||
|
||||
97
test/scenario/network/traffic_route.cc
Normal file
97
test/scenario/network/traffic_route.cc
Normal file
@ -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 <utility>
|
||||
|
||||
#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<void()> 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<void()> action_;
|
||||
// Endpoint and port will be used to free port in the endpoint after action
|
||||
// will be done.
|
||||
EndpointNode* endpoint_;
|
||||
absl::optional<uint16_t> port_ = absl::nullopt;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
TrafficRoute::TrafficRoute(Clock* clock,
|
||||
EmulatedNetworkReceiverInterface* receiver,
|
||||
EndpointNode* endpoint)
|
||||
: clock_(clock), receiver_(receiver), endpoint_(endpoint) {
|
||||
null_receiver_ = absl::make_unique<NullReceiver>();
|
||||
absl::optional<uint16_t> 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<void()> action) {
|
||||
auto action_receiver = absl::make_unique<ActionReceiver>(action, endpoint_);
|
||||
absl::optional<uint16_t> 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
|
||||
55
test/scenario/network/traffic_route.h
Normal file
55
test/scenario/network/traffic_route.h
Normal file
@ -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 <memory>
|
||||
#include <vector>
|
||||
|
||||
#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<void()> 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<EmulatedNetworkReceiverInterface> null_receiver_;
|
||||
std::vector<std::unique_ptr<EmulatedNetworkReceiverInterface>> actions_;
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // TEST_SCENARIO_NETWORK_TRAFFIC_ROUTE_H_
|
||||
Loading…
x
Reference in New Issue
Block a user