• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 #include "test/pc/e2e/network_quality_metrics_reporter.h"
11 
12 #include <utility>
13 
14 #include "api/stats/rtc_stats.h"
15 #include "api/stats/rtcstats_objects.h"
16 #include "rtc_base/event.h"
17 #include "system_wrappers/include/field_trial.h"
18 #include "test/testsupport/perf_test.h"
19 
20 namespace webrtc {
21 namespace webrtc_pc_e2e {
22 namespace {
23 
24 constexpr int kStatsWaitTimeoutMs = 1000;
25 
26 // Field trial which controls whether to report standard-compliant bytes
27 // sent/received per stream.  If enabled, padding and headers are not included
28 // in bytes sent or received.
29 constexpr char kUseStandardBytesStats[] = "WebRTC-UseStandardBytesStats";
30 }
31 
Start(absl::string_view test_case_name,const TrackIdStreamInfoMap *)32 void NetworkQualityMetricsReporter::Start(
33     absl::string_view test_case_name,
34     const TrackIdStreamInfoMap* /*reporter_helper*/) {
35   test_case_name_ = std::string(test_case_name);
36   // Check that network stats are clean before test execution.
37   EmulatedNetworkStats alice_stats = PopulateStats(alice_network_);
38   RTC_CHECK_EQ(alice_stats.packets_sent, 0);
39   RTC_CHECK_EQ(alice_stats.PacketsReceived(), 0);
40   EmulatedNetworkStats bob_stats = PopulateStats(bob_network_);
41   RTC_CHECK_EQ(bob_stats.packets_sent, 0);
42   RTC_CHECK_EQ(bob_stats.PacketsReceived(), 0);
43 }
44 
OnStatsReports(absl::string_view pc_label,const rtc::scoped_refptr<const RTCStatsReport> & report)45 void NetworkQualityMetricsReporter::OnStatsReports(
46     absl::string_view pc_label,
47     const rtc::scoped_refptr<const RTCStatsReport>& report) {
48   DataSize payload_received = DataSize::Zero();
49   DataSize payload_sent = DataSize::Zero();
50 
51   auto inbound_stats = report->GetStatsOfType<RTCInboundRTPStreamStats>();
52   for (const auto& stat : inbound_stats) {
53     payload_received +=
54         DataSize::Bytes(stat->bytes_received.ValueOrDefault(0ul) +
55                         stat->header_bytes_received.ValueOrDefault(0ul));
56   }
57 
58   auto outbound_stats = report->GetStatsOfType<RTCOutboundRTPStreamStats>();
59   for (const auto& stat : outbound_stats) {
60     payload_sent +=
61         DataSize::Bytes(stat->bytes_sent.ValueOrDefault(0ul) +
62                         stat->header_bytes_sent.ValueOrDefault(0ul));
63   }
64 
65   MutexLock lock(&lock_);
66   PCStats& stats = pc_stats_[std::string(pc_label)];
67   stats.payload_received = payload_received;
68   stats.payload_sent = payload_sent;
69 }
70 
StopAndReportResults()71 void NetworkQualityMetricsReporter::StopAndReportResults() {
72   EmulatedNetworkStats alice_stats = PopulateStats(alice_network_);
73   EmulatedNetworkStats bob_stats = PopulateStats(bob_network_);
74   ReportStats("alice", alice_stats,
75               alice_stats.packets_sent - bob_stats.PacketsReceived());
76   ReportStats("bob", bob_stats,
77               bob_stats.packets_sent - alice_stats.PacketsReceived());
78 
79   if (!webrtc::field_trial::IsEnabled(kUseStandardBytesStats)) {
80     RTC_LOG(LS_ERROR)
81         << "Non-standard GetStats; \"payload\" counts include RTP headers";
82   }
83 
84   MutexLock lock(&lock_);
85   for (const auto& pair : pc_stats_) {
86     ReportPCStats(pair.first, pair.second);
87   }
88 }
89 
PopulateStats(EmulatedNetworkManagerInterface * network)90 EmulatedNetworkStats NetworkQualityMetricsReporter::PopulateStats(
91     EmulatedNetworkManagerInterface* network) {
92   rtc::Event wait;
93   EmulatedNetworkStats stats;
94   network->GetStats([&](const EmulatedNetworkStats& s) {
95     stats = s;
96     wait.Set();
97   });
98   bool stats_received = wait.Wait(kStatsWaitTimeoutMs);
99   RTC_CHECK(stats_received);
100   return stats;
101 }
102 
ReportStats(const std::string & network_label,const EmulatedNetworkStats & stats,int64_t packet_loss)103 void NetworkQualityMetricsReporter::ReportStats(
104     const std::string& network_label,
105     const EmulatedNetworkStats& stats,
106     int64_t packet_loss) {
107   ReportResult("bytes_sent", network_label, stats.bytes_sent.bytes(),
108                "sizeInBytes");
109   ReportResult("packets_sent", network_label, stats.packets_sent, "unitless");
110   ReportResult(
111       "average_send_rate", network_label,
112       stats.packets_sent >= 2 ? stats.AverageSendRate().bytes_per_sec() : 0,
113       "bytesPerSecond");
114   ReportResult("bytes_dropped", network_label, stats.BytesDropped().bytes(),
115                "sizeInBytes");
116   ReportResult("packets_dropped", network_label, stats.PacketsDropped(),
117                "unitless");
118   ReportResult("bytes_received", network_label, stats.BytesReceived().bytes(),
119                "sizeInBytes");
120   ReportResult("packets_received", network_label, stats.PacketsReceived(),
121                "unitless");
122   ReportResult("average_receive_rate", network_label,
123                stats.PacketsReceived() >= 2
124                    ? stats.AverageReceiveRate().bytes_per_sec()
125                    : 0,
126                "bytesPerSecond");
127   ReportResult("sent_packets_loss", network_label, packet_loss, "unitless");
128 }
129 
ReportPCStats(const std::string & pc_label,const PCStats & stats)130 void NetworkQualityMetricsReporter::ReportPCStats(const std::string& pc_label,
131                                                   const PCStats& stats) {
132   ReportResult("payload_bytes_received", pc_label,
133                stats.payload_received.bytes(), "sizeInBytes");
134   ReportResult("payload_bytes_sent", pc_label, stats.payload_sent.bytes(),
135                "sizeInBytes");
136 }
137 
ReportResult(const std::string & metric_name,const std::string & network_label,const double value,const std::string & unit) const138 void NetworkQualityMetricsReporter::ReportResult(
139     const std::string& metric_name,
140     const std::string& network_label,
141     const double value,
142     const std::string& unit) const {
143   test::PrintResult(metric_name, /*modifier=*/"",
144                     GetTestCaseName(network_label), value, unit,
145                     /*important=*/false);
146 }
147 
GetTestCaseName(const std::string & network_label) const148 std::string NetworkQualityMetricsReporter::GetTestCaseName(
149     const std::string& network_label) const {
150   return test_case_name_ + "/" + network_label;
151 }
152 
153 }  // namespace webrtc_pc_e2e
154 }  // namespace webrtc
155