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