Provide per destination statistic for network outgoing stats
Network emulation layer provides per source split for incoming stats for endpoint. Do the same for outgoing stats per destination. Bug: webrtc:11756 Change-Id: I2369ae8906546c27133273b1be17ce74c253c6e8 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/180500 Reviewed-by: Christoffer Rodbro <crodbro@webrtc.org> Reviewed-by: Andrey Logvin <landrey@webrtc.org> Commit-Queue: Artem Titov <titovartem@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31820}
This commit is contained in:
parent
81bbd7199a
commit
14b46a77b2
@ -61,45 +61,66 @@ class EmulatedNetworkReceiverInterface {
|
||||
virtual void OnPacketReceived(EmulatedIpPacket packet) = 0;
|
||||
};
|
||||
|
||||
struct EmulatedNetworkIncomingStats {
|
||||
class EmulatedNetworkOutgoingStats {
|
||||
public:
|
||||
virtual ~EmulatedNetworkOutgoingStats() = default;
|
||||
|
||||
virtual int64_t PacketsSent() const = 0;
|
||||
|
||||
virtual DataSize BytesSent() const = 0;
|
||||
|
||||
virtual DataSize FirstSentPacketSize() const = 0;
|
||||
|
||||
// Returns time of the first packet sent or infinite value if no packets were
|
||||
// sent.
|
||||
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.
|
||||
virtual DataRate AverageSendRate() const = 0;
|
||||
};
|
||||
|
||||
class EmulatedNetworkIncomingStats {
|
||||
public:
|
||||
virtual ~EmulatedNetworkIncomingStats() = default;
|
||||
|
||||
// Total amount of packets received with or without destination.
|
||||
int64_t packets_received = 0;
|
||||
virtual int64_t PacketsReceived() const = 0;
|
||||
// Total amount of bytes in received packets.
|
||||
DataSize bytes_received = DataSize::Zero();
|
||||
virtual DataSize BytesReceived() const = 0;
|
||||
// Total amount of packets that were received, but no destination was found.
|
||||
int64_t packets_dropped = 0;
|
||||
virtual int64_t PacketsDropped() const = 0;
|
||||
// Total amount of bytes in dropped packets.
|
||||
DataSize bytes_dropped = DataSize::Zero();
|
||||
virtual DataSize BytesDropped() const = 0;
|
||||
|
||||
DataSize first_received_packet_size = DataSize::Zero();
|
||||
virtual DataSize FirstReceivedPacketSize() const = 0;
|
||||
|
||||
// Timestamps are initialized to different infinities for simplifying
|
||||
// computations. Client have to assume that it is some infinite value
|
||||
// if unset. Client mustn't consider sign of infinit value.
|
||||
Timestamp first_packet_received_time = Timestamp::PlusInfinity();
|
||||
Timestamp last_packet_received_time = Timestamp::MinusInfinity();
|
||||
// Returns time of the first packet received or infinite value if no packets
|
||||
// were received.
|
||||
virtual Timestamp FirstPacketReceivedTime() const = 0;
|
||||
|
||||
DataRate 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);
|
||||
}
|
||||
// Returns time of the last packet received or infinite value if no packets
|
||||
// were received.
|
||||
virtual Timestamp LastPacketReceivedTime() const = 0;
|
||||
|
||||
virtual DataRate AverageReceiveRate() const = 0;
|
||||
};
|
||||
|
||||
class EmulatedNetworkStats {
|
||||
public:
|
||||
virtual ~EmulatedNetworkStats() = default;
|
||||
|
||||
virtual int64_t PacketsSent() const = 0;
|
||||
|
||||
virtual DataSize BytesSent() const = 0;
|
||||
|
||||
// List of IP addresses that were used to send data considered in this stats
|
||||
// object.
|
||||
virtual std::vector<rtc::IPAddress> LocalAddresses() const = 0;
|
||||
|
||||
virtual int64_t PacketsSent() const = 0;
|
||||
|
||||
virtual DataSize BytesSent() const = 0;
|
||||
|
||||
virtual DataSize FirstSentPacketSize() const = 0;
|
||||
// Returns time of the first packet sent or infinite value if no packets were
|
||||
// sent.
|
||||
@ -128,7 +149,12 @@ class EmulatedNetworkStats {
|
||||
|
||||
virtual DataRate AverageReceiveRate() const = 0;
|
||||
|
||||
virtual std::map<rtc::IPAddress, EmulatedNetworkIncomingStats>
|
||||
virtual std::map<rtc::IPAddress,
|
||||
std::unique_ptr<EmulatedNetworkOutgoingStats>>
|
||||
OutgoingStatsPerDestination() const = 0;
|
||||
|
||||
virtual std::map<rtc::IPAddress,
|
||||
std::unique_ptr<EmulatedNetworkIncomingStats>>
|
||||
IncomingStatsPerSource() const = 0;
|
||||
};
|
||||
|
||||
|
||||
@ -20,36 +20,65 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
EmulatedNetworkIncomingStats EmulatedNetworkStatsImpl::GetOverallIncomingStats()
|
||||
const {
|
||||
EmulatedNetworkIncomingStats stats;
|
||||
DataRate EmulatedNetworkOutgoingStatsImpl::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 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_) {
|
||||
const EmulatedNetworkIncomingStats& source = entry.second;
|
||||
stats.packets_received += source.packets_received;
|
||||
stats.bytes_received += source.bytes_received;
|
||||
stats.packets_dropped += source.packets_dropped;
|
||||
stats.bytes_dropped += source.bytes_dropped;
|
||||
if (stats.first_packet_received_time > source.first_packet_received_time) {
|
||||
stats.first_packet_received_time = source.first_packet_received_time;
|
||||
stats.first_received_packet_size = source.first_received_packet_size;
|
||||
out.emplace(entry.first, std::make_unique<EmulatedNetworkIncomingStatsImpl>(
|
||||
*entry.second));
|
||||
}
|
||||
if (stats.last_packet_received_time < source.last_packet_received_time) {
|
||||
stats.last_packet_received_time = source.last_packet_received_time;
|
||||
}
|
||||
}
|
||||
return stats;
|
||||
return out;
|
||||
}
|
||||
|
||||
EmulatedNetworkStatsBuilder::EmulatedNetworkStatsBuilder() {
|
||||
sequence_checker_.Detach();
|
||||
std::unique_ptr<EmulatedNetworkOutgoingStats>
|
||||
EmulatedNetworkStatsImpl::GetOverallOutgoingStats() const {
|
||||
EmulatedNetworkOutgoingStatsBuilder builder;
|
||||
for (const auto& entry : outgoing_stats_per_destination_) {
|
||||
builder.AddOutgoingStats(*entry.second);
|
||||
}
|
||||
return builder.Build();
|
||||
}
|
||||
EmulatedNetworkStatsBuilder::EmulatedNetworkStatsBuilder(
|
||||
rtc::IPAddress local_ip) {
|
||||
local_addresses_.push_back(local_ip);
|
||||
|
||||
std::unique_ptr<EmulatedNetworkIncomingStats>
|
||||
EmulatedNetworkStatsImpl::GetOverallIncomingStats() const {
|
||||
EmulatedNetworkIncomingStatsBuilder builder;
|
||||
for (const auto& entry : incoming_stats_per_source_) {
|
||||
builder.AddIncomingStats(*entry.second);
|
||||
}
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
EmulatedNetworkOutgoingStatsBuilder::EmulatedNetworkOutgoingStatsBuilder() {
|
||||
sequence_checker_.Detach();
|
||||
}
|
||||
|
||||
void EmulatedNetworkStatsBuilder::OnPacketSent(Timestamp sent_time,
|
||||
void EmulatedNetworkOutgoingStatsBuilder::OnPacketSent(Timestamp sent_time,
|
||||
DataSize packet_size) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
RTC_CHECK_GE(packet_size, DataSize::Zero());
|
||||
@ -62,77 +91,150 @@ void EmulatedNetworkStatsBuilder::OnPacketSent(Timestamp sent_time,
|
||||
bytes_sent_ += packet_size;
|
||||
}
|
||||
|
||||
void EmulatedNetworkStatsBuilder::OnPacketDropped(rtc::IPAddress source_ip,
|
||||
void EmulatedNetworkOutgoingStatsBuilder::AddOutgoingStats(
|
||||
const EmulatedNetworkOutgoingStats& stats) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
packets_sent_ += stats.PacketsSent();
|
||||
bytes_sent_ += stats.BytesSent();
|
||||
if (first_packet_sent_time_ > stats.FirstPacketSentTime()) {
|
||||
first_packet_sent_time_ = stats.FirstPacketSentTime();
|
||||
first_sent_packet_size_ = stats.FirstSentPacketSize();
|
||||
}
|
||||
if (last_packet_sent_time_ < stats.LastPacketSentTime()) {
|
||||
last_packet_sent_time_ = stats.LastPacketSentTime();
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<EmulatedNetworkOutgoingStats>
|
||||
EmulatedNetworkOutgoingStatsBuilder::Build() const {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
return std::make_unique<EmulatedNetworkOutgoingStatsImpl>(
|
||||
packets_sent_, bytes_sent_, first_sent_packet_size_,
|
||||
first_packet_sent_time_, last_packet_sent_time_);
|
||||
}
|
||||
|
||||
EmulatedNetworkIncomingStatsBuilder::EmulatedNetworkIncomingStatsBuilder() {
|
||||
sequence_checker_.Detach();
|
||||
}
|
||||
|
||||
void EmulatedNetworkIncomingStatsBuilder::OnPacketDropped(
|
||||
DataSize packet_size) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
packets_dropped_++;
|
||||
bytes_dropped_ += packet_size;
|
||||
}
|
||||
|
||||
void EmulatedNetworkIncomingStatsBuilder::OnPacketReceived(
|
||||
Timestamp received_time,
|
||||
DataSize packet_size) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
RTC_CHECK_GE(packet_size, DataSize::Zero());
|
||||
EmulatedNetworkIncomingStats& source_stats =
|
||||
incoming_stats_per_source_[source_ip];
|
||||
source_stats.packets_dropped++;
|
||||
source_stats.bytes_dropped += packet_size;
|
||||
if (first_packet_received_time_.IsInfinite()) {
|
||||
first_packet_received_time_ = received_time;
|
||||
first_received_packet_size_ = packet_size;
|
||||
}
|
||||
last_packet_received_time_ = received_time;
|
||||
packets_received_++;
|
||||
bytes_received_ += packet_size;
|
||||
}
|
||||
|
||||
void EmulatedNetworkIncomingStatsBuilder::AddIncomingStats(
|
||||
const EmulatedNetworkIncomingStats& stats) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
packets_received_ += stats.PacketsReceived();
|
||||
bytes_received_ += stats.BytesReceived();
|
||||
packets_dropped_ += stats.PacketsDropped();
|
||||
bytes_dropped_ += stats.BytesDropped();
|
||||
if (first_packet_received_time_ > stats.FirstPacketReceivedTime()) {
|
||||
first_packet_received_time_ = stats.FirstPacketReceivedTime();
|
||||
first_received_packet_size_ = stats.FirstReceivedPacketSize();
|
||||
}
|
||||
if (last_packet_received_time_ < stats.LastPacketReceivedTime()) {
|
||||
last_packet_received_time_ = stats.LastPacketReceivedTime();
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<EmulatedNetworkIncomingStats>
|
||||
EmulatedNetworkIncomingStatsBuilder::Build() const {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
return std::make_unique<EmulatedNetworkIncomingStatsImpl>(
|
||||
packets_received_, bytes_received_, packets_dropped_, bytes_dropped_,
|
||||
first_received_packet_size_, first_packet_received_time_,
|
||||
last_packet_received_time_);
|
||||
}
|
||||
|
||||
EmulatedNetworkStatsBuilder::EmulatedNetworkStatsBuilder() {
|
||||
sequence_checker_.Detach();
|
||||
}
|
||||
|
||||
EmulatedNetworkStatsBuilder::EmulatedNetworkStatsBuilder(
|
||||
rtc::IPAddress local_ip) {
|
||||
local_addresses_.push_back(local_ip);
|
||||
sequence_checker_.Detach();
|
||||
}
|
||||
|
||||
void EmulatedNetworkStatsBuilder::OnPacketSent(Timestamp sent_time,
|
||||
rtc::IPAddress destination_ip,
|
||||
DataSize packet_size) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
outgoing_stats_per_destination_[destination_ip].OnPacketSent(sent_time,
|
||||
packet_size);
|
||||
}
|
||||
|
||||
void EmulatedNetworkStatsBuilder::OnPacketDropped(rtc::IPAddress source_ip,
|
||||
DataSize packet_size) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
incoming_stats_per_source_[source_ip].OnPacketDropped(packet_size);
|
||||
}
|
||||
|
||||
void EmulatedNetworkStatsBuilder::OnPacketReceived(Timestamp received_time,
|
||||
rtc::IPAddress source_ip,
|
||||
DataSize packet_size) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
RTC_CHECK_GE(packet_size, DataSize::Zero());
|
||||
EmulatedNetworkIncomingStats& source_stats =
|
||||
incoming_stats_per_source_[source_ip];
|
||||
if (source_stats.first_packet_received_time.IsInfinite()) {
|
||||
source_stats.first_packet_received_time = received_time;
|
||||
source_stats.first_received_packet_size = packet_size;
|
||||
}
|
||||
source_stats.last_packet_received_time = received_time;
|
||||
source_stats.packets_received++;
|
||||
source_stats.bytes_received += packet_size;
|
||||
incoming_stats_per_source_[source_ip].OnPacketReceived(received_time,
|
||||
packet_size);
|
||||
}
|
||||
|
||||
void EmulatedNetworkStatsBuilder::AppendEmulatedNetworkStats(
|
||||
std::unique_ptr<EmulatedNetworkStats> stats) {
|
||||
void EmulatedNetworkStatsBuilder::AddEmulatedNetworkStats(
|
||||
const EmulatedNetworkStats& stats) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
RTC_CHECK(stats);
|
||||
packets_sent_ += stats->PacketsSent();
|
||||
bytes_sent_ += stats->BytesSent();
|
||||
if (first_packet_sent_time_ > stats->FirstPacketSentTime()) {
|
||||
first_packet_sent_time_ = stats->FirstPacketSentTime();
|
||||
first_sent_packet_size_ = stats->FirstSentPacketSize();
|
||||
}
|
||||
if (last_packet_sent_time_ < stats->LastPacketSentTime()) {
|
||||
last_packet_sent_time_ = stats->LastPacketSentTime();
|
||||
}
|
||||
for (const rtc::IPAddress& addr : stats->LocalAddresses()) {
|
||||
|
||||
// Append IPs from other endpoints stats to the builder.
|
||||
for (const rtc::IPAddress& addr : stats.LocalAddresses()) {
|
||||
local_addresses_.push_back(addr);
|
||||
}
|
||||
|
||||
const std::map<rtc::IPAddress, EmulatedNetworkIncomingStats>
|
||||
incoming_stats_per_source = stats->IncomingStatsPerSource();
|
||||
// Add outgoing stats from other endpoints to the builder.
|
||||
const std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
|
||||
outgoing_stats_per_destination = stats.OutgoingStatsPerDestination();
|
||||
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.
|
||||
const std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
|
||||
incoming_stats_per_source = stats.IncomingStatsPerSource();
|
||||
for (const auto& entry : incoming_stats_per_source) {
|
||||
const EmulatedNetworkIncomingStats& source = entry.second;
|
||||
EmulatedNetworkIncomingStats& in_stats =
|
||||
incoming_stats_per_source_[entry.first];
|
||||
in_stats.packets_received += source.packets_received;
|
||||
in_stats.bytes_received += source.bytes_received;
|
||||
in_stats.packets_dropped += source.packets_dropped;
|
||||
in_stats.bytes_dropped += source.bytes_dropped;
|
||||
if (in_stats.first_packet_received_time >
|
||||
source.first_packet_received_time) {
|
||||
in_stats.first_packet_received_time = source.first_packet_received_time;
|
||||
in_stats.first_received_packet_size = source.first_received_packet_size;
|
||||
}
|
||||
if (in_stats.last_packet_received_time < source.last_packet_received_time) {
|
||||
in_stats.last_packet_received_time = source.last_packet_received_time;
|
||||
}
|
||||
incoming_stats_per_source_[entry.first].AddIncomingStats(*entry.second);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<EmulatedNetworkStats> EmulatedNetworkStatsBuilder::Build()
|
||||
const {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
|
||||
outgoing_stats;
|
||||
for (const auto& entry : outgoing_stats_per_destination_) {
|
||||
outgoing_stats.emplace(entry.first, entry.second.Build());
|
||||
}
|
||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
|
||||
incoming_stats;
|
||||
for (const auto& entry : incoming_stats_per_source_) {
|
||||
incoming_stats.emplace(entry.first, entry.second.Build());
|
||||
}
|
||||
return std::make_unique<EmulatedNetworkStatsImpl>(
|
||||
packets_sent_, bytes_sent_, local_addresses_, first_sent_packet_size_,
|
||||
first_packet_sent_time_, last_packet_sent_time_,
|
||||
incoming_stats_per_source_);
|
||||
local_addresses_, std::move(outgoing_stats), std::move(incoming_stats));
|
||||
}
|
||||
|
||||
void LinkEmulation::OnPacketReceived(EmulatedIpPacket packet) {
|
||||
@ -328,7 +430,7 @@ void EmulatedEndpointImpl::SendPacket(const rtc::SocketAddress& from,
|
||||
clock_->CurrentTime(), application_overhead);
|
||||
task_queue_->PostTask([this, packet = std::move(packet)]() mutable {
|
||||
RTC_DCHECK_RUN_ON(task_queue_);
|
||||
stats_builder_.OnPacketSent(clock_->CurrentTime(),
|
||||
stats_builder_.OnPacketSent(clock_->CurrentTime(), packet.to.ipaddr(),
|
||||
DataSize::Bytes(packet.ip_packet_size()));
|
||||
|
||||
router_.OnPacketReceived(std::move(packet));
|
||||
@ -476,7 +578,7 @@ std::vector<EmulatedEndpoint*> EndpointsContainer::endpoints() const {
|
||||
std::unique_ptr<EmulatedNetworkStats> EndpointsContainer::GetStats() const {
|
||||
EmulatedNetworkStatsBuilder stats_builder;
|
||||
for (auto* endpoint : endpoints_) {
|
||||
stats_builder.AppendEmulatedNetworkStats(endpoint->stats());
|
||||
stats_builder.AddEmulatedNetworkStats(*endpoint->stats());
|
||||
}
|
||||
return stats_builder.Build();
|
||||
}
|
||||
|
||||
@ -36,35 +36,33 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// This class is immutable and so is thread safe.
|
||||
class EmulatedNetworkStatsImpl final : public EmulatedNetworkStats {
|
||||
// This class is immutable and so thread safe.
|
||||
class EmulatedNetworkOutgoingStatsImpl final
|
||||
: public EmulatedNetworkOutgoingStats {
|
||||
public:
|
||||
EmulatedNetworkStatsImpl(
|
||||
int64_t packets_sent,
|
||||
EmulatedNetworkOutgoingStatsImpl(int64_t packets_sent,
|
||||
DataSize bytes_sent,
|
||||
std::vector<rtc::IPAddress> local_addresses,
|
||||
DataSize first_sent_packet_size,
|
||||
Timestamp first_packet_sent_time,
|
||||
Timestamp last_packet_sent_time,
|
||||
std::map<rtc::IPAddress, EmulatedNetworkIncomingStats>
|
||||
incoming_stats_per_source)
|
||||
Timestamp last_packet_sent_time)
|
||||
: packets_sent_(packets_sent),
|
||||
bytes_sent_(bytes_sent),
|
||||
local_addresses_(std::move(local_addresses)),
|
||||
first_sent_packet_size_(first_sent_packet_size),
|
||||
first_packet_sent_time_(first_packet_sent_time),
|
||||
last_packet_sent_time_(last_packet_sent_time),
|
||||
incoming_stats_per_source_(std::move(incoming_stats_per_source)) {}
|
||||
~EmulatedNetworkStatsImpl() override = default;
|
||||
last_packet_sent_time_(last_packet_sent_time) {}
|
||||
explicit EmulatedNetworkOutgoingStatsImpl(
|
||||
const EmulatedNetworkOutgoingStats& stats)
|
||||
: packets_sent_(stats.PacketsSent()),
|
||||
bytes_sent_(stats.BytesSent()),
|
||||
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_; }
|
||||
|
||||
std::vector<rtc::IPAddress> LocalAddresses() const override {
|
||||
return local_addresses_;
|
||||
}
|
||||
|
||||
DataSize FirstSentPacketSize() const override {
|
||||
return first_sent_packet_size_;
|
||||
}
|
||||
@ -77,64 +75,220 @@ class EmulatedNetworkStatsImpl final : public EmulatedNetworkStats {
|
||||
return last_packet_sent_time_;
|
||||
}
|
||||
|
||||
DataRate AverageSendRate() const override {
|
||||
RTC_DCHECK_GE(packets_sent_, 2);
|
||||
return (bytes_sent_ - first_sent_packet_size_) /
|
||||
(last_packet_sent_time_ - first_packet_sent_time_);
|
||||
}
|
||||
|
||||
int64_t PacketsReceived() const override {
|
||||
return GetOverallIncomingStats().packets_received;
|
||||
}
|
||||
|
||||
DataSize BytesReceived() const override {
|
||||
return GetOverallIncomingStats().bytes_received;
|
||||
}
|
||||
|
||||
int64_t PacketsDropped() const override {
|
||||
return GetOverallIncomingStats().packets_dropped;
|
||||
}
|
||||
|
||||
DataSize BytesDropped() const override {
|
||||
return GetOverallIncomingStats().bytes_dropped;
|
||||
}
|
||||
|
||||
DataSize FirstReceivedPacketSize() const override {
|
||||
return GetOverallIncomingStats().first_received_packet_size;
|
||||
}
|
||||
|
||||
Timestamp FirstPacketReceivedTime() const override {
|
||||
return GetOverallIncomingStats().first_packet_received_time;
|
||||
}
|
||||
|
||||
Timestamp LastPacketReceivedTime() const override {
|
||||
return GetOverallIncomingStats().last_packet_received_time;
|
||||
}
|
||||
|
||||
DataRate AverageReceiveRate() const override {
|
||||
return GetOverallIncomingStats().AverageReceiveRate();
|
||||
}
|
||||
|
||||
std::map<rtc::IPAddress, EmulatedNetworkIncomingStats>
|
||||
IncomingStatsPerSource() const override {
|
||||
return incoming_stats_per_source_;
|
||||
}
|
||||
DataRate AverageSendRate() const override;
|
||||
|
||||
private:
|
||||
EmulatedNetworkIncomingStats GetOverallIncomingStats() const;
|
||||
|
||||
const int64_t packets_sent_;
|
||||
const DataSize bytes_sent_;
|
||||
const std::vector<rtc::IPAddress> local_addresses_;
|
||||
|
||||
const DataSize first_sent_packet_size_;
|
||||
const Timestamp first_packet_sent_time_;
|
||||
const Timestamp last_packet_sent_time_;
|
||||
};
|
||||
|
||||
const std::map<rtc::IPAddress, EmulatedNetworkIncomingStats>
|
||||
// This class is immutable and so thread safe.
|
||||
class EmulatedNetworkIncomingStatsImpl final
|
||||
: public EmulatedNetworkIncomingStats {
|
||||
public:
|
||||
EmulatedNetworkIncomingStatsImpl(int64_t packets_received,
|
||||
DataSize bytes_received,
|
||||
int64_t packets_dropped,
|
||||
DataSize bytes_dropped,
|
||||
DataSize first_received_packet_size,
|
||||
Timestamp first_packet_received_time,
|
||||
Timestamp last_packet_received_time)
|
||||
: packets_received_(packets_received),
|
||||
bytes_received_(bytes_received),
|
||||
packets_dropped_(packets_dropped),
|
||||
bytes_dropped_(bytes_dropped),
|
||||
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()),
|
||||
packets_dropped_(stats.PacketsDropped()),
|
||||
bytes_dropped_(stats.BytesDropped()),
|
||||
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_; }
|
||||
|
||||
int64_t PacketsDropped() const override { return packets_dropped_; }
|
||||
|
||||
DataSize BytesDropped() const override { return bytes_dropped_; }
|
||||
|
||||
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 int64_t packets_dropped_;
|
||||
const DataSize bytes_dropped_;
|
||||
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,
|
||||
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)),
|
||||
outgoing_stats_per_destination_(
|
||||
std::move(outgoing_stats_per_destination)),
|
||||
incoming_stats_per_source_(std::move(incoming_stats_per_source)) {}
|
||||
~EmulatedNetworkStatsImpl() override = default;
|
||||
|
||||
std::vector<rtc::IPAddress> LocalAddresses() const override {
|
||||
return local_addresses_;
|
||||
}
|
||||
|
||||
int64_t PacketsSent() const override {
|
||||
return GetOverallOutgoingStats()->PacketsSent();
|
||||
}
|
||||
|
||||
DataSize BytesSent() const override {
|
||||
return GetOverallOutgoingStats()->BytesSent();
|
||||
}
|
||||
|
||||
DataSize FirstSentPacketSize() const override {
|
||||
return GetOverallOutgoingStats()->FirstSentPacketSize();
|
||||
}
|
||||
|
||||
Timestamp FirstPacketSentTime() const override {
|
||||
return GetOverallOutgoingStats()->FirstPacketSentTime();
|
||||
}
|
||||
|
||||
Timestamp LastPacketSentTime() const override {
|
||||
return GetOverallOutgoingStats()->LastPacketSentTime();
|
||||
}
|
||||
|
||||
DataRate AverageSendRate() const override {
|
||||
return GetOverallOutgoingStats()->AverageSendRate();
|
||||
}
|
||||
|
||||
int64_t PacketsReceived() const override {
|
||||
return GetOverallIncomingStats()->PacketsReceived();
|
||||
}
|
||||
|
||||
DataSize BytesReceived() const override {
|
||||
return GetOverallIncomingStats()->BytesReceived();
|
||||
}
|
||||
|
||||
int64_t PacketsDropped() const override {
|
||||
return GetOverallIncomingStats()->PacketsDropped();
|
||||
}
|
||||
|
||||
DataSize BytesDropped() const override {
|
||||
return GetOverallIncomingStats()->BytesDropped();
|
||||
}
|
||||
|
||||
DataSize FirstReceivedPacketSize() const override {
|
||||
return GetOverallIncomingStats()->FirstReceivedPacketSize();
|
||||
}
|
||||
|
||||
Timestamp FirstPacketReceivedTime() const override {
|
||||
return GetOverallIncomingStats()->FirstPacketReceivedTime();
|
||||
}
|
||||
|
||||
Timestamp LastPacketReceivedTime() const override {
|
||||
return GetOverallIncomingStats()->LastPacketReceivedTime();
|
||||
}
|
||||
|
||||
DataRate AverageReceiveRate() const override {
|
||||
return GetOverallIncomingStats()->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 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_;
|
||||
};
|
||||
|
||||
class EmulatedNetworkOutgoingStatsBuilder {
|
||||
public:
|
||||
EmulatedNetworkOutgoingStatsBuilder();
|
||||
|
||||
void OnPacketSent(Timestamp sent_time, DataSize packet_size);
|
||||
|
||||
void AddOutgoingStats(const EmulatedNetworkOutgoingStats& stats);
|
||||
|
||||
std::unique_ptr<EmulatedNetworkOutgoingStats> Build() const;
|
||||
|
||||
private:
|
||||
SequenceChecker sequence_checker_;
|
||||
|
||||
int64_t packets_sent_ RTC_GUARDED_BY(sequence_checker_) = 0;
|
||||
DataSize bytes_sent_ RTC_GUARDED_BY(sequence_checker_) = DataSize::Zero();
|
||||
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();
|
||||
};
|
||||
|
||||
class EmulatedNetworkIncomingStatsBuilder {
|
||||
public:
|
||||
EmulatedNetworkIncomingStatsBuilder();
|
||||
|
||||
void OnPacketDropped(DataSize packet_size);
|
||||
|
||||
void OnPacketReceived(Timestamp received_time, DataSize packet_size);
|
||||
|
||||
// Adds stats collected from another endpoints to the builder.
|
||||
void AddIncomingStats(const EmulatedNetworkIncomingStats& stats);
|
||||
|
||||
std::unique_ptr<EmulatedNetworkIncomingStats> Build() const;
|
||||
|
||||
private:
|
||||
SequenceChecker sequence_checker_;
|
||||
|
||||
int64_t packets_received_ RTC_GUARDED_BY(sequence_checker_) = 0;
|
||||
DataSize bytes_received_ RTC_GUARDED_BY(sequence_checker_) = DataSize::Zero();
|
||||
int64_t packets_dropped_ RTC_GUARDED_BY(sequence_checker_) = 0;
|
||||
DataSize bytes_dropped_ RTC_GUARDED_BY(sequence_checker_) = DataSize::Zero();
|
||||
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
|
||||
// thread. It may be created on another thread.
|
||||
class EmulatedNetworkStatsBuilder {
|
||||
@ -142,7 +296,9 @@ class EmulatedNetworkStatsBuilder {
|
||||
EmulatedNetworkStatsBuilder();
|
||||
explicit EmulatedNetworkStatsBuilder(rtc::IPAddress local_ip);
|
||||
|
||||
void OnPacketSent(Timestamp sent_time, DataSize packet_size);
|
||||
void OnPacketSent(Timestamp sent_time,
|
||||
rtc::IPAddress destination_ip,
|
||||
DataSize packet_size);
|
||||
|
||||
void OnPacketDropped(rtc::IPAddress source_ip, DataSize packet_size);
|
||||
|
||||
@ -150,26 +306,18 @@ class EmulatedNetworkStatsBuilder {
|
||||
rtc::IPAddress source_ip,
|
||||
DataSize packet_size);
|
||||
|
||||
void AppendEmulatedNetworkStats(std::unique_ptr<EmulatedNetworkStats> stats);
|
||||
void AddEmulatedNetworkStats(const EmulatedNetworkStats& stats);
|
||||
|
||||
std::unique_ptr<EmulatedNetworkStats> Build() const;
|
||||
|
||||
private:
|
||||
SequenceChecker sequence_checker_;
|
||||
|
||||
int64_t packets_sent_ RTC_GUARDED_BY(sequence_checker_) = 0;
|
||||
DataSize bytes_sent_ RTC_GUARDED_BY(sequence_checker_) = DataSize::Zero();
|
||||
std::vector<rtc::IPAddress> local_addresses_
|
||||
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();
|
||||
|
||||
std::map<rtc::IPAddress, EmulatedNetworkIncomingStats>
|
||||
std::map<rtc::IPAddress, EmulatedNetworkOutgoingStatsBuilder>
|
||||
outgoing_stats_per_destination_ RTC_GUARDED_BY(sequence_checker_);
|
||||
std::map<rtc::IPAddress, EmulatedNetworkIncomingStatsBuilder>
|
||||
incoming_stats_per_source_ RTC_GUARDED_BY(sequence_checker_);
|
||||
};
|
||||
|
||||
|
||||
@ -301,7 +301,7 @@ void NetworkEmulationManagerImpl::GetStats(
|
||||
task_queue_.PostTask([endpoints, stats_callback]() {
|
||||
EmulatedNetworkStatsBuilder stats_builder;
|
||||
for (auto* endpoint : endpoints) {
|
||||
stats_builder.AppendEmulatedNetworkStats(endpoint->stats());
|
||||
stats_builder.AddEmulatedNetworkStats(*endpoint->stats());
|
||||
}
|
||||
stats_callback(stats_builder.Build());
|
||||
});
|
||||
|
||||
@ -257,20 +257,22 @@ TEST(NetworkEmulationManagerTest, Run) {
|
||||
EXPECT_EQ(st->PacketsDropped(), 0l);
|
||||
EXPECT_EQ(st->BytesDropped().bytes(), 0l);
|
||||
|
||||
std::map<rtc::IPAddress, EmulatedNetworkIncomingStats> source_st =
|
||||
st->IncomingStatsPerSource();
|
||||
rtc::IPAddress bob_ip = bob_endpoint->GetPeerLocalAddress();
|
||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
|
||||
source_st = st->IncomingStatsPerSource();
|
||||
ASSERT_EQ(source_st.size(), 1lu);
|
||||
EXPECT_EQ(
|
||||
source_st.at(bob_endpoint->GetPeerLocalAddress()).packets_received,
|
||||
2000l);
|
||||
EXPECT_EQ(source_st.at(bob_endpoint->GetPeerLocalAddress())
|
||||
.bytes_received.bytes(),
|
||||
EXPECT_EQ(source_st.at(bob_ip)->PacketsReceived(), 2000l);
|
||||
EXPECT_EQ(source_st.at(bob_ip)->BytesReceived().bytes(),
|
||||
single_packet_size * 2000l);
|
||||
EXPECT_EQ(source_st.at(bob_ip)->PacketsDropped(), 0l);
|
||||
EXPECT_EQ(source_st.at(bob_ip)->BytesDropped().bytes(), 0l);
|
||||
|
||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
|
||||
dest_st = st->OutgoingStatsPerDestination();
|
||||
ASSERT_EQ(dest_st.size(), 1lu);
|
||||
EXPECT_EQ(dest_st.at(bob_ip)->PacketsSent(), 2000l);
|
||||
EXPECT_EQ(dest_st.at(bob_ip)->BytesSent().bytes(),
|
||||
single_packet_size * 2000l);
|
||||
EXPECT_EQ(source_st.at(bob_endpoint->GetPeerLocalAddress()).packets_dropped,
|
||||
0l);
|
||||
EXPECT_EQ(
|
||||
source_st.at(bob_endpoint->GetPeerLocalAddress()).bytes_dropped.bytes(),
|
||||
0l);
|
||||
received_stats_count++;
|
||||
});
|
||||
nt2->GetStats([&](std::unique_ptr<EmulatedNetworkStats> st) {
|
||||
@ -286,21 +288,22 @@ TEST(NetworkEmulationManagerTest, Run) {
|
||||
EXPECT_TRUE(st->FirstPacketReceivedTime().IsFinite());
|
||||
EXPECT_TRUE(st->LastPacketReceivedTime().IsFinite());
|
||||
|
||||
std::map<rtc::IPAddress, EmulatedNetworkIncomingStats> source_st =
|
||||
st->IncomingStatsPerSource();
|
||||
rtc::IPAddress alice_ip = alice_endpoint->GetPeerLocalAddress();
|
||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStats>>
|
||||
source_st = st->IncomingStatsPerSource();
|
||||
ASSERT_EQ(source_st.size(), 1lu);
|
||||
EXPECT_EQ(
|
||||
source_st.at(alice_endpoint->GetPeerLocalAddress()).packets_received,
|
||||
2000l);
|
||||
EXPECT_EQ(source_st.at(alice_endpoint->GetPeerLocalAddress())
|
||||
.bytes_received.bytes(),
|
||||
EXPECT_EQ(source_st.at(alice_ip)->PacketsReceived(), 2000l);
|
||||
EXPECT_EQ(source_st.at(alice_ip)->BytesReceived().bytes(),
|
||||
single_packet_size * 2000l);
|
||||
EXPECT_EQ(source_st.at(alice_ip)->PacketsDropped(), 0l);
|
||||
EXPECT_EQ(source_st.at(alice_ip)->BytesDropped().bytes(), 0l);
|
||||
|
||||
std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStats>>
|
||||
dest_st = st->OutgoingStatsPerDestination();
|
||||
ASSERT_EQ(dest_st.size(), 1lu);
|
||||
EXPECT_EQ(dest_st.at(alice_ip)->PacketsSent(), 2000l);
|
||||
EXPECT_EQ(dest_st.at(alice_ip)->BytesSent().bytes(),
|
||||
single_packet_size * 2000l);
|
||||
EXPECT_EQ(
|
||||
source_st.at(alice_endpoint->GetPeerLocalAddress()).packets_dropped,
|
||||
0l);
|
||||
EXPECT_EQ(source_st.at(alice_endpoint->GetPeerLocalAddress())
|
||||
.bytes_dropped.bytes(),
|
||||
0l);
|
||||
received_stats_count++;
|
||||
});
|
||||
ASSERT_EQ_SIMULATED_WAIT(received_stats_count.load(), 2,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user