Simplify Network Emulation stats API
Bug: b/240540204 Change-Id: I669b5b01d0a10ae5d8f0bafa661dbda6fc9260b7 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/282420 Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Commit-Queue: Artem Titov <titovartem@webrtc.org> Cr-Commit-Position: refs/heads/main@{#38590}
This commit is contained in:
committed by
WebRTC LUCI CQ
parent
e73a8b662f
commit
e4c1b1cbed
@ -12,6 +12,7 @@
|
|||||||
#include "rtc_base/net_helper.h"
|
#include "rtc_base/net_helper.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
EmulatedIpPacket::EmulatedIpPacket(const rtc::SocketAddress& from,
|
EmulatedIpPacket::EmulatedIpPacket(const rtc::SocketAddress& from,
|
||||||
const rtc::SocketAddress& to,
|
const rtc::SocketAddress& to,
|
||||||
rtc::CopyOnWriteBuffer data,
|
rtc::CopyOnWriteBuffer data,
|
||||||
@ -26,4 +27,20 @@ EmulatedIpPacket::EmulatedIpPacket(const rtc::SocketAddress& from,
|
|||||||
RTC_DCHECK(to.family() == AF_INET || to.family() == AF_INET6);
|
RTC_DCHECK(to.family() == AF_INET || to.family() == AF_INET6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DataRate EmulatedNetworkOutgoingStats::AverageSendRate() const {
|
||||||
|
RTC_DCHECK_GE(packets_sent, 2);
|
||||||
|
RTC_DCHECK(first_packet_sent_time.IsFinite());
|
||||||
|
RTC_DCHECK(last_packet_sent_time.IsFinite());
|
||||||
|
return (bytes_sent - first_sent_packet_size) /
|
||||||
|
(last_packet_sent_time - first_packet_sent_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
DataRate EmulatedNetworkIncomingStats::AverageReceiveRate() const {
|
||||||
|
RTC_DCHECK_GE(packets_received, 2);
|
||||||
|
RTC_DCHECK(first_packet_received_time.IsFinite());
|
||||||
|
RTC_DCHECK(last_packet_received_time.IsFinite());
|
||||||
|
return (bytes_received - first_received_packet_size) /
|
||||||
|
(last_packet_received_time - first_packet_received_time);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -62,140 +62,174 @@ class EmulatedNetworkReceiverInterface {
|
|||||||
virtual void OnPacketReceived(EmulatedIpPacket packet) = 0;
|
virtual void OnPacketReceived(EmulatedIpPacket packet) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class EmulatedNetworkOutgoingStats {
|
struct EmulatedNetworkOutgoingStats {
|
||||||
public:
|
int64_t packets_sent = 0;
|
||||||
virtual ~EmulatedNetworkOutgoingStats() = default;
|
|
||||||
|
|
||||||
virtual int64_t PacketsSent() const = 0;
|
DataSize bytes_sent = DataSize::Zero();
|
||||||
|
|
||||||
virtual DataSize BytesSent() const = 0;
|
// Sizes of all sent packets if EmulatedEndpointConfig::stats_gatherming_mode
|
||||||
|
// was set to StatsGatheringMode::kDebug; empty otherwise.
|
||||||
|
SamplesStatsCounter sent_packets_size;
|
||||||
|
|
||||||
// Returns the timestamped sizes of all sent packets if
|
DataSize first_sent_packet_size = DataSize::Zero();
|
||||||
// EmulatedEndpointConfig::stats_gatherming_mode was set to
|
|
||||||
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
|
|
||||||
// Returned reference is valid until the next call to a non-const method.
|
|
||||||
virtual const SamplesStatsCounter& SentPacketsSizeCounter() const = 0;
|
|
||||||
|
|
||||||
virtual DataSize FirstSentPacketSize() const = 0;
|
// Time of the first packet sent or infinite value if no packets were sent.
|
||||||
|
Timestamp first_packet_sent_time = Timestamp::PlusInfinity();
|
||||||
|
|
||||||
// Returns time of the first packet sent or infinite value if no packets were
|
// Time of the last packet sent or infinite value if no packets were sent.
|
||||||
// sent.
|
Timestamp last_packet_sent_time = Timestamp::MinusInfinity();
|
||||||
virtual Timestamp FirstPacketSentTime() const = 0;
|
|
||||||
|
|
||||||
// Returns time of the last packet sent or infinite value if no packets were
|
|
||||||
// sent.
|
|
||||||
virtual Timestamp LastPacketSentTime() const = 0;
|
|
||||||
|
|
||||||
// Returns average send rate. Requires that at least 2 packets were sent.
|
// Returns average send rate. Requires that at least 2 packets were sent.
|
||||||
virtual DataRate AverageSendRate() const = 0;
|
DataRate AverageSendRate() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class EmulatedNetworkIncomingStats {
|
struct EmulatedNetworkIncomingStats {
|
||||||
public:
|
|
||||||
virtual ~EmulatedNetworkIncomingStats() = default;
|
|
||||||
|
|
||||||
// Total amount of packets received with or without destination.
|
// Total amount of packets received with or without destination.
|
||||||
virtual int64_t PacketsReceived() const = 0;
|
int64_t packets_received = 0;
|
||||||
|
|
||||||
// Total amount of bytes in received packets.
|
// Total amount of bytes in received packets.
|
||||||
virtual DataSize BytesReceived() const = 0;
|
DataSize bytes_received = DataSize::Zero();
|
||||||
// Returns the timestamped sizes of all received packets if
|
|
||||||
|
// Sizes of all received packets if
|
||||||
// EmulatedEndpointConfig::stats_gatherming_mode was set to
|
// EmulatedEndpointConfig::stats_gatherming_mode was set to
|
||||||
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
|
// StatsGatheringMode::kDebug; empty otherwise.
|
||||||
// Returned reference is valid until the next call to a non-const method.
|
SamplesStatsCounter received_packets_size;
|
||||||
virtual const SamplesStatsCounter& ReceivedPacketsSizeCounter() const = 0;
|
|
||||||
// Total amount of packets that were received, but no destination was found.
|
// Total amount of packets that were received, but no destination was found.
|
||||||
virtual int64_t PacketsDropped() const = 0;
|
int64_t packets_discarded_no_receiver = 0;
|
||||||
// Total amount of bytes in dropped packets.
|
|
||||||
virtual DataSize BytesDropped() const = 0;
|
// Total amount of bytes in discarded packets.
|
||||||
// Returns the timestamped sizes of all packets that were received,
|
DataSize bytes_discarded_no_receiver = DataSize::Zero();
|
||||||
// but no destination was found if
|
|
||||||
|
// Sizes of all packets that were received, but no destination was found if
|
||||||
// EmulatedEndpointConfig::stats_gatherming_mode was set to
|
// EmulatedEndpointConfig::stats_gatherming_mode was set to
|
||||||
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
|
// StatsGatheringMode::kDebug; empty otherwise.
|
||||||
// Returned reference is valid until the next call to a non-const method.
|
SamplesStatsCounter packets_discarded_no_receiver_size;
|
||||||
virtual const SamplesStatsCounter& DroppedPacketsSizeCounter() const = 0;
|
|
||||||
|
|
||||||
virtual DataSize FirstReceivedPacketSize() const = 0;
|
DataSize first_received_packet_size = DataSize::Zero();
|
||||||
|
|
||||||
// Returns time of the first packet received or infinite value if no packets
|
// Time of the first packet received or infinite value if no packets were
|
||||||
// were received.
|
// received.
|
||||||
virtual Timestamp FirstPacketReceivedTime() const = 0;
|
Timestamp first_packet_received_time = Timestamp::PlusInfinity();
|
||||||
|
|
||||||
// Returns time of the last packet received or infinite value if no packets
|
// Time of the last packet received or infinite value if no packets were
|
||||||
// were received.
|
// received.
|
||||||
virtual Timestamp LastPacketReceivedTime() const = 0;
|
Timestamp last_packet_received_time = Timestamp::MinusInfinity();
|
||||||
|
|
||||||
virtual DataRate AverageReceiveRate() const = 0;
|
DataRate AverageReceiveRate() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class EmulatedNetworkStats {
|
struct EmulatedNetworkStats {
|
||||||
public:
|
int64_t PacketsSent() const { return overall_outgoing_stats.packets_sent; }
|
||||||
virtual ~EmulatedNetworkStats() = default;
|
|
||||||
|
|
||||||
// List of IP addresses that were used to send data considered in this stats
|
DataSize BytesSent() const { return overall_outgoing_stats.bytes_sent; }
|
||||||
// object.
|
|
||||||
virtual std::vector<rtc::IPAddress> LocalAddresses() const = 0;
|
|
||||||
|
|
||||||
virtual int64_t PacketsSent() const = 0;
|
|
||||||
|
|
||||||
virtual DataSize BytesSent() const = 0;
|
|
||||||
// Returns the timestamped sizes of all sent packets if
|
// Returns the timestamped sizes of all sent packets if
|
||||||
// EmulatedEndpointConfig::stats_gatherming_mode was set to
|
// EmulatedEndpointConfig::stats_gatherming_mode was set to
|
||||||
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
|
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
|
||||||
// Returned reference is valid until the next call to a non-const method.
|
// Returned reference is valid until the next call to a non-const method.
|
||||||
virtual const SamplesStatsCounter& SentPacketsSizeCounter() const = 0;
|
const SamplesStatsCounter& SentPacketsSizeCounter() const {
|
||||||
// Returns the timestamped duration between packet was received on
|
return overall_outgoing_stats.sent_packets_size;
|
||||||
// network interface and was dispatched to the network in microseconds if
|
}
|
||||||
// EmulatedEndpointConfig::stats_gatherming_mode was set to
|
|
||||||
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
|
DataSize FirstSentPacketSize() const {
|
||||||
// Returned reference is valid until the next call to a non-const method.
|
return overall_outgoing_stats.first_sent_packet_size;
|
||||||
virtual const SamplesStatsCounter& SentPacketsQueueWaitTimeUs() const = 0;
|
}
|
||||||
|
|
||||||
virtual DataSize FirstSentPacketSize() const = 0;
|
|
||||||
// Returns time of the first packet sent or infinite value if no packets were
|
// Returns time of the first packet sent or infinite value if no packets were
|
||||||
// sent.
|
// sent.
|
||||||
virtual Timestamp FirstPacketSentTime() const = 0;
|
Timestamp FirstPacketSentTime() const {
|
||||||
|
return overall_outgoing_stats.first_packet_sent_time;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns time of the last packet sent or infinite value if no packets were
|
// Returns time of the last packet sent or infinite value if no packets were
|
||||||
// sent.
|
// sent.
|
||||||
virtual Timestamp LastPacketSentTime() const = 0;
|
Timestamp LastPacketSentTime() const {
|
||||||
|
return overall_outgoing_stats.last_packet_sent_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataRate AverageSendRate() const {
|
||||||
|
return overall_outgoing_stats.AverageSendRate();
|
||||||
|
}
|
||||||
|
|
||||||
virtual DataRate AverageSendRate() const = 0;
|
|
||||||
// Total amount of packets received regardless of the destination address.
|
// Total amount of packets received regardless of the destination address.
|
||||||
virtual int64_t PacketsReceived() const = 0;
|
int64_t PacketsReceived() const {
|
||||||
|
return overall_incoming_stats.packets_received;
|
||||||
|
}
|
||||||
|
|
||||||
// Total amount of bytes in received packets.
|
// Total amount of bytes in received packets.
|
||||||
virtual DataSize BytesReceived() const = 0;
|
DataSize BytesReceived() const {
|
||||||
|
return overall_incoming_stats.bytes_received;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the timestamped sizes of all received packets if
|
// Returns the timestamped sizes of all received packets if
|
||||||
// EmulatedEndpointConfig::stats_gatherming_mode was set to
|
// EmulatedEndpointConfig::stats_gatherming_mode was set to
|
||||||
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
|
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
|
||||||
// Returned reference is valid until the next call to a non-const method.
|
// Returned reference is valid until the next call to a non-const method.
|
||||||
virtual const SamplesStatsCounter& ReceivedPacketsSizeCounter() const = 0;
|
const SamplesStatsCounter& ReceivedPacketsSizeCounter() const {
|
||||||
|
return overall_incoming_stats.received_packets_size;
|
||||||
|
}
|
||||||
|
|
||||||
// Total amount of packets that were received, but no destination was found.
|
// Total amount of packets that were received, but no destination was found.
|
||||||
virtual int64_t PacketsDropped() const = 0;
|
int64_t PacketsDiscardedNoReceiver() const {
|
||||||
|
return overall_incoming_stats.packets_discarded_no_receiver;
|
||||||
|
}
|
||||||
|
|
||||||
// Total amount of bytes in dropped packets.
|
// Total amount of bytes in dropped packets.
|
||||||
virtual DataSize BytesDropped() const = 0;
|
DataSize BytesDiscardedNoReceiver() const {
|
||||||
|
return overall_incoming_stats.bytes_discarded_no_receiver;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns counter with timestamped sizes of all packets that were received,
|
// Returns counter with timestamped sizes of all packets that were received,
|
||||||
// but no destination was found if
|
// but no destination was found if
|
||||||
// EmulatedEndpointConfig::stats_gatherming_mode was set to
|
// EmulatedEndpointConfig::stats_gatherming_mode was set to
|
||||||
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
|
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
|
||||||
// Returned reference is valid until the next call to a non-const method.
|
// Returned reference is valid until the next call to a non-const method.
|
||||||
virtual const SamplesStatsCounter& DroppedPacketsSizeCounter() const = 0;
|
const SamplesStatsCounter& PacketsDiscardedNoReceiverSizeCounter() const {
|
||||||
|
return overall_incoming_stats.packets_discarded_no_receiver_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataSize FirstReceivedPacketSize() const {
|
||||||
|
return overall_incoming_stats.first_received_packet_size;
|
||||||
|
}
|
||||||
|
|
||||||
virtual DataSize FirstReceivedPacketSize() const = 0;
|
|
||||||
// Returns time of the first packet received or infinite value if no packets
|
// Returns time of the first packet received or infinite value if no packets
|
||||||
// were received.
|
// were received.
|
||||||
virtual Timestamp FirstPacketReceivedTime() const = 0;
|
Timestamp FirstPacketReceivedTime() const {
|
||||||
|
return overall_incoming_stats.first_packet_received_time;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns time of the last packet received or infinite value if no packets
|
// Returns time of the last packet received or infinite value if no packets
|
||||||
// were received.
|
// were received.
|
||||||
virtual Timestamp LastPacketReceivedTime() const = 0;
|
Timestamp LastPacketReceivedTime() const {
|
||||||
|
return overall_incoming_stats.last_packet_received_time;
|
||||||
|
}
|
||||||
|
|
||||||
virtual DataRate AverageReceiveRate() const = 0;
|
DataRate AverageReceiveRate() const {
|
||||||
|
return overall_incoming_stats.AverageReceiveRate();
|
||||||
|
}
|
||||||
|
|
||||||
virtual std::map<rtc::IPAddress,
|
// List of IP addresses that were used to send data considered in this stats
|
||||||
std::unique_ptr<EmulatedNetworkOutgoingStats>>
|
// object.
|
||||||
OutgoingStatsPerDestination() const = 0;
|
std::vector<rtc::IPAddress> local_addresses;
|
||||||
|
|
||||||
virtual std::map<rtc::IPAddress,
|
// Overall outgoing stats for all IP addresses which were requested.
|
||||||
std::unique_ptr<EmulatedNetworkIncomingStats>>
|
EmulatedNetworkOutgoingStats overall_outgoing_stats;
|
||||||
IncomingStatsPerSource() const = 0;
|
|
||||||
|
// Overall incoming stats for all IP addresses from which data was received
|
||||||
|
// on requested interfaces.
|
||||||
|
EmulatedNetworkIncomingStats overall_incoming_stats;
|
||||||
|
|
||||||
|
std::map<rtc::IPAddress, EmulatedNetworkOutgoingStats>
|
||||||
|
outgoing_stats_per_destination;
|
||||||
|
std::map<rtc::IPAddress, EmulatedNetworkIncomingStats>
|
||||||
|
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.
|
||||||
|
SamplesStatsCounter sent_packets_queue_wait_time_us;
|
||||||
};
|
};
|
||||||
|
|
||||||
// EmulatedEndpoint is an abstraction for network interface on device. Instances
|
// EmulatedEndpoint is an abstraction for network interface on device. Instances
|
||||||
|
|||||||
@ -142,9 +142,12 @@ class EmulatedNetworkManagerInterface {
|
|||||||
// Passes summarized network stats for endpoints for this manager into
|
// Passes summarized network stats for endpoints for this manager into
|
||||||
// specified `stats_callback`. Callback will be executed on network emulation
|
// specified `stats_callback`. Callback will be executed on network emulation
|
||||||
// internal task queue.
|
// internal task queue.
|
||||||
|
// Deprecated.
|
||||||
virtual void GetStats(
|
virtual void GetStats(
|
||||||
std::function<void(std::unique_ptr<EmulatedNetworkStats>)> stats_callback)
|
std::function<void(std::unique_ptr<EmulatedNetworkStats>)> stats_callback)
|
||||||
const = 0;
|
const = 0;
|
||||||
|
virtual void GetStats(
|
||||||
|
std::function<void(EmulatedNetworkStats)> stats_callback) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class TimeMode { kRealTime, kSimulated };
|
enum class TimeMode { kRealTime, kSimulated };
|
||||||
@ -327,10 +330,14 @@ class NetworkEmulationManager {
|
|||||||
// Passes summarized network stats for specified `endpoints` into specified
|
// Passes summarized network stats for specified `endpoints` into specified
|
||||||
// `stats_callback`. Callback will be executed on network emulation
|
// `stats_callback`. Callback will be executed on network emulation
|
||||||
// internal task queue.
|
// internal task queue.
|
||||||
|
// Deprecated.
|
||||||
virtual void GetStats(
|
virtual void GetStats(
|
||||||
rtc::ArrayView<EmulatedEndpoint* const> endpoints,
|
rtc::ArrayView<EmulatedEndpoint* const> endpoints,
|
||||||
std::function<void(std::unique_ptr<EmulatedNetworkStats>)>
|
std::function<void(std::unique_ptr<EmulatedNetworkStats>)>
|
||||||
stats_callback) = 0;
|
stats_callback) = 0;
|
||||||
|
virtual void GetStats(
|
||||||
|
rtc::ArrayView<EmulatedEndpoint* const> endpoints,
|
||||||
|
std::function<void(EmulatedNetworkStats)> stats_callback) = 0;
|
||||||
|
|
||||||
// Create a EmulatedTURNServer.
|
// Create a EmulatedTURNServer.
|
||||||
// The TURN server has 2 endpoints that need to be connected with routes,
|
// The TURN server has 2 endpoints that need to be connected with routes,
|
||||||
|
|||||||
@ -87,6 +87,14 @@ void EmulatedNetworkManager::StopUpdating() {
|
|||||||
void EmulatedNetworkManager::GetStats(
|
void EmulatedNetworkManager::GetStats(
|
||||||
std::function<void(std::unique_ptr<EmulatedNetworkStats>)> stats_callback)
|
std::function<void(std::unique_ptr<EmulatedNetworkStats>)> stats_callback)
|
||||||
const {
|
const {
|
||||||
|
task_queue_->PostTask([stats_callback, this]() {
|
||||||
|
stats_callback(std::make_unique<EmulatedNetworkStats>(
|
||||||
|
endpoints_container_->GetStats()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmulatedNetworkManager::GetStats(
|
||||||
|
std::function<void(EmulatedNetworkStats)> stats_callback) const {
|
||||||
task_queue_->PostTask([stats_callback, this]() {
|
task_queue_->PostTask([stats_callback, this]() {
|
||||||
stats_callback(endpoints_container_->GetStats());
|
stats_callback(endpoints_container_->GetStats());
|
||||||
});
|
});
|
||||||
|
|||||||
@ -60,6 +60,8 @@ class EmulatedNetworkManager : public rtc::NetworkManagerBase,
|
|||||||
}
|
}
|
||||||
void GetStats(std::function<void(std::unique_ptr<EmulatedNetworkStats>)>
|
void GetStats(std::function<void(std::unique_ptr<EmulatedNetworkStats>)>
|
||||||
stats_callback) const override;
|
stats_callback) const override;
|
||||||
|
void GetStats(
|
||||||
|
std::function<void(EmulatedNetworkStats)> stats_callback) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void UpdateNetworksOnce();
|
void UpdateNetworksOnce();
|
||||||
|
|||||||
@ -22,61 +22,30 @@
|
|||||||
#include "rtc_base/logging.h"
|
#include "rtc_base/logging.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
namespace {
|
||||||
|
|
||||||
DataRate EmulatedNetworkOutgoingStatsImpl::AverageSendRate() const {
|
EmulatedNetworkOutgoingStats GetOverallOutgoingStats(
|
||||||
RTC_DCHECK_GE(packets_sent_, 2);
|
const std::map<rtc::IPAddress, EmulatedNetworkOutgoingStats>&
|
||||||
RTC_DCHECK(first_packet_sent_time_.IsFinite());
|
outgoing_stats) {
|
||||||
RTC_DCHECK(last_packet_sent_time_.IsFinite());
|
|
||||||
return (bytes_sent_ - first_sent_packet_size_) /
|
|
||||||
(last_packet_sent_time_ - first_packet_sent_time_);
|
|
||||||
}
|
|
||||||
|
|
||||||
DataRate EmulatedNetworkIncomingStatsImpl::AverageReceiveRate() const {
|
|
||||||
RTC_DCHECK_GE(packets_received_, 2);
|
|
||||||
RTC_DCHECK(first_packet_received_time_.IsFinite());
|
|
||||||
RTC_DCHECK(last_packet_received_time_.IsFinite());
|
|
||||||
return (bytes_received_ - first_received_packet_size_) /
|
|
||||||
(last_packet_received_time_ - first_packet_received_time_);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
|
|
||||||
EmulatedNetworkStatsImpl::OutgoingStatsPerDestination() const {
|
|
||||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>> out;
|
|
||||||
for (const auto& entry : outgoing_stats_per_destination_) {
|
|
||||||
out.emplace(entry.first, std::make_unique<EmulatedNetworkOutgoingStatsImpl>(
|
|
||||||
*entry.second));
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
|
|
||||||
EmulatedNetworkStatsImpl::IncomingStatsPerSource() const {
|
|
||||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>> out;
|
|
||||||
for (const auto& entry : incoming_stats_per_source_) {
|
|
||||||
out.emplace(entry.first, std::make_unique<EmulatedNetworkIncomingStatsImpl>(
|
|
||||||
*entry.second));
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<EmulatedNetworkOutgoingStats>
|
|
||||||
EmulatedNetworkStatsImpl::GetOverallOutgoingStats() const {
|
|
||||||
EmulatedNetworkOutgoingStatsBuilder builder;
|
EmulatedNetworkOutgoingStatsBuilder builder;
|
||||||
for (const auto& entry : outgoing_stats_per_destination_) {
|
for (const auto& entry : outgoing_stats) {
|
||||||
builder.AddOutgoingStats(*entry.second);
|
builder.AddOutgoingStats(entry.second);
|
||||||
}
|
}
|
||||||
return builder.Build();
|
return builder.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<EmulatedNetworkIncomingStats>
|
EmulatedNetworkIncomingStats GetOverallIncomingStats(
|
||||||
EmulatedNetworkStatsImpl::GetOverallIncomingStats() const {
|
const std::map<rtc::IPAddress, EmulatedNetworkIncomingStats>&
|
||||||
|
incoming_stats) {
|
||||||
EmulatedNetworkIncomingStatsBuilder builder;
|
EmulatedNetworkIncomingStatsBuilder builder;
|
||||||
for (const auto& entry : incoming_stats_per_source_) {
|
for (const auto& entry : incoming_stats) {
|
||||||
builder.AddIncomingStats(*entry.second);
|
builder.AddIncomingStats(entry.second);
|
||||||
}
|
}
|
||||||
return builder.Build();
|
return builder.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
EmulatedNetworkOutgoingStatsBuilder::EmulatedNetworkOutgoingStatsBuilder() {
|
EmulatedNetworkOutgoingStatsBuilder::EmulatedNetworkOutgoingStatsBuilder() {
|
||||||
sequence_checker_.Detach();
|
sequence_checker_.Detach();
|
||||||
}
|
}
|
||||||
@ -87,39 +56,37 @@ void EmulatedNetworkOutgoingStatsBuilder::OnPacketSent(
|
|||||||
EmulatedEndpointConfig::StatsGatheringMode mode) {
|
EmulatedEndpointConfig::StatsGatheringMode mode) {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
RTC_CHECK_GE(packet_size, DataSize::Zero());
|
RTC_CHECK_GE(packet_size, DataSize::Zero());
|
||||||
if (first_packet_sent_time_.IsInfinite()) {
|
if (stats_.first_packet_sent_time.IsInfinite()) {
|
||||||
first_packet_sent_time_ = sent_time;
|
stats_.first_packet_sent_time = sent_time;
|
||||||
first_sent_packet_size_ = packet_size;
|
stats_.first_sent_packet_size = packet_size;
|
||||||
}
|
}
|
||||||
last_packet_sent_time_ = sent_time;
|
stats_.last_packet_sent_time = sent_time;
|
||||||
packets_sent_++;
|
stats_.packets_sent++;
|
||||||
bytes_sent_ += packet_size;
|
stats_.bytes_sent += packet_size;
|
||||||
if (mode == EmulatedEndpointConfig::StatsGatheringMode::kDebug) {
|
if (mode == EmulatedEndpointConfig::StatsGatheringMode::kDebug) {
|
||||||
sent_packets_size_counter_.AddSample(packet_size.bytes());
|
stats_.sent_packets_size.AddSample(packet_size.bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedNetworkOutgoingStatsBuilder::AddOutgoingStats(
|
void EmulatedNetworkOutgoingStatsBuilder::AddOutgoingStats(
|
||||||
const EmulatedNetworkOutgoingStats& stats) {
|
const EmulatedNetworkOutgoingStats& stats) {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
packets_sent_ += stats.PacketsSent();
|
stats_.packets_sent += stats.packets_sent;
|
||||||
bytes_sent_ += stats.BytesSent();
|
stats_.bytes_sent += stats.bytes_sent;
|
||||||
sent_packets_size_counter_.AddSamples(stats.SentPacketsSizeCounter());
|
stats_.sent_packets_size.AddSamples(stats.sent_packets_size);
|
||||||
if (first_packet_sent_time_ > stats.FirstPacketSentTime()) {
|
if (stats_.first_packet_sent_time > stats.first_packet_sent_time) {
|
||||||
first_packet_sent_time_ = stats.FirstPacketSentTime();
|
stats_.first_packet_sent_time = stats.first_packet_sent_time;
|
||||||
first_sent_packet_size_ = stats.FirstSentPacketSize();
|
stats_.first_sent_packet_size = stats.first_sent_packet_size;
|
||||||
}
|
}
|
||||||
if (last_packet_sent_time_ < stats.LastPacketSentTime()) {
|
if (stats_.last_packet_sent_time < stats.last_packet_sent_time) {
|
||||||
last_packet_sent_time_ = stats.LastPacketSentTime();
|
stats_.last_packet_sent_time = stats.last_packet_sent_time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<EmulatedNetworkOutgoingStats>
|
EmulatedNetworkOutgoingStats EmulatedNetworkOutgoingStatsBuilder::Build()
|
||||||
EmulatedNetworkOutgoingStatsBuilder::Build() const {
|
const {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
return std::make_unique<EmulatedNetworkOutgoingStatsImpl>(
|
return stats_;
|
||||||
packets_sent_, bytes_sent_, sent_packets_size_counter_,
|
|
||||||
first_sent_packet_size_, first_packet_sent_time_, last_packet_sent_time_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EmulatedNetworkIncomingStatsBuilder::EmulatedNetworkIncomingStatsBuilder() {
|
EmulatedNetworkIncomingStatsBuilder::EmulatedNetworkIncomingStatsBuilder() {
|
||||||
@ -130,10 +97,10 @@ void EmulatedNetworkIncomingStatsBuilder::OnPacketDropped(
|
|||||||
DataSize packet_size,
|
DataSize packet_size,
|
||||||
EmulatedEndpointConfig::StatsGatheringMode mode) {
|
EmulatedEndpointConfig::StatsGatheringMode mode) {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
packets_dropped_++;
|
stats_.packets_discarded_no_receiver++;
|
||||||
bytes_dropped_ += packet_size;
|
stats_.bytes_discarded_no_receiver += packet_size;
|
||||||
if (mode == EmulatedEndpointConfig::StatsGatheringMode::kDebug) {
|
if (mode == EmulatedEndpointConfig::StatsGatheringMode::kDebug) {
|
||||||
dropped_packets_size_counter_.AddSample(packet_size.bytes());
|
stats_.packets_discarded_no_receiver_size.AddSample(packet_size.bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,44 +110,41 @@ void EmulatedNetworkIncomingStatsBuilder::OnPacketReceived(
|
|||||||
EmulatedEndpointConfig::StatsGatheringMode mode) {
|
EmulatedEndpointConfig::StatsGatheringMode mode) {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
RTC_CHECK_GE(packet_size, DataSize::Zero());
|
RTC_CHECK_GE(packet_size, DataSize::Zero());
|
||||||
if (first_packet_received_time_.IsInfinite()) {
|
if (stats_.first_packet_received_time.IsInfinite()) {
|
||||||
first_packet_received_time_ = received_time;
|
stats_.first_packet_received_time = received_time;
|
||||||
first_received_packet_size_ = packet_size;
|
stats_.first_received_packet_size = packet_size;
|
||||||
}
|
}
|
||||||
last_packet_received_time_ = received_time;
|
stats_.last_packet_received_time = received_time;
|
||||||
packets_received_++;
|
stats_.packets_received++;
|
||||||
bytes_received_ += packet_size;
|
stats_.bytes_received += packet_size;
|
||||||
if (mode == EmulatedEndpointConfig::StatsGatheringMode::kDebug) {
|
if (mode == EmulatedEndpointConfig::StatsGatheringMode::kDebug) {
|
||||||
received_packets_size_counter_.AddSample(packet_size.bytes());
|
stats_.received_packets_size.AddSample(packet_size.bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedNetworkIncomingStatsBuilder::AddIncomingStats(
|
void EmulatedNetworkIncomingStatsBuilder::AddIncomingStats(
|
||||||
const EmulatedNetworkIncomingStats& stats) {
|
const EmulatedNetworkIncomingStats& stats) {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
packets_received_ += stats.PacketsReceived();
|
stats_.packets_received += stats.packets_received;
|
||||||
bytes_received_ += stats.BytesReceived();
|
stats_.bytes_received += stats.bytes_received;
|
||||||
received_packets_size_counter_.AddSamples(stats.ReceivedPacketsSizeCounter());
|
stats_.received_packets_size.AddSamples(stats.received_packets_size);
|
||||||
packets_dropped_ += stats.PacketsDropped();
|
stats_.packets_discarded_no_receiver += stats.packets_discarded_no_receiver;
|
||||||
bytes_dropped_ += stats.BytesDropped();
|
stats_.bytes_discarded_no_receiver += stats.bytes_discarded_no_receiver;
|
||||||
dropped_packets_size_counter_.AddSamples(stats.DroppedPacketsSizeCounter());
|
stats_.packets_discarded_no_receiver_size.AddSamples(
|
||||||
if (first_packet_received_time_ > stats.FirstPacketReceivedTime()) {
|
stats.packets_discarded_no_receiver_size);
|
||||||
first_packet_received_time_ = stats.FirstPacketReceivedTime();
|
if (stats_.first_packet_received_time > stats.first_packet_received_time) {
|
||||||
first_received_packet_size_ = stats.FirstReceivedPacketSize();
|
stats_.first_packet_received_time = stats.first_packet_received_time;
|
||||||
|
stats_.first_received_packet_size = stats.first_received_packet_size;
|
||||||
}
|
}
|
||||||
if (last_packet_received_time_ < stats.LastPacketReceivedTime()) {
|
if (stats_.last_packet_received_time < stats.last_packet_received_time) {
|
||||||
last_packet_received_time_ = stats.LastPacketReceivedTime();
|
stats_.last_packet_received_time = stats.last_packet_received_time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<EmulatedNetworkIncomingStats>
|
EmulatedNetworkIncomingStats EmulatedNetworkIncomingStatsBuilder::Build()
|
||||||
EmulatedNetworkIncomingStatsBuilder::Build() const {
|
const {
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
return std::make_unique<EmulatedNetworkIncomingStatsImpl>(
|
return stats_;
|
||||||
packets_received_, bytes_received_, received_packets_size_counter_,
|
|
||||||
packets_dropped_, bytes_dropped_, dropped_packets_size_counter_,
|
|
||||||
first_received_packet_size_, first_packet_received_time_,
|
|
||||||
last_packet_received_time_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EmulatedNetworkStatsBuilder::EmulatedNetworkStatsBuilder() {
|
EmulatedNetworkStatsBuilder::EmulatedNetworkStatsBuilder() {
|
||||||
@ -230,45 +194,41 @@ void EmulatedNetworkStatsBuilder::AddEmulatedNetworkStats(
|
|||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
|
||||||
// Append IPs from other endpoints stats to the builder.
|
// Append IPs from other endpoints stats to the builder.
|
||||||
for (const rtc::IPAddress& addr : stats.LocalAddresses()) {
|
for (const rtc::IPAddress& addr : stats.local_addresses) {
|
||||||
local_addresses_.push_back(addr);
|
local_addresses_.push_back(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
sent_packets_queue_wait_time_us_.AddSamples(
|
sent_packets_queue_wait_time_us_.AddSamples(
|
||||||
stats.SentPacketsQueueWaitTimeUs());
|
stats.sent_packets_queue_wait_time_us);
|
||||||
|
|
||||||
// Add outgoing stats from other endpoints to the builder.
|
// Add outgoing stats from other endpoints to the builder.
|
||||||
const std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
|
for (const auto& entry : stats.outgoing_stats_per_destination) {
|
||||||
outgoing_stats_per_destination = stats.OutgoingStatsPerDestination();
|
outgoing_stats_per_destination_[entry.first].AddOutgoingStats(entry.second);
|
||||||
for (const auto& entry : outgoing_stats_per_destination) {
|
|
||||||
outgoing_stats_per_destination_[entry.first].AddOutgoingStats(
|
|
||||||
*entry.second);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add incoming stats from other endpoints to the builder.
|
// Add incoming stats from other endpoints to the builder.
|
||||||
const std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
|
for (const auto& entry : stats.incoming_stats_per_source) {
|
||||||
incoming_stats_per_source = stats.IncomingStatsPerSource();
|
incoming_stats_per_source_[entry.first].AddIncomingStats(entry.second);
|
||||||
for (const auto& entry : incoming_stats_per_source) {
|
|
||||||
incoming_stats_per_source_[entry.first].AddIncomingStats(*entry.second);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<EmulatedNetworkStats> EmulatedNetworkStatsBuilder::Build()
|
EmulatedNetworkStats EmulatedNetworkStatsBuilder::Build() const {
|
||||||
const {
|
|
||||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
|
std::map<rtc::IPAddress, EmulatedNetworkOutgoingStats> outgoing_stats;
|
||||||
outgoing_stats;
|
|
||||||
for (const auto& entry : outgoing_stats_per_destination_) {
|
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, std::unique_ptr<EmulatedNetworkIncomingStats>>
|
std::map<rtc::IPAddress, EmulatedNetworkIncomingStats> incoming_stats;
|
||||||
incoming_stats;
|
|
||||||
for (const auto& entry : incoming_stats_per_source_) {
|
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 std::make_unique<EmulatedNetworkStatsImpl>(
|
return EmulatedNetworkStats{
|
||||||
local_addresses_, sent_packets_queue_wait_time_us_,
|
.local_addresses = local_addresses_,
|
||||||
std::move(outgoing_stats), std::move(incoming_stats));
|
.overall_outgoing_stats = GetOverallOutgoingStats(outgoing_stats),
|
||||||
|
.overall_incoming_stats = GetOverallIncomingStats(incoming_stats),
|
||||||
|
.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_};
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkEmulation::OnPacketReceived(EmulatedIpPacket packet) {
|
void LinkEmulation::OnPacketReceived(EmulatedIpPacket packet) {
|
||||||
@ -653,7 +613,7 @@ bool EmulatedEndpointImpl::Enabled() const {
|
|||||||
return is_enabled_;
|
return is_enabled_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<EmulatedNetworkStats> EmulatedEndpointImpl::stats() const {
|
EmulatedNetworkStats EmulatedEndpointImpl::stats() const {
|
||||||
RTC_DCHECK_RUN_ON(task_queue_);
|
RTC_DCHECK_RUN_ON(task_queue_);
|
||||||
return stats_builder_.Build();
|
return stats_builder_.Build();
|
||||||
}
|
}
|
||||||
@ -698,10 +658,10 @@ std::vector<EmulatedEndpoint*> EndpointsContainer::GetEndpoints() const {
|
|||||||
return std::vector<EmulatedEndpoint*>(endpoints_.begin(), endpoints_.end());
|
return std::vector<EmulatedEndpoint*>(endpoints_.begin(), endpoints_.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<EmulatedNetworkStats> EndpointsContainer::GetStats() const {
|
EmulatedNetworkStats EndpointsContainer::GetStats() const {
|
||||||
EmulatedNetworkStatsBuilder stats_builder;
|
EmulatedNetworkStatsBuilder stats_builder;
|
||||||
for (auto* endpoint : endpoints_) {
|
for (auto* endpoint : endpoints_) {
|
||||||
stats_builder.AddEmulatedNetworkStats(*endpoint->stats());
|
stats_builder.AddEmulatedNetworkStats(endpoint->stats());
|
||||||
}
|
}
|
||||||
return stats_builder.Build();
|
return stats_builder.Build();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,257 +38,8 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
// This class is immutable and so thread safe.
|
// All methods of EmulatedNetworkOutgoingStatsBuilder have to be used on a
|
||||||
class EmulatedNetworkOutgoingStatsImpl final
|
// single thread. It may be created on another thread.
|
||||||
: public EmulatedNetworkOutgoingStats {
|
|
||||||
public:
|
|
||||||
EmulatedNetworkOutgoingStatsImpl(
|
|
||||||
int64_t packets_sent,
|
|
||||||
DataSize bytes_sent,
|
|
||||||
SamplesStatsCounter sent_packets_size_counter,
|
|
||||||
DataSize first_sent_packet_size,
|
|
||||||
Timestamp first_packet_sent_time,
|
|
||||||
Timestamp last_packet_sent_time)
|
|
||||||
: packets_sent_(packets_sent),
|
|
||||||
bytes_sent_(bytes_sent),
|
|
||||||
sent_packets_size_counter_(std::move(sent_packets_size_counter)),
|
|
||||||
first_sent_packet_size_(first_sent_packet_size),
|
|
||||||
first_packet_sent_time_(first_packet_sent_time),
|
|
||||||
last_packet_sent_time_(last_packet_sent_time) {}
|
|
||||||
explicit EmulatedNetworkOutgoingStatsImpl(
|
|
||||||
const EmulatedNetworkOutgoingStats& stats)
|
|
||||||
: packets_sent_(stats.PacketsSent()),
|
|
||||||
bytes_sent_(stats.BytesSent()),
|
|
||||||
sent_packets_size_counter_(stats.SentPacketsSizeCounter()),
|
|
||||||
first_sent_packet_size_(stats.FirstSentPacketSize()),
|
|
||||||
first_packet_sent_time_(stats.FirstPacketSentTime()),
|
|
||||||
last_packet_sent_time_(stats.LastPacketSentTime()) {}
|
|
||||||
~EmulatedNetworkOutgoingStatsImpl() override = default;
|
|
||||||
|
|
||||||
int64_t PacketsSent() const override { return packets_sent_; }
|
|
||||||
|
|
||||||
DataSize BytesSent() const override { return bytes_sent_; }
|
|
||||||
|
|
||||||
const SamplesStatsCounter& SentPacketsSizeCounter() const override {
|
|
||||||
return sent_packets_size_counter_;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataSize FirstSentPacketSize() const override {
|
|
||||||
return first_sent_packet_size_;
|
|
||||||
}
|
|
||||||
|
|
||||||
Timestamp FirstPacketSentTime() const override {
|
|
||||||
return first_packet_sent_time_;
|
|
||||||
}
|
|
||||||
|
|
||||||
Timestamp LastPacketSentTime() const override {
|
|
||||||
return last_packet_sent_time_;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataRate AverageSendRate() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const int64_t packets_sent_;
|
|
||||||
const DataSize bytes_sent_;
|
|
||||||
const SamplesStatsCounter sent_packets_size_counter_;
|
|
||||||
const DataSize first_sent_packet_size_;
|
|
||||||
const Timestamp first_packet_sent_time_;
|
|
||||||
const Timestamp last_packet_sent_time_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// This class is immutable and so thread safe.
|
|
||||||
class EmulatedNetworkIncomingStatsImpl final
|
|
||||||
: public EmulatedNetworkIncomingStats {
|
|
||||||
public:
|
|
||||||
EmulatedNetworkIncomingStatsImpl(
|
|
||||||
int64_t packets_received,
|
|
||||||
DataSize bytes_received,
|
|
||||||
SamplesStatsCounter received_packets_size_counter,
|
|
||||||
int64_t packets_dropped,
|
|
||||||
DataSize bytes_dropped,
|
|
||||||
SamplesStatsCounter dropped_packets_size_counter,
|
|
||||||
DataSize first_received_packet_size,
|
|
||||||
Timestamp first_packet_received_time,
|
|
||||||
Timestamp last_packet_received_time)
|
|
||||||
: packets_received_(packets_received),
|
|
||||||
bytes_received_(bytes_received),
|
|
||||||
received_packets_size_counter_(received_packets_size_counter),
|
|
||||||
packets_dropped_(packets_dropped),
|
|
||||||
bytes_dropped_(bytes_dropped),
|
|
||||||
dropped_packets_size_counter_(dropped_packets_size_counter),
|
|
||||||
first_received_packet_size_(first_received_packet_size),
|
|
||||||
first_packet_received_time_(first_packet_received_time),
|
|
||||||
last_packet_received_time_(last_packet_received_time) {}
|
|
||||||
explicit EmulatedNetworkIncomingStatsImpl(
|
|
||||||
const EmulatedNetworkIncomingStats& stats)
|
|
||||||
: packets_received_(stats.PacketsReceived()),
|
|
||||||
bytes_received_(stats.BytesReceived()),
|
|
||||||
received_packets_size_counter_(stats.ReceivedPacketsSizeCounter()),
|
|
||||||
packets_dropped_(stats.PacketsDropped()),
|
|
||||||
bytes_dropped_(stats.BytesDropped()),
|
|
||||||
dropped_packets_size_counter_(stats.DroppedPacketsSizeCounter()),
|
|
||||||
first_received_packet_size_(stats.FirstReceivedPacketSize()),
|
|
||||||
first_packet_received_time_(stats.FirstPacketReceivedTime()),
|
|
||||||
last_packet_received_time_(stats.LastPacketReceivedTime()) {}
|
|
||||||
~EmulatedNetworkIncomingStatsImpl() override = default;
|
|
||||||
|
|
||||||
int64_t PacketsReceived() const override { return packets_received_; }
|
|
||||||
|
|
||||||
DataSize BytesReceived() const override { return bytes_received_; }
|
|
||||||
|
|
||||||
const SamplesStatsCounter& ReceivedPacketsSizeCounter() const override {
|
|
||||||
return received_packets_size_counter_;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t PacketsDropped() const override { return packets_dropped_; }
|
|
||||||
|
|
||||||
DataSize BytesDropped() const override { return bytes_dropped_; }
|
|
||||||
|
|
||||||
const SamplesStatsCounter& DroppedPacketsSizeCounter() const override {
|
|
||||||
return dropped_packets_size_counter_;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataSize FirstReceivedPacketSize() const override {
|
|
||||||
return first_received_packet_size_;
|
|
||||||
}
|
|
||||||
|
|
||||||
Timestamp FirstPacketReceivedTime() const override {
|
|
||||||
return first_packet_received_time_;
|
|
||||||
}
|
|
||||||
|
|
||||||
Timestamp LastPacketReceivedTime() const override {
|
|
||||||
return last_packet_received_time_;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataRate AverageReceiveRate() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const int64_t packets_received_;
|
|
||||||
const DataSize bytes_received_;
|
|
||||||
const SamplesStatsCounter received_packets_size_counter_;
|
|
||||||
const int64_t packets_dropped_;
|
|
||||||
const DataSize bytes_dropped_;
|
|
||||||
const SamplesStatsCounter dropped_packets_size_counter_;
|
|
||||||
const DataSize first_received_packet_size_;
|
|
||||||
const Timestamp first_packet_received_time_;
|
|
||||||
const Timestamp last_packet_received_time_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// This class is immutable and so is thread safe.
|
|
||||||
class EmulatedNetworkStatsImpl final : public EmulatedNetworkStats {
|
|
||||||
public:
|
|
||||||
EmulatedNetworkStatsImpl(
|
|
||||||
std::vector<rtc::IPAddress> local_addresses,
|
|
||||||
SamplesStatsCounter sent_packets_queue_wait_time_us,
|
|
||||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
|
|
||||||
outgoing_stats_per_destination,
|
|
||||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
|
|
||||||
incoming_stats_per_source)
|
|
||||||
: local_addresses_(std::move(local_addresses)),
|
|
||||||
sent_packets_queue_wait_time_us_(sent_packets_queue_wait_time_us),
|
|
||||||
outgoing_stats_per_destination_(
|
|
||||||
std::move(outgoing_stats_per_destination)),
|
|
||||||
incoming_stats_per_source_(std::move(incoming_stats_per_source)),
|
|
||||||
overall_outgoing_stats_(GetOverallOutgoingStats()),
|
|
||||||
overall_incoming_stats_(GetOverallIncomingStats()) {}
|
|
||||||
~EmulatedNetworkStatsImpl() override = default;
|
|
||||||
|
|
||||||
std::vector<rtc::IPAddress> LocalAddresses() const override {
|
|
||||||
return local_addresses_;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t PacketsSent() const override {
|
|
||||||
return overall_outgoing_stats_->PacketsSent();
|
|
||||||
}
|
|
||||||
|
|
||||||
DataSize BytesSent() const override {
|
|
||||||
return overall_outgoing_stats_->BytesSent();
|
|
||||||
}
|
|
||||||
|
|
||||||
const SamplesStatsCounter& SentPacketsSizeCounter() const override {
|
|
||||||
return overall_outgoing_stats_->SentPacketsSizeCounter();
|
|
||||||
}
|
|
||||||
|
|
||||||
const SamplesStatsCounter& SentPacketsQueueWaitTimeUs() const override {
|
|
||||||
return sent_packets_queue_wait_time_us_;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataSize FirstSentPacketSize() const override {
|
|
||||||
return overall_outgoing_stats_->FirstSentPacketSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
Timestamp FirstPacketSentTime() const override {
|
|
||||||
return overall_outgoing_stats_->FirstPacketSentTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
Timestamp LastPacketSentTime() const override {
|
|
||||||
return overall_outgoing_stats_->LastPacketSentTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
DataRate AverageSendRate() const override {
|
|
||||||
return overall_outgoing_stats_->AverageSendRate();
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t PacketsReceived() const override {
|
|
||||||
return overall_incoming_stats_->PacketsReceived();
|
|
||||||
}
|
|
||||||
|
|
||||||
DataSize BytesReceived() const override {
|
|
||||||
return overall_incoming_stats_->BytesReceived();
|
|
||||||
}
|
|
||||||
|
|
||||||
const SamplesStatsCounter& ReceivedPacketsSizeCounter() const override {
|
|
||||||
return overall_incoming_stats_->ReceivedPacketsSizeCounter();
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t PacketsDropped() const override {
|
|
||||||
return overall_incoming_stats_->PacketsDropped();
|
|
||||||
}
|
|
||||||
|
|
||||||
DataSize BytesDropped() const override {
|
|
||||||
return overall_incoming_stats_->BytesDropped();
|
|
||||||
}
|
|
||||||
|
|
||||||
const SamplesStatsCounter& DroppedPacketsSizeCounter() const override {
|
|
||||||
return overall_incoming_stats_->DroppedPacketsSizeCounter();
|
|
||||||
}
|
|
||||||
|
|
||||||
DataSize FirstReceivedPacketSize() const override {
|
|
||||||
return overall_incoming_stats_->FirstReceivedPacketSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
Timestamp FirstPacketReceivedTime() const override {
|
|
||||||
return overall_incoming_stats_->FirstPacketReceivedTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
Timestamp LastPacketReceivedTime() const override {
|
|
||||||
return overall_incoming_stats_->LastPacketReceivedTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
DataRate AverageReceiveRate() const override {
|
|
||||||
return overall_incoming_stats_->AverageReceiveRate();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
|
|
||||||
OutgoingStatsPerDestination() const override;
|
|
||||||
|
|
||||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
|
|
||||||
IncomingStatsPerSource() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unique_ptr<EmulatedNetworkOutgoingStats> GetOverallOutgoingStats() const;
|
|
||||||
std::unique_ptr<EmulatedNetworkIncomingStats> GetOverallIncomingStats() const;
|
|
||||||
|
|
||||||
const std::vector<rtc::IPAddress> local_addresses_;
|
|
||||||
const SamplesStatsCounter sent_packets_queue_wait_time_us_;
|
|
||||||
const std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
|
|
||||||
outgoing_stats_per_destination_;
|
|
||||||
const std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
|
|
||||||
incoming_stats_per_source_;
|
|
||||||
const std::unique_ptr<EmulatedNetworkOutgoingStats> overall_outgoing_stats_;
|
|
||||||
const std::unique_ptr<EmulatedNetworkIncomingStats> overall_incoming_stats_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class EmulatedNetworkOutgoingStatsBuilder {
|
class EmulatedNetworkOutgoingStatsBuilder {
|
||||||
public:
|
public:
|
||||||
EmulatedNetworkOutgoingStatsBuilder();
|
EmulatedNetworkOutgoingStatsBuilder();
|
||||||
@ -299,23 +50,16 @@ class EmulatedNetworkOutgoingStatsBuilder {
|
|||||||
|
|
||||||
void AddOutgoingStats(const EmulatedNetworkOutgoingStats& stats);
|
void AddOutgoingStats(const EmulatedNetworkOutgoingStats& stats);
|
||||||
|
|
||||||
std::unique_ptr<EmulatedNetworkOutgoingStats> Build() const;
|
EmulatedNetworkOutgoingStats Build() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SequenceChecker sequence_checker_;
|
RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
|
||||||
|
|
||||||
int64_t packets_sent_ RTC_GUARDED_BY(sequence_checker_) = 0;
|
EmulatedNetworkOutgoingStats stats_ RTC_GUARDED_BY(sequence_checker_);
|
||||||
DataSize bytes_sent_ RTC_GUARDED_BY(sequence_checker_) = DataSize::Zero();
|
|
||||||
SamplesStatsCounter sent_packets_size_counter_
|
|
||||||
RTC_GUARDED_BY(sequence_checker_);
|
|
||||||
DataSize first_sent_packet_size_ RTC_GUARDED_BY(sequence_checker_) =
|
|
||||||
DataSize::Zero();
|
|
||||||
Timestamp first_packet_sent_time_ RTC_GUARDED_BY(sequence_checker_) =
|
|
||||||
Timestamp::PlusInfinity();
|
|
||||||
Timestamp last_packet_sent_time_ RTC_GUARDED_BY(sequence_checker_) =
|
|
||||||
Timestamp::MinusInfinity();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// All methods of EmulatedNetworkIncomingStatsBuilder have to be used on a
|
||||||
|
// single thread. It may be created on another thread.
|
||||||
class EmulatedNetworkIncomingStatsBuilder {
|
class EmulatedNetworkIncomingStatsBuilder {
|
||||||
public:
|
public:
|
||||||
EmulatedNetworkIncomingStatsBuilder();
|
EmulatedNetworkIncomingStatsBuilder();
|
||||||
@ -330,25 +74,12 @@ class EmulatedNetworkIncomingStatsBuilder {
|
|||||||
// Adds stats collected from another endpoints to the builder.
|
// Adds stats collected from another endpoints to the builder.
|
||||||
void AddIncomingStats(const EmulatedNetworkIncomingStats& stats);
|
void AddIncomingStats(const EmulatedNetworkIncomingStats& stats);
|
||||||
|
|
||||||
std::unique_ptr<EmulatedNetworkIncomingStats> Build() const;
|
EmulatedNetworkIncomingStats Build() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SequenceChecker sequence_checker_;
|
RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
|
||||||
|
|
||||||
int64_t packets_received_ RTC_GUARDED_BY(sequence_checker_) = 0;
|
EmulatedNetworkIncomingStats stats_ RTC_GUARDED_BY(sequence_checker_);
|
||||||
DataSize bytes_received_ RTC_GUARDED_BY(sequence_checker_) = DataSize::Zero();
|
|
||||||
SamplesStatsCounter received_packets_size_counter_
|
|
||||||
RTC_GUARDED_BY(sequence_checker_);
|
|
||||||
int64_t packets_dropped_ RTC_GUARDED_BY(sequence_checker_) = 0;
|
|
||||||
DataSize bytes_dropped_ RTC_GUARDED_BY(sequence_checker_) = DataSize::Zero();
|
|
||||||
SamplesStatsCounter dropped_packets_size_counter_
|
|
||||||
RTC_GUARDED_BY(sequence_checker_);
|
|
||||||
DataSize first_received_packet_size_ RTC_GUARDED_BY(sequence_checker_) =
|
|
||||||
DataSize::Zero();
|
|
||||||
Timestamp first_packet_received_time_ RTC_GUARDED_BY(sequence_checker_) =
|
|
||||||
Timestamp::PlusInfinity();
|
|
||||||
Timestamp last_packet_received_time_ RTC_GUARDED_BY(sequence_checker_) =
|
|
||||||
Timestamp::MinusInfinity();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// All methods of EmulatedNetworkStatsBuilder have to be used on a single
|
// All methods of EmulatedNetworkStatsBuilder have to be used on a single
|
||||||
@ -375,10 +106,10 @@ class EmulatedNetworkStatsBuilder {
|
|||||||
|
|
||||||
void AddEmulatedNetworkStats(const EmulatedNetworkStats& stats);
|
void AddEmulatedNetworkStats(const EmulatedNetworkStats& stats);
|
||||||
|
|
||||||
std::unique_ptr<EmulatedNetworkStats> Build() const;
|
EmulatedNetworkStats Build() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SequenceChecker sequence_checker_;
|
RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
|
||||||
|
|
||||||
std::vector<rtc::IPAddress> local_addresses_
|
std::vector<rtc::IPAddress> local_addresses_
|
||||||
RTC_GUARDED_BY(sequence_checker_);
|
RTC_GUARDED_BY(sequence_checker_);
|
||||||
@ -555,7 +286,7 @@ class EmulatedEndpointImpl : public EmulatedEndpoint {
|
|||||||
|
|
||||||
const rtc::Network& network() const { return *network_.get(); }
|
const rtc::Network& network() const { return *network_.get(); }
|
||||||
|
|
||||||
std::unique_ptr<EmulatedNetworkStats> stats() const;
|
EmulatedNetworkStats stats() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ReceiverBinding {
|
struct ReceiverBinding {
|
||||||
@ -572,7 +303,7 @@ class EmulatedEndpointImpl : public EmulatedEndpoint {
|
|||||||
uint16_t NextPort() RTC_EXCLUSIVE_LOCKS_REQUIRED(receiver_lock_);
|
uint16_t NextPort() RTC_EXCLUSIVE_LOCKS_REQUIRED(receiver_lock_);
|
||||||
|
|
||||||
Mutex receiver_lock_;
|
Mutex receiver_lock_;
|
||||||
SequenceChecker enabled_state_checker_;
|
RTC_NO_UNIQUE_ADDRESS SequenceChecker enabled_state_checker_;
|
||||||
|
|
||||||
const Options options_;
|
const Options options_;
|
||||||
bool is_enabled_ RTC_GUARDED_BY(enabled_state_checker_);
|
bool is_enabled_ RTC_GUARDED_BY(enabled_state_checker_);
|
||||||
@ -622,7 +353,7 @@ class EndpointsContainer {
|
|||||||
// returned rtc::Network objects.
|
// returned rtc::Network objects.
|
||||||
std::vector<std::unique_ptr<rtc::Network>> GetEnabledNetworks() const;
|
std::vector<std::unique_ptr<rtc::Network>> GetEnabledNetworks() const;
|
||||||
std::vector<EmulatedEndpoint*> GetEndpoints() const;
|
std::vector<EmulatedEndpoint*> GetEndpoints() const;
|
||||||
std::unique_ptr<EmulatedNetworkStats> GetStats() const;
|
EmulatedNetworkStats GetStats() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::vector<EmulatedEndpointImpl*> endpoints_;
|
const std::vector<EmulatedEndpointImpl*> endpoints_;
|
||||||
|
|||||||
@ -310,7 +310,24 @@ void NetworkEmulationManagerImpl::GetStats(
|
|||||||
// implementation of EmulatedEndpoint, because only it has access to
|
// implementation of EmulatedEndpoint, because only it has access to
|
||||||
// EmulatedEndpoint constructor.
|
// EmulatedEndpoint constructor.
|
||||||
auto endpoint_impl = static_cast<EmulatedEndpointImpl*>(endpoint);
|
auto endpoint_impl = static_cast<EmulatedEndpointImpl*>(endpoint);
|
||||||
stats_builder.AddEmulatedNetworkStats(*endpoint_impl->stats());
|
stats_builder.AddEmulatedNetworkStats(endpoint_impl->stats());
|
||||||
|
}
|
||||||
|
stats_callback(
|
||||||
|
std::make_unique<EmulatedNetworkStats>(stats_builder.Build()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkEmulationManagerImpl::GetStats(
|
||||||
|
rtc::ArrayView<EmulatedEndpoint* const> endpoints,
|
||||||
|
std::function<void(EmulatedNetworkStats)> stats_callback) {
|
||||||
|
task_queue_.PostTask([endpoints, stats_callback]() {
|
||||||
|
EmulatedNetworkStatsBuilder stats_builder;
|
||||||
|
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
|
||||||
|
// EmulatedEndpoint constructor.
|
||||||
|
auto endpoint_impl = static_cast<EmulatedEndpointImpl*>(endpoint);
|
||||||
|
stats_builder.AddEmulatedNetworkStats(endpoint_impl->stats());
|
||||||
}
|
}
|
||||||
stats_callback(stats_builder.Build());
|
stats_callback(stats_builder.Build());
|
||||||
});
|
});
|
||||||
|
|||||||
@ -84,6 +84,9 @@ class NetworkEmulationManagerImpl : public NetworkEmulationManager {
|
|||||||
void GetStats(rtc::ArrayView<EmulatedEndpoint* const> endpoints,
|
void GetStats(rtc::ArrayView<EmulatedEndpoint* const> endpoints,
|
||||||
std::function<void(std::unique_ptr<EmulatedNetworkStats>)>
|
std::function<void(std::unique_ptr<EmulatedNetworkStats>)>
|
||||||
stats_callback) override;
|
stats_callback) override;
|
||||||
|
void GetStats(
|
||||||
|
rtc::ArrayView<EmulatedEndpoint* const> endpoints,
|
||||||
|
std::function<void(EmulatedNetworkStats)> stats_callback) override;
|
||||||
|
|
||||||
TimeController* time_controller() override { return time_controller_.get(); }
|
TimeController* time_controller() override { return time_controller_.get(); }
|
||||||
|
|
||||||
|
|||||||
@ -254,79 +254,81 @@ TEST(NetworkEmulationManagerTest, Run) {
|
|||||||
nt1->GetStats([&](std::unique_ptr<EmulatedNetworkStats> st) {
|
nt1->GetStats([&](std::unique_ptr<EmulatedNetworkStats> st) {
|
||||||
EXPECT_EQ(st->PacketsSent(), 2000l);
|
EXPECT_EQ(st->PacketsSent(), 2000l);
|
||||||
EXPECT_EQ(st->BytesSent().bytes(), single_packet_size * 2000l);
|
EXPECT_EQ(st->BytesSent().bytes(), single_packet_size * 2000l);
|
||||||
EXPECT_THAT(st->LocalAddresses(),
|
EXPECT_THAT(st->local_addresses,
|
||||||
ElementsAreArray({alice_endpoint->GetPeerLocalAddress()}));
|
ElementsAreArray({alice_endpoint->GetPeerLocalAddress()}));
|
||||||
EXPECT_EQ(st->PacketsReceived(), 2000l);
|
EXPECT_EQ(st->PacketsReceived(), 2000l);
|
||||||
EXPECT_EQ(st->BytesReceived().bytes(), single_packet_size * 2000l);
|
EXPECT_EQ(st->BytesReceived().bytes(), single_packet_size * 2000l);
|
||||||
EXPECT_EQ(st->PacketsDropped(), 0l);
|
EXPECT_EQ(st->PacketsDiscardedNoReceiver(), 0l);
|
||||||
EXPECT_EQ(st->BytesDropped().bytes(), 0l);
|
EXPECT_EQ(st->BytesDiscardedNoReceiver().bytes(), 0l);
|
||||||
|
|
||||||
rtc::IPAddress bob_ip = bob_endpoint->GetPeerLocalAddress();
|
rtc::IPAddress bob_ip = bob_endpoint->GetPeerLocalAddress();
|
||||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
|
std::map<rtc::IPAddress, EmulatedNetworkIncomingStats> source_st =
|
||||||
source_st = st->IncomingStatsPerSource();
|
st->incoming_stats_per_source;
|
||||||
ASSERT_EQ(source_st.size(), 1lu);
|
ASSERT_EQ(source_st.size(), 1lu);
|
||||||
EXPECT_EQ(source_st.at(bob_ip)->PacketsReceived(), 2000l);
|
EXPECT_EQ(source_st.at(bob_ip).packets_received, 2000l);
|
||||||
EXPECT_EQ(source_st.at(bob_ip)->BytesReceived().bytes(),
|
EXPECT_EQ(source_st.at(bob_ip).bytes_received.bytes(),
|
||||||
single_packet_size * 2000l);
|
single_packet_size * 2000l);
|
||||||
EXPECT_EQ(source_st.at(bob_ip)->PacketsDropped(), 0l);
|
EXPECT_EQ(source_st.at(bob_ip).packets_discarded_no_receiver, 0l);
|
||||||
EXPECT_EQ(source_st.at(bob_ip)->BytesDropped().bytes(), 0l);
|
EXPECT_EQ(source_st.at(bob_ip).bytes_discarded_no_receiver.bytes(), 0l);
|
||||||
|
|
||||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
|
std::map<rtc::IPAddress, EmulatedNetworkOutgoingStats> dest_st =
|
||||||
dest_st = st->OutgoingStatsPerDestination();
|
st->outgoing_stats_per_destination;
|
||||||
ASSERT_EQ(dest_st.size(), 1lu);
|
ASSERT_EQ(dest_st.size(), 1lu);
|
||||||
EXPECT_EQ(dest_st.at(bob_ip)->PacketsSent(), 2000l);
|
EXPECT_EQ(dest_st.at(bob_ip).packets_sent, 2000l);
|
||||||
EXPECT_EQ(dest_st.at(bob_ip)->BytesSent().bytes(),
|
EXPECT_EQ(dest_st.at(bob_ip).bytes_sent.bytes(),
|
||||||
single_packet_size * 2000l);
|
single_packet_size * 2000l);
|
||||||
|
|
||||||
// No debug stats are collected by default.
|
// No debug stats are collected by default.
|
||||||
EXPECT_TRUE(st->SentPacketsSizeCounter().IsEmpty());
|
EXPECT_TRUE(st->SentPacketsSizeCounter().IsEmpty());
|
||||||
EXPECT_TRUE(st->SentPacketsQueueWaitTimeUs().IsEmpty());
|
EXPECT_TRUE(st->sent_packets_queue_wait_time_us.IsEmpty());
|
||||||
EXPECT_TRUE(st->ReceivedPacketsSizeCounter().IsEmpty());
|
EXPECT_TRUE(st->ReceivedPacketsSizeCounter().IsEmpty());
|
||||||
EXPECT_TRUE(st->DroppedPacketsSizeCounter().IsEmpty());
|
EXPECT_TRUE(st->PacketsDiscardedNoReceiverSizeCounter().IsEmpty());
|
||||||
EXPECT_TRUE(dest_st.at(bob_ip)->SentPacketsSizeCounter().IsEmpty());
|
EXPECT_TRUE(dest_st.at(bob_ip).sent_packets_size.IsEmpty());
|
||||||
EXPECT_TRUE(source_st.at(bob_ip)->ReceivedPacketsSizeCounter().IsEmpty());
|
EXPECT_TRUE(source_st.at(bob_ip).received_packets_size.IsEmpty());
|
||||||
EXPECT_TRUE(source_st.at(bob_ip)->DroppedPacketsSizeCounter().IsEmpty());
|
EXPECT_TRUE(
|
||||||
|
source_st.at(bob_ip).packets_discarded_no_receiver_size.IsEmpty());
|
||||||
|
|
||||||
received_stats_count++;
|
received_stats_count++;
|
||||||
});
|
});
|
||||||
nt2->GetStats([&](std::unique_ptr<EmulatedNetworkStats> st) {
|
nt2->GetStats([&](std::unique_ptr<EmulatedNetworkStats> st) {
|
||||||
EXPECT_EQ(st->PacketsSent(), 2000l);
|
EXPECT_EQ(st->PacketsSent(), 2000l);
|
||||||
EXPECT_EQ(st->BytesSent().bytes(), single_packet_size * 2000l);
|
EXPECT_EQ(st->BytesSent().bytes(), single_packet_size * 2000l);
|
||||||
EXPECT_THAT(st->LocalAddresses(),
|
EXPECT_THAT(st->local_addresses,
|
||||||
ElementsAreArray({bob_endpoint->GetPeerLocalAddress()}));
|
ElementsAreArray({bob_endpoint->GetPeerLocalAddress()}));
|
||||||
EXPECT_EQ(st->PacketsReceived(), 2000l);
|
EXPECT_EQ(st->PacketsReceived(), 2000l);
|
||||||
EXPECT_EQ(st->BytesReceived().bytes(), single_packet_size * 2000l);
|
EXPECT_EQ(st->BytesReceived().bytes(), single_packet_size * 2000l);
|
||||||
EXPECT_EQ(st->PacketsDropped(), 0l);
|
EXPECT_EQ(st->PacketsDiscardedNoReceiver(), 0l);
|
||||||
EXPECT_EQ(st->BytesDropped().bytes(), 0l);
|
EXPECT_EQ(st->BytesDiscardedNoReceiver().bytes(), 0l);
|
||||||
EXPECT_GT(st->FirstReceivedPacketSize(), DataSize::Zero());
|
EXPECT_GT(st->FirstReceivedPacketSize(), DataSize::Zero());
|
||||||
EXPECT_TRUE(st->FirstPacketReceivedTime().IsFinite());
|
EXPECT_TRUE(st->FirstPacketReceivedTime().IsFinite());
|
||||||
EXPECT_TRUE(st->LastPacketReceivedTime().IsFinite());
|
EXPECT_TRUE(st->LastPacketReceivedTime().IsFinite());
|
||||||
|
|
||||||
rtc::IPAddress alice_ip = alice_endpoint->GetPeerLocalAddress();
|
rtc::IPAddress alice_ip = alice_endpoint->GetPeerLocalAddress();
|
||||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
|
std::map<rtc::IPAddress, EmulatedNetworkIncomingStats> source_st =
|
||||||
source_st = st->IncomingStatsPerSource();
|
st->incoming_stats_per_source;
|
||||||
ASSERT_EQ(source_st.size(), 1lu);
|
ASSERT_EQ(source_st.size(), 1lu);
|
||||||
EXPECT_EQ(source_st.at(alice_ip)->PacketsReceived(), 2000l);
|
EXPECT_EQ(source_st.at(alice_ip).packets_received, 2000l);
|
||||||
EXPECT_EQ(source_st.at(alice_ip)->BytesReceived().bytes(),
|
EXPECT_EQ(source_st.at(alice_ip).bytes_received.bytes(),
|
||||||
single_packet_size * 2000l);
|
single_packet_size * 2000l);
|
||||||
EXPECT_EQ(source_st.at(alice_ip)->PacketsDropped(), 0l);
|
EXPECT_EQ(source_st.at(alice_ip).packets_discarded_no_receiver, 0l);
|
||||||
EXPECT_EQ(source_st.at(alice_ip)->BytesDropped().bytes(), 0l);
|
EXPECT_EQ(source_st.at(alice_ip).bytes_discarded_no_receiver.bytes(), 0l);
|
||||||
|
|
||||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
|
std::map<rtc::IPAddress, EmulatedNetworkOutgoingStats> dest_st =
|
||||||
dest_st = st->OutgoingStatsPerDestination();
|
st->outgoing_stats_per_destination;
|
||||||
ASSERT_EQ(dest_st.size(), 1lu);
|
ASSERT_EQ(dest_st.size(), 1lu);
|
||||||
EXPECT_EQ(dest_st.at(alice_ip)->PacketsSent(), 2000l);
|
EXPECT_EQ(dest_st.at(alice_ip).packets_sent, 2000l);
|
||||||
EXPECT_EQ(dest_st.at(alice_ip)->BytesSent().bytes(),
|
EXPECT_EQ(dest_st.at(alice_ip).bytes_sent.bytes(),
|
||||||
single_packet_size * 2000l);
|
single_packet_size * 2000l);
|
||||||
|
|
||||||
// No debug stats are collected by default.
|
// No debug stats are collected by default.
|
||||||
EXPECT_TRUE(st->SentPacketsSizeCounter().IsEmpty());
|
EXPECT_TRUE(st->SentPacketsSizeCounter().IsEmpty());
|
||||||
EXPECT_TRUE(st->SentPacketsQueueWaitTimeUs().IsEmpty());
|
EXPECT_TRUE(st->sent_packets_queue_wait_time_us.IsEmpty());
|
||||||
EXPECT_TRUE(st->ReceivedPacketsSizeCounter().IsEmpty());
|
EXPECT_TRUE(st->ReceivedPacketsSizeCounter().IsEmpty());
|
||||||
EXPECT_TRUE(st->DroppedPacketsSizeCounter().IsEmpty());
|
EXPECT_TRUE(st->PacketsDiscardedNoReceiverSizeCounter().IsEmpty());
|
||||||
EXPECT_TRUE(dest_st.at(alice_ip)->SentPacketsSizeCounter().IsEmpty());
|
EXPECT_TRUE(dest_st.at(alice_ip).sent_packets_size.IsEmpty());
|
||||||
EXPECT_TRUE(source_st.at(alice_ip)->ReceivedPacketsSizeCounter().IsEmpty());
|
EXPECT_TRUE(source_st.at(alice_ip).received_packets_size.IsEmpty());
|
||||||
EXPECT_TRUE(source_st.at(alice_ip)->DroppedPacketsSizeCounter().IsEmpty());
|
EXPECT_TRUE(
|
||||||
|
source_st.at(alice_ip).packets_discarded_no_receiver_size.IsEmpty());
|
||||||
|
|
||||||
received_stats_count++;
|
received_stats_count++;
|
||||||
});
|
});
|
||||||
@ -407,29 +409,29 @@ TEST(NetworkEmulationManagerTest, DebugStatsCollectedInDebugMode) {
|
|||||||
std::atomic<int> received_stats_count{0};
|
std::atomic<int> received_stats_count{0};
|
||||||
nt1->GetStats([&](std::unique_ptr<EmulatedNetworkStats> st) {
|
nt1->GetStats([&](std::unique_ptr<EmulatedNetworkStats> st) {
|
||||||
rtc::IPAddress bob_ip = bob_endpoint->GetPeerLocalAddress();
|
rtc::IPAddress bob_ip = bob_endpoint->GetPeerLocalAddress();
|
||||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
|
std::map<rtc::IPAddress, EmulatedNetworkIncomingStats> source_st =
|
||||||
source_st = st->IncomingStatsPerSource();
|
st->incoming_stats_per_source;
|
||||||
ASSERT_EQ(source_st.size(), 1lu);
|
ASSERT_EQ(source_st.size(), 1lu);
|
||||||
|
|
||||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
|
std::map<rtc::IPAddress, EmulatedNetworkOutgoingStats> dest_st =
|
||||||
dest_st = st->OutgoingStatsPerDestination();
|
st->outgoing_stats_per_destination;
|
||||||
ASSERT_EQ(dest_st.size(), 1lu);
|
ASSERT_EQ(dest_st.size(), 1lu);
|
||||||
|
|
||||||
// No debug stats are collected by default.
|
// No debug stats are collected by default.
|
||||||
EXPECT_EQ(st->SentPacketsSizeCounter().NumSamples(), 2000l);
|
EXPECT_EQ(st->SentPacketsSizeCounter().NumSamples(), 2000l);
|
||||||
EXPECT_EQ(st->ReceivedPacketsSizeCounter().GetAverage(),
|
EXPECT_EQ(st->ReceivedPacketsSizeCounter().GetAverage(),
|
||||||
single_packet_size);
|
single_packet_size);
|
||||||
EXPECT_EQ(st->SentPacketsQueueWaitTimeUs().NumSamples(), 2000l);
|
EXPECT_EQ(st->sent_packets_queue_wait_time_us.NumSamples(), 2000l);
|
||||||
EXPECT_LT(st->SentPacketsQueueWaitTimeUs().GetMax(), 1);
|
EXPECT_LT(st->sent_packets_queue_wait_time_us.GetMax(), 1);
|
||||||
EXPECT_TRUE(st->DroppedPacketsSizeCounter().IsEmpty());
|
EXPECT_TRUE(st->PacketsDiscardedNoReceiverSizeCounter().IsEmpty());
|
||||||
EXPECT_EQ(dest_st.at(bob_ip)->SentPacketsSizeCounter().NumSamples(), 2000l);
|
EXPECT_EQ(dest_st.at(bob_ip).sent_packets_size.NumSamples(), 2000l);
|
||||||
EXPECT_EQ(dest_st.at(bob_ip)->SentPacketsSizeCounter().GetAverage(),
|
EXPECT_EQ(dest_st.at(bob_ip).sent_packets_size.GetAverage(),
|
||||||
single_packet_size);
|
single_packet_size);
|
||||||
EXPECT_EQ(source_st.at(bob_ip)->ReceivedPacketsSizeCounter().NumSamples(),
|
EXPECT_EQ(source_st.at(bob_ip).received_packets_size.NumSamples(), 2000l);
|
||||||
2000l);
|
EXPECT_EQ(source_st.at(bob_ip).received_packets_size.GetAverage(),
|
||||||
EXPECT_EQ(source_st.at(bob_ip)->ReceivedPacketsSizeCounter().GetAverage(),
|
|
||||||
single_packet_size);
|
single_packet_size);
|
||||||
EXPECT_TRUE(source_st.at(bob_ip)->DroppedPacketsSizeCounter().IsEmpty());
|
EXPECT_TRUE(
|
||||||
|
source_st.at(bob_ip).packets_discarded_no_receiver_size.IsEmpty());
|
||||||
|
|
||||||
received_stats_count++;
|
received_stats_count++;
|
||||||
});
|
});
|
||||||
@ -489,7 +491,7 @@ TEST(NetworkEmulationManagerTest, ThroughputStats) {
|
|||||||
SendTask(t1, [&] { s1->Connect(a2); });
|
SendTask(t1, [&] { s1->Connect(a2); });
|
||||||
SendTask(t2, [&] { s2->Connect(a1); });
|
SendTask(t2, [&] { s2->Connect(a1); });
|
||||||
|
|
||||||
// Send 11 packets, totalizing 1 second between the first and the last.
|
// Send 11 packets, totalizing 1 second between the first and the last->
|
||||||
const int kNumPacketsSent = 11;
|
const int kNumPacketsSent = 11;
|
||||||
const TimeDelta kDelay = TimeDelta::Millis(100);
|
const TimeDelta kDelay = TimeDelta::Millis(100);
|
||||||
for (int i = 0; i < kNumPacketsSent; i++) {
|
for (int i = 0; i < kNumPacketsSent; i++) {
|
||||||
|
|||||||
@ -49,13 +49,12 @@ void NetworkQualityMetricsReporter::Start(
|
|||||||
const TrackIdStreamInfoMap* /*reporter_helper*/) {
|
const TrackIdStreamInfoMap* /*reporter_helper*/) {
|
||||||
test_case_name_ = std::string(test_case_name);
|
test_case_name_ = std::string(test_case_name);
|
||||||
// Check that network stats are clean before test execution.
|
// Check that network stats are clean before test execution.
|
||||||
std::unique_ptr<EmulatedNetworkStats> alice_stats =
|
EmulatedNetworkStats alice_stats = PopulateStats(alice_network_);
|
||||||
PopulateStats(alice_network_);
|
RTC_CHECK_EQ(alice_stats.overall_outgoing_stats.packets_sent, 0);
|
||||||
RTC_CHECK_EQ(alice_stats->PacketsSent(), 0);
|
RTC_CHECK_EQ(alice_stats.overall_incoming_stats.packets_received, 0);
|
||||||
RTC_CHECK_EQ(alice_stats->PacketsReceived(), 0);
|
EmulatedNetworkStats bob_stats = PopulateStats(bob_network_);
|
||||||
std::unique_ptr<EmulatedNetworkStats> bob_stats = PopulateStats(bob_network_);
|
RTC_CHECK_EQ(bob_stats.overall_outgoing_stats.packets_sent, 0);
|
||||||
RTC_CHECK_EQ(bob_stats->PacketsSent(), 0);
|
RTC_CHECK_EQ(bob_stats.overall_incoming_stats.packets_received, 0);
|
||||||
RTC_CHECK_EQ(bob_stats->PacketsReceived(), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkQualityMetricsReporter::OnStatsReports(
|
void NetworkQualityMetricsReporter::OnStatsReports(
|
||||||
@ -85,15 +84,16 @@ void NetworkQualityMetricsReporter::OnStatsReports(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NetworkQualityMetricsReporter::StopAndReportResults() {
|
void NetworkQualityMetricsReporter::StopAndReportResults() {
|
||||||
std::unique_ptr<EmulatedNetworkStats> alice_stats =
|
EmulatedNetworkStats alice_stats = PopulateStats(alice_network_);
|
||||||
PopulateStats(alice_network_);
|
EmulatedNetworkStats bob_stats = PopulateStats(bob_network_);
|
||||||
std::unique_ptr<EmulatedNetworkStats> bob_stats = PopulateStats(bob_network_);
|
|
||||||
int64_t alice_packets_loss =
|
int64_t alice_packets_loss =
|
||||||
alice_stats->PacketsSent() - bob_stats->PacketsReceived();
|
alice_stats.overall_outgoing_stats.packets_sent -
|
||||||
|
bob_stats.overall_incoming_stats.packets_received;
|
||||||
int64_t bob_packets_loss =
|
int64_t bob_packets_loss =
|
||||||
bob_stats->PacketsSent() - alice_stats->PacketsReceived();
|
bob_stats.overall_outgoing_stats.packets_sent -
|
||||||
ReportStats("alice", std::move(alice_stats), alice_packets_loss);
|
alice_stats.overall_incoming_stats.packets_received;
|
||||||
ReportStats("bob", std::move(bob_stats), bob_packets_loss);
|
ReportStats("alice", alice_stats, alice_packets_loss);
|
||||||
|
ReportStats("bob", bob_stats, bob_packets_loss);
|
||||||
|
|
||||||
if (!webrtc::field_trial::IsEnabled(kUseStandardBytesStats)) {
|
if (!webrtc::field_trial::IsEnabled(kUseStandardBytesStats)) {
|
||||||
RTC_LOG(LS_ERROR)
|
RTC_LOG(LS_ERROR)
|
||||||
@ -106,13 +106,12 @@ void NetworkQualityMetricsReporter::StopAndReportResults() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<EmulatedNetworkStats>
|
EmulatedNetworkStats NetworkQualityMetricsReporter::PopulateStats(
|
||||||
NetworkQualityMetricsReporter::PopulateStats(
|
|
||||||
EmulatedNetworkManagerInterface* network) {
|
EmulatedNetworkManagerInterface* network) {
|
||||||
rtc::Event wait;
|
rtc::Event wait;
|
||||||
std::unique_ptr<EmulatedNetworkStats> stats;
|
EmulatedNetworkStats stats;
|
||||||
network->GetStats([&](std::unique_ptr<EmulatedNetworkStats> s) {
|
network->GetStats([&](std::unique_ptr<EmulatedNetworkStats> s) {
|
||||||
stats = std::move(s);
|
stats = *s;
|
||||||
wait.Set();
|
wait.Set();
|
||||||
});
|
});
|
||||||
bool stats_received = wait.Wait(kStatsWaitTimeout);
|
bool stats_received = wait.Wait(kStatsWaitTimeout);
|
||||||
@ -122,38 +121,43 @@ NetworkQualityMetricsReporter::PopulateStats(
|
|||||||
|
|
||||||
void NetworkQualityMetricsReporter::ReportStats(
|
void NetworkQualityMetricsReporter::ReportStats(
|
||||||
const std::string& network_label,
|
const std::string& network_label,
|
||||||
std::unique_ptr<EmulatedNetworkStats> stats,
|
const EmulatedNetworkStats& stats,
|
||||||
int64_t packet_loss) {
|
int64_t packet_loss) {
|
||||||
metrics_logger_->LogSingleValueMetric(
|
metrics_logger_->LogSingleValueMetric(
|
||||||
"bytes_sent", GetTestCaseName(network_label), stats->BytesSent().bytes(),
|
"bytes_sent", GetTestCaseName(network_label),
|
||||||
Unit::kBytes, ImprovementDirection::kNeitherIsBetter);
|
stats.overall_outgoing_stats.bytes_sent.bytes(), Unit::kBytes,
|
||||||
|
ImprovementDirection::kNeitherIsBetter);
|
||||||
metrics_logger_->LogSingleValueMetric(
|
metrics_logger_->LogSingleValueMetric(
|
||||||
"packets_sent", GetTestCaseName(network_label), stats->PacketsSent(),
|
"packets_sent", GetTestCaseName(network_label),
|
||||||
Unit::kUnitless, ImprovementDirection::kNeitherIsBetter);
|
stats.overall_outgoing_stats.packets_sent, Unit::kUnitless,
|
||||||
|
ImprovementDirection::kNeitherIsBetter);
|
||||||
metrics_logger_->LogSingleValueMetric(
|
metrics_logger_->LogSingleValueMetric(
|
||||||
"average_send_rate", GetTestCaseName(network_label),
|
"average_send_rate", GetTestCaseName(network_label),
|
||||||
stats->PacketsSent() >= 2 ? stats->AverageSendRate().kbps<double>() : 0,
|
stats.overall_outgoing_stats.packets_sent >= 2
|
||||||
|
? stats.overall_outgoing_stats.AverageSendRate().kbps<double>()
|
||||||
|
: 0,
|
||||||
Unit::kKilobitsPerSecond, ImprovementDirection::kNeitherIsBetter);
|
Unit::kKilobitsPerSecond, ImprovementDirection::kNeitherIsBetter);
|
||||||
metrics_logger_->LogSingleValueMetric(
|
metrics_logger_->LogSingleValueMetric(
|
||||||
"bytes_discarded_no_receiver", GetTestCaseName(network_label),
|
"bytes_discarded_no_receiver", GetTestCaseName(network_label),
|
||||||
stats->BytesDropped().bytes(), Unit::kBytes,
|
stats.overall_incoming_stats.bytes_discarded_no_receiver.bytes(),
|
||||||
ImprovementDirection::kNeitherIsBetter);
|
Unit::kBytes, ImprovementDirection::kNeitherIsBetter);
|
||||||
metrics_logger_->LogSingleValueMetric(
|
metrics_logger_->LogSingleValueMetric(
|
||||||
"packets_discarded_no_receiver", GetTestCaseName(network_label),
|
"packets_discarded_no_receiver", GetTestCaseName(network_label),
|
||||||
stats->PacketsDropped(), Unit::kUnitless,
|
stats.overall_incoming_stats.packets_discarded_no_receiver,
|
||||||
ImprovementDirection::kNeitherIsBetter);
|
Unit::kUnitless, ImprovementDirection::kNeitherIsBetter);
|
||||||
metrics_logger_->LogSingleValueMetric(
|
metrics_logger_->LogSingleValueMetric(
|
||||||
"bytes_received", GetTestCaseName(network_label),
|
"bytes_received", GetTestCaseName(network_label),
|
||||||
stats->BytesReceived().bytes(), Unit::kBytes,
|
stats.overall_incoming_stats.bytes_received.bytes(), Unit::kBytes,
|
||||||
ImprovementDirection::kNeitherIsBetter);
|
ImprovementDirection::kNeitherIsBetter);
|
||||||
metrics_logger_->LogSingleValueMetric(
|
metrics_logger_->LogSingleValueMetric(
|
||||||
"packets_received", GetTestCaseName(network_label),
|
"packets_received", GetTestCaseName(network_label),
|
||||||
stats->PacketsReceived(), Unit::kUnitless,
|
stats.overall_incoming_stats.packets_received, Unit::kUnitless,
|
||||||
ImprovementDirection::kNeitherIsBetter);
|
ImprovementDirection::kNeitherIsBetter);
|
||||||
metrics_logger_->LogSingleValueMetric(
|
metrics_logger_->LogSingleValueMetric(
|
||||||
"average_receive_rate", GetTestCaseName(network_label),
|
"average_receive_rate", GetTestCaseName(network_label),
|
||||||
stats->PacketsReceived() >= 2 ? stats->AverageReceiveRate().kbps<double>()
|
stats.overall_incoming_stats.packets_received >= 2
|
||||||
: 0,
|
? stats.overall_incoming_stats.AverageReceiveRate().kbps<double>()
|
||||||
|
: 0,
|
||||||
Unit::kKilobitsPerSecond, ImprovementDirection::kNeitherIsBetter);
|
Unit::kKilobitsPerSecond, ImprovementDirection::kNeitherIsBetter);
|
||||||
metrics_logger_->LogSingleValueMetric(
|
metrics_logger_->LogSingleValueMetric(
|
||||||
"sent_packets_loss", GetTestCaseName(network_label), packet_loss,
|
"sent_packets_loss", GetTestCaseName(network_label), packet_loss,
|
||||||
|
|||||||
@ -49,10 +49,10 @@ class NetworkQualityMetricsReporter
|
|||||||
DataSize payload_sent = DataSize::Zero();
|
DataSize payload_sent = DataSize::Zero();
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::unique_ptr<EmulatedNetworkStats> PopulateStats(
|
static EmulatedNetworkStats PopulateStats(
|
||||||
EmulatedNetworkManagerInterface* network);
|
EmulatedNetworkManagerInterface* network);
|
||||||
void ReportStats(const std::string& network_label,
|
void ReportStats(const std::string& network_label,
|
||||||
std::unique_ptr<EmulatedNetworkStats> stats,
|
const EmulatedNetworkStats& stats,
|
||||||
int64_t packet_loss);
|
int64_t packet_loss);
|
||||||
void ReportPCStats(const std::string& pc_label, const PCStats& stats);
|
void ReportPCStats(const std::string& pc_label, const PCStats& stats);
|
||||||
std::string GetTestCaseName(const std::string& network_label) const;
|
std::string GetTestCaseName(const std::string& network_label) const;
|
||||||
|
|||||||
@ -51,14 +51,13 @@ constexpr TimeDelta kStatsWaitTimeout = TimeDelta::Seconds(1);
|
|||||||
// in bytes sent or received.
|
// in bytes sent or received.
|
||||||
constexpr char kUseStandardBytesStats[] = "WebRTC-UseStandardBytesStats";
|
constexpr char kUseStandardBytesStats[] = "WebRTC-UseStandardBytesStats";
|
||||||
|
|
||||||
std::unique_ptr<EmulatedNetworkStats> PopulateStats(
|
EmulatedNetworkStats PopulateStats(std::vector<EmulatedEndpoint*> endpoints,
|
||||||
std::vector<EmulatedEndpoint*> endpoints,
|
NetworkEmulationManager* network_emulation) {
|
||||||
NetworkEmulationManager* network_emulation) {
|
|
||||||
rtc::Event stats_loaded;
|
rtc::Event stats_loaded;
|
||||||
std::unique_ptr<EmulatedNetworkStats> stats;
|
EmulatedNetworkStats stats;
|
||||||
network_emulation->GetStats(endpoints,
|
network_emulation->GetStats(endpoints,
|
||||||
[&](std::unique_ptr<EmulatedNetworkStats> s) {
|
[&](std::unique_ptr<EmulatedNetworkStats> s) {
|
||||||
stats = std::move(s);
|
stats = *s;
|
||||||
stats_loaded.Set();
|
stats_loaded.Set();
|
||||||
});
|
});
|
||||||
bool stats_received = stats_loaded.Wait(kStatsWaitTimeout);
|
bool stats_received = stats_loaded.Wait(kStatsWaitTimeout);
|
||||||
@ -106,10 +105,10 @@ void StatsBasedNetworkQualityMetricsReporter::NetworkLayerStatsCollector::
|
|||||||
MutexLock lock(&mutex_);
|
MutexLock lock(&mutex_);
|
||||||
// Check that network stats are clean before test execution.
|
// Check that network stats are clean before test execution.
|
||||||
for (const auto& entry : peer_endpoints_) {
|
for (const auto& entry : peer_endpoints_) {
|
||||||
std::unique_ptr<EmulatedNetworkStats> stats =
|
EmulatedNetworkStats stats =
|
||||||
PopulateStats(entry.second, network_emulation_);
|
PopulateStats(entry.second, network_emulation_);
|
||||||
RTC_CHECK_EQ(stats->PacketsSent(), 0);
|
RTC_CHECK_EQ(stats.overall_outgoing_stats.packets_sent, 0);
|
||||||
RTC_CHECK_EQ(stats->PacketsReceived(), 0);
|
RTC_CHECK_EQ(stats.overall_incoming_stats.packets_received, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,7 +139,7 @@ StatsBasedNetworkQualityMetricsReporter::NetworkLayerStatsCollector::
|
|||||||
stats.stats = PopulateStats(entry.second, network_emulation_);
|
stats.stats = PopulateStats(entry.second, network_emulation_);
|
||||||
const std::string& peer_name = entry.first;
|
const std::string& peer_name = entry.first;
|
||||||
for (const auto& income_stats_entry :
|
for (const auto& income_stats_entry :
|
||||||
stats.stats->IncomingStatsPerSource()) {
|
stats.stats.incoming_stats_per_source) {
|
||||||
const rtc::IPAddress& source_ip = income_stats_entry.first;
|
const rtc::IPAddress& source_ip = income_stats_entry.first;
|
||||||
auto it = ip_to_peer_.find(source_ip);
|
auto it = ip_to_peer_.find(source_ip);
|
||||||
if (it == ip_to_peer_.end()) {
|
if (it == ip_to_peer_.end()) {
|
||||||
@ -257,12 +256,14 @@ void StatsBasedNetworkQualityMetricsReporter::ReportStats(
|
|||||||
{MetricMetadataKey::kPeerMetadataKey, pc_label}};
|
{MetricMetadataKey::kPeerMetadataKey, pc_label}};
|
||||||
metrics_logger_->LogSingleValueMetric(
|
metrics_logger_->LogSingleValueMetric(
|
||||||
"bytes_discarded_no_receiver", GetTestCaseName(pc_label),
|
"bytes_discarded_no_receiver", GetTestCaseName(pc_label),
|
||||||
network_layer_stats.stats->BytesDropped().bytes(), Unit::kBytes,
|
network_layer_stats.stats.overall_incoming_stats
|
||||||
ImprovementDirection::kNeitherIsBetter, metric_metadata);
|
.bytes_discarded_no_receiver.bytes(),
|
||||||
|
Unit::kBytes, ImprovementDirection::kNeitherIsBetter, metric_metadata);
|
||||||
metrics_logger_->LogSingleValueMetric(
|
metrics_logger_->LogSingleValueMetric(
|
||||||
"packets_discarded_no_receiver", GetTestCaseName(pc_label),
|
"packets_discarded_no_receiver", GetTestCaseName(pc_label),
|
||||||
network_layer_stats.stats->PacketsDropped(), Unit::kUnitless,
|
network_layer_stats.stats.overall_incoming_stats
|
||||||
ImprovementDirection::kNeitherIsBetter, metric_metadata);
|
.packets_discarded_no_receiver,
|
||||||
|
Unit::kUnitless, ImprovementDirection::kNeitherIsBetter, metric_metadata);
|
||||||
|
|
||||||
metrics_logger_->LogSingleValueMetric(
|
metrics_logger_->LogSingleValueMetric(
|
||||||
"payload_bytes_received", GetTestCaseName(pc_label),
|
"payload_bytes_received", GetTestCaseName(pc_label),
|
||||||
@ -311,101 +312,102 @@ std::string StatsBasedNetworkQualityMetricsReporter::GetTestCaseName(
|
|||||||
void StatsBasedNetworkQualityMetricsReporter::LogNetworkLayerStats(
|
void StatsBasedNetworkQualityMetricsReporter::LogNetworkLayerStats(
|
||||||
const std::string& peer_name,
|
const std::string& peer_name,
|
||||||
const NetworkLayerStats& stats) const {
|
const NetworkLayerStats& stats) const {
|
||||||
DataRate average_send_rate = stats.stats->PacketsSent() >= 2
|
DataRate average_send_rate =
|
||||||
? stats.stats->AverageSendRate()
|
stats.stats.overall_outgoing_stats.packets_sent >= 2
|
||||||
: DataRate::Zero();
|
? stats.stats.overall_outgoing_stats.AverageSendRate()
|
||||||
DataRate average_receive_rate = stats.stats->PacketsReceived() >= 2
|
: DataRate::Zero();
|
||||||
? stats.stats->AverageReceiveRate()
|
DataRate average_receive_rate =
|
||||||
: DataRate::Zero();
|
stats.stats.overall_incoming_stats.packets_received >= 2
|
||||||
|
? stats.stats.overall_incoming_stats.AverageReceiveRate()
|
||||||
|
: DataRate::Zero();
|
||||||
std::map<std::string, std::string> metric_metadata{
|
std::map<std::string, std::string> metric_metadata{
|
||||||
{MetricMetadataKey::kPeerMetadataKey, peer_name}};
|
{MetricMetadataKey::kPeerMetadataKey, peer_name}};
|
||||||
rtc::StringBuilder log;
|
rtc::StringBuilder log;
|
||||||
log << "Raw network layer statistic for [" << peer_name << "]:\n"
|
log << "Raw network layer statistic for [" << peer_name << "]:\n"
|
||||||
<< "Local IPs:\n";
|
<< "Local IPs:\n";
|
||||||
std::vector<rtc::IPAddress> local_ips = stats.stats->LocalAddresses();
|
for (size_t i = 0; i < stats.stats.local_addresses.size(); ++i) {
|
||||||
for (size_t i = 0; i < local_ips.size(); ++i) {
|
log << " " << stats.stats.local_addresses[i].ToString() << "\n";
|
||||||
log << " " << local_ips[i].ToString() << "\n";
|
|
||||||
}
|
}
|
||||||
if (!stats.stats->SentPacketsSizeCounter().IsEmpty()) {
|
if (!stats.stats.overall_outgoing_stats.sent_packets_size.IsEmpty()) {
|
||||||
metrics_logger_->LogMetric(
|
metrics_logger_->LogMetric(
|
||||||
"sent_packets_size", GetTestCaseName(peer_name),
|
"sent_packets_size", GetTestCaseName(peer_name),
|
||||||
stats.stats->SentPacketsSizeCounter(), Unit::kBytes,
|
stats.stats.overall_outgoing_stats.sent_packets_size, Unit::kBytes,
|
||||||
ImprovementDirection::kNeitherIsBetter, metric_metadata);
|
ImprovementDirection::kNeitherIsBetter, metric_metadata);
|
||||||
}
|
}
|
||||||
if (!stats.stats->ReceivedPacketsSizeCounter().IsEmpty()) {
|
if (!stats.stats.overall_incoming_stats.received_packets_size.IsEmpty()) {
|
||||||
metrics_logger_->LogMetric(
|
metrics_logger_->LogMetric(
|
||||||
"received_packets_size", GetTestCaseName(peer_name),
|
"received_packets_size", GetTestCaseName(peer_name),
|
||||||
stats.stats->ReceivedPacketsSizeCounter(), Unit::kBytes,
|
stats.stats.overall_incoming_stats.received_packets_size, Unit::kBytes,
|
||||||
ImprovementDirection::kNeitherIsBetter, metric_metadata);
|
ImprovementDirection::kNeitherIsBetter, metric_metadata);
|
||||||
}
|
}
|
||||||
if (!stats.stats->DroppedPacketsSizeCounter().IsEmpty()) {
|
if (!stats.stats.overall_incoming_stats.packets_discarded_no_receiver_size
|
||||||
|
.IsEmpty()) {
|
||||||
metrics_logger_->LogMetric(
|
metrics_logger_->LogMetric(
|
||||||
"dropped_packets_size", GetTestCaseName(peer_name),
|
"packets_discarded_no_receiver_size", GetTestCaseName(peer_name),
|
||||||
stats.stats->DroppedPacketsSizeCounter(), Unit::kBytes,
|
stats.stats.overall_incoming_stats.packets_discarded_no_receiver_size,
|
||||||
ImprovementDirection::kNeitherIsBetter, metric_metadata);
|
Unit::kBytes, ImprovementDirection::kNeitherIsBetter, metric_metadata);
|
||||||
}
|
}
|
||||||
if (!stats.stats->SentPacketsQueueWaitTimeUs().IsEmpty()) {
|
if (!stats.stats.sent_packets_queue_wait_time_us.IsEmpty()) {
|
||||||
metrics_logger_->LogMetric(
|
metrics_logger_->LogMetric(
|
||||||
"sent_packets_queue_wait_time_us", GetTestCaseName(peer_name),
|
"sent_packets_queue_wait_time_us", GetTestCaseName(peer_name),
|
||||||
stats.stats->SentPacketsQueueWaitTimeUs(), Unit::kUnitless,
|
stats.stats.sent_packets_queue_wait_time_us, Unit::kUnitless,
|
||||||
ImprovementDirection::kNeitherIsBetter, metric_metadata);
|
ImprovementDirection::kNeitherIsBetter, metric_metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
log << "Send statistic:\n"
|
log << "Send statistic:\n"
|
||||||
<< " packets: " << stats.stats->PacketsSent()
|
<< " packets: " << stats.stats.overall_outgoing_stats.packets_sent
|
||||||
<< " bytes: " << stats.stats->BytesSent().bytes()
|
<< " bytes: " << stats.stats.overall_outgoing_stats.bytes_sent.bytes()
|
||||||
<< " avg_rate (bytes/sec): " << average_send_rate.bytes_per_sec()
|
<< " avg_rate (bytes/sec): " << average_send_rate.bytes_per_sec()
|
||||||
<< " avg_rate (bps): " << average_send_rate.bps() << "\n"
|
<< " avg_rate (bps): " << average_send_rate.bps() << "\n"
|
||||||
<< "Send statistic per destination:\n";
|
<< "Send statistic per destination:\n";
|
||||||
|
|
||||||
for (const auto& entry : stats.stats->OutgoingStatsPerDestination()) {
|
for (const auto& entry : stats.stats.outgoing_stats_per_destination) {
|
||||||
DataRate source_average_send_rate = entry.second->PacketsSent() >= 2
|
DataRate source_average_send_rate = entry.second.packets_sent >= 2
|
||||||
? entry.second->AverageSendRate()
|
? entry.second.AverageSendRate()
|
||||||
: DataRate::Zero();
|
: DataRate::Zero();
|
||||||
log << "(" << entry.first.ToString() << "):\n"
|
log << "(" << entry.first.ToString() << "):\n"
|
||||||
<< " packets: " << entry.second->PacketsSent()
|
<< " packets: " << entry.second.packets_sent
|
||||||
<< " bytes: " << entry.second->BytesSent().bytes()
|
<< " bytes: " << entry.second.bytes_sent.bytes()
|
||||||
<< " avg_rate (bytes/sec): " << source_average_send_rate.bytes_per_sec()
|
<< " avg_rate (bytes/sec): " << source_average_send_rate.bytes_per_sec()
|
||||||
<< " avg_rate (bps): " << source_average_send_rate.bps() << "\n";
|
<< " avg_rate (bps): " << source_average_send_rate.bps() << "\n";
|
||||||
if (!entry.second->SentPacketsSizeCounter().IsEmpty()) {
|
if (!entry.second.sent_packets_size.IsEmpty()) {
|
||||||
metrics_logger_->LogMetric(
|
metrics_logger_->LogMetric(
|
||||||
"sent_packets_size",
|
"sent_packets_size",
|
||||||
GetTestCaseName(peer_name + "/" + entry.first.ToString()),
|
GetTestCaseName(peer_name + "/" + entry.first.ToString()),
|
||||||
stats.stats->SentPacketsSizeCounter(), Unit::kBytes,
|
entry.second.sent_packets_size, Unit::kBytes,
|
||||||
ImprovementDirection::kNeitherIsBetter, metric_metadata);
|
ImprovementDirection::kNeitherIsBetter, metric_metadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log << "Receive statistic:\n"
|
log << "Receive statistic:\n"
|
||||||
<< " packets: " << stats.stats->PacketsReceived()
|
<< " packets: " << stats.stats.overall_incoming_stats.packets_received
|
||||||
<< " bytes: " << stats.stats->BytesReceived().bytes()
|
<< " bytes: " << stats.stats.overall_incoming_stats.bytes_received.bytes()
|
||||||
<< " avg_rate (bytes/sec): " << average_receive_rate.bytes_per_sec()
|
<< " avg_rate (bytes/sec): " << average_receive_rate.bytes_per_sec()
|
||||||
<< " avg_rate (bps): " << average_receive_rate.bps() << "\n"
|
<< " avg_rate (bps): " << average_receive_rate.bps() << "\n"
|
||||||
<< "Receive statistic per source:\n";
|
<< "Receive statistic per source:\n";
|
||||||
|
|
||||||
for (const auto& entry : stats.stats->IncomingStatsPerSource()) {
|
for (const auto& entry : stats.stats.incoming_stats_per_source) {
|
||||||
DataRate source_average_receive_rate =
|
DataRate source_average_receive_rate =
|
||||||
entry.second->PacketsReceived() >= 2
|
entry.second.packets_received >= 2 ? entry.second.AverageReceiveRate()
|
||||||
? entry.second->AverageReceiveRate()
|
: DataRate::Zero();
|
||||||
: DataRate::Zero();
|
|
||||||
log << "(" << entry.first.ToString() << "):\n"
|
log << "(" << entry.first.ToString() << "):\n"
|
||||||
<< " packets: " << entry.second->PacketsReceived()
|
<< " packets: " << entry.second.packets_received
|
||||||
<< " bytes: " << entry.second->BytesReceived().bytes()
|
<< " bytes: " << entry.second.bytes_received.bytes()
|
||||||
<< " avg_rate (bytes/sec): "
|
<< " avg_rate (bytes/sec): "
|
||||||
<< source_average_receive_rate.bytes_per_sec()
|
<< source_average_receive_rate.bytes_per_sec()
|
||||||
<< " avg_rate (bps): " << source_average_receive_rate.bps() << "\n";
|
<< " avg_rate (bps): " << source_average_receive_rate.bps() << "\n";
|
||||||
if (!entry.second->ReceivedPacketsSizeCounter().IsEmpty()) {
|
if (!entry.second.received_packets_size.IsEmpty()) {
|
||||||
metrics_logger_->LogMetric(
|
metrics_logger_->LogMetric(
|
||||||
"received_packets_size",
|
"received_packets_size",
|
||||||
GetTestCaseName(peer_name + "/" + entry.first.ToString()),
|
GetTestCaseName(peer_name + "/" + entry.first.ToString()),
|
||||||
stats.stats->ReceivedPacketsSizeCounter(), Unit::kBytes,
|
entry.second.received_packets_size, Unit::kBytes,
|
||||||
ImprovementDirection::kNeitherIsBetter, metric_metadata);
|
ImprovementDirection::kNeitherIsBetter, metric_metadata);
|
||||||
}
|
}
|
||||||
if (!entry.second->DroppedPacketsSizeCounter().IsEmpty()) {
|
if (!entry.second.packets_discarded_no_receiver_size.IsEmpty()) {
|
||||||
metrics_logger_->LogMetric(
|
metrics_logger_->LogMetric(
|
||||||
"dropped_packets_size",
|
"packets_discarded_no_receiver_size",
|
||||||
GetTestCaseName(peer_name + "/" + entry.first.ToString()),
|
GetTestCaseName(peer_name + "/" + entry.first.ToString()),
|
||||||
stats.stats->DroppedPacketsSizeCounter(), Unit::kBytes,
|
entry.second.packets_discarded_no_receiver_size, Unit::kBytes,
|
||||||
ImprovementDirection::kNeitherIsBetter, metric_metadata);
|
ImprovementDirection::kNeitherIsBetter, metric_metadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,7 +72,7 @@ class StatsBasedNetworkQualityMetricsReporter
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct NetworkLayerStats {
|
struct NetworkLayerStats {
|
||||||
std::unique_ptr<EmulatedNetworkStats> stats;
|
EmulatedNetworkStats stats;
|
||||||
std::set<std::string> receivers;
|
std::set<std::string> receivers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user