Add infrastructure stats for network emulation layer
Bug: b/240540204 Change-Id: I66dfd25775faa9d1bc7e75a932a36e8aa97c0f57 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/282320 Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Commit-Queue: Artem Titov <titovartem@webrtc.org> Cr-Commit-Position: refs/heads/main@{#38613}
This commit is contained in:
committed by
WebRTC LUCI CQ
parent
6b0aea07ab
commit
b41568b6fd
@ -18,8 +18,10 @@
|
||||
namespace webrtc {
|
||||
|
||||
std::unique_ptr<NetworkEmulationManager> CreateNetworkEmulationManager(
|
||||
TimeMode mode) {
|
||||
return std::make_unique<test::NetworkEmulationManagerImpl>(mode);
|
||||
TimeMode time_mode,
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode) {
|
||||
return std::make_unique<test::NetworkEmulationManagerImpl>(
|
||||
time_mode, stats_gathering_mode);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -19,7 +19,9 @@ namespace webrtc {
|
||||
|
||||
// Returns a non-null NetworkEmulationManager instance.
|
||||
std::unique_ptr<NetworkEmulationManager> CreateNetworkEmulationManager(
|
||||
TimeMode mode = TimeMode::kRealTime);
|
||||
TimeMode time_mode = TimeMode::kRealTime,
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode =
|
||||
EmulatedNetworkStatsGatheringMode::kDefault);
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
|
||||
@ -67,8 +67,8 @@ struct EmulatedNetworkOutgoingStats {
|
||||
|
||||
DataSize bytes_sent = DataSize::Zero();
|
||||
|
||||
// Sizes of all sent packets if EmulatedEndpointConfig::stats_gatherming_mode
|
||||
// was set to StatsGatheringMode::kDebug; empty otherwise.
|
||||
// Sizes of all sent packets.
|
||||
// Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
|
||||
SamplesStatsCounter sent_packets_size;
|
||||
|
||||
DataSize first_sent_packet_size = DataSize::Zero();
|
||||
@ -90,9 +90,8 @@ struct EmulatedNetworkIncomingStats {
|
||||
// Total amount of bytes in received packets.
|
||||
DataSize bytes_received = DataSize::Zero();
|
||||
|
||||
// Sizes of all received packets if
|
||||
// EmulatedEndpointConfig::stats_gatherming_mode was set to
|
||||
// StatsGatheringMode::kDebug; empty otherwise.
|
||||
// Sizes of all received packets.
|
||||
// Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
|
||||
SamplesStatsCounter received_packets_size;
|
||||
|
||||
// Total amount of packets that were received, but no destination was found.
|
||||
@ -101,9 +100,8 @@ struct EmulatedNetworkIncomingStats {
|
||||
// Total amount of bytes in discarded packets.
|
||||
DataSize bytes_discarded_no_receiver = DataSize::Zero();
|
||||
|
||||
// Sizes of all packets that were received, but no destination was found if
|
||||
// EmulatedEndpointConfig::stats_gatherming_mode was set to
|
||||
// StatsGatheringMode::kDebug; empty otherwise.
|
||||
// Sizes of all packets that were received, but no destination was found.
|
||||
// Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
|
||||
SamplesStatsCounter packets_discarded_no_receiver_size;
|
||||
|
||||
DataSize first_received_packet_size = DataSize::Zero();
|
||||
@ -124,10 +122,9 @@ struct EmulatedNetworkStats {
|
||||
|
||||
DataSize BytesSent() const { return overall_outgoing_stats.bytes_sent; }
|
||||
|
||||
// Returns the timestamped sizes of all sent packets if
|
||||
// EmulatedEndpointConfig::stats_gatherming_mode was set to
|
||||
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
|
||||
// Returns the timestamped sizes of all sent packets.
|
||||
// Returned reference is valid until the next call to a non-const method.
|
||||
// Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
|
||||
const SamplesStatsCounter& SentPacketsSizeCounter() const {
|
||||
return overall_outgoing_stats.sent_packets_size;
|
||||
}
|
||||
@ -162,10 +159,9 @@ struct EmulatedNetworkStats {
|
||||
return overall_incoming_stats.bytes_received;
|
||||
}
|
||||
|
||||
// Returns the timestamped sizes of all received packets if
|
||||
// EmulatedEndpointConfig::stats_gatherming_mode was set to
|
||||
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
|
||||
// Returns the timestamped sizes of all received packets.
|
||||
// Returned reference is valid until the next call to a non-const method.
|
||||
// Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
|
||||
const SamplesStatsCounter& ReceivedPacketsSizeCounter() const {
|
||||
return overall_incoming_stats.received_packets_size;
|
||||
}
|
||||
@ -181,10 +177,9 @@ struct EmulatedNetworkStats {
|
||||
}
|
||||
|
||||
// Returns counter with timestamped sizes of all packets that were received,
|
||||
// but no destination was found if
|
||||
// EmulatedEndpointConfig::stats_gatherming_mode was set to
|
||||
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
|
||||
// but no destination was found.
|
||||
// Returned reference is valid until the next call to a non-const method.
|
||||
// Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
|
||||
const SamplesStatsCounter& PacketsDiscardedNoReceiverSizeCounter() const {
|
||||
return overall_incoming_stats.packets_discarded_no_receiver_size;
|
||||
}
|
||||
@ -226,12 +221,25 @@ struct EmulatedNetworkStats {
|
||||
incoming_stats_per_source;
|
||||
|
||||
// Duration between packet was received on network interface and was
|
||||
// dispatched to the network in microseconds if
|
||||
// EmulatedEndpointConfig::stats_gatherming_mode was set to
|
||||
// StatsGatheringMode::kDebug; empty otherwise.
|
||||
// dispatched to the network in microseconds.
|
||||
// Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
|
||||
SamplesStatsCounter sent_packets_queue_wait_time_us;
|
||||
};
|
||||
|
||||
struct EmulatedNetworkNodeStats {
|
||||
// Amount of time each packet spent in the emulated network node for which
|
||||
// stats were collected.
|
||||
//
|
||||
// Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
|
||||
SamplesStatsCounter packet_transport_time;
|
||||
|
||||
// For each packet contains its size divided on the amount of time which it
|
||||
// spent in the emulated network node for which stats were collected.
|
||||
//
|
||||
// Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
|
||||
SamplesStatsCounter size_to_packet_transport_time;
|
||||
};
|
||||
|
||||
// EmulatedEndpoint is an abstraction for network interface on device. Instances
|
||||
// of this are created by NetworkEmulationManager::CreateEndpoint and
|
||||
// thread safe.
|
||||
|
||||
@ -49,15 +49,18 @@ class EmulatedNetworkNode;
|
||||
// peer device to another network interface on another peer device.
|
||||
class EmulatedRoute;
|
||||
|
||||
enum class EmulatedNetworkStatsGatheringMode {
|
||||
// Gather main network stats counters. See more details on which particular
|
||||
// metrics are collected in the `EmulatedNetworkStats` and
|
||||
// `EmulatedNetworkNodeStats` documentation.
|
||||
kDefault,
|
||||
// kDefault + also gather per packet statistics. In this mode more memory
|
||||
// will be used.
|
||||
kDebug
|
||||
};
|
||||
|
||||
struct EmulatedEndpointConfig {
|
||||
enum class IpAddressFamily { kIpv4, kIpv6 };
|
||||
enum class StatsGatheringMode {
|
||||
// Gather main network stats counters.
|
||||
kDefault,
|
||||
// kDefault + also gather per packet statistics. In this mode more memory
|
||||
// will be used.
|
||||
kDebug
|
||||
};
|
||||
|
||||
// If specified will be used to name endpoint for logging purposes.
|
||||
absl::optional<std::string> name = absl::nullopt;
|
||||
@ -70,7 +73,6 @@ struct EmulatedEndpointConfig {
|
||||
bool start_as_enabled = true;
|
||||
// Network type which will be used to represent endpoint to WebRTC.
|
||||
rtc::AdapterType type = rtc::AdapterType::ADAPTER_TYPE_UNKNOWN;
|
||||
StatsGatheringMode stats_gathering_mode = StatsGatheringMode::kDefault;
|
||||
// Allow endpoint to send packets specifying source IP address different to
|
||||
// the current endpoint IP address. If false endpoint will crash if attempt
|
||||
// to send such packet will be done.
|
||||
@ -327,7 +329,7 @@ class NetworkEmulationManager {
|
||||
CreateEmulatedNetworkManagerInterface(
|
||||
const std::vector<EmulatedEndpoint*>& endpoints) = 0;
|
||||
|
||||
// Passes summarized network stats for specified `endpoints` into specified
|
||||
// Passes combined network stats for all specified `endpoints` into specified
|
||||
// `stats_callback`. Callback will be executed on network emulation
|
||||
// internal task queue.
|
||||
// Deprecated.
|
||||
@ -339,6 +341,13 @@ class NetworkEmulationManager {
|
||||
rtc::ArrayView<EmulatedEndpoint* const> endpoints,
|
||||
std::function<void(EmulatedNetworkStats)> stats_callback) = 0;
|
||||
|
||||
// Passes combined network stats for all specified `nodes` into specified
|
||||
// `stats_callback`. Callback will be executed on network emulation
|
||||
// internal task queue.
|
||||
virtual void GetStats(
|
||||
rtc::ArrayView<EmulatedNetworkNode* const> nodes,
|
||||
std::function<void(EmulatedNetworkNodeStats)> stats_callback) = 0;
|
||||
|
||||
// Create a EmulatedTURNServer.
|
||||
// The TURN server has 2 endpoints that need to be connected with routes,
|
||||
// - GetClientEndpoint() - the endpoint that accepts TURN allocations.
|
||||
|
||||
@ -53,6 +53,7 @@ struct TrafficCounterFixture {
|
||||
/*id=*/1,
|
||||
rtc::IPAddress(kTestIpAddress),
|
||||
EmulatedEndpointConfig(),
|
||||
EmulatedNetworkStatsGatheringMode::kDefault,
|
||||
},
|
||||
/*is_enabled=*/true, &task_queue_, &clock};
|
||||
};
|
||||
@ -124,7 +125,8 @@ TEST(CrossTrafficTest, RandomWalkCrossTraffic) {
|
||||
}
|
||||
|
||||
TEST(TcpMessageRouteTest, DeliveredOnLossyNetwork) {
|
||||
NetworkEmulationManagerImpl net(TimeMode::kSimulated);
|
||||
NetworkEmulationManagerImpl net(TimeMode::kSimulated,
|
||||
EmulatedNetworkStatsGatheringMode::kDefault);
|
||||
BuiltInNetworkBehaviorConfig send;
|
||||
// 800 kbps means that the 100 kB message would be delivered in ca 1 second
|
||||
// under ideal conditions and no overhead.
|
||||
|
||||
@ -18,7 +18,7 @@ namespace webrtc {
|
||||
FeedbackGeneratorImpl::FeedbackGeneratorImpl(
|
||||
FeedbackGeneratorImpl::Config config)
|
||||
: conf_(config),
|
||||
net_(TimeMode::kSimulated),
|
||||
net_(TimeMode::kSimulated, EmulatedNetworkStatsGatheringMode::kDefault),
|
||||
send_link_{new SimulatedNetwork(conf_.send_link)},
|
||||
ret_link_{new SimulatedNetwork(conf_.return_link)},
|
||||
route_(this,
|
||||
|
||||
@ -17,8 +17,11 @@
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/numerics/samples_stats_counter.h"
|
||||
#include "api/sequence_checker.h"
|
||||
#include "api/test/network_emulation/network_emulation_interfaces.h"
|
||||
#include "api/test/network_emulation_manager.h"
|
||||
#include "api/units/data_size.h"
|
||||
#include "api/units/time_delta.h"
|
||||
#include "rtc_base/logging.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -26,8 +29,9 @@ namespace {
|
||||
|
||||
EmulatedNetworkOutgoingStats GetOverallOutgoingStats(
|
||||
const std::map<rtc::IPAddress, EmulatedNetworkOutgoingStats>&
|
||||
outgoing_stats) {
|
||||
EmulatedNetworkOutgoingStatsBuilder builder;
|
||||
outgoing_stats,
|
||||
EmulatedNetworkStatsGatheringMode mode) {
|
||||
EmulatedNetworkOutgoingStatsBuilder builder(mode);
|
||||
for (const auto& entry : outgoing_stats) {
|
||||
builder.AddOutgoingStats(entry.second);
|
||||
}
|
||||
@ -36,8 +40,9 @@ EmulatedNetworkOutgoingStats GetOverallOutgoingStats(
|
||||
|
||||
EmulatedNetworkIncomingStats GetOverallIncomingStats(
|
||||
const std::map<rtc::IPAddress, EmulatedNetworkIncomingStats>&
|
||||
incoming_stats) {
|
||||
EmulatedNetworkIncomingStatsBuilder builder;
|
||||
incoming_stats,
|
||||
EmulatedNetworkStatsGatheringMode mode) {
|
||||
EmulatedNetworkIncomingStatsBuilder builder(mode);
|
||||
for (const auto& entry : incoming_stats) {
|
||||
builder.AddIncomingStats(entry.second);
|
||||
}
|
||||
@ -46,14 +51,14 @@ EmulatedNetworkIncomingStats GetOverallIncomingStats(
|
||||
|
||||
} // namespace
|
||||
|
||||
EmulatedNetworkOutgoingStatsBuilder::EmulatedNetworkOutgoingStatsBuilder() {
|
||||
EmulatedNetworkOutgoingStatsBuilder::EmulatedNetworkOutgoingStatsBuilder(
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode)
|
||||
: stats_gathering_mode_(stats_gathering_mode) {
|
||||
sequence_checker_.Detach();
|
||||
}
|
||||
|
||||
void EmulatedNetworkOutgoingStatsBuilder::OnPacketSent(
|
||||
Timestamp sent_time,
|
||||
DataSize packet_size,
|
||||
EmulatedEndpointConfig::StatsGatheringMode mode) {
|
||||
void EmulatedNetworkOutgoingStatsBuilder::OnPacketSent(Timestamp sent_time,
|
||||
DataSize packet_size) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
RTC_CHECK_GE(packet_size, DataSize::Zero());
|
||||
if (stats_.first_packet_sent_time.IsInfinite()) {
|
||||
@ -63,7 +68,7 @@ void EmulatedNetworkOutgoingStatsBuilder::OnPacketSent(
|
||||
stats_.last_packet_sent_time = sent_time;
|
||||
stats_.packets_sent++;
|
||||
stats_.bytes_sent += packet_size;
|
||||
if (mode == EmulatedEndpointConfig::StatsGatheringMode::kDebug) {
|
||||
if (stats_gathering_mode_ == EmulatedNetworkStatsGatheringMode::kDebug) {
|
||||
stats_.sent_packets_size.AddSample(packet_size.bytes());
|
||||
}
|
||||
}
|
||||
@ -89,25 +94,25 @@ EmulatedNetworkOutgoingStats EmulatedNetworkOutgoingStatsBuilder::Build()
|
||||
return stats_;
|
||||
}
|
||||
|
||||
EmulatedNetworkIncomingStatsBuilder::EmulatedNetworkIncomingStatsBuilder() {
|
||||
EmulatedNetworkIncomingStatsBuilder::EmulatedNetworkIncomingStatsBuilder(
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode)
|
||||
: stats_gathering_mode_(stats_gathering_mode) {
|
||||
sequence_checker_.Detach();
|
||||
}
|
||||
|
||||
void EmulatedNetworkIncomingStatsBuilder::OnPacketDropped(
|
||||
DataSize packet_size,
|
||||
EmulatedEndpointConfig::StatsGatheringMode mode) {
|
||||
DataSize packet_size) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
stats_.packets_discarded_no_receiver++;
|
||||
stats_.bytes_discarded_no_receiver += packet_size;
|
||||
if (mode == EmulatedEndpointConfig::StatsGatheringMode::kDebug) {
|
||||
if (stats_gathering_mode_ == EmulatedNetworkStatsGatheringMode::kDebug) {
|
||||
stats_.packets_discarded_no_receiver_size.AddSample(packet_size.bytes());
|
||||
}
|
||||
}
|
||||
|
||||
void EmulatedNetworkIncomingStatsBuilder::OnPacketReceived(
|
||||
Timestamp received_time,
|
||||
DataSize packet_size,
|
||||
EmulatedEndpointConfig::StatsGatheringMode mode) {
|
||||
DataSize packet_size) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
RTC_CHECK_GE(packet_size, DataSize::Zero());
|
||||
if (stats_.first_packet_received_time.IsInfinite()) {
|
||||
@ -117,7 +122,7 @@ void EmulatedNetworkIncomingStatsBuilder::OnPacketReceived(
|
||||
stats_.last_packet_received_time = received_time;
|
||||
stats_.packets_received++;
|
||||
stats_.bytes_received += packet_size;
|
||||
if (mode == EmulatedEndpointConfig::StatsGatheringMode::kDebug) {
|
||||
if (stats_gathering_mode_ == EmulatedNetworkStatsGatheringMode::kDebug) {
|
||||
stats_.received_packets_size.AddSample(packet_size.bytes());
|
||||
}
|
||||
}
|
||||
@ -147,46 +152,69 @@ EmulatedNetworkIncomingStats EmulatedNetworkIncomingStatsBuilder::Build()
|
||||
return stats_;
|
||||
}
|
||||
|
||||
EmulatedNetworkStatsBuilder::EmulatedNetworkStatsBuilder() {
|
||||
EmulatedNetworkStatsBuilder::EmulatedNetworkStatsBuilder(
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode)
|
||||
: stats_gathering_mode_(stats_gathering_mode) {
|
||||
sequence_checker_.Detach();
|
||||
}
|
||||
|
||||
EmulatedNetworkStatsBuilder::EmulatedNetworkStatsBuilder(
|
||||
rtc::IPAddress local_ip) {
|
||||
rtc::IPAddress local_ip,
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode)
|
||||
: stats_gathering_mode_(stats_gathering_mode) {
|
||||
local_addresses_.push_back(local_ip);
|
||||
sequence_checker_.Detach();
|
||||
}
|
||||
|
||||
void EmulatedNetworkStatsBuilder::OnPacketSent(
|
||||
Timestamp queued_time,
|
||||
Timestamp sent_time,
|
||||
rtc::IPAddress destination_ip,
|
||||
DataSize packet_size,
|
||||
EmulatedEndpointConfig::StatsGatheringMode mode) {
|
||||
void EmulatedNetworkStatsBuilder::OnPacketSent(Timestamp queued_time,
|
||||
Timestamp sent_time,
|
||||
rtc::IPAddress destination_ip,
|
||||
DataSize packet_size) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
if (mode == EmulatedEndpointConfig::StatsGatheringMode::kDebug) {
|
||||
if (stats_gathering_mode_ == EmulatedNetworkStatsGatheringMode::kDebug) {
|
||||
sent_packets_queue_wait_time_us_.AddSample((sent_time - queued_time).us());
|
||||
}
|
||||
outgoing_stats_per_destination_[destination_ip].OnPacketSent(
|
||||
sent_time, packet_size, mode);
|
||||
auto it = outgoing_stats_per_destination_.find(destination_ip);
|
||||
if (it == outgoing_stats_per_destination_.end()) {
|
||||
outgoing_stats_per_destination_
|
||||
.emplace(destination_ip,
|
||||
std::make_unique<EmulatedNetworkOutgoingStatsBuilder>(
|
||||
stats_gathering_mode_))
|
||||
.first->second->OnPacketSent(sent_time, packet_size);
|
||||
} else {
|
||||
it->second->OnPacketSent(sent_time, packet_size);
|
||||
}
|
||||
}
|
||||
|
||||
void EmulatedNetworkStatsBuilder::OnPacketDropped(
|
||||
rtc::IPAddress source_ip,
|
||||
DataSize packet_size,
|
||||
EmulatedEndpointConfig::StatsGatheringMode mode) {
|
||||
void EmulatedNetworkStatsBuilder::OnPacketDropped(rtc::IPAddress source_ip,
|
||||
DataSize packet_size) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
incoming_stats_per_source_[source_ip].OnPacketDropped(packet_size, mode);
|
||||
auto it = incoming_stats_per_source_.find(source_ip);
|
||||
if (it == incoming_stats_per_source_.end()) {
|
||||
incoming_stats_per_source_
|
||||
.emplace(source_ip,
|
||||
std::make_unique<EmulatedNetworkIncomingStatsBuilder>(
|
||||
stats_gathering_mode_))
|
||||
.first->second->OnPacketDropped(packet_size);
|
||||
} else {
|
||||
it->second->OnPacketDropped(packet_size);
|
||||
}
|
||||
}
|
||||
|
||||
void EmulatedNetworkStatsBuilder::OnPacketReceived(
|
||||
Timestamp received_time,
|
||||
rtc::IPAddress source_ip,
|
||||
DataSize packet_size,
|
||||
EmulatedEndpointConfig::StatsGatheringMode mode) {
|
||||
void EmulatedNetworkStatsBuilder::OnPacketReceived(Timestamp received_time,
|
||||
rtc::IPAddress source_ip,
|
||||
DataSize packet_size) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
incoming_stats_per_source_[source_ip].OnPacketReceived(received_time,
|
||||
packet_size, mode);
|
||||
auto it = incoming_stats_per_source_.find(source_ip);
|
||||
if (it == incoming_stats_per_source_.end()) {
|
||||
incoming_stats_per_source_
|
||||
.emplace(source_ip,
|
||||
std::make_unique<EmulatedNetworkIncomingStatsBuilder>(
|
||||
stats_gathering_mode_))
|
||||
.first->second->OnPacketReceived(received_time, packet_size);
|
||||
} else {
|
||||
it->second->OnPacketReceived(received_time, packet_size);
|
||||
}
|
||||
}
|
||||
|
||||
void EmulatedNetworkStatsBuilder::AddEmulatedNetworkStats(
|
||||
@ -203,12 +231,30 @@ void EmulatedNetworkStatsBuilder::AddEmulatedNetworkStats(
|
||||
|
||||
// Add outgoing stats from other endpoints to the builder.
|
||||
for (const auto& entry : stats.outgoing_stats_per_destination) {
|
||||
outgoing_stats_per_destination_[entry.first].AddOutgoingStats(entry.second);
|
||||
auto it = outgoing_stats_per_destination_.find(entry.first);
|
||||
if (it == outgoing_stats_per_destination_.end()) {
|
||||
outgoing_stats_per_destination_
|
||||
.emplace(entry.first,
|
||||
std::make_unique<EmulatedNetworkOutgoingStatsBuilder>(
|
||||
stats_gathering_mode_))
|
||||
.first->second->AddOutgoingStats(entry.second);
|
||||
} else {
|
||||
it->second->AddOutgoingStats(entry.second);
|
||||
}
|
||||
}
|
||||
|
||||
// Add incoming stats from other endpoints to the builder.
|
||||
for (const auto& entry : stats.incoming_stats_per_source) {
|
||||
incoming_stats_per_source_[entry.first].AddIncomingStats(entry.second);
|
||||
auto it = incoming_stats_per_source_.find(entry.first);
|
||||
if (it == incoming_stats_per_source_.end()) {
|
||||
incoming_stats_per_source_
|
||||
.emplace(entry.first,
|
||||
std::make_unique<EmulatedNetworkIncomingStatsBuilder>(
|
||||
stats_gathering_mode_))
|
||||
.first->second->AddIncomingStats(entry.second);
|
||||
} else {
|
||||
it->second->AddIncomingStats(entry.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,21 +262,53 @@ EmulatedNetworkStats EmulatedNetworkStatsBuilder::Build() const {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
std::map<rtc::IPAddress, EmulatedNetworkOutgoingStats> outgoing_stats;
|
||||
for (const auto& entry : outgoing_stats_per_destination_) {
|
||||
outgoing_stats.emplace(entry.first, entry.second.Build());
|
||||
outgoing_stats.emplace(entry.first, entry.second->Build());
|
||||
}
|
||||
std::map<rtc::IPAddress, EmulatedNetworkIncomingStats> incoming_stats;
|
||||
for (const auto& entry : incoming_stats_per_source_) {
|
||||
incoming_stats.emplace(entry.first, entry.second.Build());
|
||||
incoming_stats.emplace(entry.first, entry.second->Build());
|
||||
}
|
||||
return EmulatedNetworkStats{
|
||||
.local_addresses = local_addresses_,
|
||||
.overall_outgoing_stats = GetOverallOutgoingStats(outgoing_stats),
|
||||
.overall_incoming_stats = GetOverallIncomingStats(incoming_stats),
|
||||
.overall_outgoing_stats =
|
||||
GetOverallOutgoingStats(outgoing_stats, stats_gathering_mode_),
|
||||
.overall_incoming_stats =
|
||||
GetOverallIncomingStats(incoming_stats, stats_gathering_mode_),
|
||||
.outgoing_stats_per_destination = std::move(outgoing_stats),
|
||||
.incoming_stats_per_source = std::move(incoming_stats),
|
||||
.sent_packets_queue_wait_time_us = sent_packets_queue_wait_time_us_};
|
||||
}
|
||||
|
||||
EmulatedNetworkNodeStatsBuilder::EmulatedNetworkNodeStatsBuilder(
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode)
|
||||
: stats_gathering_mode_(stats_gathering_mode) {
|
||||
sequence_checker_.Detach();
|
||||
}
|
||||
|
||||
void EmulatedNetworkNodeStatsBuilder::AddPacketTransportTime(
|
||||
TimeDelta time,
|
||||
size_t packet_size) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
if (stats_gathering_mode_ == EmulatedNetworkStatsGatheringMode::kDebug) {
|
||||
stats_.packet_transport_time.AddSample(time.ms<double>());
|
||||
stats_.size_to_packet_transport_time.AddSample(packet_size /
|
||||
time.ms<double>());
|
||||
}
|
||||
}
|
||||
|
||||
void EmulatedNetworkNodeStatsBuilder::AddEmulatedNetworkNodeStats(
|
||||
const EmulatedNetworkNodeStats& stats) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
stats_.packet_transport_time.AddSamples(stats.packet_transport_time);
|
||||
stats_.size_to_packet_transport_time.AddSamples(
|
||||
stats.size_to_packet_transport_time);
|
||||
}
|
||||
|
||||
EmulatedNetworkNodeStats EmulatedNetworkNodeStatsBuilder::Build() const {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
return stats_;
|
||||
}
|
||||
|
||||
void LinkEmulation::OnPacketReceived(EmulatedIpPacket packet) {
|
||||
task_queue_->PostTask([this, packet = std::move(packet)]() mutable {
|
||||
RTC_DCHECK_RUN_ON(task_queue_);
|
||||
@ -239,7 +317,10 @@ void LinkEmulation::OnPacketReceived(EmulatedIpPacket packet) {
|
||||
bool sent = network_behavior_->EnqueuePacket(PacketInFlightInfo(
|
||||
packet.ip_packet_size(), packet.arrival_time.us(), packet_id));
|
||||
if (sent) {
|
||||
packets_.emplace_back(StoredPacket{packet_id, std::move(packet), false});
|
||||
packets_.emplace_back(StoredPacket{.id = packet_id,
|
||||
.sent_time = clock_->CurrentTime(),
|
||||
.packet = std::move(packet),
|
||||
.removed = false});
|
||||
}
|
||||
if (process_task_.Running())
|
||||
return;
|
||||
@ -268,6 +349,11 @@ void LinkEmulation::OnPacketReceived(EmulatedIpPacket packet) {
|
||||
});
|
||||
}
|
||||
|
||||
EmulatedNetworkNodeStats LinkEmulation::stats() const {
|
||||
RTC_DCHECK_RUN_ON(task_queue_);
|
||||
return stats_builder_.Build();
|
||||
}
|
||||
|
||||
void LinkEmulation::Process(Timestamp at_time) {
|
||||
std::vector<PacketDeliveryInfo> delivery_infos =
|
||||
network_behavior_->DequeueDeliverablePackets(at_time.us());
|
||||
@ -282,6 +368,9 @@ void LinkEmulation::Process(Timestamp at_time) {
|
||||
RTC_CHECK(packet);
|
||||
RTC_DCHECK(!packet->removed);
|
||||
packet->removed = true;
|
||||
stats_builder_.AddPacketTransportTime(
|
||||
clock_->CurrentTime() - packet->sent_time,
|
||||
packet->packet.ip_packet_size());
|
||||
|
||||
if (delivery_info.receive_time_us != PacketDeliveryInfo::kNotReceived) {
|
||||
packet->packet.arrival_time =
|
||||
@ -371,14 +460,23 @@ void NetworkRouterNode::SetFilter(
|
||||
EmulatedNetworkNode::EmulatedNetworkNode(
|
||||
Clock* clock,
|
||||
rtc::TaskQueue* task_queue,
|
||||
std::unique_ptr<NetworkBehaviorInterface> network_behavior)
|
||||
std::unique_ptr<NetworkBehaviorInterface> network_behavior,
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode)
|
||||
: router_(task_queue),
|
||||
link_(clock, task_queue, std::move(network_behavior), &router_) {}
|
||||
link_(clock,
|
||||
task_queue,
|
||||
std::move(network_behavior),
|
||||
&router_,
|
||||
stats_gathering_mode) {}
|
||||
|
||||
void EmulatedNetworkNode::OnPacketReceived(EmulatedIpPacket packet) {
|
||||
link_.OnPacketReceived(std::move(packet));
|
||||
}
|
||||
|
||||
EmulatedNetworkNodeStats EmulatedNetworkNode::stats() const {
|
||||
return link_.stats();
|
||||
}
|
||||
|
||||
void EmulatedNetworkNode::CreateRoute(
|
||||
const rtc::IPAddress& receiver_ip,
|
||||
std::vector<EmulatedNetworkNode*> nodes,
|
||||
@ -397,12 +495,14 @@ void EmulatedNetworkNode::ClearRoute(const rtc::IPAddress& receiver_ip,
|
||||
|
||||
EmulatedNetworkNode::~EmulatedNetworkNode() = default;
|
||||
|
||||
EmulatedEndpointImpl::Options::Options(uint64_t id,
|
||||
const rtc::IPAddress& ip,
|
||||
const EmulatedEndpointConfig& config)
|
||||
EmulatedEndpointImpl::Options::Options(
|
||||
uint64_t id,
|
||||
const rtc::IPAddress& ip,
|
||||
const EmulatedEndpointConfig& config,
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode)
|
||||
: id(id),
|
||||
ip(ip),
|
||||
stats_gathering_mode(config.stats_gathering_mode),
|
||||
stats_gathering_mode(stats_gathering_mode),
|
||||
type(config.type),
|
||||
allow_send_packet_with_different_source_ip(
|
||||
config.allow_send_packet_with_different_source_ip),
|
||||
@ -420,7 +520,7 @@ EmulatedEndpointImpl::EmulatedEndpointImpl(const Options& options,
|
||||
task_queue_(task_queue),
|
||||
router_(task_queue_),
|
||||
next_port_(kFirstEphemeralPort),
|
||||
stats_builder_(options_.ip) {
|
||||
stats_builder_(options_.ip, options_.stats_gathering_mode) {
|
||||
constexpr int kIPv4NetworkPrefixLength = 24;
|
||||
constexpr int kIPv6NetworkPrefixLength = 64;
|
||||
|
||||
@ -459,8 +559,7 @@ void EmulatedEndpointImpl::SendPacket(const rtc::SocketAddress& from,
|
||||
RTC_DCHECK_RUN_ON(task_queue_);
|
||||
stats_builder_.OnPacketSent(packet.arrival_time, clock_->CurrentTime(),
|
||||
packet.to.ipaddr(),
|
||||
DataSize::Bytes(packet.ip_packet_size()),
|
||||
options_.stats_gathering_mode);
|
||||
DataSize::Bytes(packet.ip_packet_size()));
|
||||
|
||||
if (packet.to.ipaddr() == options_.ip) {
|
||||
OnPacketReceived(std::move(packet));
|
||||
@ -566,8 +665,7 @@ void EmulatedEndpointImpl::OnPacketReceived(EmulatedIpPacket packet) {
|
||||
}
|
||||
MutexLock lock(&receiver_lock_);
|
||||
stats_builder_.OnPacketReceived(clock_->CurrentTime(), packet.from.ipaddr(),
|
||||
DataSize::Bytes(packet.ip_packet_size()),
|
||||
options_.stats_gathering_mode);
|
||||
DataSize::Bytes(packet.ip_packet_size()));
|
||||
auto it = port_to_receiver_.find(packet.to.port());
|
||||
if (it == port_to_receiver_.end()) {
|
||||
if (default_receiver_.has_value()) {
|
||||
@ -582,8 +680,7 @@ void EmulatedEndpointImpl::OnPacketReceived(EmulatedIpPacket packet) {
|
||||
<< " on port " << packet.to.port()
|
||||
<< ". Packet source: " << packet.from.ToString();
|
||||
stats_builder_.OnPacketDropped(packet.from.ipaddr(),
|
||||
DataSize::Bytes(packet.ip_packet_size()),
|
||||
options_.stats_gathering_mode);
|
||||
DataSize::Bytes(packet.ip_packet_size()));
|
||||
return;
|
||||
}
|
||||
// Endpoint holds lock during packet processing to ensure that a call to
|
||||
@ -618,10 +715,6 @@ EmulatedNetworkStats EmulatedEndpointImpl::stats() const {
|
||||
return stats_builder_.Build();
|
||||
}
|
||||
|
||||
EndpointsContainer::EndpointsContainer(
|
||||
const std::vector<EmulatedEndpointImpl*>& endpoints)
|
||||
: endpoints_(endpoints) {}
|
||||
|
||||
EmulatedEndpointImpl* EndpointsContainer::LookupByLocalAddress(
|
||||
const rtc::IPAddress& local_ip) const {
|
||||
for (auto* endpoint : endpoints_) {
|
||||
@ -633,6 +726,11 @@ EmulatedEndpointImpl* EndpointsContainer::LookupByLocalAddress(
|
||||
RTC_CHECK(false) << "No network found for address" << local_ip.ToString();
|
||||
}
|
||||
|
||||
EndpointsContainer::EndpointsContainer(
|
||||
const std::vector<EmulatedEndpointImpl*>& endpoints,
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode)
|
||||
: endpoints_(endpoints), stats_gathering_mode_(stats_gathering_mode) {}
|
||||
|
||||
bool EndpointsContainer::HasEndpoint(EmulatedEndpointImpl* endpoint) const {
|
||||
for (auto* e : endpoints_) {
|
||||
if (e->GetId() == endpoint->GetId()) {
|
||||
@ -659,7 +757,7 @@ std::vector<EmulatedEndpoint*> EndpointsContainer::GetEndpoints() const {
|
||||
}
|
||||
|
||||
EmulatedNetworkStats EndpointsContainer::GetStats() const {
|
||||
EmulatedNetworkStatsBuilder stats_builder;
|
||||
EmulatedNetworkStatsBuilder stats_builder(stats_gathering_mode_);
|
||||
for (auto* endpoint : endpoints_) {
|
||||
stats_builder.AddEmulatedNetworkStats(endpoint->stats());
|
||||
}
|
||||
|
||||
@ -23,8 +23,10 @@
|
||||
#include "api/array_view.h"
|
||||
#include "api/numerics/samples_stats_counter.h"
|
||||
#include "api/sequence_checker.h"
|
||||
#include "api/test/network_emulation/network_emulation_interfaces.h"
|
||||
#include "api/test/network_emulation_manager.h"
|
||||
#include "api/test/simulated_network.h"
|
||||
#include "api/units/time_delta.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "rtc_base/copy_on_write_buffer.h"
|
||||
#include "rtc_base/network.h"
|
||||
@ -42,19 +44,19 @@ namespace webrtc {
|
||||
// single thread. It may be created on another thread.
|
||||
class EmulatedNetworkOutgoingStatsBuilder {
|
||||
public:
|
||||
EmulatedNetworkOutgoingStatsBuilder();
|
||||
explicit EmulatedNetworkOutgoingStatsBuilder(
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode);
|
||||
|
||||
void OnPacketSent(Timestamp sent_time,
|
||||
DataSize packet_size,
|
||||
EmulatedEndpointConfig::StatsGatheringMode mode);
|
||||
void OnPacketSent(Timestamp sent_time, DataSize packet_size);
|
||||
|
||||
void AddOutgoingStats(const EmulatedNetworkOutgoingStats& stats);
|
||||
|
||||
EmulatedNetworkOutgoingStats Build() const;
|
||||
|
||||
private:
|
||||
RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
|
||||
const EmulatedNetworkStatsGatheringMode stats_gathering_mode_;
|
||||
|
||||
RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
|
||||
EmulatedNetworkOutgoingStats stats_ RTC_GUARDED_BY(sequence_checker_);
|
||||
};
|
||||
|
||||
@ -62,14 +64,12 @@ class EmulatedNetworkOutgoingStatsBuilder {
|
||||
// single thread. It may be created on another thread.
|
||||
class EmulatedNetworkIncomingStatsBuilder {
|
||||
public:
|
||||
EmulatedNetworkIncomingStatsBuilder();
|
||||
explicit EmulatedNetworkIncomingStatsBuilder(
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode);
|
||||
|
||||
void OnPacketDropped(DataSize packet_size,
|
||||
EmulatedEndpointConfig::StatsGatheringMode mode);
|
||||
void OnPacketDropped(DataSize packet_size);
|
||||
|
||||
void OnPacketReceived(Timestamp received_time,
|
||||
DataSize packet_size,
|
||||
EmulatedEndpointConfig::StatsGatheringMode mode);
|
||||
void OnPacketReceived(Timestamp received_time, DataSize packet_size);
|
||||
|
||||
// Adds stats collected from another endpoints to the builder.
|
||||
void AddIncomingStats(const EmulatedNetworkIncomingStats& stats);
|
||||
@ -77,8 +77,9 @@ class EmulatedNetworkIncomingStatsBuilder {
|
||||
EmulatedNetworkIncomingStats Build() const;
|
||||
|
||||
private:
|
||||
RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
|
||||
const EmulatedNetworkStatsGatheringMode stats_gathering_mode_;
|
||||
|
||||
RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
|
||||
EmulatedNetworkIncomingStats stats_ RTC_GUARDED_BY(sequence_checker_);
|
||||
};
|
||||
|
||||
@ -86,55 +87,80 @@ class EmulatedNetworkIncomingStatsBuilder {
|
||||
// thread. It may be created on another thread.
|
||||
class EmulatedNetworkStatsBuilder {
|
||||
public:
|
||||
EmulatedNetworkStatsBuilder();
|
||||
explicit EmulatedNetworkStatsBuilder(rtc::IPAddress local_ip);
|
||||
explicit EmulatedNetworkStatsBuilder(
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode);
|
||||
explicit EmulatedNetworkStatsBuilder(
|
||||
rtc::IPAddress local_ip,
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode);
|
||||
|
||||
void OnPacketSent(Timestamp queued_time,
|
||||
Timestamp sent_time,
|
||||
rtc::IPAddress destination_ip,
|
||||
DataSize packet_size,
|
||||
EmulatedEndpointConfig::StatsGatheringMode mode);
|
||||
DataSize packet_size);
|
||||
|
||||
void OnPacketDropped(rtc::IPAddress source_ip,
|
||||
DataSize packet_size,
|
||||
EmulatedEndpointConfig::StatsGatheringMode mode);
|
||||
void OnPacketDropped(rtc::IPAddress source_ip, DataSize packet_size);
|
||||
|
||||
void OnPacketReceived(Timestamp received_time,
|
||||
rtc::IPAddress source_ip,
|
||||
DataSize packet_size,
|
||||
EmulatedEndpointConfig::StatsGatheringMode mode);
|
||||
DataSize packet_size);
|
||||
|
||||
void AddEmulatedNetworkStats(const EmulatedNetworkStats& stats);
|
||||
|
||||
EmulatedNetworkStats Build() const;
|
||||
|
||||
private:
|
||||
RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
|
||||
const EmulatedNetworkStatsGatheringMode stats_gathering_mode_;
|
||||
|
||||
RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
|
||||
std::vector<rtc::IPAddress> local_addresses_
|
||||
RTC_GUARDED_BY(sequence_checker_);
|
||||
SamplesStatsCounter sent_packets_queue_wait_time_us_;
|
||||
std::map<rtc::IPAddress, EmulatedNetworkOutgoingStatsBuilder>
|
||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStatsBuilder>>
|
||||
outgoing_stats_per_destination_ RTC_GUARDED_BY(sequence_checker_);
|
||||
std::map<rtc::IPAddress, EmulatedNetworkIncomingStatsBuilder>
|
||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStatsBuilder>>
|
||||
incoming_stats_per_source_ RTC_GUARDED_BY(sequence_checker_);
|
||||
};
|
||||
|
||||
// All methods of EmulatedNetworkNodeStatsBuilder have to be used on a
|
||||
// single thread. It may be created on another thread.
|
||||
class EmulatedNetworkNodeStatsBuilder {
|
||||
public:
|
||||
explicit EmulatedNetworkNodeStatsBuilder(
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode);
|
||||
|
||||
void AddPacketTransportTime(TimeDelta time, size_t packet_size);
|
||||
|
||||
void AddEmulatedNetworkNodeStats(const EmulatedNetworkNodeStats& stats);
|
||||
|
||||
EmulatedNetworkNodeStats Build() const;
|
||||
|
||||
private:
|
||||
const EmulatedNetworkStatsGatheringMode stats_gathering_mode_;
|
||||
|
||||
RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
|
||||
EmulatedNetworkNodeStats stats_ RTC_GUARDED_BY(sequence_checker_);
|
||||
};
|
||||
|
||||
class LinkEmulation : public EmulatedNetworkReceiverInterface {
|
||||
public:
|
||||
LinkEmulation(Clock* clock,
|
||||
rtc::TaskQueue* task_queue,
|
||||
std::unique_ptr<NetworkBehaviorInterface> network_behavior,
|
||||
EmulatedNetworkReceiverInterface* receiver)
|
||||
EmulatedNetworkReceiverInterface* receiver,
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode)
|
||||
: clock_(clock),
|
||||
task_queue_(task_queue),
|
||||
network_behavior_(std::move(network_behavior)),
|
||||
receiver_(receiver) {}
|
||||
receiver_(receiver),
|
||||
stats_builder_(stats_gathering_mode) {}
|
||||
void OnPacketReceived(EmulatedIpPacket packet) override;
|
||||
|
||||
EmulatedNetworkNodeStats stats() const;
|
||||
|
||||
private:
|
||||
struct StoredPacket {
|
||||
uint64_t id;
|
||||
Timestamp sent_time;
|
||||
EmulatedIpPacket packet;
|
||||
bool removed;
|
||||
};
|
||||
@ -145,9 +171,12 @@ class LinkEmulation : public EmulatedNetworkReceiverInterface {
|
||||
const std::unique_ptr<NetworkBehaviorInterface> network_behavior_
|
||||
RTC_GUARDED_BY(task_queue_);
|
||||
EmulatedNetworkReceiverInterface* const receiver_;
|
||||
|
||||
RepeatingTaskHandle process_task_ RTC_GUARDED_BY(task_queue_);
|
||||
std::deque<StoredPacket> packets_ RTC_GUARDED_BY(task_queue_);
|
||||
uint64_t next_packet_id_ RTC_GUARDED_BY(task_queue_) = 1;
|
||||
|
||||
EmulatedNetworkNodeStatsBuilder stats_builder_ RTC_GUARDED_BY(task_queue_);
|
||||
};
|
||||
|
||||
// Represents a component responsible for routing packets based on their IP
|
||||
@ -195,7 +224,8 @@ class EmulatedNetworkNode : public EmulatedNetworkReceiverInterface {
|
||||
EmulatedNetworkNode(
|
||||
Clock* clock,
|
||||
rtc::TaskQueue* task_queue,
|
||||
std::unique_ptr<NetworkBehaviorInterface> network_behavior);
|
||||
std::unique_ptr<NetworkBehaviorInterface> network_behavior,
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode);
|
||||
~EmulatedNetworkNode() override;
|
||||
|
||||
EmulatedNetworkNode(const EmulatedNetworkNode&) = delete;
|
||||
@ -205,6 +235,7 @@ class EmulatedNetworkNode : public EmulatedNetworkReceiverInterface {
|
||||
|
||||
LinkEmulation* link() { return &link_; }
|
||||
NetworkRouterNode* router() { return &router_; }
|
||||
EmulatedNetworkNodeStats stats() const;
|
||||
|
||||
// Creates a route for the given receiver_ip over all the given nodes to the
|
||||
// given receiver.
|
||||
@ -228,13 +259,14 @@ class EmulatedEndpointImpl : public EmulatedEndpoint {
|
||||
struct Options {
|
||||
Options(uint64_t id,
|
||||
const rtc::IPAddress& ip,
|
||||
const EmulatedEndpointConfig& config);
|
||||
const EmulatedEndpointConfig& config,
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode);
|
||||
|
||||
// TODO(titovartem) check if we can remove id.
|
||||
uint64_t id;
|
||||
// Endpoint local IP address.
|
||||
rtc::IPAddress ip;
|
||||
EmulatedEndpointConfig::StatsGatheringMode stats_gathering_mode;
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode;
|
||||
rtc::AdapterType type;
|
||||
// Allow endpoint to send packets specifying source IP address different to
|
||||
// the current endpoint IP address. If false endpoint will crash if attempt
|
||||
@ -343,8 +375,8 @@ class EmulatedRoute {
|
||||
// This object is immutable and so thread safe.
|
||||
class EndpointsContainer {
|
||||
public:
|
||||
explicit EndpointsContainer(
|
||||
const std::vector<EmulatedEndpointImpl*>& endpoints);
|
||||
EndpointsContainer(const std::vector<EmulatedEndpointImpl*>& endpoints,
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode);
|
||||
|
||||
EmulatedEndpointImpl* LookupByLocalAddress(
|
||||
const rtc::IPAddress& local_ip) const;
|
||||
@ -357,6 +389,7 @@ class EndpointsContainer {
|
||||
|
||||
private:
|
||||
const std::vector<EmulatedEndpointImpl*> endpoints_;
|
||||
const EmulatedNetworkStatsGatheringMode stats_gathering_mode_;
|
||||
};
|
||||
|
||||
template <typename FakePacketType>
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
#include "api/units/time_delta.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#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"
|
||||
@ -45,8 +44,11 @@ std::unique_ptr<TimeController> CreateTimeController(TimeMode mode) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
NetworkEmulationManagerImpl::NetworkEmulationManagerImpl(TimeMode mode)
|
||||
NetworkEmulationManagerImpl::NetworkEmulationManagerImpl(
|
||||
TimeMode mode,
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode)
|
||||
: time_mode_(mode),
|
||||
stats_gathering_mode_(stats_gathering_mode),
|
||||
time_controller_(CreateTimeController(mode)),
|
||||
clock_(time_controller_->GetClock()),
|
||||
next_node_id_(1),
|
||||
@ -74,7 +76,7 @@ EmulatedNetworkNode* NetworkEmulationManagerImpl::CreateEmulatedNode(
|
||||
EmulatedNetworkNode* NetworkEmulationManagerImpl::CreateEmulatedNode(
|
||||
std::unique_ptr<NetworkBehaviorInterface> network_behavior) {
|
||||
auto node = std::make_unique<EmulatedNetworkNode>(
|
||||
clock_, &task_queue_, std::move(network_behavior));
|
||||
clock_, &task_queue_, std::move(network_behavior), stats_gathering_mode_);
|
||||
EmulatedNetworkNode* out = node.get();
|
||||
task_queue_.PostTask([this, node = std::move(node)]() mutable {
|
||||
network_nodes_.push_back(std::move(node));
|
||||
@ -107,7 +109,8 @@ EmulatedEndpointImpl* NetworkEmulationManagerImpl::CreateEndpoint(
|
||||
bool res = used_ip_addresses_.insert(*ip).second;
|
||||
RTC_CHECK(res) << "IP=" << ip->ToString() << " already in use";
|
||||
auto node = std::make_unique<EmulatedEndpointImpl>(
|
||||
EmulatedEndpointImpl::Options(next_node_id_++, *ip, config),
|
||||
EmulatedEndpointImpl::Options(next_node_id_++, *ip, config,
|
||||
stats_gathering_mode_),
|
||||
config.start_as_enabled, &task_queue_, clock_);
|
||||
EmulatedEndpointImpl* out = node.get();
|
||||
endpoints_.push_back(std::move(node));
|
||||
@ -279,8 +282,8 @@ NetworkEmulationManagerImpl::CreateEmulatedNetworkManagerInterface(
|
||||
for (EmulatedEndpoint* endpoint : endpoints) {
|
||||
endpoint_impls.push_back(static_cast<EmulatedEndpointImpl*>(endpoint));
|
||||
}
|
||||
auto endpoints_container =
|
||||
std::make_unique<EndpointsContainer>(endpoint_impls);
|
||||
auto endpoints_container = std::make_unique<EndpointsContainer>(
|
||||
endpoint_impls, stats_gathering_mode_);
|
||||
auto network_manager = std::make_unique<EmulatedNetworkManager>(
|
||||
time_controller_.get(), &task_queue_, endpoints_container.get());
|
||||
for (auto* endpoint : endpoints) {
|
||||
@ -303,8 +306,9 @@ NetworkEmulationManagerImpl::CreateEmulatedNetworkManagerInterface(
|
||||
void NetworkEmulationManagerImpl::GetStats(
|
||||
rtc::ArrayView<EmulatedEndpoint* const> endpoints,
|
||||
std::function<void(std::unique_ptr<EmulatedNetworkStats>)> stats_callback) {
|
||||
task_queue_.PostTask([endpoints, stats_callback]() {
|
||||
EmulatedNetworkStatsBuilder stats_builder;
|
||||
task_queue_.PostTask([endpoints, stats_callback,
|
||||
stats_gathering_mode = stats_gathering_mode_]() {
|
||||
EmulatedNetworkStatsBuilder stats_builder(stats_gathering_mode);
|
||||
for (auto* endpoint : endpoints) {
|
||||
// It's safe to cast here because EmulatedEndpointImpl can be the only
|
||||
// implementation of EmulatedEndpoint, because only it has access to
|
||||
@ -320,8 +324,9 @@ void NetworkEmulationManagerImpl::GetStats(
|
||||
void NetworkEmulationManagerImpl::GetStats(
|
||||
rtc::ArrayView<EmulatedEndpoint* const> endpoints,
|
||||
std::function<void(EmulatedNetworkStats)> stats_callback) {
|
||||
task_queue_.PostTask([endpoints, stats_callback]() {
|
||||
EmulatedNetworkStatsBuilder stats_builder;
|
||||
task_queue_.PostTask([endpoints, stats_callback,
|
||||
stats_gathering_mode = stats_gathering_mode_]() {
|
||||
EmulatedNetworkStatsBuilder stats_builder(stats_gathering_mode);
|
||||
for (auto* endpoint : endpoints) {
|
||||
// It's safe to cast here because EmulatedEndpointImpl can be the only
|
||||
// implementation of EmulatedEndpoint, because only it has access to
|
||||
@ -333,6 +338,19 @@ void NetworkEmulationManagerImpl::GetStats(
|
||||
});
|
||||
}
|
||||
|
||||
void NetworkEmulationManagerImpl::GetStats(
|
||||
rtc::ArrayView<EmulatedNetworkNode* const> nodes,
|
||||
std::function<void(EmulatedNetworkNodeStats)> stats_callback) {
|
||||
task_queue_.PostTask(
|
||||
[nodes, stats_callback, stats_gathering_mode = stats_gathering_mode_]() {
|
||||
EmulatedNetworkNodeStatsBuilder stats_builder(stats_gathering_mode);
|
||||
for (auto* node : nodes) {
|
||||
stats_builder.AddEmulatedNetworkNodeStats(node->stats());
|
||||
}
|
||||
stats_callback(stats_builder.Build());
|
||||
});
|
||||
}
|
||||
|
||||
absl::optional<rtc::IPAddress>
|
||||
NetworkEmulationManagerImpl::GetNextIPv4Address() {
|
||||
uint32_t addresses_count = kMaxIPv4Address - kMinIPv4Address;
|
||||
|
||||
@ -23,16 +23,12 @@
|
||||
#include "api/test/time_controller.h"
|
||||
#include "api/units/time_delta.h"
|
||||
#include "api/units/timestamp.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/network.h"
|
||||
#include "rtc_base/task_queue_for_test.h"
|
||||
#include "rtc_base/task_utils/repeating_task.h"
|
||||
#include "rtc_base/thread.h"
|
||||
#include "system_wrappers/include/clock.h"
|
||||
#include "test/network/cross_traffic.h"
|
||||
#include "test/network/emulated_network_manager.h"
|
||||
#include "test/network/emulated_turn_server.h"
|
||||
#include "test/network/fake_network_socket_server.h"
|
||||
#include "test/network/network_emulation.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -40,7 +36,9 @@ namespace test {
|
||||
|
||||
class NetworkEmulationManagerImpl : public NetworkEmulationManager {
|
||||
public:
|
||||
explicit NetworkEmulationManagerImpl(TimeMode mode);
|
||||
NetworkEmulationManagerImpl(
|
||||
TimeMode mode,
|
||||
EmulatedNetworkStatsGatheringMode stats_gathering_mode);
|
||||
~NetworkEmulationManagerImpl();
|
||||
|
||||
EmulatedNetworkNode* CreateEmulatedNode(BuiltInNetworkBehaviorConfig config,
|
||||
@ -88,6 +86,10 @@ class NetworkEmulationManagerImpl : public NetworkEmulationManager {
|
||||
rtc::ArrayView<EmulatedEndpoint* const> endpoints,
|
||||
std::function<void(EmulatedNetworkStats)> stats_callback) override;
|
||||
|
||||
void GetStats(
|
||||
rtc::ArrayView<EmulatedNetworkNode* const> nodes,
|
||||
std::function<void(EmulatedNetworkNodeStats)> stats_callback) override;
|
||||
|
||||
TimeController* time_controller() override { return time_controller_.get(); }
|
||||
|
||||
TimeMode time_mode() const override { return time_mode_; }
|
||||
@ -104,6 +106,7 @@ class NetworkEmulationManagerImpl : public NetworkEmulationManager {
|
||||
absl::optional<rtc::IPAddress> GetNextIPv4Address();
|
||||
|
||||
const TimeMode time_mode_;
|
||||
const EmulatedNetworkStatsGatheringMode stats_gathering_mode_;
|
||||
const std::unique_ptr<TimeController> time_controller_;
|
||||
Clock* const clock_;
|
||||
int next_node_id_;
|
||||
|
||||
@ -118,7 +118,8 @@ TEST(NetworkEmulationManagerPCTest, Run) {
|
||||
signaling_thread->Start();
|
||||
|
||||
// Setup emulated network
|
||||
NetworkEmulationManagerImpl emulation(TimeMode::kRealTime);
|
||||
NetworkEmulationManagerImpl emulation(
|
||||
TimeMode::kRealTime, EmulatedNetworkStatsGatheringMode::kDefault);
|
||||
|
||||
EmulatedNetworkNode* alice_node = emulation.CreateEmulatedNode(
|
||||
std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
|
||||
@ -209,7 +210,8 @@ TEST(NetworkEmulationManagerPCTest, RunTURN) {
|
||||
signaling_thread->Start();
|
||||
|
||||
// Setup emulated network
|
||||
NetworkEmulationManagerImpl emulation(TimeMode::kRealTime);
|
||||
NetworkEmulationManagerImpl emulation(
|
||||
TimeMode::kRealTime, EmulatedNetworkStatsGatheringMode::kDefault);
|
||||
|
||||
EmulatedNetworkNode* alice_node = emulation.CreateEmulatedNode(
|
||||
std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
|
||||
|
||||
@ -142,7 +142,8 @@ class NetworkEmulationManagerThreeNodesRoutingTest : public ::testing::Test {
|
||||
MockReceiver r_e1_e3_;
|
||||
MockReceiver r_e3_e1_;
|
||||
|
||||
NetworkEmulationManagerImpl emulation_{TimeMode::kRealTime};
|
||||
NetworkEmulationManagerImpl emulation_{
|
||||
TimeMode::kRealTime, EmulatedNetworkStatsGatheringMode::kDefault};
|
||||
EmulatedEndpoint* e1_;
|
||||
EmulatedEndpoint* e2_;
|
||||
EmulatedEndpoint* e3_;
|
||||
@ -159,7 +160,8 @@ EmulatedNetworkNode* CreateEmulatedNodeWithDefaultBuiltInConfig(
|
||||
using ::testing::_;
|
||||
|
||||
TEST(NetworkEmulationManagerTest, GeneratedIpv4AddressDoesNotCollide) {
|
||||
NetworkEmulationManagerImpl network_manager(TimeMode::kRealTime);
|
||||
NetworkEmulationManagerImpl network_manager(
|
||||
TimeMode::kRealTime, EmulatedNetworkStatsGatheringMode::kDefault);
|
||||
std::set<rtc::IPAddress> ips;
|
||||
EmulatedEndpointConfig config;
|
||||
config.generated_ip_family = EmulatedEndpointConfig::IpAddressFamily::kIpv4;
|
||||
@ -172,7 +174,8 @@ TEST(NetworkEmulationManagerTest, GeneratedIpv4AddressDoesNotCollide) {
|
||||
}
|
||||
|
||||
TEST(NetworkEmulationManagerTest, GeneratedIpv6AddressDoesNotCollide) {
|
||||
NetworkEmulationManagerImpl network_manager(TimeMode::kRealTime);
|
||||
NetworkEmulationManagerImpl network_manager(
|
||||
TimeMode::kRealTime, EmulatedNetworkStatsGatheringMode::kDefault);
|
||||
std::set<rtc::IPAddress> ips;
|
||||
EmulatedEndpointConfig config;
|
||||
config.generated_ip_family = EmulatedEndpointConfig::IpAddressFamily::kIpv6;
|
||||
@ -185,7 +188,8 @@ TEST(NetworkEmulationManagerTest, GeneratedIpv6AddressDoesNotCollide) {
|
||||
}
|
||||
|
||||
TEST(NetworkEmulationManagerTest, Run) {
|
||||
NetworkEmulationManagerImpl network_manager(TimeMode::kRealTime);
|
||||
NetworkEmulationManagerImpl network_manager(
|
||||
TimeMode::kRealTime, EmulatedNetworkStatsGatheringMode::kDefault);
|
||||
|
||||
EmulatedNetworkNode* alice_node = network_manager.CreateEmulatedNode(
|
||||
std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
|
||||
@ -338,17 +342,15 @@ TEST(NetworkEmulationManagerTest, Run) {
|
||||
}
|
||||
|
||||
TEST(NetworkEmulationManagerTest, DebugStatsCollectedInDebugMode) {
|
||||
NetworkEmulationManagerImpl network_manager(TimeMode::kSimulated);
|
||||
NetworkEmulationManagerImpl network_manager(
|
||||
TimeMode::kSimulated, EmulatedNetworkStatsGatheringMode::kDebug);
|
||||
|
||||
EmulatedNetworkNode* alice_node = network_manager.CreateEmulatedNode(
|
||||
std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
|
||||
EmulatedNetworkNode* bob_node = network_manager.CreateEmulatedNode(
|
||||
std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
|
||||
EmulatedEndpointConfig debug_config;
|
||||
debug_config.stats_gathering_mode =
|
||||
EmulatedEndpointConfig::StatsGatheringMode::kDebug;
|
||||
EmulatedEndpoint* alice_endpoint =
|
||||
network_manager.CreateEndpoint(debug_config);
|
||||
network_manager.CreateEndpoint(EmulatedEndpointConfig());
|
||||
EmulatedEndpoint* bob_endpoint =
|
||||
network_manager.CreateEndpoint(EmulatedEndpointConfig());
|
||||
network_manager.CreateRoute(alice_endpoint, {alice_node}, bob_endpoint);
|
||||
@ -441,7 +443,8 @@ TEST(NetworkEmulationManagerTest, DebugStatsCollectedInDebugMode) {
|
||||
}
|
||||
|
||||
TEST(NetworkEmulationManagerTest, ThroughputStats) {
|
||||
NetworkEmulationManagerImpl network_manager(TimeMode::kRealTime);
|
||||
NetworkEmulationManagerImpl network_manager(
|
||||
TimeMode::kRealTime, EmulatedNetworkStatsGatheringMode::kDefault);
|
||||
|
||||
EmulatedNetworkNode* alice_node = network_manager.CreateEmulatedNode(
|
||||
std::make_unique<SimulatedNetwork>(BuiltInNetworkBehaviorConfig()));
|
||||
@ -571,7 +574,8 @@ TEST_F(NetworkEmulationManagerThreeNodesRoutingTest,
|
||||
}
|
||||
|
||||
TEST(NetworkEmulationManagerTest, EndpointLoopback) {
|
||||
NetworkEmulationManagerImpl network_manager(TimeMode::kSimulated);
|
||||
NetworkEmulationManagerImpl network_manager(
|
||||
TimeMode::kSimulated, EmulatedNetworkStatsGatheringMode::kDefault);
|
||||
auto endpoint = network_manager.CreateEndpoint(EmulatedEndpointConfig());
|
||||
|
||||
MockReceiver receiver;
|
||||
@ -587,7 +591,8 @@ TEST(NetworkEmulationManagerTest, EndpointLoopback) {
|
||||
TEST(NetworkEmulationManagerTest, EndpointCanSendWithDifferentSourceIp) {
|
||||
constexpr uint32_t kEndpointIp = 0xC0A80011; // 192.168.0.17
|
||||
constexpr uint32_t kSourceIp = 0xC0A80012; // 192.168.0.18
|
||||
NetworkEmulationManagerImpl network_manager(TimeMode::kSimulated);
|
||||
NetworkEmulationManagerImpl network_manager(
|
||||
TimeMode::kSimulated, EmulatedNetworkStatsGatheringMode::kDefault);
|
||||
EmulatedEndpointConfig endpoint_config;
|
||||
endpoint_config.ip = rtc::IPAddress(kEndpointIp);
|
||||
endpoint_config.allow_send_packet_with_different_source_ip = true;
|
||||
@ -607,7 +612,8 @@ TEST(NetworkEmulationManagerTest,
|
||||
EndpointCanReceiveWithDifferentDestIpThroughDefaultRoute) {
|
||||
constexpr uint32_t kDestEndpointIp = 0xC0A80011; // 192.168.0.17
|
||||
constexpr uint32_t kDestIp = 0xC0A80012; // 192.168.0.18
|
||||
NetworkEmulationManagerImpl network_manager(TimeMode::kSimulated);
|
||||
NetworkEmulationManagerImpl network_manager(
|
||||
TimeMode::kSimulated, EmulatedNetworkStatsGatheringMode::kDefault);
|
||||
auto sender_endpoint =
|
||||
network_manager.CreateEndpoint(EmulatedEndpointConfig());
|
||||
EmulatedEndpointConfig endpoint_config;
|
||||
@ -630,7 +636,8 @@ TEST(NetworkEmulationManagerTest,
|
||||
}
|
||||
|
||||
TEST(NetworkEmulationManagerTURNTest, GetIceServerConfig) {
|
||||
NetworkEmulationManagerImpl network_manager(TimeMode::kRealTime);
|
||||
NetworkEmulationManagerImpl network_manager(
|
||||
TimeMode::kRealTime, EmulatedNetworkStatsGatheringMode::kDefault);
|
||||
auto turn = network_manager.CreateTURNServer(EmulatedTURNServerConfig());
|
||||
|
||||
EXPECT_GT(turn->GetIceServerConfig().username.size(), 0u);
|
||||
@ -641,7 +648,8 @@ TEST(NetworkEmulationManagerTURNTest, GetIceServerConfig) {
|
||||
}
|
||||
|
||||
TEST(NetworkEmulationManagerTURNTest, ClientTraffic) {
|
||||
NetworkEmulationManagerImpl emulation(TimeMode::kSimulated);
|
||||
NetworkEmulationManagerImpl emulation(
|
||||
TimeMode::kSimulated, EmulatedNetworkStatsGatheringMode::kDefault);
|
||||
auto* ep = emulation.CreateEndpoint(EmulatedEndpointConfig());
|
||||
auto* turn = emulation.CreateTURNServer(EmulatedTURNServerConfig());
|
||||
auto* node = CreateEmulatedNodeWithDefaultBuiltInConfig(&emulation);
|
||||
|
||||
@ -55,7 +55,7 @@ PeerScenario::PeerScenario(
|
||||
std::unique_ptr<LogWriterFactoryInterface> log_writer_manager,
|
||||
TimeMode mode)
|
||||
: log_writer_manager_(std::move(log_writer_manager)),
|
||||
net_(mode),
|
||||
net_(mode, EmulatedNetworkStatsGatheringMode::kDefault),
|
||||
signaling_thread_(net_.time_controller()->GetMainThread()) {}
|
||||
|
||||
PeerScenarioClient* PeerScenario::CreateClient(
|
||||
|
||||
@ -65,7 +65,8 @@ Scenario::Scenario(
|
||||
std::unique_ptr<LogWriterFactoryInterface> log_writer_factory,
|
||||
bool real_time)
|
||||
: log_writer_factory_(std::move(log_writer_factory)),
|
||||
network_manager_(real_time ? TimeMode::kRealTime : TimeMode::kSimulated),
|
||||
network_manager_(real_time ? TimeMode::kRealTime : TimeMode::kSimulated,
|
||||
EmulatedNetworkStatsGatheringMode::kDefault),
|
||||
clock_(network_manager_.time_controller()->GetClock()),
|
||||
audio_decoder_factory_(CreateBuiltinAudioDecoderFactory()),
|
||||
audio_encoder_factory_(CreateBuiltinAudioEncoderFactory()),
|
||||
|
||||
Reference in New Issue
Block a user